about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.bundler-audit.yml3
-rw-r--r--.circleci/config.yml109
-rw-r--r--.codeclimate.yml2
-rw-r--r--.devcontainer/devcontainer.json24
-rw-r--r--.eslintrc.js5
-rw-r--r--.github/workflows/build-image.yml2
-rw-r--r--.github/workflows/check-i18n.yml13
-rw-r--r--.github/workflows/lint-css.yml3
-rw-r--r--.github/workflows/lint-js.yml3
-rw-r--r--.github/workflows/lint-json.yml3
-rw-r--r--.github/workflows/lint-ruby.yml34
-rw-r--r--.github/workflows/lint-yml.yml3
-rw-r--r--.github/workflows/rebase-needed.yml5
-rw-r--r--.github/workflows/test-js.yml41
-rw-r--r--.github/workflows/test-migrations-one-step.yml100
-rw-r--r--.github/workflows/test-migrations-two-step.yml108
-rw-r--r--.prettierignore20
-rw-r--r--.rubocop.yml420
-rw-r--r--.rubocop_todo.yml3220
-rw-r--r--.ruby-version2
-rw-r--r--Dockerfile2
-rw-r--r--Gemfile10
-rw-r--r--Gemfile.lock66
-rw-r--r--app/controllers/admin/dashboard_controller.rb12
-rw-r--r--app/controllers/admin/domain_blocks_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts/follower_accounts_controller.rb8
-rw-r--r--app/controllers/api/v1/accounts/following_accounts_controller.rb8
-rw-r--r--app/controllers/api/v1/accounts/statuses_controller.rb8
-rw-r--r--app/controllers/api/v1/admin/accounts_controller.rb4
-rw-r--r--app/controllers/api/v1/announcements_controller.rb4
-rw-r--r--app/controllers/api/v1/blocks_controller.rb8
-rw-r--r--app/controllers/api/v1/conversations_controller.rb8
-rw-r--r--app/controllers/api/v1/domain_blocks_controller.rb8
-rw-r--r--app/controllers/api/v1/endorsements_controller.rb8
-rw-r--r--app/controllers/api/v1/favourites_controller.rb8
-rw-r--r--app/controllers/api/v1/follow_requests_controller.rb8
-rw-r--r--app/controllers/api/v1/lists/accounts_controller.rb8
-rw-r--r--app/controllers/api/v1/mutes_controller.rb8
-rw-r--r--app/controllers/api/v1/notifications_controller.rb8
-rw-r--r--app/controllers/api/v1/scheduled_statuses_controller.rb8
-rw-r--r--app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb8
-rw-r--r--app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb8
-rw-r--r--app/controllers/api/v1/trends/links_controller.rb12
-rw-r--r--app/controllers/api/v1/trends/statuses_controller.rb12
-rw-r--r--app/controllers/api/v1/trends/tags_controller.rb12
-rw-r--r--app/controllers/api/v2/admin/accounts_controller.rb4
-rw-r--r--app/controllers/auth/registrations_controller.rb4
-rw-r--r--app/controllers/auth/sessions_controller.rb4
-rw-r--r--app/controllers/concerns/rate_limit_headers.rb14
-rw-r--r--app/controllers/concerns/two_factor_authentication_concern.rb12
-rw-r--r--app/controllers/filters/statuses_controller.rb4
-rw-r--r--app/controllers/tags_controller.rb2
-rw-r--r--app/helpers/admin/dashboard_helper.rb24
-rw-r--r--app/helpers/admin/trends/statuses_helper.rb12
-rw-r--r--app/helpers/application_helper.rb4
-rw-r--r--app/helpers/branding_helper.rb14
-rw-r--r--app/helpers/domain_control_helper.rb12
-rw-r--r--app/helpers/formatting_helper.rb44
-rw-r--r--app/helpers/instance_helper.rb12
-rw-r--r--app/helpers/jsonld_helper.rb16
-rw-r--r--app/javascript/mastodon/actions/compose.js18
-rw-r--r--app/javascript/mastodon/components/autosuggest_input.js2
-rw-r--r--app/javascript/mastodon/locales/ar.json16
-rw-r--r--app/javascript/mastodon/locales/ast.json90
-rw-r--r--app/javascript/mastodon/locales/bg.json2
-rw-r--r--app/javascript/mastodon/locales/cy.json34
-rw-r--r--app/javascript/mastodon/locales/de.json8
-rw-r--r--app/javascript/mastodon/locales/el.json12
-rw-r--r--app/javascript/mastodon/locales/es-AR.json2
-rw-r--r--app/javascript/mastodon/locales/fo.json2
-rw-r--r--app/javascript/mastodon/locales/gd.json28
-rw-r--r--app/javascript/mastodon/locales/kab.json2
-rw-r--r--app/javascript/mastodon/locales/my.json468
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json4
-rw-r--r--app/javascript/mastodon/locales/ro.json20
-rw-r--r--app/javascript/mastodon/locales/sk.json2
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json2
-rw-r--r--app/javascript/mastodon/utils/notifications.js2
-rw-r--r--app/lib/activity_tracker.rb14
-rw-r--r--app/lib/activitypub/activity/create.rb42
-rw-r--r--app/lib/activitypub/forwarder.rb12
-rw-r--r--app/lib/activitypub/linked_data_signature.rb4
-rw-r--r--app/lib/activitypub/parser/media_attachment_parser.rb4
-rw-r--r--app/lib/admin/metrics/dimension/software_versions_dimension.rb12
-rw-r--r--app/lib/admin/metrics/dimension/space_usage_dimension.rb12
-rw-r--r--app/lib/extractor.rb14
-rw-r--r--app/lib/importer/statuses_index_importer.rb12
-rw-r--r--app/lib/link_details_extractor.rb30
-rw-r--r--app/lib/rate_limiter.rb2
-rw-r--r--app/lib/request.rb34
-rw-r--r--app/lib/status_finder.rb4
-rw-r--r--app/lib/translation_service/deepl.rb2
-rw-r--r--app/lib/webfinger.rb4
-rw-r--r--app/models/account.rb17
-rw-r--r--app/models/account/field.rb12
-rw-r--r--app/models/account_statuses_cleanup_policy.rb8
-rw-r--r--app/models/admin/account_action.rb12
-rw-r--r--app/models/announcement.rb12
-rw-r--r--app/models/backup.rb2
-rw-r--r--app/models/concerns/account_interactions.rb4
-rw-r--r--app/models/concerns/account_merging.rb16
-rw-r--r--app/models/concerns/expireable.rb2
-rw-r--r--app/models/concerns/omniauthable.rb4
-rw-r--r--app/models/concerns/paginable.rb4
-rw-r--r--app/models/concerns/pam_authenticable.rb12
-rw-r--r--app/models/email_domain_block.rb12
-rw-r--r--app/models/form/admin_settings.rb12
-rw-r--r--app/models/form/custom_emoji_batch.rb12
-rw-r--r--app/models/notification.rb12
-rw-r--r--app/models/remote_follow.rb12
-rw-r--r--app/models/status.rb17
-rw-r--r--app/models/status_edit.rb14
-rw-r--r--app/models/system_key.rb2
-rw-r--r--app/models/tag.rb2
-rw-r--r--app/models/trends/links.rb24
-rw-r--r--app/models/trends/statuses.rb26
-rw-r--r--app/models/trends/tag_filter.rb12
-rw-r--r--app/models/trends/tags.rb12
-rw-r--r--app/models/web/push_subscription.rb24
-rw-r--r--app/models/webauthn_credential.rb2
-rw-r--r--app/presenters/tag_relationships_presenter.rb12
-rw-r--r--app/serializers/initial_state_serializer.rb5
-rw-r--r--app/serializers/rest/account_serializer.rb8
-rw-r--r--app/serializers/rest/instance_serializer.rb4
-rw-r--r--app/services/account_search_service.rb16
-rw-r--r--app/services/activitypub/fetch_featured_tags_collection_service.rb14
-rw-r--r--app/services/activitypub/fetch_remote_actor_service.rb4
-rw-r--r--app/services/activitypub/fetch_remote_status_service.rb12
-rw-r--r--app/services/activitypub/fetch_replies_service.rb2
-rw-r--r--app/services/activitypub/process_status_update_service.rb4
-rw-r--r--app/services/backup_service.rb2
-rw-r--r--app/services/fetch_link_card_service.rb18
-rw-r--r--app/services/process_mentions_service.rb12
-rw-r--r--app/services/reblog_service.rb12
-rw-r--r--app/services/remove_from_followers_service.rb4
-rw-r--r--app/services/resolve_account_service.rb16
-rw-r--r--app/services/search_service.rb4
-rw-r--r--app/validators/domain_validator.rb12
-rw-r--r--app/validators/existing_username_validator.rb14
-rw-r--r--app/validators/import_validator.rb12
-rw-r--r--app/workers/backup_worker.rb10
-rw-r--r--app/workers/concerns/exponential_backoff.rb2
-rw-r--r--app/workers/post_process_media_worker.rb12
-rw-r--r--app/workers/scheduler/follow_recommendations_scheduler.rb12
-rw-r--r--config.ru2
-rw-r--r--config/locales/activerecord.de.yml6
-rw-r--r--config/locales/activerecord.el.yml13
-rw-r--r--config/locales/activerecord.my.yml34
-rw-r--r--config/locales/activerecord.zh-TW.yml2
-rw-r--r--config/locales/ar.yml33
-rw-r--r--config/locales/ast.yml83
-rw-r--r--config/locales/bg.yml10
-rw-r--r--config/locales/cy.yml18
-rw-r--r--config/locales/de.yml6
-rw-r--r--config/locales/devise.ar.yml4
-rw-r--r--config/locales/devise.ast.yml4
-rw-r--r--config/locales/devise.my.yml57
-rw-r--r--config/locales/devise.zh-TW.yml6
-rw-r--r--config/locales/doorkeeper.ar.yml1
-rw-r--r--config/locales/doorkeeper.ast.yml14
-rw-r--r--config/locales/doorkeeper.cy.yml6
-rw-r--r--config/locales/doorkeeper.el.yml19
-rw-r--r--config/locales/doorkeeper.gd.yml12
-rw-r--r--config/locales/doorkeeper.my.yml23
-rw-r--r--config/locales/el.yml32
-rw-r--r--config/locales/en-GB.yml42
-rw-r--r--config/locales/en.yml17
-rw-r--r--config/locales/fi.yml50
-rw-r--r--config/locales/gd.yml43
-rw-r--r--config/locales/he.yml2
-rw-r--r--config/locales/my.yml292
-rw-r--r--config/locales/nl.yml2
-rw-r--r--config/locales/pt-BR.yml2
-rw-r--r--config/locales/simple_form.ar.yml8
-rw-r--r--config/locales/simple_form.ast.yml31
-rw-r--r--config/locales/simple_form.be.yml1
-rw-r--r--config/locales/simple_form.bg.yml16
-rw-r--r--config/locales/simple_form.de.yml20
-rw-r--r--config/locales/simple_form.es.yml5
-rw-r--r--config/locales/simple_form.gd.yml12
-rw-r--r--config/locales/simple_form.pt-BR.yml1
-rw-r--r--config/locales/simple_form.zh-TW.yml2
-rw-r--r--config/locales/sk.yml9
-rw-r--r--config/locales/th.yml2
-rw-r--r--config/locales/zh-TW.yml112
-rw-r--r--config/routes.rb2
-rw-r--r--db/migrate/20160305115639_add_devise_to_users.rb2
-rw-r--r--db/migrate/20161006213403_rails_settings_migration.rb10
-rw-r--r--db/migrate/20161122163057_remove_unneeded_indexes.rb6
-rw-r--r--db/migrate/20170125145934_add_spoiler_text_to_statuses.rb2
-rw-r--r--db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb4
-rw-r--r--db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb4
-rw-r--r--db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb8
-rw-r--r--db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb4
-rw-r--r--db/migrate/20180528141303_fix_accounts_unique_index.rb16
-rw-r--r--db/migrate/20180617162849_remove_unused_indexes.rb6
-rw-r--r--db/migrate/20180812173710_copy_status_stats.rb12
-rw-r--r--db/migrate/20181116173541_copy_account_stats.rb12
-rw-r--r--db/migrate/20190306145741_add_lock_version_to_polls.rb1
-rw-r--r--db/migrate/20190807135426_add_comments_to_domain_blocks.rb1
-rw-r--r--db/migrate/20200312162302_add_status_ids_to_announcements.rb1
-rw-r--r--db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb1
-rw-r--r--db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb2
-rw-r--r--db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb2
-rw-r--r--db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb2
-rw-r--r--db/migrate/20200628133322_create_account_notes.rb1
-rw-r--r--db/migrate/20210306164523_account_ids_to_timestamp_ids.rb2
-rw-r--r--db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb2
-rw-r--r--db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb1
-rw-r--r--db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb2
-rw-r--r--jest.config.js29
-rw-r--r--lib/cli.rb2
-rw-r--r--lib/mastodon/accounts_cli.rb28
-rw-r--r--lib/mastodon/cli_helper.rb42
-rw-r--r--lib/mastodon/domains_cli.rb2
-rw-r--r--lib/mastodon/emoji_cli.rb2
-rw-r--r--lib/mastodon/ip_blocks_cli.rb12
-rw-r--r--lib/mastodon/maintenance_cli.rb84
-rw-r--r--lib/mastodon/media_cli.rb16
-rw-r--r--lib/mastodon/migration_helpers.rb4
-rw-r--r--lib/mastodon/redis_config.rb4
-rw-r--r--lib/mastodon/search_cli.rb12
-rw-r--r--lib/mastodon/upgrade_cli.rb18
-rw-r--r--lib/paperclip/attachment_extensions.rb10
-rw-r--r--lib/paperclip/color_extractor.rb34
-rw-r--r--lib/rails/engine_extensions.rb2
-rw-r--r--lib/sanitize_ext/sanitize_config.rb12
-rw-r--r--lib/tasks/db.rake14
-rw-r--r--lib/tasks/mastodon.rake6
-rw-r--r--lib/tasks/statistics.rake2
-rw-r--r--package.json24
-rw-r--r--spec/config/initializers/rack_attack_spec.rb21
-rw-r--r--spec/controllers/accounts_controller_spec.rb2
-rw-r--r--spec/controllers/activitypub/collections_controller_spec.rb2
-rw-r--r--spec/controllers/activitypub/outboxes_controller_spec.rb2
-rw-r--r--spec/controllers/activitypub/replies_controller_spec.rb2
-rw-r--r--spec/controllers/admin/accounts_controller_spec.rb2
-rw-r--r--spec/controllers/admin/change_email_controller_spec.rb8
-rw-r--r--spec/controllers/admin/dashboard_controller_spec.rb8
-rw-r--r--spec/controllers/admin/domain_blocks_controller_spec.rb6
-rw-r--r--spec/controllers/admin/reports_controller_spec.rb1
-rw-r--r--spec/controllers/admin/resets_controller_spec.rb1
-rw-r--r--spec/controllers/api/v1/accounts/credentials_controller_spec.rb4
-rw-r--r--spec/controllers/api/v1/admin/accounts_controller_spec.rb2
-rw-r--r--spec/controllers/api/v1/apps_controller_spec.rb2
-rw-r--r--spec/controllers/api/v1/markers_controller_spec.rb4
-rw-r--r--spec/controllers/api/v1/push/subscriptions_controller_spec.rb6
-rw-r--r--spec/controllers/api/v1/reports_controller_spec.rb2
-rw-r--r--spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb2
-rw-r--r--spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb2
-rw-r--r--spec/controllers/api/v1/statuses_controller_spec.rb2
-rw-r--r--spec/controllers/api/v1/streaming_controller_spec.rb2
-rw-r--r--spec/controllers/api/v1/suggestions_controller_spec.rb2
-rw-r--r--spec/controllers/api/v2/admin/accounts_controller_spec.rb2
-rw-r--r--spec/controllers/api/v2/filters/statuses_controller_spec.rb4
-rw-r--r--spec/controllers/api/web/embeds_controller_spec.rb1
-rw-r--r--spec/controllers/api/web/push_subscriptions_controller_spec.rb6
-rw-r--r--spec/controllers/application_controller_spec.rb4
-rw-r--r--spec/controllers/auth/registrations_controller_spec.rb24
-rw-r--r--spec/controllers/auth/sessions_controller_spec.rb36
-rw-r--r--spec/controllers/authorize_interactions_controller_spec.rb1
-rw-r--r--spec/controllers/instance_actors_controller_spec.rb4
-rw-r--r--spec/controllers/intents_controller_spec.rb1
-rw-r--r--spec/controllers/oauth/authorized_applications_controller_spec.rb2
-rw-r--r--spec/controllers/settings/applications_controller_spec.rb29
-rw-r--r--spec/controllers/settings/imports_controller_spec.rb12
-rw-r--r--spec/controllers/settings/migrations_controller_spec.rb2
-rw-r--r--spec/controllers/settings/preferences/notifications_controller_spec.rb2
-rw-r--r--spec/controllers/settings/preferences/other_controller_spec.rb2
-rw-r--r--spec/controllers/settings/profiles_controller_spec.rb4
-rw-r--r--spec/controllers/settings/sessions_controller_spec.rb1
-rw-r--r--spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb1
-rw-r--r--spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb4
-rw-r--r--spec/controllers/shares_controller_spec.rb1
-rw-r--r--spec/controllers/statuses_cleanup_controller_spec.rb4
-rw-r--r--spec/controllers/statuses_controller_spec.rb2
-rw-r--r--spec/controllers/well_known/host_meta_controller_spec.rb12
-rw-r--r--spec/controllers/well_known/nodeinfo_controller_spec.rb4
-rw-r--r--spec/fabricators/account_moderation_note_fabricator.rb2
-rw-r--r--spec/fabricators/account_note_fabricator.rb2
-rw-r--r--spec/fabricators/account_stat_fabricator.rb6
-rw-r--r--spec/fabricators/account_tag_stat_fabricator.rb2
-rw-r--r--spec/fabricators/account_warning_preset_fabricator.rb2
-rw-r--r--spec/fabricators/admin_action_log_fabricator.rb2
-rw-r--r--spec/fabricators/canonical_email_block_fabricator.rb2
-rw-r--r--spec/fabricators/conversation_account_fabricator.rb2
-rw-r--r--spec/fabricators/custom_emoji_category_fabricator.rb2
-rw-r--r--spec/fabricators/custom_filter_keyword_fabricator.rb2
-rw-r--r--spec/fabricators/domain_allow_fabricator.rb2
-rw-r--r--spec/fabricators/encrypted_message_fabricator.rb4
-rw-r--r--spec/fabricators/identity_fabricator.rb4
-rw-r--r--spec/fabricators/ip_block_fabricator.rb10
-rw-r--r--spec/fabricators/list_fabricator.rb2
-rw-r--r--spec/fabricators/poll_vote_fabricator.rb2
-rw-r--r--spec/fabricators/relay_fabricator.rb2
-rw-r--r--spec/fabricators/report_fabricator.rb2
-rw-r--r--spec/fabricators/report_note_fabricator.rb2
-rw-r--r--spec/fabricators/session_activation_fabricator.rb2
-rw-r--r--spec/fabricators/status_edit_fabricator.rb6
-rw-r--r--spec/fabricators/status_fabricator.rb2
-rw-r--r--spec/fabricators/status_stat_fabricator.rb6
-rw-r--r--spec/fabricators/system_key_fabricator.rb1
-rw-r--r--spec/fabricators/user_fabricator.rb2
-rw-r--r--spec/fabricators/user_role_fabricator.rb4
-rw-r--r--spec/features/log_in_spec.rb22
-rw-r--r--spec/features/profile_spec.rb14
-rw-r--r--spec/helpers/accounts_helper_spec.rb8
-rw-r--r--spec/helpers/application_helper_spec.rb11
-rw-r--r--spec/helpers/jsonld_helper_spec.rb2
-rw-r--r--spec/lib/activitypub/activity/announce_spec.rb8
-rw-r--r--spec/lib/activitypub/activity/create_spec.rb15
-rw-r--r--spec/lib/activitypub/activity/flag_spec.rb2
-rw-r--r--spec/lib/extractor_spec.rb8
-rw-r--r--spec/lib/fast_ip_map_spec.rb2
-rw-r--r--spec/lib/feed_manager_spec.rb2
-rw-r--r--spec/lib/link_details_extractor_spec.rb124
-rw-r--r--spec/lib/request_spec.rb8
-rw-r--r--spec/lib/settings/extend_spec.rb2
-rw-r--r--spec/lib/status_filter_spec.rb1
-rw-r--r--spec/lib/text_formatter_spec.rb4
-rw-r--r--spec/lib/webfinger_resource_spec.rb28
-rw-r--r--spec/mailers/notification_mailer_spec.rb44
-rw-r--r--spec/mailers/user_mailer_spec.rb2
-rw-r--r--spec/models/account/field_spec.rb4
-rw-r--r--spec/models/account_alias_spec.rb1
-rw-r--r--spec/models/account_spec.rb59
-rw-r--r--spec/models/account_statuses_cleanup_policy_spec.rb61
-rw-r--r--spec/models/concerns/account_interactions_spec.rb40
-rw-r--r--spec/models/custom_emoji_filter_spec.rb10
-rw-r--r--spec/models/custom_emoji_spec.rb2
-rw-r--r--spec/models/device_spec.rb1
-rw-r--r--spec/models/encrypted_message_spec.rb1
-rw-r--r--spec/models/export_spec.rb2
-rw-r--r--spec/models/import_spec.rb6
-rw-r--r--spec/models/login_activity_spec.rb1
-rw-r--r--spec/models/media_attachment_spec.rb22
-rw-r--r--spec/models/one_time_key_spec.rb1
-rw-r--r--spec/models/session_activation_spec.rb8
-rw-r--r--spec/models/setting_spec.rb6
-rw-r--r--spec/models/system_key_spec.rb1
-rw-r--r--spec/models/trends/statuses_spec.rb2
-rw-r--r--spec/models/user_role_spec.rb10
-rw-r--r--spec/models/user_spec.rb24
-rw-r--r--spec/models/web/push_subscription_spec.rb2
-rw-r--r--spec/models/webauthn_credentials_spec.rb4
-rw-r--r--spec/presenters/instance_presenter_spec.rb30
-rw-r--r--spec/rails_helper.rb4
-rw-r--r--spec/requests/catch_all_route_request_spec.rb20
-rw-r--r--spec/requests/host_meta_request_spec.rb10
-rw-r--r--spec/requests/localization_spec.rb6
-rw-r--r--spec/routing/api_routing_spec.rb72
-rw-r--r--spec/routing/well_known_routes_spec.rb20
-rw-r--r--spec/serializers/rest/account_serializer_spec.rb12
-rw-r--r--spec/services/account_search_service_spec.rb2
-rw-r--r--spec/services/account_statuses_cleanup_service_spec.rb4
-rw-r--r--spec/services/activitypub/fetch_featured_collection_service_spec.rb2
-rw-r--r--spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb2
-rw-r--r--spec/services/activitypub/fetch_remote_status_service_spec.rb44
-rw-r--r--spec/services/activitypub/fetch_replies_service_spec.rb2
-rw-r--r--spec/services/activitypub/process_account_service_spec.rb6
-rw-r--r--spec/services/activitypub/process_collection_service_spec.rb108
-rw-r--r--spec/services/activitypub/process_status_update_service_spec.rb46
-rw-r--r--spec/services/activitypub/synchronize_followers_service_spec.rb2
-rw-r--r--spec/services/bootstrap_timeline_service_spec.rb1
-rw-r--r--spec/services/delete_account_service_spec.rb12
-rw-r--r--spec/services/favourite_service_spec.rb4
-rw-r--r--spec/services/fetch_link_card_service_spec.rb8
-rw-r--r--spec/services/fetch_oembed_service_spec.rb9
-rw-r--r--spec/services/fetch_remote_status_service_spec.rb2
-rw-r--r--spec/services/fetch_resource_service_spec.rb13
-rw-r--r--spec/services/follow_service_spec.rb2
-rw-r--r--spec/services/import_service_spec.rb13
-rw-r--r--spec/services/post_status_service_spec.rb42
-rw-r--r--spec/services/precompute_feed_service_spec.rb1
-rw-r--r--spec/services/process_mentions_service_spec.rb8
-rw-r--r--spec/services/remove_from_follwers_service_spec.rb2
-rw-r--r--spec/services/remove_status_service_spec.rb68
-rw-r--r--spec/services/resolve_account_service_spec.rb20
-rw-r--r--spec/services/resolve_url_service_spec.rb2
-rw-r--r--spec/services/search_service_spec.rb2
-rw-r--r--spec/services/update_status_service_spec.rb2
-rw-r--r--spec/spec_helper.rb6
-rw-r--r--spec/support/matchers/model/model_have_error_on_field.rb4
-rw-r--r--spec/support/stories/profile_stories.rb4
-rw-r--r--spec/validators/note_length_validator_spec.rb4
-rw-r--r--spec/validators/poll_validator_spec.rb1
-rw-r--r--spec/validators/unreserved_username_validator_spec.rb6
-rw-r--r--spec/workers/activitypub/distribution_worker_spec.rb2
-rw-r--r--spec/workers/activitypub/move_distribution_worker_spec.rb8
-rw-r--r--spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb2
-rw-r--r--yarn.lock806
391 files changed, 6717 insertions, 3149 deletions
diff --git a/.bundler-audit.yml b/.bundler-audit.yml
new file mode 100644
index 000000000..f84ec8087
--- /dev/null
+++ b/.bundler-audit.yml
@@ -0,0 +1,3 @@
+---
+ignore:
+  - CVE-2015-9284 # Mitigation following https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284#mitigating-in-rails-applications
diff --git a/.circleci/config.yml b/.circleci/config.yml
index fabb6967e..3913a6b0f 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -46,7 +46,7 @@ commands:
           name: Set bundler settings
       - ruby/install-deps:
           bundler-version: '2.3.26'
-          key: ruby<< parameters.ruby-version >>-gems-v1
+          key: ruby<< parameters.ruby-version >>-gems-v2
   wait-db:
     steps:
       - run:
@@ -56,14 +56,14 @@ commands:
 jobs:
   build:
     docker:
-      - image: cimg/ruby:3.0-node
+      - image: cimg/ruby:3.2-node
         environment:
           RAILS_ENV: test
     steps:
       - checkout
       - install-system-dependencies
       - install-ruby-dependencies:
-          ruby-version: '3.0'
+          ruby-version: '3.2'
       - node/install-packages:
           cache-version: v1
           pkg-manager: yarn
@@ -95,7 +95,7 @@ jobs:
       - checkout
       - install-system-dependencies
       - run:
-          command: sudo apt-get install -y ffmpeg imagemagick libpam-dev
+          command: sudo apt-get install -y ffmpeg imagemagick libmagickcore-dev libmagickwand-dev libjpeg-dev libpng-dev libtiff-dev libwebp-dev libpam-dev
           name: Install additional system dependencies
       - run:
           command: bundle config with 'pam_authentication'
@@ -110,91 +110,6 @@ jobs:
           name: Load database schema
       - ruby/rspec-test
 
-  test-migrations:
-    executor:
-      name: default
-      ruby-version: '3.0'
-    steps:
-      - checkout
-      - install-system-dependencies
-      - install-ruby-dependencies:
-          ruby-version: '3.0'
-      - wait-db
-      - run:
-          command: ./bin/rails db:create
-          name: Create database
-      - run:
-          command: ./bin/rails db:migrate VERSION=20171010025614
-          name: Run migrations up to v2.0.0
-      - run:
-          command: ./bin/rails tests:migrations:populate_v2
-          name: Populate database with test data
-      - run:
-          command: ./bin/rails db:migrate VERSION=20180514140000
-          name: Run migrations up to v2.4.0
-      - run:
-          command: ./bin/rails tests:migrations:populate_v2_4
-          name: Populate database with test data
-      - run:
-          command: ./bin/rails db:migrate VERSION=20180707154237
-          name: Run migrations up to v2.4.3
-      - run:
-          command: ./bin/rails tests:migrations:populate_v2_4_3
-          name: Populate database with test data
-      - run:
-          command: ./bin/rails db:migrate
-          name: Run all remaining migrations
-      - run:
-          command: ./bin/rails tests:migrations:check_database
-          name: Check migration result
-
-  test-two-step-migrations:
-    executor:
-      name: default
-      ruby-version: '3.0'
-    steps:
-      - checkout
-      - install-system-dependencies
-      - install-ruby-dependencies:
-          ruby-version: '3.0'
-      - wait-db
-      - run:
-          command: ./bin/rails db:create
-          name: Create database
-      - run:
-          command: ./bin/rails db:migrate VERSION=20171010025614
-          name: Run migrations up to v2.0.0
-      - run:
-          command: ./bin/rails tests:migrations:populate_v2
-          name: Populate database with test data
-      - run:
-          command: ./bin/rails db:migrate VERSION=20180514140000
-          name: Run pre-deployment migrations up to v2.4.0
-          environment:
-            SKIP_POST_DEPLOYMENT_MIGRATIONS: true
-      - run:
-          command: ./bin/rails tests:migrations:populate_v2_4
-          name: Populate database with test data
-      - run:
-          command: ./bin/rails db:migrate VERSION=20180707154237
-          name: Run migrations up to v2.4.3
-          environment:
-            SKIP_POST_DEPLOYMENT_MIGRATIONS: true
-      - run:
-          command: ./bin/rails tests:migrations:populate_v2_4_3
-          name: Populate database with test data
-      - run:
-          command: ./bin/rails db:migrate
-          name: Run all remaining pre-deployment migrations
-          environment:
-            SKIP_POST_DEPLOYMENT_MIGRATIONS: true
-      - run:
-          command: ./bin/rails db:migrate
-          name: Run all post-deployment migrations
-      - run:
-          command: ./bin/rails tests:migrations:check_database
-          name: Check migration result
-
 workflows:
   version: 2
   build-and-test:
@@ -206,20 +121,8 @@ workflows:
               ruby-version:
                 - '2.7'
                 - '3.0'
+                - '3.1'
+                - '3.2'
           name: test-ruby<< matrix.ruby-version >>
           requires:
             - build
-      - test-migrations:
-          requires:
-            - build
-      - test-two-step-migrations:
-          requires:
-            - build
-      - node/run:
-          cache-version: v1
-          name: test-webui
-          pkg-manager: yarn
-          requires:
-            - build
-          version: '16.19'
-          yarn-run: test:jest
diff --git a/.codeclimate.yml b/.codeclimate.yml
index 59051aae7..00469df00 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -24,7 +24,7 @@ plugins:
   brakeman:
     enabled: true
   bundler-audit:
-    enabled: true
+    enabled: false
   eslint:
     enabled: false
   rubocop:
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index b98f6a21e..6ac6993ee 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -4,16 +4,22 @@
   "service": "app",
   "workspaceFolder": "/mastodon",
 
-  // Set *default* container specific settings.json values on container create.
-  "settings": {},
+  // Configure tool-specific properties.
+  "customizations": {
+    // Configure properties specific to VS Code.
+    "vscode": {
+      // Set *default* container specific settings.json values on container create.
+      "settings": {},
 
-  // Add the IDs of extensions you want installed when the container is created.
-  "extensions": [
-    "EditorConfig.EditorConfig",
-    "dbaeumer.vscode-eslint",
-    "rebornix.Ruby",
-    "webben.browserslist"
-  ],
+      // Add the IDs of extensions you want installed when the container is created.
+      "extensions": [
+        "EditorConfig.EditorConfig",
+        "dbaeumer.vscode-eslint",
+        "rebornix.Ruby",
+        "webben.browserslist"
+      ]
+    }
+  },
 
   "features": {
     "ghcr.io/devcontainers/features/sshd:1": {
diff --git a/.eslintrc.js b/.eslintrc.js
index 4d81aa47e..b5ab511f8 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -6,6 +6,7 @@ module.exports = {
     'plugin:react/recommended',
     'plugin:jsx-a11y/recommended',
     'plugin:import/recommended',
+    'plugin:promise/recommended',
   ],
 
   env: {
@@ -199,11 +200,15 @@ module.exports = {
     ],
     'import/no-webpack-loader-syntax': 'error',
 
+    'promise/always-return': 'off',
     'promise/catch-or-return': [
       'error',
       {
         allowFinally: true,
       },
     ],
+    'promise/no-callback-in-promise': 'off',
+    'promise/no-nesting': 'off',
+    'promise/no-promise-in-callback': 'off',
   },
 };
diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml
index 36e9bf370..c254418ea 100644
--- a/.github/workflows/build-image.yml
+++ b/.github/workflows/build-image.yml
@@ -17,7 +17,7 @@ jobs:
     runs-on: ubuntu-latest
 
     concurrency:
-      group: ${{ github.ref }}
+      group: ${{ github.workflow }}-${{ github.ref }}
       cancel-in-progress: true
 
     steps:
diff --git a/.github/workflows/check-i18n.yml b/.github/workflows/check-i18n.yml
index b2e619786..aa8f1f584 100644
--- a/.github/workflows/check-i18n.yml
+++ b/.github/workflows/check-i18n.yml
@@ -14,24 +14,35 @@ permissions:
 
 jobs:
   check-i18n:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v3
+
       - name: Install system dependencies
         run: |
           sudo apt-get update
           sudo apt-get install -y libicu-dev libidn11-dev
+
       - name: Set up Ruby
         uses: ruby/setup-ruby@v1
         with:
           ruby-version: .ruby-version
           bundler-cache: true
+
       - name: Check locale file normalization
         run: bundle exec i18n-tasks check-normalized
+
       - name: Check for unused strings
         run: bundle exec i18n-tasks unused
+
+      - name: Check for missing strings in English
+        run: |
+          bundle exec i18n-tasks add-missing -l en
+          git diff --exit-code
+
       - name: Check for wrong string interpolations
         run: bundle exec i18n-tasks check-consistent-interpolations
+
       - name: Check that all required locale files exist
         run: bundle exec rake repo:check_locales_files
diff --git a/.github/workflows/lint-css.yml b/.github/workflows/lint-css.yml
index 431b88e8d..e13d227bd 100644
--- a/.github/workflows/lint-css.yml
+++ b/.github/workflows/lint-css.yml
@@ -6,6 +6,7 @@ on:
     paths:
       - 'package.json'
       - 'yarn.lock'
+      - '.nvmrc'
       - '.prettier*'
       - 'stylelint.config.js'
       - '**/*.css'
@@ -17,6 +18,7 @@ on:
     paths:
       - 'package.json'
       - 'yarn.lock'
+      - '.nvmrc'
       - '.prettier*'
       - 'stylelint.config.js'
       - '**/*.css'
@@ -36,6 +38,7 @@ jobs:
         uses: actions/setup-node@v3
         with:
           cache: yarn
+          node-version-file: '.nvmrc'
 
       - name: Install all yarn packages
         run: yarn --frozen-lockfile
diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml
index 49d989771..3e0d9d1a9 100644
--- a/.github/workflows/lint-js.yml
+++ b/.github/workflows/lint-js.yml
@@ -6,6 +6,7 @@ on:
     paths:
       - 'package.json'
       - 'yarn.lock'
+      - '.nvmrc'
       - '.prettier*'
       - '.eslint*'
       - '**/*.js'
@@ -15,6 +16,7 @@ on:
     paths:
       - 'package.json'
       - 'yarn.lock'
+      - '.nvmrc'
       - '.prettier*'
       - '.eslint*'
       - '**/*.js'
@@ -32,6 +34,7 @@ jobs:
         uses: actions/setup-node@v3
         with:
           cache: yarn
+          node-version-file: '.nvmrc'
 
       - name: Install all yarn packages
         run: yarn --frozen-lockfile
diff --git a/.github/workflows/lint-json.yml b/.github/workflows/lint-json.yml
index 524ed083a..98f101ad9 100644
--- a/.github/workflows/lint-json.yml
+++ b/.github/workflows/lint-json.yml
@@ -6,6 +6,7 @@ on:
     paths:
       - 'package.json'
       - 'yarn.lock'
+      - '.nvmrc'
       - '.prettier*'
       - '**/*.json'
       - '.github/workflows/lint-json.yml'
@@ -15,6 +16,7 @@ on:
     paths:
       - 'package.json'
       - 'yarn.lock'
+      - '.nvmrc'
       - '.prettier*'
       - '**/*.json'
       - '.github/workflows/lint-json.yml'
@@ -32,6 +34,7 @@ jobs:
         uses: actions/setup-node@v3
         with:
           cache: yarn
+          node-version-file: '.nvmrc'
 
       - name: Install all yarn packages
         run: yarn --frozen-lockfile
diff --git a/.github/workflows/lint-ruby.yml b/.github/workflows/lint-ruby.yml
index b834e3053..de54fe9ae 100644
--- a/.github/workflows/lint-ruby.yml
+++ b/.github/workflows/lint-ruby.yml
@@ -5,7 +5,9 @@ on:
       - 'dependabot/**'
     paths:
       - 'Gemfile*'
-      - '.rubocop.yml'
+      - '.rubocop*.yml'
+      - '.ruby-version'
+      - '.bundler-audit.yml'
       - '**/*.rb'
       - '**/*.rake'
       - '.github/workflows/lint-ruby.yml'
@@ -13,7 +15,9 @@ on:
   pull_request:
     paths:
       - 'Gemfile*'
-      - '.rubocop.yml'
+      - '.rubocop*.yml'
+      - '.ruby-version'
+      - '.bundler-audit.yml'
       - '**/*.rb'
       - '**/*.rake'
       - '.github/workflows/lint-ruby.yml'
@@ -21,21 +25,25 @@ on:
 jobs:
   lint:
     runs-on: ubuntu-latest
+
     steps:
-      - name: Checkout Code
+      - name: Clone repository
         uses: actions/checkout@v3
+
+      - name: Install native Ruby dependencies
+        run: sudo apt-get install -y libicu-dev libidn11-dev
+
+      - name: Set up Ruby
+        uses: ruby/setup-ruby@v1
         with:
-          fetch-depth: 0
+          ruby-version: .ruby-version
+          bundler-cache: true
 
-      - name: Set-up RuboCop Problem Mathcher
+      - name: Set-up RuboCop Problem Matcher
         uses: r7kamura/rubocop-problem-matchers-action@v1
 
       - name: Run rubocop
-        uses: github/super-linter@v4
-        env:
-          DEFAULT_BRANCH: main
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          LINTER_RULES_PATH: .
-          RUBY_CONFIG_FILE: .rubocop.yml
-          VALIDATE_ALL_CODEBASE: false
-          VALIDATE_RUBY: true
+        run: bundle exec rubocop
+
+      - name: Run bundler-audit
+        run: bundle exec bundler-audit
diff --git a/.github/workflows/lint-yml.yml b/.github/workflows/lint-yml.yml
index 48f8170b3..6f79babcf 100644
--- a/.github/workflows/lint-yml.yml
+++ b/.github/workflows/lint-yml.yml
@@ -6,6 +6,7 @@ on:
     paths:
       - 'package.json'
       - 'yarn.lock'
+      - '.nvmrc'
       - '.prettier*'
       - '**/*.yaml'
       - '**/*.yml'
@@ -16,6 +17,7 @@ on:
     paths:
       - 'package.json'
       - 'yarn.lock'
+      - '.nvmrc'
       - '.prettier*'
       - '**/*.yaml'
       - '**/*.yml'
@@ -34,6 +36,7 @@ jobs:
         uses: actions/setup-node@v3
         with:
           cache: yarn
+          node-version-file: '.nvmrc'
 
       - name: Install all yarn packages
         run: yarn --frozen-lockfile
diff --git a/.github/workflows/rebase-needed.yml b/.github/workflows/rebase-needed.yml
index 6f903ee61..a5899e0f0 100644
--- a/.github/workflows/rebase-needed.yml
+++ b/.github/workflows/rebase-needed.yml
@@ -8,6 +8,11 @@ on:
 jobs:
   label-rebase-needed:
     runs-on: ubuntu-latest
+
+    concurrency:
+      group: ${{ github.workflow }}-${{ github.ref }}
+      cancel-in-progress: true
+
     steps:
       - name: Check for merge conflicts
         uses: eps1lon/actions-label-merge-conflict@releases/2.x
diff --git a/.github/workflows/test-js.yml b/.github/workflows/test-js.yml
new file mode 100644
index 000000000..60b8e318e
--- /dev/null
+++ b/.github/workflows/test-js.yml
@@ -0,0 +1,41 @@
+name: JavaScript Testing
+on:
+  push:
+    branches-ignore:
+      - 'dependabot/**'
+    paths:
+      - 'package.json'
+      - 'yarn.lock'
+      - '.nvmrc'
+      - '**/*.js'
+      - '**/*.snap'
+      - '.github/workflows/test-js.yml'
+
+  pull_request:
+    paths:
+      - 'package.json'
+      - 'yarn.lock'
+      - '.nvmrc'
+      - '**/*.js'
+      - '**/*.snap'
+      - '.github/workflows/test-js.yml'
+
+jobs:
+  test:
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Clone repository
+        uses: actions/checkout@v3
+
+      - name: Set up Node.js
+        uses: actions/setup-node@v3
+        with:
+          cache: yarn
+          node-version-file: '.nvmrc'
+
+      - name: Install all yarn packages
+        run: yarn --frozen-lockfile
+
+      - name: Jest testing
+        run: yarn test:jest --reporters github-actions summary
diff --git a/.github/workflows/test-migrations-one-step.yml b/.github/workflows/test-migrations-one-step.yml
new file mode 100644
index 000000000..8f070697c
--- /dev/null
+++ b/.github/workflows/test-migrations-one-step.yml
@@ -0,0 +1,100 @@
+name: Test one step migrations
+on:
+  push:
+    branches-ignore:
+      - 'dependabot/**'
+  pull_request:
+
+jobs:
+  pre_job:
+    runs-on: ubuntu-latest
+
+    outputs:
+      should_skip: ${{ steps.skip_check.outputs.should_skip }}
+
+    steps:
+      - id: skip_check
+        uses: fkirc/skip-duplicate-actions@v5
+        with:
+          paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-one-step.yml"]'
+
+  test:
+    runs-on: ubuntu-latest
+    needs: pre_job
+    if: needs.pre_job.outputs.should_skip != 'true'
+
+    services:
+      postgres:
+        image: postgres:14.5
+        env:
+          POSTGRES_PASSWORD: postgres
+          POSTGRES_USER: postgres
+        options: >-
+          --health-cmd pg_isready
+          --health-interval 10s
+          --health-timeout 5s
+          --health-retries 5
+        ports:
+          - 5432:5432
+
+      redis:
+        image: redis:7.0
+        options: >-
+          --health-cmd "redis-cli ping"
+          --health-interval 10s
+          --health-timeout 5s
+          --health-retries 5
+        ports:
+          - 6379:6379
+
+    env:
+      CONTINUOUS_INTEGRATION: true
+      DB_HOST: localhost
+      DB_USER: postgres
+      DB_PASS: postgres
+      DISABLE_SIMPLECOV: true
+      RAILS_ENV: test
+      BUNDLE_CLEAN: true
+      BUNDLE_FROZEN: true
+      BUNDLE_WITHOUT: 'development production'
+      BUNDLE_JOBS: 3
+      BUNDLE_RETRY: 3
+
+    steps:
+      - uses: actions/checkout@v3
+
+      - name: Install native Ruby dependencies
+        run: sudo apt-get install -y libicu-dev libidn11-dev
+
+      - name: Set up bundler cache
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: .ruby-version
+          bundler-cache: true
+
+      - name: Create database
+        run: './bin/rails db:create'
+
+      - name: Run migrations up to v2.0.0
+        run: './bin/rails db:migrate VERSION=20171010025614'
+
+      - name: Populate database with test data
+        run: './bin/rails tests:migrations:populate_v2'
+
+      - name: Run migrations up to v2.4.0
+        run: './bin/rails db:migrate VERSION=20180514140000'
+
+      - name: Populate database with test data
+        run: './bin/rails tests:migrations:populate_v2_4'
+
+      - name: Run migrations up to v2.4.3
+        run: './bin/rails db:migrate VERSION=20180707154237'
+
+      - name: Populate database with test data
+        run: './bin/rails tests:migrations:populate_v2_4_3'
+
+      - name: Run all remaining migrations
+        run: './bin/rails db:migrate'
+
+      - name: Check migration result
+        run: './bin/rails tests:migrations:check_database'
diff --git a/.github/workflows/test-migrations-two-step.yml b/.github/workflows/test-migrations-two-step.yml
new file mode 100644
index 000000000..2fdce8025
--- /dev/null
+++ b/.github/workflows/test-migrations-two-step.yml
@@ -0,0 +1,108 @@
+name: Test two step migrations
+on:
+  push:
+    branches-ignore:
+      - 'dependabot/**'
+  pull_request:
+
+jobs:
+  pre_job:
+    runs-on: ubuntu-latest
+
+    outputs:
+      should_skip: ${{ steps.skip_check.outputs.should_skip }}
+
+    steps:
+      - id: skip_check
+        uses: fkirc/skip-duplicate-actions@v5
+        with:
+          paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-two-step.yml"]'
+
+  test:
+    runs-on: ubuntu-latest
+    needs: pre_job
+    if: needs.pre_job.outputs.should_skip != 'true'
+
+    services:
+      postgres:
+        image: postgres:14.5
+        env:
+          POSTGRES_PASSWORD: postgres
+          POSTGRES_USER: postgres
+        options: >-
+          --health-cmd pg_isready
+          --health-interval 10s
+          --health-timeout 5s
+          --health-retries 5
+        ports:
+          - 5432:5432
+      redis:
+        image: redis:7.0
+        options: >-
+          --health-cmd "redis-cli ping"
+          --health-interval 10s
+          --health-timeout 5s
+          --health-retries 5
+        ports:
+          - 6379:6379
+
+    env:
+      CONTINUOUS_INTEGRATION: true
+      DB_HOST: localhost
+      DB_USER: postgres
+      DB_PASS: postgres
+      DISABLE_SIMPLECOV: true
+      RAILS_ENV: test
+      BUNDLE_CLEAN: true
+      BUNDLE_FROZEN: true
+      BUNDLE_WITHOUT: 'development production'
+      BUNDLE_JOBS: 3
+      BUNDLE_RETRY: 3
+
+    steps:
+      - uses: actions/checkout@v3
+
+      - name: Install native Ruby dependencies
+        run: sudo apt-get install -y libicu-dev libidn11-dev
+
+      - name: Set up bundler cache
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: .ruby-version
+          bundler-cache: true
+
+      - name: Create database
+        run: './bin/rails db:create'
+
+      - name: Run migrations up to v2.0.0
+        run: './bin/rails db:migrate VERSION=20171010025614'
+
+      - name: Populate database with test data
+        run: './bin/rails tests:migrations:populate_v2'
+
+      - name: Run pre-deployment migrations up to v2.4.0
+        run: './bin/rails db:migrate VERSION=20180514140000'
+        env:
+          SKIP_POST_DEPLOYMENT_MIGRATIONS: true
+
+      - name: Populate database with test data
+        run: './bin/rails tests:migrations:populate_v2_4'
+
+      - name: Run migrations up to v2.4.3
+        run: './bin/rails db:migrate VERSION=20180707154237'
+        env:
+          SKIP_POST_DEPLOYMENT_MIGRATIONS: true
+
+      - name: Populate database with test data
+        run: './bin/rails tests:migrations:populate_v2_4_3'
+
+      - name: Run all remaining pre-deployment migrations
+        run: './bin/rails db:migrate'
+        env:
+          SKIP_POST_DEPLOYMENT_MIGRATIONS: true
+
+      - name: Run all post-deployment migrations
+        run: './bin/rails db:migrate'
+
+      - name: Check migration result
+        run: './bin/rails tests:migrations:check_database'
diff --git a/.prettierignore b/.prettierignore
index e55c28416..ab68ba16d 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -51,15 +51,8 @@
 *~
 *.swp
 
-# Ignore npm debug log
-npm-debug.log
-
-# Ignore yarn log files
-yarn-error.log
-yarn-debug.log
-
-# Ignore vagrant log files
-*-cloudimg-console.log
+# Ignore log files
+*.log
 
 # Ignore Docker option files
 docker-compose.override.yml
@@ -74,6 +67,15 @@ docker-compose.override.yml
 # Ignore vendored CSS reset
 app/javascript/styles/mastodon/reset.scss
 
+# Ignore Javascript pending https://github.com/mastodon/mastodon/pull/23631
+*.js
+
+# Ignore Markdownlint pending https://github.com/mastodon/mastodon/pull/21972
+*.md
+
+# Ignore HTML till cleaned and included in CI
+*.html
+
 # Ignore glitch-soc emoji map file
 /app/javascript/flavours/glitch/features/emoji/emoji_map.json
 
diff --git a/.rubocop.yml b/.rubocop.yml
index 3c9223470..3783ccf48 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,3 +1,9 @@
+inherit_from: .rubocop_todo.yml
+
+inherit_mode:
+  merge:
+    - Exclude
+
 require:
   - rubocop-rails
   - rubocop-rspec
@@ -23,50 +29,19 @@ AllCops:
     - 'lib/json_ld/*'
     - 'lib/templates/**/*'
 
-Bundler/OrderedGems:
-  Enabled: false
-
-Layout/AccessModifierIndentation:
-  EnforcedStyle: indent
-
-Layout/EmptyLineAfterMagicComment:
-  Enabled: false
-
-Layout/EmptyLineAfterGuardClause:
-  Enabled: false
-
-Layout/EmptyLineBetweenDefs:
-  AllowAdjacentOneLineDefs: true
-
-Layout/EmptyLinesAroundAttributeAccessor:
-  Enabled: true
-
 Layout/FirstHashElementIndentation:
   EnforcedStyle: consistent
 
-Layout/HashAlignment:
-  Enabled: false
-
-Layout/SpaceAroundMethodCallOperator:
-  Enabled: true
-
-Layout/SpaceInsideHashLiteralBraces:
-  EnforcedStyle: space
-
-Lint/DeprecatedOpenSSLConstant:
-  Enabled: true
-
-Lint/DuplicateElsifCondition:
-  Enabled: true
-
-Lint/MixedRegexpCaptureTypes:
-  Enabled: true
-
-Lint/RaiseException:
-  Enabled: true
-
-Lint/StructNewOverride:
-  Enabled: true
+Layout/LineLength:
+  Max: 140 # RuboCop default 120
+  AllowedPatterns:
+    # Allow comments to be long lines
+    - !ruby/regexp / \# .*$/
+    - !ruby/regexp /^\# .*$/
+  Exclude:
+    - lib/**/*cli*.rb
+    - db/*migrate/**/*
+    - db/seeds/**/*
 
 Lint/UselessAccessModifier:
   ContextCreatingMethods:
@@ -77,403 +52,62 @@ Metrics/AbcSize:
   Exclude:
     - 'lib/**/*cli*.rb'
     - db/*migrate/**/*
-    - lib/paperclip/color_extractor.rb
-    - app/workers/scheduler/follow_recommendations_scheduler.rb
-    - app/services/activitypub/fetch*_service.rb
-    - lib/paperclip/**/*
-  CountRepeatedAttributes: false
-  AllowedMethods:
-    - update_media_attachments!
-    - account_link_to
-    - attempt_oembed
-    - build_crutches
-    - calculate_scores
-    - cc
-    - dump_actor!
-    - filter_from_home?
-    - hydrate
-    - import_bookmarks!
-    - import_relationships!
-    - initialize
-    - link_to_mention
-    - log_target
-    - matches_time_window?
-    - parse_metadata
-    - perform_statuses_search!
-    - privatize_media_attachments!
-    - process_update
-    - publish_media_attachments!
-    - remotable_attachment
-    - render_initial_state
-    - render_with_cache
-    - searchable_by
-    - self.cached_filters_for
-    - set_fetchable_attributes!
-    - signed_request_actor
-    - statuses_to_delete
-    - update_poll!
 
 Metrics/BlockLength:
-  Max: 55
+  Max: 55 # Default 25
+  CountAsOne: [array, heredoc]
   Exclude:
     - 'lib/mastodon/*_cli.rb'
-  CountComments: false
-  CountAsOne: [array, heredoc]
-  AllowedMethods:
-    - task
-    - namespace
-    - class_methods
-    - included
 
 Metrics/BlockNesting:
-  Max: 3
   Exclude:
     - 'lib/mastodon/*_cli.rb'
 
 Metrics/ClassLength:
-  CountComments: false
-  Max: 500
+  Max: 500 # Default 100
   CountAsOne: [array, heredoc]
   Exclude:
     - 'lib/mastodon/*_cli.rb'
 
 Metrics/CyclomaticComplexity:
-  Max: 12
+  Max: 12 # Default 7
   Exclude:
     - lib/mastodon/*cli*.rb
     - db/*migrate/**/*
-  AllowedMethods:
-    - attempt_oembed
-    - blocked?
-    - build_crutches
-    - calculate_scores
-    - cc
-    - discover_endpoint!
-    - filter_from_home?
-    - hydrate
-    - klass
-    - link_to_mention
-    - log_target
-    - matches_time_window?
-    - patch_for_forwarding!
-    - preprocess_attributes!
-    - process_update
-    - remotable_attachment
-    - scan_text!
-    - self.cached_filters_for
-    - set_fetchable_attributes!
-    - setup_redis_env_url
-    - update_media_attachments!
-
-Layout/LineLength:
-  Max: 140 # RuboCop default 120
-  AllowHeredoc: true
-  AllowURI: true
-  IgnoreCopDirectives: true
-  AllowedPatterns:
-    # Allow comments to be long lines
-    - !ruby/regexp / \# .*$/
-    - !ruby/regexp /^\# .*$/
-  Exclude:
-    - lib/**/*cli*.rb
-    - db/*migrate/**/*
-    - db/seeds/**/*
 
 Metrics/MethodLength:
-  CountComments: false
-  CountAsOne: [array, heredoc]
   Max: 25 # RuboCop default 10
+  CountAsOne: [array, heredoc]
   Exclude:
     - 'lib/mastodon/*_cli.rb'
-  AllowedMethods:
-    - account_link_to
-    - attempt_oembed
-    - body_with_limit
-    - build_crutches
-    - cached_filters_for
-    - calculate_scores
-    - check_webfinger!
-    - clean_feeds!
-    - collection_items
-    - collection_presenter
-    - copy_account_notes!
-    - deduplicate_accounts!
-    - deduplicate_conversations!
-    - deduplicate_local_accounts!
-    - deduplicate_statuses!
-    - deduplicate_tags!
-    - deduplicate_users!
-    - discover_endpoint!
-    - extract_extra_uris_with_indices
-    - extract_hashtags_with_indices
-    - extract_mentions_or_lists_with_indices
-    - filter_from_home?
-    - from_elasticsearch
-    - handle_explicit_update!
-    - handle_mark_as_sensitive!
-    - hsl_to_rgb
-    - import_bookmarks!
-    - import_domain_blocks!
-    - import_relationships!
-    - ldap_options
-    - matches_time_window?
-    - outbox_presenter
-    - pam_get_user
-    - parallelize_with_progress
-    - parse_and_transform
-    - patch_for_forwarding!
-    - populate_home
-    - post_process_style
-    - preload_cache_collection_target_statuses
-    - privatize_media_attachments!
-    - provides_callback_for
-    - publish_media_attachments!
-    - relevant_account_timestamp
-    - remotable_attachment
-    - rgb_to_hsl
-    - rss_status_content_format
-    - set_fetchable_attributes!
-    - setup_redis_env_url
-    - signed_request_actor
-    - to_preview_card_attributes
-    - upgrade_storage_filesystem
-    - upgrade_storage_s3
-    - user_settings_params
-    - hydrate
-    - cc
-    - self_destruct
 
 Metrics/ModuleLength:
-  CountComments: false
-  Max: 200
+  Max: 200 # Default 100
   CountAsOne: [array, heredoc]
 
-Metrics/ParameterLists:
-  Max: 5 # RuboCop default 5
-  CountKeywordArgs: true # RuboCop default true
-  MaxOptionalParameters: 3 # RuboCop default 3
-  Exclude:
-    - app/models/concerns/account_interactions.rb
-    - app/services/activitypub/fetch_remote_account_service.rb
-    - app/services/activitypub/fetch_remote_actor_service.rb
-
 Metrics/PerceivedComplexity:
   Max: 16 # RuboCop default 8
-  AllowedMethods:
-    - attempt_oembed
-    - build_crutches
-    - calculate_scores
-    - deduplicate_users!
-    - discover_endpoint!
-    - filter_from_home?
-    - hydrate
-    - patch_for_forwarding!
-    - process_update
-    - remove_orphans
-    - update_media_attachments!
-
-Naming/MemoizedInstanceVariableName:
-  Enabled: false
-
-Naming/MethodParameterName:
-  Enabled: true
-
-Rails:
-  Enabled: true
-
-Rails/ApplicationController:
-  Enabled: false
-  Exclude:
-    - 'app/controllers/well_known/**/*.rb'
-
-Rails/BelongsTo:
-  Enabled: false
-
-Rails/ContentTag:
-  Enabled: false
-
-Rails/EnumHash:
-  Enabled: false
 
 Rails/Exit:
   Exclude:
-    - 'lib/mastodon/*'
+    - 'lib/mastodon/*_cli.rb'
+    - 'lib/mastodon/cli_helper.rb'
     - 'lib/cli.rb'
 
-Rails/FilePath:
-  Enabled: false
-
-Rails/HasAndBelongsToMany:
-  Enabled: false
-
-Rails/HasManyOrHasOneDependent:
-  Enabled: false
-
-Rails/HelperInstanceVariable:
-  Enabled: false
-
-Rails/HttpStatus:
-  Enabled: false
-
-Rails/IndexBy:
-  Enabled: false
-
-Rails/InverseOf:
-  Enabled: false
-
-Rails/LexicallyScopedActionFilter:
-  Enabled: false
-
-Rails/OutputSafety:
-  Enabled: true
-
-Rails/RakeEnvironment:
-  Enabled: false
-
-Rails/RedundantForeignKey:
-  Enabled: false
-
-Rails/SkipsModelValidations:
-  Enabled: false
-
-Rails/UniqueValidationWithoutIndex:
-  Enabled: false
-
-Style/AccessorGrouping:
-  Enabled: true
-
-Style/AccessModifierDeclarations:
-  Enabled: false
-
-Style/ArrayCoercion:
-  Enabled: true
-
-Style/BisectedAttrAccessor:
-  Enabled: true
-
-Style/CaseLikeIf:
-  Enabled: false
-
-Style/ClassAndModuleChildren:
-  Enabled: false
-
-Style/CollectionMethods:
-  Enabled: true
-  PreferredMethods:
-    find_all: 'select'
-
-Style/Documentation:
-  Enabled: false
-
-Style/DoubleNegation:
-  Enabled: true
-
-Style/ExpandPathArguments:
-  Enabled: false
-
-Style/ExponentialNotation:
-  Enabled: true
-
-Style/FormatString:
-  Enabled: false
-
-Style/FormatStringToken:
-  Enabled: false
-
-Style/FrozenStringLiteralComment:
-  Enabled: true
-
-Style/GuardClause:
-  Enabled: false
-
-Style/HashAsLastArrayItem:
-  Enabled: false
-
-Style/HashEachMethods:
-  Enabled: true
-
-Style/HashLikeCase:
-  Enabled: true
-
-Style/HashTransformKeys:
-  Enabled: true
-
-Style/HashTransformValues:
-  Enabled: false
-
 Style/HashSyntax:
-  Enabled: true
   EnforcedStyle: ruby19_no_mixed_keys
 
-Style/IfUnlessModifier:
-  Enabled: false
-
-Style/InverseMethods:
-  Enabled: false
-
-Style/Lambda:
-  Enabled: false
-
-Style/MutableConstant:
-  Enabled: false
+Style/NumericLiterals:
+  AllowedPatterns:
+    - \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability
 
 Style/PercentLiteralDelimiters:
   PreferredDelimiters:
     '%i': '()'
     '%w': '()'
 
-Style/PerlBackrefs:
-  AutoCorrect: false
-
-Style/RedundantFetchBlock:
-  Enabled: true
-
-Style/RedundantFileExtensionInRequire:
-  Enabled: true
-
-Style/RedundantRegexpCharacterClass:
-  Enabled: false
-
-Style/RedundantRegexpEscape:
-  Enabled: false
-
-Style/RedundantReturn:
-  Enabled: true
-
-Style/RedundantBegin:
-  Enabled: false
-
-Style/RegexpLiteral:
-  Enabled: false
-
-Style/RescueStandardError:
-  Enabled: true
-
-Style/SignalException:
-  Enabled: false
-
-Style/SlicingWithRange:
-  Enabled: true
-
-Style/SymbolArray:
-  Enabled: false
-
 Style/TrailingCommaInArrayLiteral:
   EnforcedStyleForMultiline: 'comma'
 
 Style/TrailingCommaInHashLiteral:
   EnforcedStyleForMultiline: 'comma'
-
-Style/UnpackFirst:
-  Enabled: false
-
-RSpec/ScatteredSetup:
-  Enabled: false
-RSpec/ImplicitExpect:
-  Enabled: false
-RSpec/NamedSubject:
-  Enabled: false
-RSpec/DescribeClass:
-  Enabled: false
-RSpec/LetSetup:
-  Enabled: false
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
new file mode 100644
index 000000000..c3a62c2d9
--- /dev/null
+++ b/.rubocop_todo.yml
@@ -0,0 +1,3220 @@
+# This configuration was generated by
+# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit`
+# on 2023-02-16 05:53:07 UTC using RuboCop version 1.45.1.
+# The point is for the user to remove these configuration records
+# one by one as the offenses are removed from the code base.
+# Note that changes in the inspected code, or installation of new
+# versions of RuboCop, may require this file to be generated again.
+
+# Offense count: 15
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
+# Include: **/*.gemfile, **/Gemfile, **/gems.rb
+Bundler/OrderedGems:
+  Exclude:
+    - 'Gemfile'
+
+# Offense count: 81
+# This cop supports safe autocorrection (--autocorrect).
+Layout/EmptyLineAfterGuardClause:
+  Exclude:
+    - 'app/controllers/api/v1/tags_controller.rb'
+    - 'app/controllers/application_controller.rb'
+    - 'app/controllers/concerns/session_tracking_concern.rb'
+    - 'app/controllers/concerns/signature_verification.rb'
+    - 'app/helpers/application_helper.rb'
+    - 'app/lib/activitypub/activity.rb'
+    - 'app/lib/activitypub/tag_manager.rb'
+    - 'app/lib/request.rb'
+    - 'app/lib/settings/scoped_settings.rb'
+    - 'app/lib/status_filter.rb'
+    - 'app/lib/tag_manager.rb'
+    - 'app/lib/webfinger.rb'
+    - 'app/models/account.rb'
+    - 'app/models/account_conversation.rb'
+    - 'app/models/admin/import.rb'
+    - 'app/models/custom_filter.rb'
+    - 'app/models/favourite.rb'
+    - 'app/models/form/admin_settings.rb'
+    - 'app/models/poll.rb'
+    - 'app/models/session_activation.rb'
+    - 'app/models/setting.rb'
+    - 'app/models/status_edit.rb'
+    - 'app/models/user.rb'
+    - 'app/models/user_role.rb'
+    - 'app/services/activitypub/fetch_remote_actor_service.rb'
+    - 'app/services/activitypub/fetch_remote_status_service.rb'
+    - 'app/services/activitypub/fetch_replies_service.rb'
+    - 'app/services/activitypub/process_account_service.rb'
+    - 'app/services/favourite_service.rb'
+    - 'app/services/notify_service.rb'
+    - 'app/services/post_status_service.rb'
+    - 'app/services/vote_service.rb'
+    - 'app/validators/follow_limit_validator.rb'
+    - 'app/validators/unreserved_username_validator.rb'
+    - 'app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb'
+    - 'db/migrate/20190314181829_migrate_open_registrations_setting.rb'
+    - 'db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb'
+    - 'db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb'
+    - 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
+    - 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
+    - 'lib/mastodon/domains_cli.rb'
+
+# Offense count: 71
+# This cop supports safe autocorrection (--autocorrect).
+Layout/EmptyLineAfterMagicComment:
+  Exclude:
+    - 'Capfile'
+    - 'app/helpers/languages_helper.rb'
+    - 'app/models/account.rb'
+    - 'app/models/account_conversation.rb'
+    - 'app/models/account_domain_block.rb'
+    - 'app/models/account_moderation_note.rb'
+    - 'app/models/account_note.rb'
+    - 'app/models/account_pin.rb'
+    - 'app/models/account_stat.rb'
+    - 'app/models/account_summary.rb'
+    - 'app/models/account_warning.rb'
+    - 'app/models/backup.rb'
+    - 'app/models/block.rb'
+    - 'app/models/bookmark.rb'
+    - 'app/models/canonical_email_block.rb'
+    - 'app/models/conversation.rb'
+    - 'app/models/conversation_mute.rb'
+    - 'app/models/custom_emoji.rb'
+    - 'app/models/custom_filter.rb'
+    - 'app/models/custom_filter_keyword.rb'
+    - 'app/models/custom_filter_status.rb'
+    - 'app/models/device.rb'
+    - 'app/models/domain_block.rb'
+    - 'app/models/email_domain_block.rb'
+    - 'app/models/encrypted_message.rb'
+    - 'app/models/favourite.rb'
+    - 'app/models/featured_tag.rb'
+    - 'app/models/follow.rb'
+    - 'app/models/follow_recommendation.rb'
+    - 'app/models/follow_recommendation_suppression.rb'
+    - 'app/models/follow_request.rb'
+    - 'app/models/identity.rb'
+    - 'app/models/import.rb'
+    - 'app/models/instance.rb'
+    - 'app/models/invite.rb'
+    - 'app/models/ip_block.rb'
+    - 'app/models/list.rb'
+    - 'app/models/list_account.rb'
+    - 'app/models/login_activity.rb'
+    - 'app/models/media_attachment.rb'
+    - 'app/models/mention.rb'
+    - 'app/models/mute.rb'
+    - 'app/models/notification.rb'
+    - 'app/models/one_time_key.rb'
+    - 'app/models/poll.rb'
+    - 'app/models/poll_vote.rb'
+    - 'app/models/preview_card.rb'
+    - 'app/models/preview_card_provider.rb'
+    - 'app/models/relay.rb'
+    - 'app/models/report.rb'
+    - 'app/models/report_note.rb'
+    - 'app/models/session_activation.rb'
+    - 'app/models/setting.rb'
+    - 'app/models/site_upload.rb'
+    - 'app/models/status.rb'
+    - 'app/models/status_edit.rb'
+    - 'app/models/status_pin.rb'
+    - 'app/models/status_stat.rb'
+    - 'app/models/tag.rb'
+    - 'app/models/unavailable_domain.rb'
+    - 'app/models/user.rb'
+    - 'app/models/user_ip.rb'
+    - 'app/models/web/push_subscription.rb'
+    - 'app/models/web/setting.rb'
+    - 'app/models/webauthn_credential.rb'
+    - 'config.ru'
+    - 'db/migrate/20220613110834_add_action_to_custom_filters.rb'
+    - 'db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb'
+    - 'db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb'
+    - 'spec/controllers/api/v1/accounts/statuses_controller_spec.rb'
+    - 'spec/models/tag_spec.rb'
+
+# Offense count: 113
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
+# SupportedHashRocketStyles: key, separator, table
+# SupportedColonStyles: key, separator, table
+# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
+Layout/HashAlignment:
+  Exclude:
+    - 'app/lib/activitypub/linked_data_signature.rb'
+    - 'app/lib/ostatus/tag_manager.rb'
+    - 'app/models/account/field.rb'
+    - 'app/models/account_warning.rb'
+    - 'app/models/media_attachment.rb'
+    - 'app/models/notification.rb'
+    - 'app/models/poll.rb'
+    - 'app/presenters/account_relationships_presenter.rb'
+    - 'app/services/keys/claim_service.rb'
+    - 'app/services/keys/query_service.rb'
+    - 'app/workers/web/push_notification_worker.rb'
+    - 'db/post_migrate/20200917193528_migrate_notifications_type.rb'
+    - 'lib/sanitize_ext/sanitize_config.rb'
+    - 'lib/tasks/auto_annotate_models.rake'
+    - 'lib/tasks/mastodon.rake'
+    - 'spec/models/admin/account_action_spec.rb'
+    - 'spec/models/concerns/account_interactions_spec.rb'
+
+# Offense count: 577
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
+# URISchemes: http, https
+Layout/LineLength:
+  Enabled: false
+
+# Offense count: 14
+# Configuration parameters: AllowedMethods, AllowedPatterns.
+Lint/AmbiguousBlockAssociation:
+  Exclude:
+    - 'spec/controllers/admin/account_moderation_notes_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/otp_authentication_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/services/post_status_service_spec.rb'
+    - 'spec/services/suspend_account_service_spec.rb'
+    - 'spec/services/unsuspend_account_service_spec.rb'
+    - 'spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb'
+
+# Offense count: 15
+# Configuration parameters: AllowedMethods.
+# AllowedMethods: enums
+Lint/ConstantDefinitionInBlock:
+  Exclude:
+    - 'spec/controllers/api/base_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/concerns/accountable_concern_spec.rb'
+    - 'spec/controllers/concerns/signature_verification_spec.rb'
+    - 'spec/lib/activitypub/adapter_spec.rb'
+    - 'spec/lib/connection_pool/shared_connection_pool_spec.rb'
+    - 'spec/lib/connection_pool/shared_timed_stack_spec.rb'
+    - 'spec/lib/settings/extend_spec.rb'
+    - 'spec/models/concerns/remotable_spec.rb'
+
+# Offense count: 5
+# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches.
+Lint/DuplicateBranch:
+  Exclude:
+    - 'app/lib/permalink_redirector.rb'
+    - 'app/models/account_statuses_filter.rb'
+    - 'app/validators/email_mx_validator.rb'
+    - 'app/validators/vote_validator.rb'
+    - 'lib/mastodon/maintenance_cli.rb'
+
+# Offense count: 42
+# Configuration parameters: AllowComments, AllowEmptyLambdas.
+Lint/EmptyBlock:
+  Exclude:
+    - 'spec/controllers/api/v2/search_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/fabricators/access_token_fabricator.rb'
+    - 'spec/fabricators/conversation_fabricator.rb'
+    - 'spec/fabricators/conversation_mute_fabricator.rb'
+    - 'spec/fabricators/import_fabricator.rb'
+    - 'spec/fabricators/setting_fabricator.rb'
+    - 'spec/fabricators/system_key_fabricator.rb'
+    - 'spec/fabricators/web_setting_fabricator.rb'
+    - 'spec/helpers/admin/action_log_helper_spec.rb'
+    - 'spec/lib/activitypub/adapter_spec.rb'
+    - 'spec/models/account_alias_spec.rb'
+    - 'spec/models/account_deletion_request_spec.rb'
+    - 'spec/models/account_moderation_note_spec.rb'
+    - 'spec/models/announcement_mute_spec.rb'
+    - 'spec/models/announcement_reaction_spec.rb'
+    - 'spec/models/announcement_spec.rb'
+    - 'spec/models/backup_spec.rb'
+    - 'spec/models/conversation_mute_spec.rb'
+    - 'spec/models/custom_filter_keyword_spec.rb'
+    - 'spec/models/custom_filter_spec.rb'
+    - 'spec/models/device_spec.rb'
+    - 'spec/models/encrypted_message_spec.rb'
+    - 'spec/models/featured_tag_spec.rb'
+    - 'spec/models/follow_recommendation_suppression_spec.rb'
+    - 'spec/models/list_account_spec.rb'
+    - 'spec/models/list_spec.rb'
+    - 'spec/models/login_activity_spec.rb'
+    - 'spec/models/mute_spec.rb'
+    - 'spec/models/one_time_key_spec.rb'
+    - 'spec/models/preview_card_spec.rb'
+    - 'spec/models/preview_card_trend_spec.rb'
+    - 'spec/models/relay_spec.rb'
+    - 'spec/models/scheduled_status_spec.rb'
+    - 'spec/models/status_stat_spec.rb'
+    - 'spec/models/status_trend_spec.rb'
+    - 'spec/models/system_key_spec.rb'
+    - 'spec/models/tag_follow_spec.rb'
+    - 'spec/models/unavailable_domain_spec.rb'
+    - 'spec/models/user_invite_request_spec.rb'
+    - 'spec/models/user_role_spec.rb'
+    - 'spec/models/web/setting_spec.rb'
+
+# Offense count: 1
+# Configuration parameters: AllowComments.
+Lint/EmptyClass:
+  Exclude:
+    - 'spec/controllers/api/base_controller_spec.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Lint/NonDeterministicRequireOrder:
+  Exclude:
+    - 'spec/rails_helper.rb'
+
+# Offense count: 1
+Lint/NonLocalExitFromIterator:
+  Exclude:
+    - 'app/helpers/jsonld_helper.rb'
+
+# Offense count: 2
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Lint/OrAssignmentToConstant:
+  Exclude:
+    - 'lib/sanitize_ext/sanitize_config.rb'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
+Lint/UnusedBlockArgument:
+  Exclude:
+    - 'spec/lib/activitypub/activity/add_spec.rb'
+    - 'spec/lib/request_pool_spec.rb'
+
+# Offense count: 33
+Lint/UselessAssignment:
+  Exclude:
+    - 'app/services/activitypub/process_status_update_service.rb'
+    - 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
+    - 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
+    - 'spec/controllers/api/v1/bookmarks_controller_spec.rb'
+    - 'spec/controllers/api/v1/favourites_controller_spec.rb'
+    - 'spec/controllers/concerns/account_controller_concern_spec.rb'
+    - 'spec/helpers/jsonld_helper_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/domain_block_spec.rb'
+    - 'spec/models/status_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/models/webauthn_credentials_spec.rb'
+    - 'spec/services/account_search_service_spec.rb'
+    - 'spec/services/post_status_service_spec.rb'
+    - 'spec/services/precompute_feed_service_spec.rb'
+    - 'spec/services/resolve_url_service_spec.rb'
+    - 'spec/views/statuses/show.html.haml_spec.rb'
+
+# Offense count: 3
+# Configuration parameters: CheckForMethodsWithNoSideEffects.
+Lint/Void:
+  Exclude:
+    - 'spec/services/resolve_account_service_spec.rb'
+
+# Offense count: 65
+# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
+Metrics/AbcSize:
+  Enabled: false
+
+# Offense count: 11
+# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
+# AllowedMethods: refine
+Metrics/BlockLength:
+  Exclude:
+    - 'app/models/concerns/account_interactions.rb'
+    - 'app/models/concerns/omniauthable.rb'
+    - 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
+    - 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
+    - 'lib/tasks/branding.rake'
+    - 'lib/tasks/mastodon.rake'
+    - 'lib/tasks/repo.rake'
+    - 'lib/tasks/tests.rake'
+
+# Offense count: 1
+# Configuration parameters: CountBlocks, Max.
+Metrics/BlockNesting:
+  Exclude:
+    - 'lib/tasks/mastodon.rake'
+
+# Offense count: 39
+# Configuration parameters: AllowedMethods, AllowedPatterns.
+Metrics/CyclomaticComplexity:
+  Enabled: false
+
+# Offense count: 40
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
+Metrics/MethodLength:
+  Enabled: false
+
+# Offense count: 1
+# Configuration parameters: CountComments, Max, CountAsOne.
+Metrics/ModuleLength:
+  Exclude:
+    - 'app/models/concerns/account_interactions.rb'
+
+# Offense count: 5
+# Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters.
+Metrics/ParameterLists:
+  Exclude:
+    - 'app/models/concerns/account_interactions.rb'
+    - 'app/services/activitypub/fetch_remote_account_service.rb'
+    - 'app/services/activitypub/fetch_remote_actor_service.rb'
+    - 'app/services/activitypub/fetch_remote_status_service.rb'
+
+# Offense count: 16
+# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
+Metrics/PerceivedComplexity:
+  Exclude:
+    - 'app/helpers/jsonld_helper.rb'
+    - 'app/lib/feed_manager.rb'
+    - 'app/lib/status_cache_hydrator.rb'
+    - 'app/lib/user_settings_decorator.rb'
+    - 'app/models/trends/links.rb'
+    - 'app/services/activitypub/fetch_remote_key_service.rb'
+    - 'app/services/activitypub/fetch_remote_status_service.rb'
+    - 'app/services/activitypub/process_account_service.rb'
+    - 'app/services/fetch_link_card_service.rb'
+    - 'app/services/fetch_oembed_service.rb'
+    - 'app/services/process_mentions_service.rb'
+    - 'app/services/resolve_account_service.rb'
+    - 'lib/mastodon/accounts_cli.rb'
+    - 'lib/mastodon/domains_cli.rb'
+    - 'lib/mastodon/maintenance_cli.rb'
+
+# Offense count: 1
+Naming/AccessorMethodName:
+  Exclude:
+    - 'app/controllers/auth/sessions_controller.rb'
+
+# Offense count: 7
+# Configuration parameters: EnforcedStyleForLeadingUnderscores.
+# SupportedStylesForLeadingUnderscores: disallowed, required, optional
+Naming/MemoizedInstanceVariableName:
+  Exclude:
+    - 'app/controllers/api/v1/bookmarks_controller.rb'
+    - 'app/controllers/api/v1/favourites_controller.rb'
+    - 'app/controllers/concerns/rate_limit_headers.rb'
+    - 'app/lib/activitypub/activity.rb'
+    - 'app/services/resolve_url_service.rb'
+    - 'app/services/search_service.rb'
+
+# Offense count: 50
+# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
+# SupportedStyles: snake_case, normalcase, non_integer
+# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
+Naming/VariableNumber:
+  Exclude:
+    - 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
+    - 'db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
+    - 'db/migrate/20190820003045_update_statuses_index.rb'
+    - 'db/migrate/20190823221802_add_local_index_to_statuses.rb'
+    - 'db/migrate/20200119112504_add_public_index_to_statuses.rb'
+    - 'spec/controllers/activitypub/followers_synchronizations_controller_spec.rb'
+    - 'spec/lib/feed_manager_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/concerns/account_interactions_spec.rb'
+    - 'spec/models/custom_emoji_filter_spec.rb'
+    - 'spec/models/domain_block_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/services/activitypub/fetch_featured_collection_service_spec.rb'
+
+# Offense count: 12
+# Configuration parameters: MinSize.
+Performance/CollectionLiteralInLoop:
+  Exclude:
+    - 'app/models/admin/appeal_filter.rb'
+    - 'app/models/admin/status_filter.rb'
+    - 'app/models/relationship_filter.rb'
+    - 'app/models/trends/preview_card_filter.rb'
+    - 'app/models/trends/status_filter.rb'
+    - 'app/presenters/status_relationships_presenter.rb'
+    - 'app/services/fetch_resource_service.rb'
+    - 'app/services/suspend_account_service.rb'
+    - 'app/services/unsuspend_account_service.rb'
+    - 'lib/mastodon/media_cli.rb'
+
+# Offense count: 4
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Performance/Count:
+  Exclude:
+    - 'app/lib/importer/accounts_index_importer.rb'
+    - 'app/lib/importer/tags_index_importer.rb'
+
+# Offense count: 10
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: SafeMultiline.
+Performance/DeletePrefix:
+  Exclude:
+    - 'app/controllers/authorize_interactions_controller.rb'
+    - 'app/controllers/concerns/signature_verification.rb'
+    - 'app/controllers/intents_controller.rb'
+    - 'app/lib/activitypub/case_transform.rb'
+    - 'app/lib/permalink_redirector.rb'
+    - 'app/lib/webfinger_resource.rb'
+    - 'app/services/activitypub/fetch_remote_actor_service.rb'
+    - 'app/services/backup_service.rb'
+    - 'app/services/resolve_account_service.rb'
+    - 'app/services/tag_search_service.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: SafeMultiline.
+Performance/DeleteSuffix:
+  Exclude:
+    - 'lib/tasks/repo.rake'
+
+# Offense count: 19
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Performance/MapCompact:
+  Exclude:
+    - 'app/lib/admin/metrics/dimension.rb'
+    - 'app/lib/admin/metrics/measure.rb'
+    - 'app/lib/feed_manager.rb'
+    - 'app/models/account.rb'
+    - 'app/models/account_statuses_cleanup_policy.rb'
+    - 'app/models/account_suggestions/setting_source.rb'
+    - 'app/models/account_suggestions/source.rb'
+    - 'app/models/follow_recommendation_filter.rb'
+    - 'app/models/notification.rb'
+    - 'app/models/user_role.rb'
+    - 'app/models/webhook.rb'
+    - 'app/services/process_mentions_service.rb'
+    - 'app/validators/existing_username_validator.rb'
+    - 'db/migrate/20200407202420_migrate_unavailable_inboxes.rb'
+    - 'spec/presenters/status_relationships_presenter_spec.rb'
+
+# Offense count: 7
+Performance/MethodObjectAsBlock:
+  Exclude:
+    - 'app/models/account_suggestions/source.rb'
+    - 'spec/models/export_spec.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Performance/RedundantEqualityComparisonBlock:
+  Exclude:
+    - 'spec/requests/link_headers_spec.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: SafeMultiline.
+Performance/StartWith:
+  Exclude:
+    - 'app/lib/extractor.rb'
+
+# Offense count: 4
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: OnlySumOrWithInitialValue.
+Performance/Sum:
+  Exclude:
+    - 'app/lib/activity_tracker.rb'
+    - 'app/models/trends/history.rb'
+    - 'app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb'
+    - 'lib/paperclip/color_extractor.rb'
+
+# Offense count: 15
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Performance/TimesMap:
+  Exclude:
+    - 'spec/controllers/api/v1/blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/mutes_controller_spec.rb'
+    - 'spec/lib/feed_manager_spec.rb'
+    - 'spec/lib/request_pool_spec.rb'
+    - 'spec/models/account_spec.rb'
+
+# Offense count: 4
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Performance/UnfreezeString:
+  Exclude:
+    - 'app/lib/rss/builder.rb'
+    - 'app/lib/text_formatter.rb'
+    - 'app/validators/status_length_validator.rb'
+    - 'lib/tasks/mastodon.rake'
+
+# Offense count: 27
+RSpec/AnyInstance:
+  Exclude:
+    - 'spec/controllers/activitypub/inboxes_controller_spec.rb'
+    - 'spec/controllers/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/admin/resets_controller_spec.rb'
+    - 'spec/controllers/admin/settings/branding_controller_spec.rb'
+    - 'spec/controllers/api/v1/media_controller_spec.rb'
+    - 'spec/controllers/auth/sessions_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/recovery_codes_controller_spec.rb'
+    - 'spec/lib/request_spec.rb'
+    - 'spec/lib/status_filter_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/setting_spec.rb'
+    - 'spec/services/activitypub/process_collection_service_spec.rb'
+    - 'spec/validators/blacklisted_email_validator_spec.rb'
+    - 'spec/validators/follow_limit_validator_spec.rb'
+    - 'spec/workers/activitypub/delivery_worker_spec.rb'
+    - 'spec/workers/web/push_notification_worker_spec.rb'
+
+# Offense count: 139
+# This cop supports unsafe autocorrection (--autocorrect-all).
+RSpec/BeEq:
+  Exclude:
+    - 'spec/controllers/admin/export_domain_allows_controller_spec.rb'
+    - 'spec/controllers/admin/reports/actions_controller_spec.rb'
+    - 'spec/controllers/admin/reports_controller_spec.rb'
+    - 'spec/controllers/admin/users/two_factor_authentications_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/credentials_controller_spec.rb'
+    - 'spec/controllers/api/v1/bookmarks_controller_spec.rb'
+    - 'spec/controllers/api/v1/favourites_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/keywords_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/controllers/statuses_cleanup_controller_spec.rb'
+    - 'spec/helpers/application_helper_spec.rb'
+    - 'spec/helpers/jsonld_helper_spec.rb'
+    - 'spec/lib/activitypub/activity/add_spec.rb'
+    - 'spec/lib/activitypub/activity/create_spec.rb'
+    - 'spec/lib/feed_manager_spec.rb'
+    - 'spec/lib/ostatus/tag_manager_spec.rb'
+    - 'spec/lib/tag_manager_spec.rb'
+    - 'spec/lib/user_settings_decorator_spec.rb'
+    - 'spec/models/account_domain_block_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/block_spec.rb'
+    - 'spec/models/domain_block_spec.rb'
+    - 'spec/models/favourite_spec.rb'
+    - 'spec/models/media_attachment_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/models/web/push_subscription_spec.rb'
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/services/fetch_oembed_service_spec.rb'
+    - 'spec/services/fetch_resource_service_spec.rb'
+    - 'spec/services/post_status_service_spec.rb'
+    - 'spec/services/precompute_feed_service_spec.rb'
+    - 'spec/services/resolve_account_service_spec.rb'
+    - 'spec/support/examples/lib/settings/scoped_settings.rb'
+    - 'spec/workers/domain_block_worker_spec.rb'
+    - 'spec/workers/domain_clear_media_worker_spec.rb'
+    - 'spec/workers/feed_insert_worker_spec.rb'
+    - 'spec/workers/regeneration_worker_spec.rb'
+
+# Offense count: 1
+RSpec/BeforeAfterAll:
+  Exclude:
+    - 'spec/requests/localization_spec.rb'
+
+# Offense count: 558
+# Configuration parameters: Prefixes, AllowedPatterns.
+# Prefixes: when, with, without
+RSpec/ContextWording:
+  Exclude:
+    - 'spec/config/initializers/rack_attack_spec.rb'
+    - 'spec/controllers/accounts_controller_spec.rb'
+    - 'spec/controllers/activitypub/collections_controller_spec.rb'
+    - 'spec/controllers/activitypub/inboxes_controller_spec.rb'
+    - 'spec/controllers/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/reports/actions_controller_spec.rb'
+    - 'spec/controllers/admin/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/relationships_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/emails/confirmations_controller_spec.rb'
+    - 'spec/controllers/api/v1/instances/activity_controller_spec.rb'
+    - 'spec/controllers/api/v1/instances/peers_controller_spec.rb'
+    - 'spec/controllers/api/v1/media_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/controllers/auth/sessions_controller_spec.rb'
+    - 'spec/controllers/concerns/cache_concern_spec.rb'
+    - 'spec/controllers/concerns/challengable_concern_spec.rb'
+    - 'spec/controllers/concerns/localized_spec.rb'
+    - 'spec/controllers/concerns/rate_limit_headers_spec.rb'
+    - 'spec/controllers/instance_actors_controller_spec.rb'
+    - 'spec/controllers/settings/applications_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
+    - 'spec/controllers/statuses_controller_spec.rb'
+    - 'spec/helpers/admin/account_moderation_notes_helper_spec.rb'
+    - 'spec/helpers/jsonld_helper_spec.rb'
+    - 'spec/helpers/routing_helper_spec.rb'
+    - 'spec/lib/activitypub/activity/accept_spec.rb'
+    - 'spec/lib/activitypub/activity/announce_spec.rb'
+    - 'spec/lib/activitypub/activity/create_spec.rb'
+    - 'spec/lib/activitypub/activity/follow_spec.rb'
+    - 'spec/lib/activitypub/activity/reject_spec.rb'
+    - 'spec/lib/emoji_formatter_spec.rb'
+    - 'spec/lib/entity_cache_spec.rb'
+    - 'spec/lib/feed_manager_spec.rb'
+    - 'spec/lib/html_aware_formatter_spec.rb'
+    - 'spec/lib/link_details_extractor_spec.rb'
+    - 'spec/lib/ostatus/tag_manager_spec.rb'
+    - 'spec/lib/plain_text_formatter_spec.rb'
+    - 'spec/lib/scope_transformer_spec.rb'
+    - 'spec/lib/status_cache_hydrator_spec.rb'
+    - 'spec/lib/status_reach_finder_spec.rb'
+    - 'spec/lib/text_formatter_spec.rb'
+    - 'spec/models/account/field_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/admin/account_action_spec.rb'
+    - 'spec/models/concerns/account_interactions_spec.rb'
+    - 'spec/models/concerns/remotable_spec.rb'
+    - 'spec/models/custom_emoji_filter_spec.rb'
+    - 'spec/models/custom_emoji_spec.rb'
+    - 'spec/models/email_domain_block_spec.rb'
+    - 'spec/models/media_attachment_spec.rb'
+    - 'spec/models/notification_spec.rb'
+    - 'spec/models/remote_follow_spec.rb'
+    - 'spec/models/report_spec.rb'
+    - 'spec/models/session_activation_spec.rb'
+    - 'spec/models/setting_spec.rb'
+    - 'spec/models/status_spec.rb'
+    - 'spec/models/web/push_subscription_spec.rb'
+    - 'spec/policies/account_moderation_note_policy_spec.rb'
+    - 'spec/policies/account_policy_spec.rb'
+    - 'spec/policies/backup_policy_spec.rb'
+    - 'spec/policies/custom_emoji_policy_spec.rb'
+    - 'spec/policies/domain_block_policy_spec.rb'
+    - 'spec/policies/email_domain_block_policy_spec.rb'
+    - 'spec/policies/instance_policy_spec.rb'
+    - 'spec/policies/invite_policy_spec.rb'
+    - 'spec/policies/relay_policy_spec.rb'
+    - 'spec/policies/report_note_policy_spec.rb'
+    - 'spec/policies/report_policy_spec.rb'
+    - 'spec/policies/settings_policy_spec.rb'
+    - 'spec/policies/tag_policy_spec.rb'
+    - 'spec/policies/user_policy_spec.rb'
+    - 'spec/presenters/account_relationships_presenter_spec.rb'
+    - 'spec/presenters/status_relationships_presenter_spec.rb'
+    - 'spec/services/account_search_service_spec.rb'
+    - 'spec/services/account_statuses_cleanup_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_status_service_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/services/fetch_link_card_service_spec.rb'
+    - 'spec/services/fetch_oembed_service_spec.rb'
+    - 'spec/services/fetch_remote_status_service_spec.rb'
+    - 'spec/services/follow_service_spec.rb'
+    - 'spec/services/import_service_spec.rb'
+    - 'spec/services/notify_service_spec.rb'
+    - 'spec/services/process_mentions_service_spec.rb'
+    - 'spec/services/reblog_service_spec.rb'
+    - 'spec/services/report_service_spec.rb'
+    - 'spec/services/resolve_account_service_spec.rb'
+    - 'spec/services/resolve_url_service_spec.rb'
+    - 'spec/services/search_service_spec.rb'
+    - 'spec/services/unallow_domain_service_spec.rb'
+    - 'spec/services/verify_link_service_spec.rb'
+    - 'spec/validators/disallowed_hashtags_validator_spec.rb'
+    - 'spec/validators/email_mx_validator_spec.rb'
+    - 'spec/validators/follow_limit_validator_spec.rb'
+    - 'spec/validators/poll_validator_spec.rb'
+    - 'spec/validators/status_pin_validator_spec.rb'
+    - 'spec/validators/unreserved_username_validator_spec.rb'
+    - 'spec/validators/url_validator_spec.rb'
+    - 'spec/workers/move_worker_spec.rb'
+    - 'spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb'
+
+# Offense count: 339
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: SkipBlocks, EnforcedStyle.
+# SupportedStyles: described_class, explicit
+RSpec/DescribedClass:
+  Exclude:
+    - 'spec/controllers/concerns/cache_concern_spec.rb'
+    - 'spec/controllers/concerns/challengable_concern_spec.rb'
+    - 'spec/lib/entity_cache_spec.rb'
+    - 'spec/lib/extractor_spec.rb'
+    - 'spec/lib/feed_manager_spec.rb'
+    - 'spec/lib/hash_object_spec.rb'
+    - 'spec/lib/ostatus/tag_manager_spec.rb'
+    - 'spec/lib/request_spec.rb'
+    - 'spec/lib/tag_manager_spec.rb'
+    - 'spec/lib/webfinger_resource_spec.rb'
+    - 'spec/mailers/notification_mailer_spec.rb'
+    - 'spec/mailers/user_mailer_spec.rb'
+    - 'spec/models/account_conversation_spec.rb'
+    - 'spec/models/account_domain_block_spec.rb'
+    - 'spec/models/account_migration_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/block_spec.rb'
+    - 'spec/models/domain_block_spec.rb'
+    - 'spec/models/email_domain_block_spec.rb'
+    - 'spec/models/export_spec.rb'
+    - 'spec/models/favourite_spec.rb'
+    - 'spec/models/follow_spec.rb'
+    - 'spec/models/identity_spec.rb'
+    - 'spec/models/import_spec.rb'
+    - 'spec/models/media_attachment_spec.rb'
+    - 'spec/models/notification_spec.rb'
+    - 'spec/models/relationship_filter_spec.rb'
+    - 'spec/models/report_filter_spec.rb'
+    - 'spec/models/session_activation_spec.rb'
+    - 'spec/models/setting_spec.rb'
+    - 'spec/models/site_upload_spec.rb'
+    - 'spec/models/status_pin_spec.rb'
+    - 'spec/models/status_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/policies/account_moderation_note_policy_spec.rb'
+    - 'spec/presenters/account_relationships_presenter_spec.rb'
+    - 'spec/presenters/instance_presenter_spec.rb'
+    - 'spec/presenters/status_relationships_presenter_spec.rb'
+    - 'spec/serializers/activitypub/note_spec.rb'
+    - 'spec/serializers/activitypub/update_poll_spec.rb'
+    - 'spec/serializers/rest/account_serializer_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_account_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_actor_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_key_service_spec.rb'
+    - 'spec/services/after_block_domain_from_account_service_spec.rb'
+    - 'spec/services/authorize_follow_service_spec.rb'
+    - 'spec/services/batched_remove_status_service_spec.rb'
+    - 'spec/services/block_domain_service_spec.rb'
+    - 'spec/services/block_service_spec.rb'
+    - 'spec/services/bootstrap_timeline_service_spec.rb'
+    - 'spec/services/clear_domain_media_service_spec.rb'
+    - 'spec/services/favourite_service_spec.rb'
+    - 'spec/services/follow_service_spec.rb'
+    - 'spec/services/import_service_spec.rb'
+    - 'spec/services/post_status_service_spec.rb'
+    - 'spec/services/precompute_feed_service_spec.rb'
+    - 'spec/services/process_mentions_service_spec.rb'
+    - 'spec/services/purge_domain_service_spec.rb'
+    - 'spec/services/reblog_service_spec.rb'
+    - 'spec/services/reject_follow_service_spec.rb'
+    - 'spec/services/remove_from_follwers_service_spec.rb'
+    - 'spec/services/remove_status_service_spec.rb'
+    - 'spec/services/unallow_domain_service_spec.rb'
+    - 'spec/services/unblock_service_spec.rb'
+    - 'spec/services/unfollow_service_spec.rb'
+    - 'spec/services/unmute_service_spec.rb'
+    - 'spec/services/update_account_service_spec.rb'
+    - 'spec/validators/note_length_validator_spec.rb'
+
+# Offense count: 32
+# This cop supports unsafe autocorrection (--autocorrect-all).
+RSpec/EmptyExampleGroup:
+  Exclude:
+    - 'spec/helpers/admin/action_log_helper_spec.rb'
+    - 'spec/models/account_alias_spec.rb'
+    - 'spec/models/account_deletion_request_spec.rb'
+    - 'spec/models/account_moderation_note_spec.rb'
+    - 'spec/models/announcement_mute_spec.rb'
+    - 'spec/models/announcement_reaction_spec.rb'
+    - 'spec/models/announcement_spec.rb'
+    - 'spec/models/backup_spec.rb'
+    - 'spec/models/conversation_mute_spec.rb'
+    - 'spec/models/custom_filter_keyword_spec.rb'
+    - 'spec/models/custom_filter_spec.rb'
+    - 'spec/models/device_spec.rb'
+    - 'spec/models/encrypted_message_spec.rb'
+    - 'spec/models/featured_tag_spec.rb'
+    - 'spec/models/follow_recommendation_suppression_spec.rb'
+    - 'spec/models/list_account_spec.rb'
+    - 'spec/models/list_spec.rb'
+    - 'spec/models/login_activity_spec.rb'
+    - 'spec/models/mute_spec.rb'
+    - 'spec/models/one_time_key_spec.rb'
+    - 'spec/models/preview_card_spec.rb'
+    - 'spec/models/preview_card_trend_spec.rb'
+    - 'spec/models/relay_spec.rb'
+    - 'spec/models/scheduled_status_spec.rb'
+    - 'spec/models/status_stat_spec.rb'
+    - 'spec/models/status_trend_spec.rb'
+    - 'spec/models/system_key_spec.rb'
+    - 'spec/models/tag_follow_spec.rb'
+    - 'spec/models/unavailable_domain_spec.rb'
+    - 'spec/models/user_invite_request_spec.rb'
+    - 'spec/models/web/setting_spec.rb'
+    - 'spec/services/unmute_service_spec.rb'
+
+# Offense count: 19
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/EmptyLineAfterSubject:
+  Exclude:
+    - 'spec/controllers/activitypub/collections_controller_spec.rb'
+    - 'spec/controllers/activitypub/followers_synchronizations_controller_spec.rb'
+    - 'spec/controllers/activitypub/outboxes_controller_spec.rb'
+    - 'spec/controllers/activitypub/replies_controller_spec.rb'
+    - 'spec/controllers/admin/reports/actions_controller_spec.rb'
+    - 'spec/controllers/api/web/embeds_controller_spec.rb'
+    - 'spec/controllers/emojis_controller_spec.rb'
+    - 'spec/controllers/follower_accounts_controller_spec.rb'
+    - 'spec/controllers/following_accounts_controller_spec.rb'
+    - 'spec/controllers/relationships_controller_spec.rb'
+    - 'spec/lib/activitypub/activity/delete_spec.rb'
+    - 'spec/lib/activitypub/activity/flag_spec.rb'
+    - 'spec/models/admin/account_action_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/services/fetch_remote_status_service_spec.rb'
+    - 'spec/workers/refollow_worker_spec.rb'
+
+# Offense count: 178
+# Configuration parameters: CountAsOne.
+RSpec/ExampleLength:
+  Max: 22
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/ExpectActual:
+  Exclude:
+    - 'spec/controllers/well_known/nodeinfo_controller_spec.rb'
+
+# Offense count: 21
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: method_call, block
+RSpec/ExpectChange:
+  Exclude:
+    - 'spec/controllers/admin/account_moderation_notes_controller_spec.rb'
+    - 'spec/controllers/admin/custom_emojis_controller_spec.rb'
+    - 'spec/controllers/admin/invites_controller_spec.rb'
+    - 'spec/controllers/admin/report_notes_controller_spec.rb'
+    - 'spec/controllers/concerns/accountable_concern_spec.rb'
+    - 'spec/controllers/invites_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
+    - 'spec/models/admin/account_action_spec.rb'
+    - 'spec/services/suspend_account_service_spec.rb'
+    - 'spec/services/unsuspend_account_service_spec.rb'
+    - 'spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb'
+
+# Offense count: 5
+RSpec/ExpectInHook:
+  Exclude:
+    - 'spec/controllers/api/v1/media_controller_spec.rb'
+    - 'spec/controllers/settings/applications_controller_spec.rb'
+    - 'spec/lib/status_filter_spec.rb'
+
+# Offense count: 61
+# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
+# Include: **/*_spec*rb*, **/spec/**/*
+RSpec/FilePath:
+  Exclude:
+    - 'spec/config/initializers/rack_attack_spec.rb'
+    - 'spec/controllers/activitypub/collections_controller_spec.rb'
+    - 'spec/controllers/activitypub/followers_synchronizations_controller_spec.rb'
+    - 'spec/controllers/activitypub/inboxes_controller_spec.rb'
+    - 'spec/controllers/activitypub/outboxes_controller_spec.rb'
+    - 'spec/controllers/activitypub/replies_controller_spec.rb'
+    - 'spec/controllers/admin/change_email_controller_spec.rb'
+    - 'spec/controllers/admin/users/roles_controller.rb'
+    - 'spec/controllers/api/oembed_controller_spec.rb'
+    - 'spec/controllers/concerns/account_controller_concern_spec.rb'
+    - 'spec/controllers/concerns/export_controller_concern_spec.rb'
+    - 'spec/controllers/concerns/localized_spec.rb'
+    - 'spec/controllers/concerns/rate_limit_headers_spec.rb'
+    - 'spec/controllers/concerns/signature_verification_spec.rb'
+    - 'spec/controllers/concerns/user_tracking_concern_spec.rb'
+    - 'spec/controllers/well_known/nodeinfo_controller_spec.rb'
+    - 'spec/helpers/admin/action_log_helper_spec.rb'
+    - 'spec/helpers/jsonld_helper_spec.rb'
+    - 'spec/lib/activitypub/activity/accept_spec.rb'
+    - 'spec/lib/activitypub/activity/add_spec.rb'
+    - 'spec/lib/activitypub/activity/announce_spec.rb'
+    - 'spec/lib/activitypub/activity/block_spec.rb'
+    - 'spec/lib/activitypub/activity/create_spec.rb'
+    - 'spec/lib/activitypub/activity/delete_spec.rb'
+    - 'spec/lib/activitypub/activity/flag_spec.rb'
+    - 'spec/lib/activitypub/activity/follow_spec.rb'
+    - 'spec/lib/activitypub/activity/like_spec.rb'
+    - 'spec/lib/activitypub/activity/move_spec.rb'
+    - 'spec/lib/activitypub/activity/reject_spec.rb'
+    - 'spec/lib/activitypub/activity/remove_spec.rb'
+    - 'spec/lib/activitypub/activity/undo_spec.rb'
+    - 'spec/lib/activitypub/activity/update_spec.rb'
+    - 'spec/lib/activitypub/adapter_spec.rb'
+    - 'spec/lib/activitypub/dereferencer_spec.rb'
+    - 'spec/lib/activitypub/linked_data_signature_spec.rb'
+    - 'spec/lib/activitypub/tag_manager_spec.rb'
+    - 'spec/lib/ostatus/tag_manager_spec.rb'
+    - 'spec/lib/sanitize_config_spec.rb'
+    - 'spec/serializers/activitypub/note_spec.rb'
+    - 'spec/serializers/activitypub/update_poll_spec.rb'
+    - 'spec/services/activitypub/fetch_featured_collection_service_spec.rb'
+    - 'spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_account_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_actor_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_key_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_status_service_spec.rb'
+    - 'spec/services/activitypub/fetch_replies_service_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+    - 'spec/services/activitypub/process_collection_service_spec.rb'
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/services/activitypub/synchronize_followers_service_spec.rb'
+    - 'spec/services/fetch_oembed_service_spec.rb'
+    - 'spec/services/remove_from_follwers_service_spec.rb'
+    - 'spec/workers/activitypub/delivery_worker_spec.rb'
+    - 'spec/workers/activitypub/distribute_poll_update_worker_spec.rb'
+    - 'spec/workers/activitypub/distribution_worker_spec.rb'
+    - 'spec/workers/activitypub/fetch_replies_worker_spec.rb'
+    - 'spec/workers/activitypub/move_distribution_worker_spec.rb'
+    - 'spec/workers/activitypub/processing_worker_spec.rb'
+    - 'spec/workers/activitypub/status_update_distribution_worker_spec.rb'
+    - 'spec/workers/activitypub/update_distribution_worker_spec.rb'
+
+# Offense count: 16
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: implicit, each, example
+RSpec/HookArgument:
+  Exclude:
+    - 'spec/controllers/api/v1/streaming_controller_spec.rb'
+    - 'spec/controllers/well_known/webfinger_controller_spec.rb'
+    - 'spec/helpers/instance_helper_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/rails_helper.rb'
+    - 'spec/serializers/activitypub/note_spec.rb'
+    - 'spec/serializers/activitypub/update_poll_spec.rb'
+    - 'spec/services/import_service_spec.rb'
+    - 'spec/spec_helper.rb'
+
+# Offense count: 159
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: single_line_only, single_statement_only, disallow, require_implicit
+RSpec/ImplicitSubject:
+  Exclude:
+    - 'spec/controllers/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/admin/instances_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/home_controller_spec.rb'
+    - 'spec/controllers/relationships_controller_spec.rb'
+    - 'spec/controllers/settings/featured_tags_controller_spec.rb'
+    - 'spec/controllers/settings/migrations_controller_spec.rb'
+    - 'spec/controllers/settings/sessions_controller_spec.rb'
+    - 'spec/features/log_in_spec.rb'
+    - 'spec/features/profile_spec.rb'
+    - 'spec/lib/emoji_formatter_spec.rb'
+    - 'spec/lib/entity_cache_spec.rb'
+    - 'spec/lib/html_aware_formatter_spec.rb'
+    - 'spec/lib/ostatus/tag_manager_spec.rb'
+    - 'spec/lib/plain_text_formatter_spec.rb'
+    - 'spec/lib/text_formatter_spec.rb'
+    - 'spec/models/concerns/account_interactions_spec.rb'
+    - 'spec/models/custom_emoji_spec.rb'
+    - 'spec/models/media_attachment_spec.rb'
+    - 'spec/models/notification_spec.rb'
+    - 'spec/models/remote_follow_spec.rb'
+    - 'spec/models/report_spec.rb'
+    - 'spec/models/session_activation_spec.rb'
+    - 'spec/models/setting_spec.rb'
+
+# Offense count: 101
+# Configuration parameters: AssignmentOnly.
+RSpec/InstanceVariable:
+  Exclude:
+    - 'spec/controllers/api/v1/streaming_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/auth/confirmations_controller_spec.rb'
+    - 'spec/controllers/auth/passwords_controller_spec.rb'
+    - 'spec/controllers/auth/sessions_controller_spec.rb'
+    - 'spec/controllers/concerns/export_controller_concern_spec.rb'
+    - 'spec/controllers/home_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
+    - 'spec/controllers/statuses_cleanup_controller_spec.rb'
+    - 'spec/models/concerns/account_finder_concern_spec.rb'
+    - 'spec/models/concerns/account_interactions_spec.rb'
+    - 'spec/models/concerns/remotable_spec.rb'
+    - 'spec/models/public_feed_spec.rb'
+    - 'spec/serializers/activitypub/note_spec.rb'
+    - 'spec/serializers/activitypub/update_poll_spec.rb'
+    - 'spec/services/remove_status_service_spec.rb'
+    - 'spec/services/search_service_spec.rb'
+    - 'spec/services/unblock_domain_service_spec.rb'
+
+# Offense count: 118
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/LeadingSubject:
+  Exclude:
+    - 'spec/controllers/activitypub/collections_controller_spec.rb'
+    - 'spec/controllers/activitypub/followers_synchronizations_controller_spec.rb'
+    - 'spec/controllers/activitypub/inboxes_controller_spec.rb'
+    - 'spec/controllers/activitypub/outboxes_controller_spec.rb'
+    - 'spec/controllers/admin/invites_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/controllers/well_known/webfinger_controller_spec.rb'
+    - 'spec/lib/activitypub/activity/accept_spec.rb'
+    - 'spec/lib/activitypub/activity/announce_spec.rb'
+    - 'spec/lib/activitypub/activity/create_spec.rb'
+    - 'spec/lib/activitypub/activity/reject_spec.rb'
+    - 'spec/lib/activitypub/activity/undo_spec.rb'
+    - 'spec/lib/activitypub/activity/update_spec.rb'
+    - 'spec/lib/activitypub/adapter_spec.rb'
+    - 'spec/lib/activitypub/dereferencer_spec.rb'
+    - 'spec/lib/activitypub/linked_data_signature_spec.rb'
+    - 'spec/lib/link_details_extractor_spec.rb'
+    - 'spec/lib/status_filter_spec.rb'
+    - 'spec/lib/status_reach_finder_spec.rb'
+    - 'spec/lib/suspicious_sign_in_detector_spec.rb'
+    - 'spec/lib/text_formatter_spec.rb'
+    - 'spec/lib/vacuum/backups_vacuum_spec.rb'
+    - 'spec/lib/vacuum/media_attachments_vacuum_spec.rb'
+    - 'spec/lib/vacuum/preview_cards_vacuum_spec.rb'
+    - 'spec/lib/vacuum/statuses_vacuum_spec.rb'
+    - 'spec/models/account/field_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/account_statuses_cleanup_policy_spec.rb'
+    - 'spec/models/account_statuses_filter_spec.rb'
+    - 'spec/models/concerns/account_interactions_spec.rb'
+    - 'spec/models/custom_emoji_filter_spec.rb'
+    - 'spec/models/custom_emoji_spec.rb'
+    - 'spec/models/home_feed_spec.rb'
+    - 'spec/models/media_attachment_spec.rb'
+    - 'spec/models/public_feed_spec.rb'
+    - 'spec/models/remote_follow_spec.rb'
+    - 'spec/models/setting_spec.rb'
+    - 'spec/models/status_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/models/web/push_subscription_spec.rb'
+    - 'spec/presenters/familiar_followers_presenter_spec.rb'
+    - 'spec/serializers/activitypub/note_spec.rb'
+    - 'spec/serializers/activitypub/update_poll_spec.rb'
+    - 'spec/serializers/rest/account_serializer_spec.rb'
+    - 'spec/services/activitypub/fetch_featured_collection_service_spec.rb'
+    - 'spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_status_service_spec.rb'
+    - 'spec/services/activitypub/fetch_replies_service_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+    - 'spec/services/activitypub/process_collection_service_spec.rb'
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/services/activitypub/synchronize_followers_service_spec.rb'
+    - 'spec/services/after_block_domain_from_account_service_spec.rb'
+    - 'spec/services/app_sign_up_service_spec.rb'
+    - 'spec/services/authorize_follow_service_spec.rb'
+    - 'spec/services/block_domain_service_spec.rb'
+    - 'spec/services/block_service_spec.rb'
+    - 'spec/services/clear_domain_media_service_spec.rb'
+    - 'spec/services/delete_account_service_spec.rb'
+    - 'spec/services/fan_out_on_write_service_spec.rb'
+    - 'spec/services/favourite_service_spec.rb'
+    - 'spec/services/fetch_resource_service_spec.rb'
+    - 'spec/services/follow_service_spec.rb'
+    - 'spec/services/process_mentions_service_spec.rb'
+    - 'spec/services/purge_domain_service_spec.rb'
+    - 'spec/services/reblog_service_spec.rb'
+    - 'spec/services/reject_follow_service_spec.rb'
+    - 'spec/services/remove_from_follwers_service_spec.rb'
+    - 'spec/services/report_service_spec.rb'
+    - 'spec/services/suspend_account_service_spec.rb'
+    - 'spec/services/unallow_domain_service_spec.rb'
+    - 'spec/services/unblock_service_spec.rb'
+    - 'spec/services/unfollow_service_spec.rb'
+    - 'spec/services/unsuspend_account_service_spec.rb'
+    - 'spec/validators/blacklisted_email_validator_spec.rb'
+    - 'spec/workers/move_worker_spec.rb'
+    - 'spec/workers/unfollow_follow_worker_spec.rb'
+
+# Offense count: 15
+RSpec/LeakyConstantDeclaration:
+  Exclude:
+    - 'spec/controllers/api/base_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/concerns/accountable_concern_spec.rb'
+    - 'spec/controllers/concerns/signature_verification_spec.rb'
+    - 'spec/lib/activitypub/adapter_spec.rb'
+    - 'spec/lib/connection_pool/shared_connection_pool_spec.rb'
+    - 'spec/lib/connection_pool/shared_timed_stack_spec.rb'
+    - 'spec/lib/settings/extend_spec.rb'
+    - 'spec/models/concerns/remotable_spec.rb'
+
+# Offense count: 108
+RSpec/LetSetup:
+  Exclude:
+    - 'spec/controllers/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/admin/action_logs_controller_spec.rb'
+    - 'spec/controllers/admin/instances_controller_spec.rb'
+    - 'spec/controllers/admin/reports/actions_controller_spec.rb'
+    - 'spec/controllers/admin/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_allows_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/filters_controller_spec.rb'
+    - 'spec/controllers/api/v1/followed_tags_controller_spec.rb'
+    - 'spec/controllers/api/v1/tags_controller_spec.rb'
+    - 'spec/controllers/api/v2/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/keywords_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters_controller_spec.rb'
+    - 'spec/controllers/auth/confirmations_controller_spec.rb'
+    - 'spec/controllers/auth/passwords_controller_spec.rb'
+    - 'spec/controllers/auth/sessions_controller_spec.rb'
+    - 'spec/controllers/follower_accounts_controller_spec.rb'
+    - 'spec/controllers/following_accounts_controller_spec.rb'
+    - 'spec/controllers/oauth/authorized_applications_controller_spec.rb'
+    - 'spec/controllers/oauth/tokens_controller_spec.rb'
+    - 'spec/controllers/tags_controller_spec.rb'
+    - 'spec/lib/activitypub/activity/delete_spec.rb'
+    - 'spec/lib/vacuum/preview_cards_vacuum_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/account_statuses_cleanup_policy_spec.rb'
+    - 'spec/models/canonical_email_block_spec.rb'
+    - 'spec/models/status_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/services/account_statuses_cleanup_service_spec.rb'
+    - 'spec/services/activitypub/fetch_featured_collection_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_status_service_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+    - 'spec/services/activitypub/process_collection_service_spec.rb'
+    - 'spec/services/batched_remove_status_service_spec.rb'
+    - 'spec/services/block_domain_service_spec.rb'
+    - 'spec/services/delete_account_service_spec.rb'
+    - 'spec/services/import_service_spec.rb'
+    - 'spec/services/notify_service_spec.rb'
+    - 'spec/services/remove_status_service_spec.rb'
+    - 'spec/services/report_service_spec.rb'
+    - 'spec/services/resolve_account_service_spec.rb'
+    - 'spec/services/suspend_account_service_spec.rb'
+    - 'spec/services/unallow_domain_service_spec.rb'
+    - 'spec/services/unsuspend_account_service_spec.rb'
+    - 'spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb'
+    - 'spec/workers/scheduler/user_cleanup_scheduler_spec.rb'
+
+# Offense count: 7
+RSpec/MessageChain:
+  Exclude:
+    - 'spec/controllers/api/v1/media_controller_spec.rb'
+    - 'spec/models/concerns/remotable_spec.rb'
+    - 'spec/models/session_activation_spec.rb'
+    - 'spec/models/setting_spec.rb'
+
+# Offense count: 47
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: have_received, receive
+RSpec/MessageSpies:
+  Exclude:
+    - 'spec/controllers/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/api/base_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/helpers/admin/account_moderation_notes_helper_spec.rb'
+    - 'spec/helpers/application_helper_spec.rb'
+    - 'spec/lib/status_finder_spec.rb'
+    - 'spec/lib/webfinger_resource_spec.rb'
+    - 'spec/models/admin/account_action_spec.rb'
+    - 'spec/models/concerns/remotable_spec.rb'
+    - 'spec/models/follow_request_spec.rb'
+    - 'spec/models/identity_spec.rb'
+    - 'spec/models/session_activation_spec.rb'
+    - 'spec/models/setting_spec.rb'
+    - 'spec/services/activitypub/fetch_replies_service_spec.rb'
+    - 'spec/services/activitypub/process_collection_service_spec.rb'
+    - 'spec/spec_helper.rb'
+    - 'spec/validators/status_length_validator_spec.rb'
+
+# Offense count: 35
+RSpec/MissingExampleGroupArgument:
+  Exclude:
+    - 'spec/controllers/accounts_controller_spec.rb'
+    - 'spec/controllers/activitypub/collections_controller_spec.rb'
+    - 'spec/controllers/admin/statuses_controller_spec.rb'
+    - 'spec/controllers/admin/users/roles_controller.rb'
+    - 'spec/controllers/api/v1/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/account_actions_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_allows_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/features/log_in_spec.rb'
+    - 'spec/lib/activitypub/activity/undo_spec.rb'
+    - 'spec/lib/status_reach_finder_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/email_domain_block_spec.rb'
+    - 'spec/models/trends/statuses_spec.rb'
+    - 'spec/models/trends/tags_spec.rb'
+    - 'spec/models/user_role_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/services/fetch_link_card_service_spec.rb'
+    - 'spec/services/notify_service_spec.rb'
+    - 'spec/services/process_mentions_service_spec.rb'
+
+# Offense count: 599
+RSpec/MultipleExpectations:
+  Max: 19
+
+# Offense count: 443
+# Configuration parameters: AllowSubject.
+RSpec/MultipleMemoizedHelpers:
+  Max: 21
+
+# Offense count: 7
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/MultipleSubjects:
+  Exclude:
+    - 'spec/controllers/activitypub/collections_controller_spec.rb'
+    - 'spec/controllers/activitypub/followers_synchronizations_controller_spec.rb'
+    - 'spec/controllers/activitypub/outboxes_controller_spec.rb'
+    - 'spec/controllers/api/web/embeds_controller_spec.rb'
+    - 'spec/controllers/emojis_controller_spec.rb'
+    - 'spec/controllers/follower_accounts_controller_spec.rb'
+    - 'spec/controllers/following_accounts_controller_spec.rb'
+
+# Offense count: 1252
+# Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
+# SupportedStyles: always, named_only
+RSpec/NamedSubject:
+  Exclude:
+    - 'spec/controllers/admin/account_moderation_notes_controller_spec.rb'
+    - 'spec/controllers/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/admin/confirmations_controller_spec.rb'
+    - 'spec/controllers/admin/custom_emojis_controller_spec.rb'
+    - 'spec/controllers/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/invites_controller_spec.rb'
+    - 'spec/controllers/admin/report_notes_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/notes_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/pins_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/auth/passwords_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/controllers/invites_controller_spec.rb'
+    - 'spec/controllers/oauth/authorizations_controller_spec.rb'
+    - 'spec/controllers/oauth/authorized_applications_controller_spec.rb'
+    - 'spec/controllers/relationships_controller_spec.rb'
+    - 'spec/controllers/settings/featured_tags_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb'
+    - 'spec/controllers/well_known/webfinger_controller_spec.rb'
+    - 'spec/lib/activitypub/activity/accept_spec.rb'
+    - 'spec/lib/activitypub/activity/add_spec.rb'
+    - 'spec/lib/activitypub/activity/announce_spec.rb'
+    - 'spec/lib/activitypub/activity/block_spec.rb'
+    - 'spec/lib/activitypub/activity/create_spec.rb'
+    - 'spec/lib/activitypub/activity/delete_spec.rb'
+    - 'spec/lib/activitypub/activity/flag_spec.rb'
+    - 'spec/lib/activitypub/activity/follow_spec.rb'
+    - 'spec/lib/activitypub/activity/like_spec.rb'
+    - 'spec/lib/activitypub/activity/move_spec.rb'
+    - 'spec/lib/activitypub/activity/reject_spec.rb'
+    - 'spec/lib/activitypub/activity/remove_spec.rb'
+    - 'spec/lib/activitypub/activity/undo_spec.rb'
+    - 'spec/lib/activitypub/activity/update_spec.rb'
+    - 'spec/lib/activitypub/adapter_spec.rb'
+    - 'spec/lib/activitypub/dereferencer_spec.rb'
+    - 'spec/lib/activitypub/linked_data_signature_spec.rb'
+    - 'spec/lib/activitypub/tag_manager_spec.rb'
+    - 'spec/lib/connection_pool/shared_connection_pool_spec.rb'
+    - 'spec/lib/connection_pool/shared_timed_stack_spec.rb'
+    - 'spec/lib/delivery_failure_tracker_spec.rb'
+    - 'spec/lib/emoji_formatter_spec.rb'
+    - 'spec/lib/fast_ip_map_spec.rb'
+    - 'spec/lib/feed_manager_spec.rb'
+    - 'spec/lib/hashtag_normalizer_spec.rb'
+    - 'spec/lib/link_details_extractor_spec.rb'
+    - 'spec/lib/request_pool_spec.rb'
+    - 'spec/lib/request_spec.rb'
+    - 'spec/lib/sanitize_config_spec.rb'
+    - 'spec/lib/status_finder_spec.rb'
+    - 'spec/lib/status_reach_finder_spec.rb'
+    - 'spec/lib/suspicious_sign_in_detector_spec.rb'
+    - 'spec/lib/vacuum/access_tokens_vacuum_spec.rb'
+    - 'spec/lib/vacuum/backups_vacuum_spec.rb'
+    - 'spec/lib/vacuum/feeds_vacuum_spec.rb'
+    - 'spec/lib/vacuum/media_attachments_vacuum_spec.rb'
+    - 'spec/lib/vacuum/preview_cards_vacuum_spec.rb'
+    - 'spec/lib/vacuum/statuses_vacuum_spec.rb'
+    - 'spec/lib/vacuum/system_keys_vacuum_spec.rb'
+    - 'spec/models/account/field_spec.rb'
+    - 'spec/models/account_migration_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/account_statuses_cleanup_policy_spec.rb'
+    - 'spec/models/account_statuses_filter_spec.rb'
+    - 'spec/models/admin/account_action_spec.rb'
+    - 'spec/models/canonical_email_block_spec.rb'
+    - 'spec/models/concerns/account_interactions_spec.rb'
+    - 'spec/models/custom_emoji_filter_spec.rb'
+    - 'spec/models/follow_spec.rb'
+    - 'spec/models/home_feed_spec.rb'
+    - 'spec/models/notification_spec.rb'
+    - 'spec/models/public_feed_spec.rb'
+    - 'spec/models/relationship_filter_spec.rb'
+    - 'spec/models/status_spec.rb'
+    - 'spec/models/tag_spec.rb'
+    - 'spec/models/trends/statuses_spec.rb'
+    - 'spec/models/trends/tags_spec.rb'
+    - 'spec/models/user_role_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/models/web/push_subscription_spec.rb'
+    - 'spec/policies/account_moderation_note_policy_spec.rb'
+    - 'spec/policies/account_policy_spec.rb'
+    - 'spec/policies/backup_policy_spec.rb'
+    - 'spec/policies/custom_emoji_policy_spec.rb'
+    - 'spec/policies/domain_block_policy_spec.rb'
+    - 'spec/policies/email_domain_block_policy_spec.rb'
+    - 'spec/policies/instance_policy_spec.rb'
+    - 'spec/policies/invite_policy_spec.rb'
+    - 'spec/policies/relay_policy_spec.rb'
+    - 'spec/policies/report_note_policy_spec.rb'
+    - 'spec/policies/report_policy_spec.rb'
+    - 'spec/policies/settings_policy_spec.rb'
+    - 'spec/policies/status_policy_spec.rb'
+    - 'spec/policies/tag_policy_spec.rb'
+    - 'spec/policies/user_policy_spec.rb'
+    - 'spec/presenters/familiar_followers_presenter_spec.rb'
+    - 'spec/serializers/activitypub/note_spec.rb'
+    - 'spec/serializers/activitypub/update_poll_spec.rb'
+    - 'spec/serializers/rest/account_serializer_spec.rb'
+    - 'spec/services/account_search_service_spec.rb'
+    - 'spec/services/account_statuses_cleanup_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_account_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_actor_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_status_service_spec.rb'
+    - 'spec/services/activitypub/fetch_replies_service_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+    - 'spec/services/activitypub/process_collection_service_spec.rb'
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/services/after_block_domain_from_account_service_spec.rb'
+    - 'spec/services/after_block_service_spec.rb'
+    - 'spec/services/app_sign_up_service_spec.rb'
+    - 'spec/services/authorize_follow_service_spec.rb'
+    - 'spec/services/batched_remove_status_service_spec.rb'
+    - 'spec/services/block_domain_service_spec.rb'
+    - 'spec/services/block_service_spec.rb'
+    - 'spec/services/bootstrap_timeline_service_spec.rb'
+    - 'spec/services/clear_domain_media_service_spec.rb'
+    - 'spec/services/delete_account_service_spec.rb'
+    - 'spec/services/fan_out_on_write_service_spec.rb'
+    - 'spec/services/favourite_service_spec.rb'
+    - 'spec/services/fetch_link_card_service_spec.rb'
+    - 'spec/services/fetch_oembed_service_spec.rb'
+    - 'spec/services/fetch_remote_status_service_spec.rb'
+    - 'spec/services/fetch_resource_service_spec.rb'
+    - 'spec/services/follow_service_spec.rb'
+    - 'spec/services/import_service_spec.rb'
+    - 'spec/services/mute_service_spec.rb'
+    - 'spec/services/notify_service_spec.rb'
+    - 'spec/services/post_status_service_spec.rb'
+    - 'spec/services/precompute_feed_service_spec.rb'
+    - 'spec/services/process_mentions_service_spec.rb'
+    - 'spec/services/purge_domain_service_spec.rb'
+    - 'spec/services/reblog_service_spec.rb'
+    - 'spec/services/reject_follow_service_spec.rb'
+    - 'spec/services/remove_from_follwers_service_spec.rb'
+    - 'spec/services/remove_status_service_spec.rb'
+    - 'spec/services/report_service_spec.rb'
+    - 'spec/services/resolve_account_service_spec.rb'
+    - 'spec/services/resolve_url_service_spec.rb'
+    - 'spec/services/search_service_spec.rb'
+    - 'spec/services/suspend_account_service_spec.rb'
+    - 'spec/services/unallow_domain_service_spec.rb'
+    - 'spec/services/unblock_domain_service_spec.rb'
+    - 'spec/services/unblock_service_spec.rb'
+    - 'spec/services/unfollow_service_spec.rb'
+    - 'spec/services/unsuspend_account_service_spec.rb'
+    - 'spec/services/update_account_service_spec.rb'
+    - 'spec/services/update_status_service_spec.rb'
+    - 'spec/services/verify_link_service_spec.rb'
+    - 'spec/validators/blacklisted_email_validator_spec.rb'
+    - 'spec/validators/email_mx_validator_spec.rb'
+    - 'spec/validators/note_length_validator_spec.rb'
+    - 'spec/validators/reaction_validator_spec.rb'
+    - 'spec/validators/status_length_validator_spec.rb'
+    - 'spec/validators/status_pin_validator_spec.rb'
+    - 'spec/validators/unique_username_validator_spec.rb'
+    - 'spec/workers/activitypub/delivery_worker_spec.rb'
+    - 'spec/workers/activitypub/distribute_poll_update_worker_spec.rb'
+    - 'spec/workers/activitypub/distribution_worker_spec.rb'
+    - 'spec/workers/activitypub/fetch_replies_worker_spec.rb'
+    - 'spec/workers/activitypub/move_distribution_worker_spec.rb'
+    - 'spec/workers/activitypub/processing_worker_spec.rb'
+    - 'spec/workers/activitypub/status_update_distribution_worker_spec.rb'
+    - 'spec/workers/activitypub/update_distribution_worker_spec.rb'
+    - 'spec/workers/admin/domain_purge_worker_spec.rb'
+    - 'spec/workers/domain_block_worker_spec.rb'
+    - 'spec/workers/domain_clear_media_worker_spec.rb'
+    - 'spec/workers/feed_insert_worker_spec.rb'
+    - 'spec/workers/move_worker_spec.rb'
+    - 'spec/workers/publish_scheduled_announcement_worker_spec.rb'
+    - 'spec/workers/publish_scheduled_status_worker_spec.rb'
+    - 'spec/workers/refollow_worker_spec.rb'
+    - 'spec/workers/regeneration_worker_spec.rb'
+    - 'spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb'
+    - 'spec/workers/scheduler/user_cleanup_scheduler_spec.rb'
+    - 'spec/workers/unfollow_follow_worker_spec.rb'
+    - 'spec/workers/web/push_notification_worker_spec.rb'
+
+# Offense count: 552
+# Configuration parameters: AllowedGroups.
+RSpec/NestedGroups:
+  Max: 6
+
+# Offense count: 2
+# Configuration parameters: AllowedPatterns.
+# AllowedPatterns: ^expect_, ^assert_
+RSpec/NoExpectationExample:
+  Exclude:
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/services/precompute_feed_service_spec.rb'
+
+# Offense count: 370
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: not_to, to_not
+RSpec/NotToNot:
+  Exclude:
+    - 'spec/config/initializers/rack_attack_spec.rb'
+    - 'spec/controllers/accounts_controller_spec.rb'
+    - 'spec/controllers/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/admin/email_domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/roles_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/account_actions_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_allows_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/announcements/reactions_controller_spec.rb'
+    - 'spec/controllers/api/v1/announcements_controller_spec.rb'
+    - 'spec/controllers/api/v1/apps/credentials_controller_spec.rb'
+    - 'spec/controllers/api/v1/apps_controller_spec.rb'
+    - 'spec/controllers/api/v1/filters_controller_spec.rb'
+    - 'spec/controllers/api/v1/media_controller_spec.rb'
+    - 'spec/controllers/api/v1/notifications_controller_spec.rb'
+    - 'spec/controllers/api/v1/polls/votes_controller_spec.rb'
+    - 'spec/controllers/api/v1/reports_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/mutes_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/keywords_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters_controller_spec.rb'
+    - 'spec/controllers/auth/challenges_controller_spec.rb'
+    - 'spec/controllers/auth/confirmations_controller_spec.rb'
+    - 'spec/controllers/auth/passwords_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/controllers/concerns/challengable_concern_spec.rb'
+    - 'spec/controllers/oauth/authorized_applications_controller_spec.rb'
+    - 'spec/controllers/oauth/tokens_controller_spec.rb'
+    - 'spec/controllers/settings/applications_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
+    - 'spec/controllers/statuses_controller_spec.rb'
+    - 'spec/helpers/application_helper_spec.rb'
+    - 'spec/lib/activitypub/activity/announce_spec.rb'
+    - 'spec/lib/activitypub/activity/create_spec.rb'
+    - 'spec/lib/activitypub/activity/delete_spec.rb'
+    - 'spec/lib/activitypub/activity/flag_spec.rb'
+    - 'spec/lib/activitypub/dereferencer_spec.rb'
+    - 'spec/lib/activitypub/tag_manager_spec.rb'
+    - 'spec/lib/delivery_failure_tracker_spec.rb'
+    - 'spec/lib/feed_manager_spec.rb'
+    - 'spec/lib/html_aware_formatter_spec.rb'
+    - 'spec/lib/request_pool_spec.rb'
+    - 'spec/lib/status_reach_finder_spec.rb'
+    - 'spec/lib/vacuum/access_tokens_vacuum_spec.rb'
+    - 'spec/lib/vacuum/backups_vacuum_spec.rb'
+    - 'spec/lib/vacuum/media_attachments_vacuum_spec.rb'
+    - 'spec/lib/vacuum/preview_cards_vacuum_spec.rb'
+    - 'spec/lib/vacuum/statuses_vacuum_spec.rb'
+    - 'spec/lib/vacuum/system_keys_vacuum_spec.rb'
+    - 'spec/models/account/field_spec.rb'
+    - 'spec/models/account_conversation_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/account_statuses_cleanup_policy_spec.rb'
+    - 'spec/models/account_statuses_filter_spec.rb'
+    - 'spec/models/concerns/remotable_spec.rb'
+    - 'spec/models/concerns/status_threading_concern_spec.rb'
+    - 'spec/models/follow_spec.rb'
+    - 'spec/models/media_attachment_spec.rb'
+    - 'spec/models/status_spec.rb'
+    - 'spec/models/tag_feed_spec.rb'
+    - 'spec/models/trends/statuses_spec.rb'
+    - 'spec/models/trends/tags_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/models/webhook_spec.rb'
+    - 'spec/policies/account_moderation_note_policy_spec.rb'
+    - 'spec/policies/account_policy_spec.rb'
+    - 'spec/policies/backup_policy_spec.rb'
+    - 'spec/policies/custom_emoji_policy_spec.rb'
+    - 'spec/policies/domain_block_policy_spec.rb'
+    - 'spec/policies/email_domain_block_policy_spec.rb'
+    - 'spec/policies/instance_policy_spec.rb'
+    - 'spec/policies/invite_policy_spec.rb'
+    - 'spec/policies/relay_policy_spec.rb'
+    - 'spec/policies/report_note_policy_spec.rb'
+    - 'spec/policies/report_policy_spec.rb'
+    - 'spec/policies/settings_policy_spec.rb'
+    - 'spec/policies/status_policy_spec.rb'
+    - 'spec/policies/tag_policy_spec.rb'
+    - 'spec/policies/user_policy_spec.rb'
+    - 'spec/presenters/familiar_followers_presenter_spec.rb'
+    - 'spec/serializers/activitypub/note_spec.rb'
+    - 'spec/services/account_statuses_cleanup_service_spec.rb'
+    - 'spec/services/activitypub/fetch_remote_status_service_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/services/app_sign_up_service_spec.rb'
+    - 'spec/services/batched_remove_status_service_spec.rb'
+    - 'spec/services/block_domain_service_spec.rb'
+    - 'spec/services/bootstrap_timeline_service_spec.rb'
+    - 'spec/services/fan_out_on_write_service_spec.rb'
+    - 'spec/services/favourite_service_spec.rb'
+    - 'spec/services/fetch_link_card_service_spec.rb'
+    - 'spec/services/fetch_oembed_service_spec.rb'
+    - 'spec/services/fetch_remote_status_service_spec.rb'
+    - 'spec/services/follow_service_spec.rb'
+    - 'spec/services/mute_service_spec.rb'
+    - 'spec/services/notify_service_spec.rb'
+    - 'spec/services/remove_status_service_spec.rb'
+    - 'spec/services/report_service_spec.rb'
+    - 'spec/services/resolve_account_service_spec.rb'
+    - 'spec/services/search_service_spec.rb'
+    - 'spec/services/suspend_account_service_spec.rb'
+    - 'spec/services/unallow_domain_service_spec.rb'
+    - 'spec/services/unsuspend_account_service_spec.rb'
+    - 'spec/services/update_status_service_spec.rb'
+    - 'spec/support/examples/models/concerns/account_avatar.rb'
+    - 'spec/support/examples/models/concerns/account_header.rb'
+    - 'spec/validators/email_mx_validator_spec.rb'
+    - 'spec/validators/note_length_validator_spec.rb'
+    - 'spec/validators/reaction_validator_spec.rb'
+    - 'spec/validators/status_length_validator_spec.rb'
+    - 'spec/validators/unique_username_validator_spec.rb'
+    - 'spec/workers/activitypub/fetch_replies_worker_spec.rb'
+    - 'spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb'
+
+# Offense count: 3
+RSpec/PendingWithoutReason:
+  Exclude:
+    - 'spec/models/account_spec.rb'
+    - 'spec/support/examples/lib/settings/scoped_settings.rb'
+
+# Offense count: 9
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Strict, EnforcedStyle, AllowedExplicitMatchers.
+# SupportedStyles: inflected, explicit
+RSpec/PredicateMatcher:
+  Exclude:
+    - 'spec/controllers/api/v1/accounts/notes_controller_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/services/post_status_service_spec.rb'
+
+# Offense count: 3
+# This cop supports unsafe autocorrection (--autocorrect-all).
+RSpec/Rails/HaveHttpStatus:
+  Exclude:
+    - 'spec/controllers/settings/applications_controller_spec.rb'
+    - 'spec/requests/catch_all_route_request_spec.rb'
+
+# Offense count: 432
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: numeric, symbolic
+RSpec/Rails/HttpStatus:
+  Exclude:
+    - 'spec/controllers/about_controller_spec.rb'
+    - 'spec/controllers/accounts_controller_spec.rb'
+    - 'spec/controllers/activitypub/collections_controller_spec.rb'
+    - 'spec/controllers/activitypub/followers_synchronizations_controller_spec.rb'
+    - 'spec/controllers/activitypub/inboxes_controller_spec.rb'
+    - 'spec/controllers/activitypub/outboxes_controller_spec.rb'
+    - 'spec/controllers/activitypub/replies_controller_spec.rb'
+    - 'spec/controllers/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/admin/action_logs_controller_spec.rb'
+    - 'spec/controllers/admin/change_email_controller_spec.rb'
+    - 'spec/controllers/admin/confirmations_controller_spec.rb'
+    - 'spec/controllers/admin/custom_emojis_controller_spec.rb'
+    - 'spec/controllers/admin/dashboard_controller_spec.rb'
+    - 'spec/controllers/admin/domain_allows_controller_spec.rb'
+    - 'spec/controllers/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/email_domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/export_domain_allows_controller_spec.rb'
+    - 'spec/controllers/admin/export_domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/instances_controller_spec.rb'
+    - 'spec/controllers/admin/reports/actions_controller_spec.rb'
+    - 'spec/controllers/admin/reports_controller_spec.rb'
+    - 'spec/controllers/admin/settings/branding_controller_spec.rb'
+    - 'spec/controllers/admin/statuses_controller_spec.rb'
+    - 'spec/controllers/admin/tags_controller_spec.rb'
+    - 'spec/controllers/api/base_controller_spec.rb'
+    - 'spec/controllers/api/oembed_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/credentials_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/follower_accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/following_accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/lists_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/notes_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/pins_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/relationships_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/search_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/account_actions_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_allows_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/reports_controller_spec.rb'
+    - 'spec/controllers/api/v1/announcements/reactions_controller_spec.rb'
+    - 'spec/controllers/api/v1/announcements_controller_spec.rb'
+    - 'spec/controllers/api/v1/apps/credentials_controller_spec.rb'
+    - 'spec/controllers/api/v1/apps_controller_spec.rb'
+    - 'spec/controllers/api/v1/blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/conversations_controller_spec.rb'
+    - 'spec/controllers/api/v1/custom_emojis_controller_spec.rb'
+    - 'spec/controllers/api/v1/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/endorsements_controller_spec.rb'
+    - 'spec/controllers/api/v1/filters_controller_spec.rb'
+    - 'spec/controllers/api/v1/follow_requests_controller_spec.rb'
+    - 'spec/controllers/api/v1/instances/activity_controller_spec.rb'
+    - 'spec/controllers/api/v1/instances/peers_controller_spec.rb'
+    - 'spec/controllers/api/v1/instances_controller_spec.rb'
+    - 'spec/controllers/api/v1/lists/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/lists_controller_spec.rb'
+    - 'spec/controllers/api/v1/markers_controller_spec.rb'
+    - 'spec/controllers/api/v1/media_controller_spec.rb'
+    - 'spec/controllers/api/v1/mutes_controller_spec.rb'
+    - 'spec/controllers/api/v1/notifications_controller_spec.rb'
+    - 'spec/controllers/api/v1/polls/votes_controller_spec.rb'
+    - 'spec/controllers/api/v1/polls_controller_spec.rb'
+    - 'spec/controllers/api/v1/reports_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/bookmarks_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/favourites_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/histories_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/mutes_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/pins_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/reblogs_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/sources_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v1/streaming_controller_spec.rb'
+    - 'spec/controllers/api/v1/suggestions_controller_spec.rb'
+    - 'spec/controllers/api/v1/timelines/home_controller_spec.rb'
+    - 'spec/controllers/api/v1/timelines/list_controller_spec.rb'
+    - 'spec/controllers/api/v1/timelines/public_controller_spec.rb'
+    - 'spec/controllers/api/v1/timelines/tag_controller_spec.rb'
+    - 'spec/controllers/api/v1/trends/tags_controller_spec.rb'
+    - 'spec/controllers/api/v2/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/keywords_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters_controller_spec.rb'
+    - 'spec/controllers/api/v2/search_controller_spec.rb'
+    - 'spec/controllers/api/web/settings_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/auth/confirmations_controller_spec.rb'
+    - 'spec/controllers/auth/passwords_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/controllers/auth/sessions_controller_spec.rb'
+    - 'spec/controllers/authorize_interactions_controller_spec.rb'
+    - 'spec/controllers/concerns/account_controller_concern_spec.rb'
+    - 'spec/controllers/concerns/export_controller_concern_spec.rb'
+    - 'spec/controllers/concerns/signature_verification_spec.rb'
+    - 'spec/controllers/emojis_controller_spec.rb'
+    - 'spec/controllers/follower_accounts_controller_spec.rb'
+    - 'spec/controllers/following_accounts_controller_spec.rb'
+    - 'spec/controllers/instance_actors_controller_spec.rb'
+    - 'spec/controllers/intents_controller_spec.rb'
+    - 'spec/controllers/invites_controller_spec.rb'
+    - 'spec/controllers/manifests_controller_spec.rb'
+    - 'spec/controllers/media_controller_spec.rb'
+    - 'spec/controllers/media_proxy_controller_spec.rb'
+    - 'spec/controllers/oauth/authorizations_controller_spec.rb'
+    - 'spec/controllers/oauth/authorized_applications_controller_spec.rb'
+    - 'spec/controllers/relationships_controller_spec.rb'
+    - 'spec/controllers/settings/applications_controller_spec.rb'
+    - 'spec/controllers/settings/deletes_controller_spec.rb'
+    - 'spec/controllers/settings/exports_controller_spec.rb'
+    - 'spec/controllers/settings/imports_controller_spec.rb'
+    - 'spec/controllers/settings/migrations_controller_spec.rb'
+    - 'spec/controllers/settings/preferences/notifications_controller_spec.rb'
+    - 'spec/controllers/settings/preferences/other_controller_spec.rb'
+    - 'spec/controllers/settings/profiles_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/otp_authentication_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/recovery_codes_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb'
+    - 'spec/controllers/statuses_cleanup_controller_spec.rb'
+    - 'spec/controllers/statuses_controller_spec.rb'
+    - 'spec/controllers/tags_controller_spec.rb'
+    - 'spec/controllers/well_known/host_meta_controller_spec.rb'
+    - 'spec/controllers/well_known/nodeinfo_controller_spec.rb'
+    - 'spec/controllers/well_known/webfinger_controller_spec.rb'
+    - 'spec/requests/host_meta_request_spec.rb'
+    - 'spec/requests/webfinger_request_spec.rb'
+
+# Offense count: 180
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Inferences.
+RSpec/Rails/InferredSpecType:
+  Exclude:
+    - 'spec/controllers/about_controller_spec.rb'
+    - 'spec/controllers/accounts_controller_spec.rb'
+    - 'spec/controllers/activitypub/collections_controller_spec.rb'
+    - 'spec/controllers/activitypub/followers_synchronizations_controller_spec.rb'
+    - 'spec/controllers/activitypub/inboxes_controller_spec.rb'
+    - 'spec/controllers/activitypub/outboxes_controller_spec.rb'
+    - 'spec/controllers/activitypub/replies_controller_spec.rb'
+    - 'spec/controllers/admin/account_moderation_notes_controller_spec.rb'
+    - 'spec/controllers/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/admin/action_logs_controller_spec.rb'
+    - 'spec/controllers/admin/base_controller_spec.rb'
+    - 'spec/controllers/admin/change_email_controller_spec.rb'
+    - 'spec/controllers/admin/confirmations_controller_spec.rb'
+    - 'spec/controllers/admin/dashboard_controller_spec.rb'
+    - 'spec/controllers/admin/disputes/appeals_controller_spec.rb'
+    - 'spec/controllers/admin/domain_allows_controller_spec.rb'
+    - 'spec/controllers/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/email_domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/export_domain_allows_controller_spec.rb'
+    - 'spec/controllers/admin/export_domain_blocks_controller_spec.rb'
+    - 'spec/controllers/admin/instances_controller_spec.rb'
+    - 'spec/controllers/admin/settings/branding_controller_spec.rb'
+    - 'spec/controllers/admin/tags_controller_spec.rb'
+    - 'spec/controllers/api/oembed_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/pins_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts/search_controller_spec.rb'
+    - 'spec/controllers/api/v1/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/account_actions_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_allows_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/reports_controller_spec.rb'
+    - 'spec/controllers/api/v1/announcements/reactions_controller_spec.rb'
+    - 'spec/controllers/api/v1/announcements_controller_spec.rb'
+    - 'spec/controllers/api/v1/apps_controller_spec.rb'
+    - 'spec/controllers/api/v1/blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/bookmarks_controller_spec.rb'
+    - 'spec/controllers/api/v1/conversations_controller_spec.rb'
+    - 'spec/controllers/api/v1/custom_emojis_controller_spec.rb'
+    - 'spec/controllers/api/v1/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/emails/confirmations_controller_spec.rb'
+    - 'spec/controllers/api/v1/endorsements_controller_spec.rb'
+    - 'spec/controllers/api/v1/favourites_controller_spec.rb'
+    - 'spec/controllers/api/v1/filters_controller_spec.rb'
+    - 'spec/controllers/api/v1/follow_requests_controller_spec.rb'
+    - 'spec/controllers/api/v1/followed_tags_controller_spec.rb'
+    - 'spec/controllers/api/v1/instances/activity_controller_spec.rb'
+    - 'spec/controllers/api/v1/instances/peers_controller_spec.rb'
+    - 'spec/controllers/api/v1/instances_controller_spec.rb'
+    - 'spec/controllers/api/v1/lists_controller_spec.rb'
+    - 'spec/controllers/api/v1/markers_controller_spec.rb'
+    - 'spec/controllers/api/v1/media_controller_spec.rb'
+    - 'spec/controllers/api/v1/mutes_controller_spec.rb'
+    - 'spec/controllers/api/v1/notifications_controller_spec.rb'
+    - 'spec/controllers/api/v1/polls/votes_controller_spec.rb'
+    - 'spec/controllers/api/v1/polls_controller_spec.rb'
+    - 'spec/controllers/api/v1/reports_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v1/suggestions_controller_spec.rb'
+    - 'spec/controllers/api/v1/tags_controller_spec.rb'
+    - 'spec/controllers/api/v1/trends/tags_controller_spec.rb'
+    - 'spec/controllers/api/v2/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/keywords_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters/statuses_controller_spec.rb'
+    - 'spec/controllers/api/v2/filters_controller_spec.rb'
+    - 'spec/controllers/api/v2/search_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/auth/challenges_controller_spec.rb'
+    - 'spec/controllers/auth/confirmations_controller_spec.rb'
+    - 'spec/controllers/auth/passwords_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/controllers/auth/sessions_controller_spec.rb'
+    - 'spec/controllers/concerns/account_controller_concern_spec.rb'
+    - 'spec/controllers/concerns/cache_concern_spec.rb'
+    - 'spec/controllers/concerns/challengable_concern_spec.rb'
+    - 'spec/controllers/concerns/export_controller_concern_spec.rb'
+    - 'spec/controllers/concerns/localized_spec.rb'
+    - 'spec/controllers/concerns/signature_verification_spec.rb'
+    - 'spec/controllers/concerns/user_tracking_concern_spec.rb'
+    - 'spec/controllers/disputes/appeals_controller_spec.rb'
+    - 'spec/controllers/disputes/strikes_controller_spec.rb'
+    - 'spec/controllers/home_controller_spec.rb'
+    - 'spec/controllers/instance_actors_controller_spec.rb'
+    - 'spec/controllers/intents_controller_spec.rb'
+    - 'spec/controllers/oauth/authorizations_controller_spec.rb'
+    - 'spec/controllers/oauth/tokens_controller_spec.rb'
+    - 'spec/controllers/settings/imports_controller_spec.rb'
+    - 'spec/controllers/settings/profiles_controller_spec.rb'
+    - 'spec/controllers/statuses_cleanup_controller_spec.rb'
+    - 'spec/controllers/tags_controller_spec.rb'
+    - 'spec/controllers/well_known/host_meta_controller_spec.rb'
+    - 'spec/controllers/well_known/nodeinfo_controller_spec.rb'
+    - 'spec/controllers/well_known/webfinger_controller_spec.rb'
+    - 'spec/helpers/accounts_helper_spec.rb'
+    - 'spec/helpers/admin/account_moderation_notes_helper_spec.rb'
+    - 'spec/helpers/admin/action_log_helper_spec.rb'
+    - 'spec/helpers/flashes_helper_spec.rb'
+    - 'spec/helpers/formatting_helper_spec.rb'
+    - 'spec/helpers/home_helper_spec.rb'
+    - 'spec/helpers/routing_helper_spec.rb'
+    - 'spec/helpers/statuses_helper_spec.rb'
+    - 'spec/mailers/admin_mailer_spec.rb'
+    - 'spec/mailers/notification_mailer_spec.rb'
+    - 'spec/mailers/user_mailer_spec.rb'
+    - 'spec/models/account/field_spec.rb'
+    - 'spec/models/account_alias_spec.rb'
+    - 'spec/models/account_conversation_spec.rb'
+    - 'spec/models/account_deletion_request_spec.rb'
+    - 'spec/models/account_domain_block_spec.rb'
+    - 'spec/models/account_migration_spec.rb'
+    - 'spec/models/account_moderation_note_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/account_statuses_cleanup_policy_spec.rb'
+    - 'spec/models/admin/account_action_spec.rb'
+    - 'spec/models/admin/action_log_spec.rb'
+    - 'spec/models/announcement_mute_spec.rb'
+    - 'spec/models/announcement_reaction_spec.rb'
+    - 'spec/models/announcement_spec.rb'
+    - 'spec/models/appeal_spec.rb'
+    - 'spec/models/backup_spec.rb'
+    - 'spec/models/block_spec.rb'
+    - 'spec/models/canonical_email_block_spec.rb'
+    - 'spec/models/conversation_mute_spec.rb'
+    - 'spec/models/conversation_spec.rb'
+    - 'spec/models/custom_emoji_category_spec.rb'
+    - 'spec/models/custom_emoji_spec.rb'
+    - 'spec/models/custom_filter_keyword_spec.rb'
+    - 'spec/models/custom_filter_spec.rb'
+    - 'spec/models/device_spec.rb'
+    - 'spec/models/domain_allow_spec.rb'
+    - 'spec/models/domain_block_spec.rb'
+    - 'spec/models/email_domain_block_spec.rb'
+    - 'spec/models/encrypted_message_spec.rb'
+    - 'spec/models/favourite_spec.rb'
+    - 'spec/models/featured_tag_spec.rb'
+    - 'spec/models/follow_recommendation_suppression_spec.rb'
+    - 'spec/models/follow_request_spec.rb'
+    - 'spec/models/follow_spec.rb'
+    - 'spec/models/home_feed_spec.rb'
+    - 'spec/models/identity_spec.rb'
+    - 'spec/models/import_spec.rb'
+    - 'spec/models/invite_spec.rb'
+    - 'spec/models/ip_block_spec.rb'
+    - 'spec/models/list_account_spec.rb'
+    - 'spec/models/list_spec.rb'
+    - 'spec/models/login_activity_spec.rb'
+    - 'spec/models/marker_spec.rb'
+    - 'spec/models/media_attachment_spec.rb'
+    - 'spec/models/mention_spec.rb'
+    - 'spec/models/mute_spec.rb'
+    - 'spec/models/notification_spec.rb'
+    - 'spec/models/one_time_key_spec.rb'
+    - 'spec/models/poll_spec.rb'
+    - 'spec/models/poll_vote_spec.rb'
+    - 'spec/models/preview_card_spec.rb'
+    - 'spec/models/preview_card_trend_spec.rb'
+    - 'spec/models/public_feed_spec.rb'
+    - 'spec/models/relay_spec.rb'
+    - 'spec/models/rule_spec.rb'
+    - 'spec/models/scheduled_status_spec.rb'
+    - 'spec/models/session_activation_spec.rb'
+    - 'spec/models/setting_spec.rb'
+    - 'spec/models/site_upload_spec.rb'
+    - 'spec/models/status_edit_spec.rb'
+    - 'spec/models/status_pin_spec.rb'
+    - 'spec/models/status_spec.rb'
+    - 'spec/models/status_stat_spec.rb'
+    - 'spec/models/status_trend_spec.rb'
+    - 'spec/models/system_key_spec.rb'
+    - 'spec/models/tag_follow_spec.rb'
+    - 'spec/models/unavailable_domain_spec.rb'
+    - 'spec/models/user_invite_request_spec.rb'
+    - 'spec/models/user_role_spec.rb'
+    - 'spec/models/user_spec.rb'
+    - 'spec/models/web/push_subscription_spec.rb'
+    - 'spec/models/web/setting_spec.rb'
+    - 'spec/models/webauthn_credentials_spec.rb'
+    - 'spec/models/webhook_spec.rb'
+
+# Offense count: 6
+RSpec/RepeatedExample:
+  Exclude:
+    - 'spec/policies/status_policy_spec.rb'
+
+# Offense count: 6
+RSpec/RepeatedExampleGroupBody:
+  Exclude:
+    - 'spec/controllers/statuses_controller_spec.rb'
+
+# Offense count: 4
+RSpec/RepeatedExampleGroupDescription:
+  Exclude:
+    - 'spec/controllers/admin/reports/actions_controller_spec.rb'
+    - 'spec/policies/report_note_policy_spec.rb'
+
+# Offense count: 6
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: and_return, block
+RSpec/ReturnFromStub:
+  Exclude:
+    - 'spec/controllers/api/v1/accounts/credentials_controller_spec.rb'
+    - 'spec/controllers/api/v1/apps/credentials_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb'
+    - 'spec/controllers/api/v1/statuses_controller_spec.rb'
+    - 'spec/validators/blacklisted_email_validator_spec.rb'
+
+# Offense count: 18
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/ScatteredLet:
+  Exclude:
+    - 'spec/controllers/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/push/subscriptions_controller_spec.rb'
+    - 'spec/lib/activitypub/activity/create_spec.rb'
+    - 'spec/lib/vacuum/media_attachments_vacuum_spec.rb'
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/services/fan_out_on_write_service_spec.rb'
+    - 'spec/services/import_service_spec.rb'
+
+# Offense count: 12
+RSpec/ScatteredSetup:
+  Exclude:
+    - 'spec/controllers/activitypub/followers_synchronizations_controller_spec.rb'
+    - 'spec/controllers/activitypub/outboxes_controller_spec.rb'
+    - 'spec/controllers/admin/disputes/appeals_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+    - 'spec/services/fetch_resource_service_spec.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/SharedContext:
+  Exclude:
+    - 'spec/services/unsuspend_account_service_spec.rb'
+
+# Offense count: 16
+RSpec/StubbedMock:
+  Exclude:
+    - 'spec/controllers/api/base_controller_spec.rb'
+    - 'spec/controllers/api/v1/media_controller_spec.rb'
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/helpers/application_helper_spec.rb'
+    - 'spec/lib/status_filter_spec.rb'
+    - 'spec/lib/status_finder_spec.rb'
+    - 'spec/lib/webfinger_resource_spec.rb'
+    - 'spec/services/activitypub/process_collection_service_spec.rb'
+
+# Offense count: 22
+RSpec/SubjectDeclaration:
+  Exclude:
+    - 'spec/controllers/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb'
+    - 'spec/models/account_migration_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/relationship_filter_spec.rb'
+    - 'spec/models/user_role_spec.rb'
+    - 'spec/policies/account_moderation_note_policy_spec.rb'
+    - 'spec/policies/account_policy_spec.rb'
+    - 'spec/policies/backup_policy_spec.rb'
+    - 'spec/policies/custom_emoji_policy_spec.rb'
+    - 'spec/policies/domain_block_policy_spec.rb'
+    - 'spec/policies/email_domain_block_policy_spec.rb'
+    - 'spec/policies/instance_policy_spec.rb'
+    - 'spec/policies/invite_policy_spec.rb'
+    - 'spec/policies/relay_policy_spec.rb'
+    - 'spec/policies/report_note_policy_spec.rb'
+    - 'spec/policies/report_policy_spec.rb'
+    - 'spec/policies/settings_policy_spec.rb'
+    - 'spec/policies/tag_policy_spec.rb'
+    - 'spec/policies/user_policy_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+
+# Offense count: 5
+RSpec/SubjectStub:
+  Exclude:
+    - 'spec/services/unallow_domain_service_spec.rb'
+    - 'spec/validators/blacklisted_email_validator_spec.rb'
+
+# Offense count: 119
+# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
+RSpec/VerifiedDoubles:
+  Exclude:
+    - 'spec/controllers/admin/change_email_controller_spec.rb'
+    - 'spec/controllers/admin/confirmations_controller_spec.rb'
+    - 'spec/controllers/admin/disputes/appeals_controller_spec.rb'
+    - 'spec/controllers/admin/domain_allows_controller_spec.rb'
+    - 'spec/controllers/admin/domain_blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/reports_controller_spec.rb'
+    - 'spec/controllers/api/web/embeds_controller_spec.rb'
+    - 'spec/controllers/auth/sessions_controller_spec.rb'
+    - 'spec/controllers/disputes/appeals_controller_spec.rb'
+    - 'spec/controllers/settings/imports_controller_spec.rb'
+    - 'spec/helpers/statuses_helper_spec.rb'
+    - 'spec/lib/suspicious_sign_in_detector_spec.rb'
+    - 'spec/models/account/field_spec.rb'
+    - 'spec/models/session_activation_spec.rb'
+    - 'spec/models/setting_spec.rb'
+    - 'spec/services/account_search_service_spec.rb'
+    - 'spec/services/post_status_service_spec.rb'
+    - 'spec/services/search_service_spec.rb'
+    - 'spec/validators/blacklisted_email_validator_spec.rb'
+    - 'spec/validators/disallowed_hashtags_validator_spec.rb'
+    - 'spec/validators/email_mx_validator_spec.rb'
+    - 'spec/validators/follow_limit_validator_spec.rb'
+    - 'spec/validators/note_length_validator_spec.rb'
+    - 'spec/validators/poll_validator_spec.rb'
+    - 'spec/validators/status_length_validator_spec.rb'
+    - 'spec/validators/status_pin_validator_spec.rb'
+    - 'spec/validators/unique_username_validator_spec.rb'
+    - 'spec/validators/unreserved_username_validator_spec.rb'
+    - 'spec/validators/url_validator_spec.rb'
+    - 'spec/views/statuses/show.html.haml_spec.rb'
+    - 'spec/workers/activitypub/processing_worker_spec.rb'
+    - 'spec/workers/admin/domain_purge_worker_spec.rb'
+    - 'spec/workers/domain_block_worker_spec.rb'
+    - 'spec/workers/domain_clear_media_worker_spec.rb'
+    - 'spec/workers/feed_insert_worker_spec.rb'
+    - 'spec/workers/regeneration_worker_spec.rb'
+
+# Offense count: 19
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: ExpectedOrder, Include.
+# ExpectedOrder: index, show, new, edit, create, update, destroy
+# Include: app/controllers/**/*.rb
+Rails/ActionOrder:
+  Exclude:
+    - 'app/controllers/admin/announcements_controller.rb'
+    - 'app/controllers/admin/roles_controller.rb'
+    - 'app/controllers/admin/rules_controller.rb'
+    - 'app/controllers/admin/warning_presets_controller.rb'
+    - 'app/controllers/admin/webhooks_controller.rb'
+    - 'app/controllers/api/v1/admin/domain_allows_controller.rb'
+    - 'app/controllers/api/v1/admin/domain_blocks_controller.rb'
+    - 'app/controllers/api/v1/admin/email_domain_blocks_controller.rb'
+    - 'app/controllers/api/v1/admin/ip_blocks_controller.rb'
+    - 'app/controllers/api/v1/filters_controller.rb'
+    - 'app/controllers/api/v1/media_controller.rb'
+    - 'app/controllers/api/v1/push/subscriptions_controller.rb'
+    - 'app/controllers/api/v2/filters/keywords_controller.rb'
+    - 'app/controllers/api/v2/filters/statuses_controller.rb'
+    - 'app/controllers/api/v2/filters_controller.rb'
+    - 'app/controllers/auth/registrations_controller.rb'
+    - 'app/controllers/filters_controller.rb'
+    - 'app/controllers/settings/applications_controller.rb'
+    - 'app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb'
+
+# Offense count: 7
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
+Rails/ActiveRecordCallbacksOrder:
+  Exclude:
+    - 'app/models/account.rb'
+    - 'app/models/account_conversation.rb'
+    - 'app/models/announcement_reaction.rb'
+    - 'app/models/block.rb'
+    - 'app/models/media_attachment.rb'
+    - 'app/models/session_activation.rb'
+    - 'app/models/status.rb'
+
+# Offense count: 4
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/ApplicationController:
+  Exclude:
+    - 'app/controllers/health_controller.rb'
+    - 'app/controllers/well_known/host_meta_controller.rb'
+    - 'app/controllers/well_known/nodeinfo_controller.rb'
+    - 'app/controllers/well_known/webfinger_controller.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent.
+Rails/Blank:
+  Exclude:
+    - 'app/services/activitypub/fetch_remote_actor_service.rb'
+
+# Offense count: 35
+# Configuration parameters: Database, Include.
+# SupportedDatabases: mysql, postgresql
+# Include: db/migrate/*.rb
+Rails/BulkChangeTable:
+  Exclude:
+    - 'db/migrate/20160222143943_add_profile_fields_to_accounts.rb'
+    - 'db/migrate/20160223162837_add_metadata_to_statuses.rb'
+    - 'db/migrate/20160305115639_add_devise_to_users.rb'
+    - 'db/migrate/20160314164231_add_owner_to_application.rb'
+    - 'db/migrate/20160926213048_remove_owner_from_application.rb'
+    - 'db/migrate/20161003142332_add_confirmable_to_users.rb'
+    - 'db/migrate/20170112154826_migrate_settings.rb'
+    - 'db/migrate/20170127165745_add_devise_two_factor_to_users.rb'
+    - 'db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb'
+    - 'db/migrate/20170330021336_add_counter_caches.rb'
+    - 'db/migrate/20170425202925_add_oembed_to_preview_cards.rb'
+    - 'db/migrate/20170427011934_re_add_owner_to_application.rb'
+    - 'db/migrate/20170520145338_change_language_filter_to_opt_out.rb'
+    - 'db/migrate/20170624134742_add_description_to_session_activations.rb'
+    - 'db/migrate/20170718211102_add_activitypub_to_accounts.rb'
+    - 'db/migrate/20171006142024_add_uri_to_custom_emojis.rb'
+    - 'db/migrate/20180812123222_change_relays_enabled.rb'
+    - 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
+    - 'db/migrate/20190805123746_add_capabilities_to_tags.rb'
+    - 'db/migrate/20190807135426_add_comments_to_domain_blocks.rb'
+    - 'db/migrate/20190815225426_add_last_status_at_to_tags.rb'
+    - 'db/migrate/20190901035623_add_max_score_to_tags.rb'
+    - 'db/migrate/20200417125749_add_storage_schema_version.rb'
+    - 'db/migrate/20200608113046_add_sign_in_token_to_users.rb'
+    - 'db/migrate/20211112011713_add_language_to_preview_cards.rb'
+    - 'db/migrate/20211231080958_add_category_to_reports.rb'
+    - 'db/migrate/20220202200743_add_trendable_to_accounts.rb'
+    - 'db/migrate/20220224010024_add_ips_to_email_domain_blocks.rb'
+    - 'db/migrate/20220227041951_add_last_used_at_to_oauth_access_tokens.rb'
+    - 'db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.rb'
+    - 'db/migrate/20220824164433_add_human_identifier_to_admin_action_logs.rb'
+
+# Offense count: 7
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/CompactBlank:
+  Exclude:
+    - 'app/helpers/application_helper.rb'
+    - 'app/helpers/statuses_helper.rb'
+    - 'app/models/concerns/attachmentable.rb'
+    - 'app/models/poll.rb'
+    - 'app/models/user.rb'
+    - 'app/services/import_service.rb'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+Rails/ContentTag:
+  Exclude:
+    - 'app/helpers/application_helper.rb'
+    - 'app/helpers/branding_helper.rb'
+
+# Offense count: 8
+# Configuration parameters: Include.
+# Include: db/migrate/*.rb
+Rails/CreateTableWithTimestamps:
+  Exclude:
+    - 'db/migrate/20170508230434_create_conversation_mutes.rb'
+    - 'db/migrate/20170823162448_create_status_pins.rb'
+    - 'db/migrate/20171116161857_create_list_accounts.rb'
+    - 'db/migrate/20180929222014_create_account_conversations.rb'
+    - 'db/migrate/20181007025445_create_pghero_space_stats.rb'
+    - 'db/migrate/20190103124649_create_scheduled_statuses.rb'
+    - 'db/migrate/20220824233535_create_status_trends.rb'
+    - 'db/migrate/20221006061337_create_preview_card_trends.rb'
+
+# Offense count: 4
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/DeprecatedActiveModelErrorsMethods:
+  Exclude:
+    - 'app/validators/ed25519_key_validator.rb'
+    - 'app/validators/ed25519_signature_validator.rb'
+    - 'lib/mastodon/accounts_cli.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+Rails/DuplicateAssociation:
+  Exclude:
+    - 'app/serializers/activitypub/collection_serializer.rb'
+    - 'app/serializers/activitypub/note_serializer.rb'
+
+# Offense count: 12
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
+Rails/EnumHash:
+  Exclude:
+    - 'app/models/account.rb'
+    - 'app/models/custom_filter.rb'
+    - 'app/models/domain_block.rb'
+    - 'app/models/import.rb'
+    - 'app/models/list.rb'
+    - 'app/models/media_attachment.rb'
+    - 'app/models/preview_card.rb'
+    - 'app/models/relay.rb'
+    - 'app/models/status.rb'
+
+# Offense count: 76
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: slashes, arguments
+Rails/FilePath:
+  Exclude:
+    - 'app/lib/themes.rb'
+    - 'app/models/setting.rb'
+    - 'app/validators/reaction_validator.rb'
+    - 'db/migrate/20170716191202_add_hide_notifications_to_mute.rb'
+    - 'db/migrate/20170918125918_ids_to_bigints.rb'
+    - 'db/migrate/20171005171936_add_disabled_to_custom_emojis.rb'
+    - 'db/migrate/20171028221157_add_reblogs_to_follows.rb'
+    - 'db/migrate/20171107143332_add_memorial_to_accounts.rb'
+    - 'db/migrate/20171107143624_add_disabled_to_users.rb'
+    - 'db/migrate/20171109012327_add_moderator_to_accounts.rb'
+    - 'db/migrate/20171130000000_add_embed_url_to_preview_cards.rb'
+    - 'db/migrate/20180615122121_add_autofollow_to_invites.rb'
+    - 'db/migrate/20180707154237_add_whole_word_to_custom_filter.rb'
+    - 'db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb'
+    - 'db/migrate/20181010141500_add_silent_to_mentions.rb'
+    - 'db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb'
+    - 'db/migrate/20181018205649_add_unread_to_account_conversations.rb'
+    - 'db/migrate/20181127130500_identity_id_to_bigint.rb'
+    - 'db/migrate/20181127165847_add_show_replies_to_lists.rb'
+    - 'db/migrate/20190201012802_add_overwrite_to_imports.rb'
+    - 'db/migrate/20190306145741_add_lock_version_to_polls.rb'
+    - 'db/migrate/20190307234537_add_approved_to_users.rb'
+    - 'db/migrate/20191001213028_add_lock_version_to_account_stats.rb'
+    - 'db/migrate/20191212003415_increase_backup_size.rb'
+    - 'db/migrate/20200312144258_add_title_to_account_warning_presets.rb'
+    - 'db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb'
+    - 'db/migrate/20200917192924_add_notify_to_follows.rb'
+    - 'db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb'
+    - 'db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb'
+    - 'db/migrate/20211231080958_add_category_to_reports.rb'
+    - 'db/migrate/20220613110834_add_action_to_custom_filters.rb'
+    - 'db/post_migrate/20220307083603_optimize_null_index_conversations_uri.rb'
+    - 'db/post_migrate/20220310060545_optimize_null_index_statuses_in_reply_to_account_id.rb'
+    - 'db/post_migrate/20220310060556_optimize_null_index_statuses_in_reply_to_id.rb'
+    - 'db/post_migrate/20220310060614_optimize_null_index_media_attachments_scheduled_status_id.rb'
+    - 'db/post_migrate/20220310060626_optimize_null_index_media_attachments_shortcode.rb'
+    - 'db/post_migrate/20220310060641_optimize_null_index_users_reset_password_token.rb'
+    - 'db/post_migrate/20220310060653_optimize_null_index_users_created_by_application_id.rb'
+    - 'db/post_migrate/20220310060706_optimize_null_index_statuses_uri.rb'
+    - 'db/post_migrate/20220310060722_optimize_null_index_accounts_moved_to_account_id.rb'
+    - 'db/post_migrate/20220310060740_optimize_null_index_oauth_access_tokens_refresh_token.rb'
+    - 'db/post_migrate/20220310060750_optimize_null_index_accounts_url.rb'
+    - 'db/post_migrate/20220310060809_optimize_null_index_oauth_access_tokens_resource_owner_id.rb'
+    - 'db/post_migrate/20220310060833_optimize_null_index_announcement_reactions_custom_emoji_id.rb'
+    - 'db/post_migrate/20220310060854_optimize_null_index_appeals_approved_by_account_id.rb'
+    - 'db/post_migrate/20220310060913_optimize_null_index_account_migrations_target_account_id.rb'
+    - 'db/post_migrate/20220310060926_optimize_null_index_appeals_rejected_by_account_id.rb'
+    - 'db/post_migrate/20220310060939_optimize_null_index_list_accounts_follow_id.rb'
+    - 'db/post_migrate/20220310060959_optimize_null_index_web_push_subscriptions_access_token_id.rb'
+    - 'db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb'
+    - 'db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb'
+    - 'db/post_migrate/20220617202502_migrate_roles.rb'
+    - 'db/seeds.rb'
+    - 'db/seeds/03_roles.rb'
+    - 'lib/tasks/branding.rake'
+    - 'lib/tasks/emojis.rake'
+    - 'lib/tasks/repo.rake'
+    - 'spec/controllers/admin/custom_emojis_controller_spec.rb'
+    - 'spec/fabricators/custom_emoji_fabricator.rb'
+    - 'spec/fabricators/site_upload_fabricator.rb'
+    - 'spec/rails_helper.rb'
+    - 'spec/spec_helper.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+Rails/FindById:
+  Exclude:
+    - 'app/controllers/api/v1/notifications_controller.rb'
+    - 'app/controllers/media_controller.rb'
+
+# Offense count: 6
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
+Rails/HasAndBelongsToMany:
+  Exclude:
+    - 'app/models/concerns/account_associations.rb'
+    - 'app/models/preview_card.rb'
+    - 'app/models/status.rb'
+    - 'app/models/tag.rb'
+
+# Offense count: 15
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
+Rails/HasManyOrHasOneDependent:
+  Exclude:
+    - 'app/models/concerns/account_counters.rb'
+    - 'app/models/conversation.rb'
+    - 'app/models/custom_emoji.rb'
+    - 'app/models/custom_emoji_category.rb'
+    - 'app/models/domain_block.rb'
+    - 'app/models/invite.rb'
+    - 'app/models/status.rb'
+    - 'app/models/user.rb'
+    - 'app/models/web/push_subscription.rb'
+
+# Offense count: 4
+# Configuration parameters: Include.
+# Include: app/helpers/**/*.rb
+Rails/HelperInstanceVariable:
+  Exclude:
+    - 'app/helpers/application_helper.rb'
+    - 'app/helpers/instance_helper.rb'
+    - 'app/helpers/jsonld_helper.rb'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Include.
+# Include: spec/**/*, test/**/*
+Rails/HttpPositionalArguments:
+  Exclude:
+    - 'spec/config/initializers/rack_attack_spec.rb'
+
+# Offense count: 49
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: numeric, symbolic
+Rails/HttpStatus:
+  Exclude:
+    - 'app/controllers/activitypub/inboxes_controller.rb'
+    - 'app/controllers/api/base_controller.rb'
+    - 'app/controllers/api/v1/admin/domain_blocks_controller.rb'
+    - 'app/controllers/api/v1/instances/activity_controller.rb'
+    - 'app/controllers/api/v1/instances/domain_blocks_controller.rb'
+    - 'app/controllers/api/v1/instances/peers_controller.rb'
+    - 'app/controllers/api/v1/lists_controller.rb'
+    - 'app/controllers/api/v1/markers_controller.rb'
+    - 'app/controllers/api/v1/media_controller.rb'
+    - 'app/controllers/api/v1/statuses_controller.rb'
+    - 'app/controllers/api/v1/streaming_controller.rb'
+    - 'app/controllers/api/v2/media_controller.rb'
+    - 'app/controllers/api/v2/search_controller.rb'
+    - 'app/controllers/api/web/base_controller.rb'
+    - 'app/controllers/settings/pictures_controller.rb'
+    - 'app/controllers/well_known/webfinger_controller.rb'
+    - 'spec/controllers/api/base_controller_spec.rb'
+    - 'spec/controllers/application_controller_spec.rb'
+    - 'spec/controllers/concerns/account_controller_concern_spec.rb'
+    - 'spec/controllers/concerns/localized_spec.rb'
+    - 'spec/controllers/concerns/rate_limit_headers_spec.rb'
+    - 'spec/controllers/concerns/signature_verification_spec.rb'
+
+# Offense count: 7
+# Configuration parameters: Include.
+# Include: spec/**/*.rb, test/**/*.rb
+Rails/I18nLocaleAssignment:
+  Exclude:
+    - 'spec/controllers/auth/registrations_controller_spec.rb'
+    - 'spec/helpers/application_helper_spec.rb'
+    - 'spec/requests/localization_spec.rb'
+
+# Offense count: 6
+Rails/I18nLocaleTexts:
+  Exclude:
+    - 'lib/tasks/mastodon.rake'
+    - 'spec/helpers/flashes_helper_spec.rb'
+
+# Offense count: 8
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/IgnoredColumnsAssignment:
+  Exclude:
+    - 'app/models/account.rb'
+    - 'app/models/account_stat.rb'
+    - 'app/models/admin/action_log.rb'
+    - 'app/models/custom_filter.rb'
+    - 'app/models/email_domain_block.rb'
+    - 'app/models/report.rb'
+    - 'app/models/status_edit.rb'
+    - 'app/models/user.rb'
+
+# Offense count: 25
+# Configuration parameters: IgnoreScopes, Include.
+# Include: app/models/**/*.rb
+Rails/InverseOf:
+  Exclude:
+    - 'app/models/appeal.rb'
+    - 'app/models/concerns/account_interactions.rb'
+    - 'app/models/custom_emoji.rb'
+    - 'app/models/domain_block.rb'
+    - 'app/models/follow_recommendation.rb'
+    - 'app/models/instance.rb'
+    - 'app/models/notification.rb'
+    - 'app/models/status.rb'
+    - 'app/models/user_ip.rb'
+
+# Offense count: 13
+# Configuration parameters: Include.
+# Include: app/controllers/**/*.rb, app/mailers/**/*.rb
+Rails/LexicallyScopedActionFilter:
+  Exclude:
+    - 'app/controllers/admin/domain_blocks_controller.rb'
+    - 'app/controllers/admin/email_domain_blocks_controller.rb'
+    - 'app/controllers/auth/passwords_controller.rb'
+    - 'app/controllers/auth/registrations_controller.rb'
+    - 'app/controllers/auth/sessions_controller.rb'
+
+# Offense count: 18
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/NegateInclude:
+  Exclude:
+    - 'app/controllers/concerns/signature_verification.rb'
+    - 'app/helpers/jsonld_helper.rb'
+    - 'app/lib/activitypub/activity/create.rb'
+    - 'app/lib/activitypub/activity/move.rb'
+    - 'app/lib/feed_manager.rb'
+    - 'app/lib/link_details_extractor.rb'
+    - 'app/models/concerns/attachmentable.rb'
+    - 'app/models/concerns/remotable.rb'
+    - 'app/models/custom_filter.rb'
+    - 'app/models/webhook.rb'
+    - 'app/services/activitypub/process_status_update_service.rb'
+    - 'app/services/fetch_link_card_service.rb'
+    - 'app/services/search_service.rb'
+    - 'app/workers/web/push_notification_worker.rb'
+    - 'lib/paperclip/color_extractor.rb'
+
+# Offense count: 2
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Include.
+# Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb
+Rails/Output:
+  Exclude:
+    - 'lib/mastodon/ip_blocks_cli.rb'
+
+# Offense count: 14
+# This cop supports safe autocorrection (--autocorrect).
+Rails/Pluck:
+  Exclude:
+    - 'app/lib/importer/base_importer.rb'
+    - 'app/lib/link_details_extractor.rb'
+    - 'app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb'
+    - 'spec/controllers/api/v1/notifications_controller_spec.rb'
+    - 'spec/controllers/api/v1/suggestions_controller_spec.rb'
+    - 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
+
+# Offense count: 9
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Include.
+# Include: **/Rakefile, **/*.rake
+Rails/RakeEnvironment:
+  Exclude:
+    - 'lib/tasks/auto_annotate_models.rake'
+    - 'lib/tasks/db.rake'
+    - 'lib/tasks/emojis.rake'
+    - 'lib/tasks/mastodon.rake'
+    - 'lib/tasks/repo.rake'
+    - 'lib/tasks/statistics.rake'
+
+# Offense count: 8
+# This cop supports safe autocorrection (--autocorrect).
+Rails/RedundantForeignKey:
+  Exclude:
+    - 'app/models/custom_filter.rb'
+    - 'app/models/follow_recommendation.rb'
+    - 'app/models/report.rb'
+    - 'app/models/status.rb'
+    - 'app/models/user_ip.rb'
+    - 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
+    - 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
+
+# Offense count: 29
+# Configuration parameters: Include.
+# Include: db/**/*.rb
+Rails/ReversibleMigration:
+  Exclude:
+    - 'db/migrate/20160223164502_make_uris_nullable_in_statuses.rb'
+    - 'db/migrate/20161122163057_remove_unneeded_indexes.rb'
+    - 'db/migrate/20170205175257_remove_devices.rb'
+    - 'db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb'
+    - 'db/migrate/20170520145338_change_language_filter_to_opt_out.rb'
+    - 'db/migrate/20170609145826_remove_default_language_from_statuses.rb'
+    - 'db/migrate/20170711225116_fix_null_booleans.rb'
+    - 'db/migrate/20171129172043_add_index_on_stream_entries.rb'
+    - 'db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb'
+    - 'db/migrate/20171226094803_more_faster_index_on_notifications.rb'
+    - 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
+    - 'db/migrate/20180617162849_remove_unused_indexes.rb'
+    - 'db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb'
+
+# Offense count: 10
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/RootPathnameMethods:
+  Exclude:
+    - 'lib/mastodon/premailer_webpack_strategy.rb'
+    - 'lib/tasks/emojis.rake'
+    - 'lib/tasks/mastodon.rake'
+    - 'lib/tasks/repo.rake'
+    - 'spec/fabricators/custom_emoji_fabricator.rb'
+    - 'spec/fabricators/site_upload_fabricator.rb'
+    - 'spec/rails_helper.rb'
+
+# Offense count: 141
+# Configuration parameters: ForbiddenMethods, AllowedMethods.
+# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
+Rails/SkipsModelValidations:
+  Exclude:
+    - 'app/controllers/admin/invites_controller.rb'
+    - 'app/controllers/concerns/session_tracking_concern.rb'
+    - 'app/models/concerns/account_merging.rb'
+    - 'app/models/concerns/expireable.rb'
+    - 'app/models/status.rb'
+    - 'app/models/trends/links.rb'
+    - 'app/models/trends/preview_card_batch.rb'
+    - 'app/models/trends/preview_card_provider_batch.rb'
+    - 'app/models/trends/status_batch.rb'
+    - 'app/models/trends/statuses.rb'
+    - 'app/models/trends/tag_batch.rb'
+    - 'app/models/trends/tags.rb'
+    - 'app/models/user.rb'
+    - 'app/services/activitypub/process_status_update_service.rb'
+    - 'app/services/approve_appeal_service.rb'
+    - 'app/services/block_domain_service.rb'
+    - 'app/services/delete_account_service.rb'
+    - 'app/services/process_mentions_service.rb'
+    - 'app/services/unallow_domain_service.rb'
+    - 'app/services/unblock_domain_service.rb'
+    - 'app/services/update_status_service.rb'
+    - 'app/workers/activitypub/post_upgrade_worker.rb'
+    - 'app/workers/move_worker.rb'
+    - 'app/workers/scheduler/ip_cleanup_scheduler.rb'
+    - 'app/workers/scheduler/scheduled_statuses_scheduler.rb'
+    - 'db/migrate/20161203164520_add_from_account_id_to_notifications.rb'
+    - 'db/migrate/20170105224407_add_shortcode_to_media_attachments.rb'
+    - 'db/migrate/20170209184350_add_reply_to_statuses.rb'
+    - 'db/migrate/20170304202101_add_type_to_media_attachments.rb'
+    - 'db/migrate/20180528141303_fix_accounts_unique_index.rb'
+    - 'db/migrate/20180609104432_migrate_web_push_subscriptions2.rb'
+    - 'db/migrate/20181207011115_downcase_custom_emoji_domains.rb'
+    - 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
+    - 'db/migrate/20191007013357_update_pt_locales.rb'
+    - 'db/migrate/20220316233212_update_kurdish_locales.rb'
+    - 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
+    - 'db/post_migrate/20200917193528_migrate_notifications_type.rb'
+    - 'db/post_migrate/20201017234926_fill_account_suspension_origin.rb'
+    - 'db/post_migrate/20220617202502_migrate_roles.rb'
+    - 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
+    - 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
+    - 'lib/cli.rb'
+    - 'lib/mastodon/accounts_cli.rb'
+    - 'lib/mastodon/maintenance_cli.rb'
+    - 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
+    - 'spec/lib/activitypub/activity/follow_spec.rb'
+    - 'spec/services/follow_service_spec.rb'
+    - 'spec/services/update_account_service_spec.rb'
+
+# Offense count: 11
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/SquishedSQLHeredocs:
+  Exclude:
+    - 'db/migrate/20170920024819_status_ids_to_timestamp_ids.rb'
+    - 'db/migrate/20180608213548_reject_following_blocked_users.rb'
+    - 'db/post_migrate/20190519130537_remove_boosts_widening_audience.rb'
+    - 'lib/mastodon/snowflake.rb'
+    - 'lib/tasks/tests.rake'
+
+# Offense count: 7
+Rails/TransactionExitStatement:
+  Exclude:
+    - 'app/lib/activitypub/activity/announce.rb'
+    - 'app/lib/activitypub/activity/create.rb'
+    - 'app/lib/activitypub/activity/delete.rb'
+    - 'app/services/activitypub/process_account_service.rb'
+
+# Offense count: 4
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
+Rails/UniqueValidationWithoutIndex:
+  Exclude:
+    - 'app/models/account_alias.rb'
+    - 'app/models/custom_filter_status.rb'
+    - 'app/models/identity.rb'
+    - 'app/models/webauthn_credential.rb'
+
+# Offense count: 19
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
+Rails/UnusedIgnoredColumns:
+  Exclude:
+    - 'app/models/account.rb'
+    - 'app/models/account_stat.rb'
+    - 'app/models/admin/action_log.rb'
+    - 'app/models/custom_filter.rb'
+    - 'app/models/email_domain_block.rb'
+    - 'app/models/report.rb'
+    - 'app/models/status_edit.rb'
+    - 'app/models/user.rb'
+
+# Offense count: 2
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Rails/WhereEquals:
+  Exclude:
+    - 'app/models/announcement.rb'
+    - 'app/models/status.rb'
+
+# Offense count: 61
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: exists, where
+Rails/WhereExists:
+  Exclude:
+    - 'app/controllers/activitypub/inboxes_controller.rb'
+    - 'app/controllers/admin/email_domain_blocks_controller.rb'
+    - 'app/controllers/auth/registrations_controller.rb'
+    - 'app/lib/activitypub/activity/create.rb'
+    - 'app/lib/delivery_failure_tracker.rb'
+    - 'app/lib/feed_manager.rb'
+    - 'app/lib/status_cache_hydrator.rb'
+    - 'app/lib/suspicious_sign_in_detector.rb'
+    - 'app/models/concerns/account_interactions.rb'
+    - 'app/models/featured_tag.rb'
+    - 'app/models/poll.rb'
+    - 'app/models/session_activation.rb'
+    - 'app/models/status.rb'
+    - 'app/models/user.rb'
+    - 'app/policies/status_policy.rb'
+    - 'app/serializers/rest/announcement_serializer.rb'
+    - 'app/serializers/rest/tag_serializer.rb'
+    - 'app/services/activitypub/fetch_remote_status_service.rb'
+    - 'app/services/app_sign_up_service.rb'
+    - 'app/services/vote_service.rb'
+    - 'app/validators/reaction_validator.rb'
+    - 'app/validators/vote_validator.rb'
+    - 'app/workers/move_worker.rb'
+    - 'db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb'
+    - 'lib/mastodon/email_domain_blocks_cli.rb'
+    - 'lib/tasks/tests.rake'
+    - 'spec/controllers/api/v1/accounts/notes_controller_spec.rb'
+    - 'spec/controllers/api/v1/tags_controller_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/services/activitypub/process_collection_service_spec.rb'
+    - 'spec/services/post_status_service_spec.rb'
+    - 'spec/services/purge_domain_service_spec.rb'
+    - 'spec/services/unallow_domain_service_spec.rb'
+
+# Offense count: 3
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Security/IoMethods:
+  Exclude:
+    - 'spec/controllers/admin/export_domain_allows_controller_spec.rb'
+    - 'spec/controllers/admin/export_domain_blocks_controller_spec.rb'
+
+# Offense count: 5
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/CaseLikeIf:
+  Exclude:
+    - 'app/controllers/authorize_interactions_controller.rb'
+    - 'app/controllers/concerns/signature_verification.rb'
+    - 'app/helpers/jsonld_helper.rb'
+    - 'app/models/account.rb'
+    - 'app/services/resolve_url_service.rb'
+
+# Offense count: 445
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: nested, compact
+Style/ClassAndModuleChildren:
+  Enabled: false
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowedMethods, AllowedPatterns.
+# AllowedMethods: ==, equal?, eql?
+Style/ClassEqualityComparison:
+  Exclude:
+    - 'app/helpers/jsonld_helper.rb'
+    - 'app/serializers/activitypub/outbox_serializer.rb'
+
+# Offense count: 7
+Style/CombinableLoops:
+  Exclude:
+    - 'app/models/form/custom_emoji_batch.rb'
+    - 'app/models/form/ip_block_batch.rb'
+
+# Offense count: 5
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/ConcatArrayLiterals:
+  Exclude:
+    - 'app/lib/feed_manager.rb'
+
+# Offense count: 1433
+# Configuration parameters: AllowedConstants.
+Style/Documentation:
+  Enabled: false
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: compact, expanded
+Style/EmptyMethod:
+  Exclude:
+    - 'db/migrate/20181024224956_migrate_account_conversations.rb'
+    - 'db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb'
+    - 'db/migrate/20200510110808_reset_web_app_secret.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Style/ExplicitBlockArgument:
+  Exclude:
+    - 'app/mailers/application_mailer.rb'
+
+# Offense count: 10
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowedVars.
+Style/FetchEnvVar:
+  Exclude:
+    - 'app/helpers/application_helper.rb'
+    - 'app/lib/redis_configuration.rb'
+    - 'app/lib/translation_service.rb'
+    - 'lib/mastodon/premailer_webpack_strategy.rb'
+    - 'lib/mastodon/redis_config.rb'
+    - 'lib/tasks/repo.rake'
+    - 'spec/features/profile_spec.rb'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: format, sprintf, percent
+Style/FormatString:
+  Exclude:
+    - 'app/serializers/rest/privacy_policy_serializer.rb'
+    - 'lib/mastodon/maintenance_cli.rb'
+    - 'lib/paperclip/color_extractor.rb'
+
+# Offense count: 15
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
+# SupportedStyles: annotated, template, unannotated
+Style/FormatStringToken:
+  Exclude:
+    - 'app/models/privacy_policy.rb'
+    - 'lib/mastodon/maintenance_cli.rb'
+    - 'lib/paperclip/color_extractor.rb'
+
+# Offense count: 713
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: always, always_true, never
+Style/FrozenStringLiteralComment:
+  Enabled: false
+
+# Offense count: 69
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
+Style/GuardClause:
+  Exclude:
+    - 'app/controllers/admin/confirmations_controller.rb'
+    - 'app/controllers/admin/domain_blocks_controller.rb'
+    - 'app/controllers/api/v1/accounts/follower_accounts_controller.rb'
+    - 'app/controllers/api/v1/accounts/following_accounts_controller.rb'
+    - 'app/controllers/api/v1/accounts/statuses_controller.rb'
+    - 'app/controllers/api/v1/blocks_controller.rb'
+    - 'app/controllers/api/v1/conversations_controller.rb'
+    - 'app/controllers/api/v1/domain_blocks_controller.rb'
+    - 'app/controllers/api/v1/endorsements_controller.rb'
+    - 'app/controllers/api/v1/favourites_controller.rb'
+    - 'app/controllers/api/v1/follow_requests_controller.rb'
+    - 'app/controllers/api/v1/lists/accounts_controller.rb'
+    - 'app/controllers/api/v1/mutes_controller.rb'
+    - 'app/controllers/api/v1/notifications_controller.rb'
+    - 'app/controllers/api/v1/scheduled_statuses_controller.rb'
+    - 'app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb'
+    - 'app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb'
+    - 'app/controllers/auth/confirmations_controller.rb'
+    - 'app/controllers/auth/passwords_controller.rb'
+    - 'app/controllers/filters/statuses_controller.rb'
+    - 'app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb'
+    - 'app/lib/activitypub/activity/block.rb'
+    - 'app/lib/activitypub/linked_data_signature.rb'
+    - 'app/lib/connection_pool/shared_connection_pool.rb'
+    - 'app/lib/request.rb'
+    - 'app/lib/request_pool.rb'
+    - 'app/lib/status_finder.rb'
+    - 'app/lib/webfinger.rb'
+    - 'app/lib/webfinger_resource.rb'
+    - 'app/models/account_statuses_cleanup_policy.rb'
+    - 'app/models/concerns/account_counters.rb'
+    - 'app/models/concerns/ldap_authenticable.rb'
+    - 'app/models/tag.rb'
+    - 'app/models/user.rb'
+    - 'app/serializers/rest/instance_serializer.rb'
+    - 'app/services/fan_out_on_write_service.rb'
+    - 'app/services/post_status_service.rb'
+    - 'app/services/process_hashtags_service.rb'
+    - 'app/workers/move_worker.rb'
+    - 'app/workers/redownload_avatar_worker.rb'
+    - 'app/workers/redownload_header_worker.rb'
+    - 'app/workers/redownload_media_worker.rb'
+    - 'app/workers/remote_account_refresh_worker.rb'
+    - 'db/migrate/20170901141119_truncate_preview_cards.rb'
+    - 'db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb'
+    - 'lib/devise/two_factor_ldap_authenticatable.rb'
+    - 'lib/devise/two_factor_pam_authenticatable.rb'
+    - 'lib/mastodon/accounts_cli.rb'
+    - 'lib/mastodon/maintenance_cli.rb'
+    - 'lib/mastodon/media_cli.rb'
+    - 'lib/paperclip/attachment_extensions.rb'
+    - 'lib/tasks/repo.rake'
+
+# Offense count: 13
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: braces, no_braces
+Style/HashAsLastArrayItem:
+  Exclude:
+    - 'app/controllers/admin/statuses_controller.rb'
+    - 'app/controllers/api/v1/statuses_controller.rb'
+    - 'app/models/account.rb'
+    - 'app/models/concerns/account_counters.rb'
+    - 'app/models/concerns/status_threading_concern.rb'
+    - 'app/models/status.rb'
+    - 'app/services/batched_remove_status_service.rb'
+    - 'app/services/notify_service.rb'
+    - 'db/migrate/20181024224956_migrate_account_conversations.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowSplatArgument.
+Style/HashConversion:
+  Exclude:
+    - 'app/services/import_service.rb'
+
+# Offense count: 12
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
+# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
+# SupportedShorthandSyntax: always, never, either, consistent
+Style/HashSyntax:
+  Exclude:
+    - 'app/helpers/application_helper.rb'
+    - 'app/models/media_attachment.rb'
+    - 'lib/terrapin/multi_pipe_extensions.rb'
+    - 'spec/controllers/admin/reports/actions_controller_spec.rb'
+    - 'spec/controllers/admin/statuses_controller_spec.rb'
+    - 'spec/controllers/concerns/signature_verification_spec.rb'
+
+# Offense count: 3
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/HashTransformValues:
+  Exclude:
+    - 'app/serializers/rest/web_push_subscription_serializer.rb'
+    - 'app/services/import_service.rb'
+
+# Offense count: 3
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: InverseMethods, InverseBlocks.
+Style/InverseMethods:
+  Exclude:
+    - 'app/models/custom_filter.rb'
+    - 'app/services/update_account_service.rb'
+    - 'spec/controllers/activitypub/replies_controller_spec.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/MapToHash:
+  Exclude:
+    - 'app/models/status.rb'
+
+# Offense count: 17
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: literals, strict
+Style/MutableConstant:
+  Exclude:
+    - 'app/lib/link_details_extractor.rb'
+    - 'app/models/account.rb'
+    - 'app/models/custom_emoji.rb'
+    - 'app/models/tag.rb'
+    - 'app/services/account_search_service.rb'
+    - 'app/services/delete_account_service.rb'
+    - 'app/services/fetch_link_card_service.rb'
+    - 'app/services/resolve_url_service.rb'
+    - 'app/validators/html_validator.rb'
+    - 'lib/mastodon/snowflake.rb'
+    - 'spec/controllers/api/base_controller_spec.rb'
+
+# Offense count: 10
+# Configuration parameters: AllowedMethods.
+# AllowedMethods: respond_to_missing?
+Style/OptionalBooleanParameter:
+  Exclude:
+    - 'app/helpers/admin/account_moderation_notes_helper.rb'
+    - 'app/helpers/jsonld_helper.rb'
+    - 'app/lib/request.rb'
+    - 'app/lib/webfinger.rb'
+    - 'app/services/block_domain_service.rb'
+    - 'app/services/fetch_resource_service.rb'
+    - 'app/workers/domain_block_worker.rb'
+    - 'app/workers/unfollow_follow_worker.rb'
+    - 'lib/mastodon/redis_config.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: short, verbose
+Style/PreferredHashMethods:
+  Exclude:
+    - 'spec/support/matchers/model/model_have_error_on_field.rb'
+
+# Offense count: 5
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Methods.
+Style/RedundantArgument:
+  Exclude:
+    - 'app/controllers/concerns/signature_verification.rb'
+    - 'app/helpers/application_helper.rb'
+    - 'lib/tasks/emojis.rake'
+
+# Offense count: 16
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantRegexpCharacterClass:
+  Exclude:
+    - 'app/lib/link_details_extractor.rb'
+    - 'app/lib/tag_manager.rb'
+    - 'app/models/domain_allow.rb'
+    - 'app/models/domain_block.rb'
+    - 'app/services/fetch_oembed_service.rb'
+    - 'lib/tasks/emojis.rake'
+    - 'lib/tasks/mastodon.rake'
+
+# Offense count: 10
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantRegexpEscape:
+  Exclude:
+    - 'app/lib/webfinger_resource.rb'
+    - 'app/models/account.rb'
+    - 'app/models/tag.rb'
+    - 'app/services/fetch_link_card_service.rb'
+    - 'lib/paperclip/color_extractor.rb'
+    - 'lib/tasks/mastodon.rake'
+
+# Offense count: 19
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
+# SupportedStyles: slashes, percent_r, mixed
+Style/RegexpLiteral:
+  Exclude:
+    - 'app/lib/link_details_extractor.rb'
+    - 'app/lib/permalink_redirector.rb'
+    - 'app/lib/plain_text_formatter.rb'
+    - 'app/lib/tag_manager.rb'
+    - 'app/lib/text_formatter.rb'
+    - 'app/models/account.rb'
+    - 'app/models/domain_allow.rb'
+    - 'app/models/domain_block.rb'
+    - 'app/models/site_upload.rb'
+    - 'app/models/tag.rb'
+    - 'app/services/backup_service.rb'
+    - 'app/services/fetch_oembed_service.rb'
+    - 'app/services/search_service.rb'
+    - 'lib/mastodon/premailer_webpack_strategy.rb'
+    - 'lib/tasks/mastodon.rake'
+
+# Offense count: 21
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: implicit, explicit
+Style/RescueStandardError:
+  Exclude:
+    - 'app/lib/activitypub/activity/move.rb'
+    - 'app/lib/request.rb'
+    - 'app/models/account.rb'
+    - 'app/workers/move_worker.rb'
+    - 'app/workers/scheduler/vacuum_scheduler.rb'
+    - 'lib/mastodon/accounts_cli.rb'
+    - 'lib/mastodon/cli_helper.rb'
+    - 'lib/mastodon/media_cli.rb'
+    - 'lib/mastodon/sidekiq_middleware.rb'
+    - 'lib/mastodon/statuses_cli.rb'
+    - 'lib/mastodon/upgrade_cli.rb'
+
+# Offense count: 2
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
+# AllowedMethods: present?, blank?, presence, try, try!
+Style/SafeNavigation:
+  Exclude:
+    - 'app/models/concerns/account_finder_concern.rb'
+    - 'app/models/status.rb'
+
+# Offense count: 5
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowAsExpressionSeparator.
+Style/Semicolon:
+  Exclude:
+    - 'spec/services/activitypub/process_status_update_service_spec.rb'
+    - 'spec/validators/blacklisted_email_validator_spec.rb'
+    - 'spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: only_raise, only_fail, semantic
+Style/SignalException:
+  Exclude:
+    - 'lib/devise/two_factor_ldap_authenticatable.rb'
+    - 'lib/devise/two_factor_pam_authenticatable.rb'
+
+# Offense count: 3
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/SingleArgumentDig:
+  Exclude:
+    - 'lib/webpacker/manifest_extensions.rb'
+
+# Offense count: 14
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/SlicingWithRange:
+  Exclude:
+    - 'app/lib/emoji_formatter.rb'
+    - 'app/lib/text_formatter.rb'
+    - 'app/lib/toc_generator.rb'
+    - 'app/models/account_alias.rb'
+    - 'app/models/domain_block.rb'
+    - 'app/models/email_domain_block.rb'
+    - 'app/models/preview_card_provider.rb'
+    - 'app/validators/status_length_validator.rb'
+    - 'db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb'
+    - 'lib/active_record/batches.rb'
+    - 'lib/mastodon/premailer_webpack_strategy.rb'
+    - 'lib/tasks/repo.rake'
+
+# Offense count: 25
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Mode.
+Style/StringConcatenation:
+  Exclude:
+    - 'app/lib/activitypub/case_transform.rb'
+    - 'app/lib/validation_error_formatter.rb'
+    - 'app/services/backup_service.rb'
+    - 'app/services/fetch_link_card_service.rb'
+    - 'lib/mastodon/emoji_cli.rb'
+    - 'lib/mastodon/redis_config.rb'
+    - 'lib/mastodon/snowflake.rb'
+    - 'lib/paperclip/gif_transcoder.rb'
+    - 'lib/paperclip/type_corrector.rb'
+    - 'spec/controllers/api/v1/apps_controller_spec.rb'
+    - 'spec/controllers/api/v1/streaming_controller_spec.rb'
+    - 'spec/validators/disallowed_hashtags_validator_spec.rb'
+    - 'spec/workers/web/push_notification_worker_spec.rb'
+
+# Offense count: 272
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, MinSize.
+# SupportedStyles: percent, brackets
+Style/SymbolArray:
+  Exclude:
+    - 'app/controllers/accounts_controller.rb'
+    - 'app/controllers/activitypub/replies_controller.rb'
+    - 'app/controllers/admin/accounts_controller.rb'
+    - 'app/controllers/admin/announcements_controller.rb'
+    - 'app/controllers/admin/domain_blocks_controller.rb'
+    - 'app/controllers/admin/email_domain_blocks_controller.rb'
+    - 'app/controllers/admin/relationships_controller.rb'
+    - 'app/controllers/admin/relays_controller.rb'
+    - 'app/controllers/admin/roles_controller.rb'
+    - 'app/controllers/admin/rules_controller.rb'
+    - 'app/controllers/admin/statuses_controller.rb'
+    - 'app/controllers/admin/trends/statuses_controller.rb'
+    - 'app/controllers/admin/warning_presets_controller.rb'
+    - 'app/controllers/admin/webhooks_controller.rb'
+    - 'app/controllers/api/v1/accounts/credentials_controller.rb'
+    - 'app/controllers/api/v1/accounts_controller.rb'
+    - 'app/controllers/api/v1/admin/accounts_controller.rb'
+    - 'app/controllers/api/v1/admin/canonical_email_blocks_controller.rb'
+    - 'app/controllers/api/v1/admin/domain_allows_controller.rb'
+    - 'app/controllers/api/v1/admin/domain_blocks_controller.rb'
+    - 'app/controllers/api/v1/admin/email_domain_blocks_controller.rb'
+    - 'app/controllers/api/v1/admin/ip_blocks_controller.rb'
+    - 'app/controllers/api/v1/admin/reports_controller.rb'
+    - 'app/controllers/api/v1/crypto/deliveries_controller.rb'
+    - 'app/controllers/api/v1/crypto/keys/claims_controller.rb'
+    - 'app/controllers/api/v1/crypto/keys/uploads_controller.rb'
+    - 'app/controllers/api/v1/featured_tags_controller.rb'
+    - 'app/controllers/api/v1/filters_controller.rb'
+    - 'app/controllers/api/v1/lists_controller.rb'
+    - 'app/controllers/api/v1/notifications_controller.rb'
+    - 'app/controllers/api/v1/push/subscriptions_controller.rb'
+    - 'app/controllers/api/v1/scheduled_statuses_controller.rb'
+    - 'app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb'
+    - 'app/controllers/api/v1/statuses_controller.rb'
+    - 'app/controllers/api/v2/filters/keywords_controller.rb'
+    - 'app/controllers/api/v2/filters/statuses_controller.rb'
+    - 'app/controllers/api/v2/filters_controller.rb'
+    - 'app/controllers/api/web/push_subscriptions_controller.rb'
+    - 'app/controllers/application_controller.rb'
+    - 'app/controllers/auth/registrations_controller.rb'
+    - 'app/controllers/filters_controller.rb'
+    - 'app/controllers/settings/applications_controller.rb'
+    - 'app/controllers/settings/featured_tags_controller.rb'
+    - 'app/controllers/settings/profiles_controller.rb'
+    - 'app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb'
+    - 'app/controllers/statuses_controller.rb'
+    - 'app/lib/feed_manager.rb'
+    - 'app/models/account.rb'
+    - 'app/models/account_filter.rb'
+    - 'app/models/admin/status_filter.rb'
+    - 'app/models/announcement.rb'
+    - 'app/models/concerns/ldap_authenticable.rb'
+    - 'app/models/concerns/status_threading_concern.rb'
+    - 'app/models/custom_filter.rb'
+    - 'app/models/domain_block.rb'
+    - 'app/models/import.rb'
+    - 'app/models/list.rb'
+    - 'app/models/media_attachment.rb'
+    - 'app/models/preview_card.rb'
+    - 'app/models/relay.rb'
+    - 'app/models/report.rb'
+    - 'app/models/site_upload.rb'
+    - 'app/models/status.rb'
+    - 'app/serializers/initial_state_serializer.rb'
+    - 'app/serializers/rest/notification_serializer.rb'
+    - 'db/migrate/20160220174730_create_accounts.rb'
+    - 'db/migrate/20160221003621_create_follows.rb'
+    - 'db/migrate/20160223171800_create_favourites.rb'
+    - 'db/migrate/20160224223247_create_mentions.rb'
+    - 'db/migrate/20160314164231_add_owner_to_application.rb'
+    - 'db/migrate/20160316103650_add_missing_indices.rb'
+    - 'db/migrate/20160926213048_remove_owner_from_application.rb'
+    - 'db/migrate/20161003145426_create_blocks.rb'
+    - 'db/migrate/20161006213403_rails_settings_migration.rb'
+    - 'db/migrate/20161105130633_create_statuses_tags_join_table.rb'
+    - 'db/migrate/20161119211120_create_notifications.rb'
+    - 'db/migrate/20161128103007_create_subscriptions.rb'
+    - 'db/migrate/20161222204147_create_follow_requests.rb'
+    - 'db/migrate/20170112154826_migrate_settings.rb'
+    - 'db/migrate/20170301222600_create_mutes.rb'
+    - 'db/migrate/20170406215816_add_notifications_and_favourites_indices.rb'
+    - 'db/migrate/20170424003227_create_account_domain_blocks.rb'
+    - 'db/migrate/20170427011934_re_add_owner_to_application.rb'
+    - 'db/migrate/20170507141759_optimize_index_subscriptions.rb'
+    - 'db/migrate/20170508230434_create_conversation_mutes.rb'
+    - 'db/migrate/20170720000000_add_index_favourites_on_account_id_and_id.rb'
+    - 'db/migrate/20170823162448_create_status_pins.rb'
+    - 'db/migrate/20170901142658_create_join_table_preview_cards_statuses.rb'
+    - 'db/migrate/20170905044538_add_index_id_account_id_activity_type_on_notifications.rb'
+    - 'db/migrate/20170917153509_create_custom_emojis.rb'
+    - 'db/migrate/20170918125918_ids_to_bigints.rb'
+    - 'db/migrate/20171116161857_create_list_accounts.rb'
+    - 'db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb'
+    - 'db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb'
+    - 'db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb'
+    - 'db/migrate/20171129172043_add_index_on_stream_entries.rb'
+    - 'db/migrate/20171226094803_more_faster_index_on_notifications.rb'
+    - 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
+    - 'db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
+    - 'db/migrate/20180808175627_create_account_pins.rb'
+    - 'db/migrate/20180831171112_create_bookmarks.rb'
+    - 'db/migrate/20180929222014_create_account_conversations.rb'
+    - 'db/migrate/20181007025445_create_pghero_space_stats.rb'
+    - 'db/migrate/20181203003808_create_accounts_tags_join_table.rb'
+    - 'db/migrate/20190316190352_create_account_identity_proofs.rb'
+    - 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
+    - 'db/migrate/20190820003045_update_statuses_index.rb'
+    - 'db/migrate/20190823221802_add_local_index_to_statuses.rb'
+    - 'db/migrate/20190904222339_create_markers.rb'
+    - 'db/migrate/20200113125135_create_announcement_mutes.rb'
+    - 'db/migrate/20200114113335_create_announcement_reactions.rb'
+    - 'db/migrate/20200119112504_add_public_index_to_statuses.rb'
+    - 'db/migrate/20200628133322_create_account_notes.rb'
+    - 'db/migrate/20200917222316_add_index_notifications_on_type.rb'
+    - 'db/migrate/20210425135952_add_index_on_media_attachments_account_id_status_id.rb'
+    - 'db/migrate/20220714171049_create_tag_follows.rb'
+    - 'db/migrate/20221021055441_add_index_featured_tags_on_account_id_and_tag_id.rb'
+    - 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
+    - 'db/post_migrate/20200917222734_remove_index_notifications_on_account_activity.rb'
+    - 'spec/controllers/api/v1/streaming_controller_spec.rb'
+    - 'spec/controllers/api/v2/admin/accounts_controller_spec.rb'
+    - 'spec/controllers/concerns/signature_verification_spec.rb'
+    - 'spec/fabricators/notification_fabricator.rb'
+    - 'spec/models/public_feed_spec.rb'
+
+# Offense count: 4
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
+# AllowedMethods: define_method, mail, respond_to
+Style/SymbolProc:
+  Exclude:
+    - 'spec/lib/request_spec.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+Style/UnpackFirst:
+  Exclude:
+    - 'app/models/concerns/account_interactions.rb'
+    - 'lib/paperclip/gif_transcoder.rb'
+
+# Offense count: 25
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, MinSize, WordRegex.
+# SupportedStyles: percent, brackets
+Style/WordArray:
+  Exclude:
+    - 'db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb'
+    - 'db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
+    - 'lib/mastodon/maintenance_cli.rb'
+    - 'lib/tasks/statistics.rake'
+    - 'spec/controllers/api/v1/blocks_controller_spec.rb'
+    - 'spec/controllers/api/v1/bookmarks_controller_spec.rb'
+    - 'spec/controllers/api/v1/favourites_controller_spec.rb'
+    - 'spec/controllers/api/v1/mutes_controller_spec.rb'
+    - 'spec/controllers/settings/applications_controller_spec.rb'
+    - 'spec/controllers/settings/preferences/other_controller_spec.rb'
+    - 'spec/models/account_spec.rb'
+    - 'spec/models/account_statuses_cleanup_policy_spec.rb'
+    - 'spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb'
+    - 'spec/services/activitypub/process_account_service_spec.rb'
+    - 'spec/services/delete_account_service_spec.rb'
+    - 'spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb'
diff --git a/.ruby-version b/.ruby-version
index eca690e73..e4604e3af 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-3.0.5
+3.2.1
diff --git a/Dockerfile b/Dockerfile
index 04e3b58b1..c2b18ce88 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,7 +2,7 @@
 # This needs to be bullseye-slim because the Ruby image is built on bullseye-slim
 ARG NODE_VERSION="16.19-bullseye-slim"
 
-FROM ghcr.io/moritzheiber/ruby-jemalloc:3.0.5-slim as ruby
+FROM ghcr.io/moritzheiber/ruby-jemalloc:3.2.1-slim as ruby
 FROM node:${NODE_VERSION} as build
 
 COPY --link --from=ruby /opt/ruby /opt/ruby
diff --git a/Gemfile b/Gemfile
index a3d2a9bde..7a7fcc9da 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 source 'https://rubygems.org'
-ruby '>= 2.7.0', '< 3.1.0'
+ruby '>= 2.7.0', '< 3.3.0'
 
 gem 'pkg-config', '~> 1.5'
 gem 'rexml', '~> 3.2'
@@ -21,7 +21,7 @@ gem 'dotenv-rails', '~> 2.8'
 gem 'aws-sdk-s3', '~> 1.119', require: false
 gem 'fog-core', '<= 2.4.0'
 gem 'fog-openstack', '~> 0.3', require: false
-gem 'kt-paperclip', '~> 7.1'
+gem 'kt-paperclip', '~> 7.1', github: 'kreeti/kt-paperclip', ref: '11abf222dc31bff71160a1d138b445214f434b2b'
 gem 'blurhash', '~> 0.1'
 
 gem 'active_model_serializers', '~> 0.10'
@@ -62,7 +62,7 @@ gem 'link_header', '~> 0.0'
 gem 'mime-types', '~> 3.4.1', require: 'mime/types/columnar'
 gem 'nokogiri', '~> 1.14'
 gem 'nsa', '~> 0.2'
-gem 'oj', '~> 3.13'
+gem 'oj', '~> 3.14'
 gem 'ox', '~> 2.14'
 gem 'parslet'
 gem 'posix-spawn'
@@ -72,7 +72,7 @@ gem 'premailer-rails'
 gem 'rack-attack', '~> 6.6'
 gem 'rack-cors', '~> 1.1', require: 'rack/cors'
 gem 'rails-i18n', '~> 6.0'
-gem 'rails-settings-cached', '~> 0.6'
+gem 'rails-settings-cached', '~> 0.6', git: 'https://github.com/mastodon/rails-settings-cached.git', branch: 'v0.6.6-aliases-true'
 gem 'redcarpet', '~> 3.6'
 gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
 gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
@@ -94,7 +94,7 @@ gem 'twitter-text', '~> 3.1.0'
 gem 'tzinfo-data', '~> 1.2022'
 gem 'webpacker', '~> 5.4'
 gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9'
-gem 'webauthn', '~> 2.5'
+gem 'webauthn', '~> 3.0'
 
 gem 'json-ld'
 gem 'json-ld-preloaded', '~> 3.2'
diff --git a/Gemfile.lock b/Gemfile.lock
index 0ad3d6328..5a95954aa 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -7,6 +7,26 @@ GIT
       hkdf (~> 0.2)
       jwt (~> 2.0)
 
+GIT
+  remote: https://github.com/kreeti/kt-paperclip.git
+  revision: 11abf222dc31bff71160a1d138b445214f434b2b
+  ref: 11abf222dc31bff71160a1d138b445214f434b2b
+  specs:
+    kt-paperclip (7.1.1)
+      activemodel (>= 4.2.0)
+      activesupport (>= 4.2.0)
+      marcel (~> 1.0.1)
+      mime-types
+      terrapin (~> 0.6.0)
+
+GIT
+  remote: https://github.com/mastodon/rails-settings-cached.git
+  revision: 86328ef0bd04ce21cc0504ff5e334591e8c2ccab
+  branch: v0.6.6-aliases-true
+  specs:
+    rails-settings-cached (0.6.6)
+      rails (>= 4.2.0)
+
 GEM
   remote: https://rubygems.org/
   specs:
@@ -90,7 +110,7 @@ GEM
     attr_required (1.0.1)
     awrence (1.2.1)
     aws-eventstream (1.2.0)
-    aws-partitions (1.701.0)
+    aws-partitions (1.711.0)
     aws-sdk-core (3.170.0)
       aws-eventstream (~> 1, >= 1.0.2)
       aws-partitions (~> 1, >= 1.651.0)
@@ -99,7 +119,7 @@ GEM
     aws-sdk-kms (1.62.0)
       aws-sdk-core (~> 3, >= 3.165.0)
       aws-sigv4 (~> 1.1)
-    aws-sdk-s3 (1.119.0)
+    aws-sdk-s3 (1.119.1)
       aws-sdk-core (~> 3, >= 3.165.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.4)
@@ -117,7 +137,7 @@ GEM
       erubi (~> 1.4)
       parser (>= 2.4)
       smart_properties
-    bindata (2.4.14)
+    bindata (2.4.15)
     binding_of_caller (1.0.0)
       debug_inspector (>= 0.0.1)
     blurhash (0.1.7)
@@ -175,7 +195,7 @@ GEM
     color_diff (0.1)
     concurrent-ruby (1.2.0)
     connection_pool (2.3.0)
-    cose (1.2.1)
+    cose (1.3.0)
       cbor (~> 0.5.9)
       openssl-signature_algorithm (~> 1.0)
     crack (0.4.5)
@@ -346,7 +366,7 @@ GEM
     json-schema (3.0.0)
       addressable (>= 2.8)
     jsonapi-renderer (0.2.2)
-    jwt (2.5.0)
+    jwt (2.7.0)
     kaminari (1.2.2)
       activesupport (>= 4.1.0)
       kaminari-actionview (= 1.2.2)
@@ -359,12 +379,6 @@ GEM
       activerecord
       kaminari-core (= 1.2.2)
     kaminari-core (1.2.2)
-    kt-paperclip (7.1.1)
-      activemodel (>= 4.2.0)
-      activesupport (>= 4.2.0)
-      marcel (~> 1.0.1)
-      mime-types
-      terrapin (~> 0.6.0)
     launchy (2.5.0)
       addressable (~> 2.7)
     letter_opener (1.8.1)
@@ -424,7 +438,7 @@ GEM
       net-protocol
     net-ssh (7.0.1)
     nio4r (2.5.8)
-    nokogiri (1.14.1)
+    nokogiri (1.14.2)
       mini_portile2 (~> 2.8.0)
       racc (~> 1.4)
     nsa (0.2.8)
@@ -432,7 +446,7 @@ GEM
       concurrent-ruby (~> 1.0, >= 1.0.2)
       sidekiq (>= 3.5)
       statsd-ruby (~> 1.4, >= 1.4.0)
-    oj (3.13.23)
+    oj (3.14.2)
     omniauth (1.9.2)
       hashie (>= 3.4.6)
       rack (>= 1.6.2, < 3)
@@ -460,9 +474,9 @@ GEM
       validate_email
       validate_url
       webfinger (~> 1.2)
-    openssl (3.0.0)
-    openssl-signature_algorithm (1.2.1)
-      openssl (> 2.0, < 3.1)
+    openssl (3.1.0)
+    openssl-signature_algorithm (1.3.0)
+      openssl (> 2.0)
     orm_adapter (0.5.0)
     ox (2.14.14)
     parallel (1.22.1)
@@ -542,8 +556,6 @@ GEM
     rails-i18n (6.0.0)
       i18n (>= 0.7, < 2)
       railties (>= 6.0.0, < 7)
-    rails-settings-cached (0.6.6)
-      rails (>= 4.2.0)
     railties (6.1.7.2)
       actionpack (= 6.1.7.2)
       activesupport (= 6.1.7.2)
@@ -693,9 +705,9 @@ GEM
     thor (1.2.1)
     tilt (2.0.11)
     timeout (0.3.1)
-    tpm-key_attestation (0.11.0)
+    tpm-key_attestation (0.12.0)
       bindata (~> 2.4)
-      openssl (> 2.0, < 3.1)
+      openssl (> 2.0)
       openssl-signature_algorithm (~> 1.0)
     tty-color (0.6.0)
     tty-cursor (0.7.1)
@@ -728,15 +740,15 @@ GEM
       public_suffix
     warden (1.2.9)
       rack (>= 2.0.9)
-    webauthn (2.5.2)
+    webauthn (3.0.0)
       android_key_attestation (~> 0.3.0)
       awrence (~> 1.1)
       bindata (~> 2.4)
       cbor (~> 0.5.9)
       cose (~> 1.1)
-      openssl (>= 2.2, < 3.1)
+      openssl (>= 2.2)
       safety_net_attestation (~> 0.4.0)
-      tpm-key_attestation (~> 0.11.0)
+      tpm-key_attestation (~> 0.12.0)
     webfinger (1.2.0)
       activesupport
       httpclient (>= 2.4)
@@ -814,7 +826,7 @@ DEPENDENCIES
   json-ld-preloaded (~> 3.2)
   json-schema (~> 3.0)
   kaminari (~> 1.2)
-  kt-paperclip (~> 7.1)
+  kt-paperclip (~> 7.1)!
   letter_opener (~> 1.8)
   letter_opener_web (~> 2.0)
   link_header (~> 0.0)
@@ -827,7 +839,7 @@ DEPENDENCIES
   net-ldap (~> 0.17)
   nokogiri (~> 1.14)
   nsa (~> 0.2)
-  oj (~> 3.13)
+  oj (~> 3.14)
   omniauth (~> 1.9)
   omniauth-cas (~> 2.0)
   omniauth-rails_csrf_protection (~> 0.1)
@@ -853,7 +865,7 @@ DEPENDENCIES
   rails (~> 6.1.7)
   rails-controller-testing (~> 1.0)
   rails-i18n (~> 6.0)
-  rails-settings-cached (~> 0.6)
+  rails-settings-cached (~> 0.6)!
   rdf-normalize (~> 0.5)
   redcarpet (~> 3.6)
   redis (~> 4.5)
@@ -886,7 +898,7 @@ DEPENDENCIES
   tty-prompt (~> 0.23)
   twitter-text (~> 3.1.0)
   tzinfo-data (~> 1.2022)
-  webauthn (~> 2.5)
+  webauthn (~> 3.0)
   webmock (~> 3.18)
   webpacker (~> 5.4)
   webpush!
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index 924b623ad..099512248 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -18,13 +18,11 @@ module Admin
     private
 
     def redis_info
-      @redis_info ||= begin
-        if redis.is_a?(Redis::Namespace)
-          redis.redis.info
-        else
-          redis.info
-        end
-      end
+      @redis_info ||= if redis.is_a?(Redis::Namespace)
+                        redis.redis.info
+                      else
+                        redis.info
+                      end
     end
   end
 end
diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb
index 74764640b..060db11bb 100644
--- a/app/controllers/admin/domain_blocks_controller.rb
+++ b/app/controllers/admin/domain_blocks_controller.rb
@@ -90,9 +90,7 @@ module Admin
     end
 
     def action_from_button
-      if params[:save]
-        'save'
-      end
+      'save' if params[:save]
     end
   end
 end
diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
index b61de13b9..68952de89 100644
--- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
@@ -45,15 +45,11 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_account_followers_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_account_followers_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @accounts.empty?
-      api_v1_account_followers_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_account_followers_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb
index 37d3c2d78..0a4d2ae7b 100644
--- a/app/controllers/api/v1/accounts/following_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb
@@ -45,15 +45,11 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_account_following_index_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_account_following_index_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @accounts.empty?
-      api_v1_account_following_index_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_account_following_index_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index 38c9f5a20..7ed48cf65 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -39,15 +39,11 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_account_statuses_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_account_statuses_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @statuses.empty?
-      api_v1_account_statuses_url pagination_params(min_id: pagination_since_id)
-    end
+    api_v1_account_statuses_url pagination_params(min_id: pagination_since_id) unless @statuses.empty?
   end
 
   def records_continue?
diff --git a/app/controllers/api/v1/admin/accounts_controller.rb b/app/controllers/api/v1/admin/accounts_controller.rb
index f48300072..ff9cae639 100644
--- a/app/controllers/api/v1/admin/accounts_controller.rb
+++ b/app/controllers/api/v1/admin/accounts_controller.rb
@@ -120,9 +120,7 @@ class Api::V1::Admin::AccountsController < Api::BaseController
       translated_params[:status] = status.to_s if params[status].present?
     end
 
-    if params[:staff].present?
-      translated_params[:role_ids] = UserRole.that_can(:manage_reports).map(&:id)
-    end
+    translated_params[:role_ids] = UserRole.that_can(:manage_reports).map(&:id) if params[:staff].present?
 
     translated_params
   end
diff --git a/app/controllers/api/v1/announcements_controller.rb b/app/controllers/api/v1/announcements_controller.rb
index ee79fc19f..82e9cf7de 100644
--- a/app/controllers/api/v1/announcements_controller.rb
+++ b/app/controllers/api/v1/announcements_controller.rb
@@ -18,9 +18,7 @@ class Api::V1::AnnouncementsController < Api::BaseController
   private
 
   def set_announcements
-    @announcements = begin
-      Announcement.published.chronological
-    end
+    @announcements = Announcement.published.chronological
   end
 
   def set_announcement
diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb
index a65e762c9..06a8bfa89 100644
--- a/app/controllers/api/v1/blocks_controller.rb
+++ b/app/controllers/api/v1/blocks_controller.rb
@@ -33,15 +33,11 @@ class Api::V1::BlocksController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_blocks_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_blocks_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless paginated_blocks.empty?
-      api_v1_blocks_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_blocks_url pagination_params(since_id: pagination_since_id) unless paginated_blocks.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/conversations_controller.rb b/app/controllers/api/v1/conversations_controller.rb
index 6c7583403..9034e8a2f 100644
--- a/app/controllers/api/v1/conversations_controller.rb
+++ b/app/controllers/api/v1/conversations_controller.rb
@@ -40,15 +40,11 @@ class Api::V1::ConversationsController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_conversations_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_conversations_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @conversations.empty?
-      api_v1_conversations_url pagination_params(min_id: pagination_since_id)
-    end
+    api_v1_conversations_url pagination_params(min_id: pagination_since_id) unless @conversations.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/domain_blocks_controller.rb b/app/controllers/api/v1/domain_blocks_controller.rb
index 1891261b9..34def3c44 100644
--- a/app/controllers/api/v1/domain_blocks_controller.rb
+++ b/app/controllers/api/v1/domain_blocks_controller.rb
@@ -43,15 +43,11 @@ class Api::V1::DomainBlocksController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_domain_blocks_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_domain_blocks_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @blocks.empty?
-      api_v1_domain_blocks_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_domain_blocks_url pagination_params(since_id: pagination_since_id) unless @blocks.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/endorsements_controller.rb b/app/controllers/api/v1/endorsements_controller.rb
index 9e80f468a..46e3fcd64 100644
--- a/app/controllers/api/v1/endorsements_controller.rb
+++ b/app/controllers/api/v1/endorsements_controller.rb
@@ -35,17 +35,13 @@ class Api::V1::EndorsementsController < Api::BaseController
   def next_path
     return if unlimited?
 
-    if records_continue?
-      api_v1_endorsements_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_endorsements_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
     return if unlimited?
 
-    unless @accounts.empty?
-      api_v1_endorsements_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_endorsements_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/favourites_controller.rb b/app/controllers/api/v1/favourites_controller.rb
index 2a873696c..bd7f3d775 100644
--- a/app/controllers/api/v1/favourites_controller.rb
+++ b/app/controllers/api/v1/favourites_controller.rb
@@ -36,15 +36,11 @@ class Api::V1::FavouritesController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_favourites_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_favourites_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless results.empty?
-      api_v1_favourites_url pagination_params(min_id: pagination_since_id)
-    end
+    api_v1_favourites_url pagination_params(min_id: pagination_since_id) unless results.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb
index 54ff0e11d..7c197ce6b 100644
--- a/app/controllers/api/v1/follow_requests_controller.rb
+++ b/app/controllers/api/v1/follow_requests_controller.rb
@@ -53,15 +53,11 @@ class Api::V1::FollowRequestsController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_follow_requests_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_follow_requests_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @accounts.empty?
-      api_v1_follow_requests_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_follow_requests_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/lists/accounts_controller.rb b/app/controllers/api/v1/lists/accounts_controller.rb
index b66ea9bfe..8e12cb7b6 100644
--- a/app/controllers/api/v1/lists/accounts_controller.rb
+++ b/app/controllers/api/v1/lists/accounts_controller.rb
@@ -62,17 +62,13 @@ class Api::V1::Lists::AccountsController < Api::BaseController
   def next_path
     return if unlimited?
 
-    if records_continue?
-      api_v1_list_accounts_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_list_accounts_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
     return if unlimited?
 
-    unless @accounts.empty?
-      api_v1_list_accounts_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_list_accounts_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/mutes_controller.rb b/app/controllers/api/v1/mutes_controller.rb
index 6cde53a2a..555485823 100644
--- a/app/controllers/api/v1/mutes_controller.rb
+++ b/app/controllers/api/v1/mutes_controller.rb
@@ -33,15 +33,11 @@ class Api::V1::MutesController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_mutes_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_mutes_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless paginated_mutes.empty?
-      api_v1_mutes_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_mutes_url pagination_params(since_id: pagination_since_id) unless paginated_mutes.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb
index 93785b14a..871221d4a 100644
--- a/app/controllers/api/v1/notifications_controller.rb
+++ b/app/controllers/api/v1/notifications_controller.rb
@@ -67,15 +67,11 @@ class Api::V1::NotificationsController < Api::BaseController
   end
 
   def next_path
-    unless @notifications.empty?
-      api_v1_notifications_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_notifications_url pagination_params(max_id: pagination_max_id) unless @notifications.empty?
   end
 
   def prev_path
-    unless @notifications.empty?
-      api_v1_notifications_url pagination_params(min_id: pagination_since_id)
-    end
+    api_v1_notifications_url pagination_params(min_id: pagination_since_id) unless @notifications.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/scheduled_statuses_controller.rb b/app/controllers/api/v1/scheduled_statuses_controller.rb
index f90642a73..2220b6d22 100644
--- a/app/controllers/api/v1/scheduled_statuses_controller.rb
+++ b/app/controllers/api/v1/scheduled_statuses_controller.rb
@@ -52,15 +52,11 @@ class Api::V1::ScheduledStatusesController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_scheduled_statuses_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_scheduled_statuses_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @statuses.empty?
-      api_v1_scheduled_statuses_url pagination_params(min_id: pagination_since_id)
-    end
+    api_v1_scheduled_statuses_url pagination_params(min_id: pagination_since_id) unless @statuses.empty?
   end
 
   def records_continue?
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 2b614a837..b138fa265 100644
--- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
@@ -41,15 +41,11 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_status_favourited_by_index_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_status_favourited_by_index_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @accounts.empty?
-      api_v1_status_favourited_by_index_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_status_favourited_by_index_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
   end
 
   def pagination_max_id
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 24db30fcc..4b545f982 100644
--- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
@@ -37,15 +37,11 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
   end
 
   def next_path
-    if records_continue?
-      api_v1_status_reblogged_by_index_url pagination_params(max_id: pagination_max_id)
-    end
+    api_v1_status_reblogged_by_index_url pagination_params(max_id: pagination_max_id) if records_continue?
   end
 
   def prev_path
-    unless @accounts.empty?
-      api_v1_status_reblogged_by_index_url pagination_params(since_id: pagination_since_id)
-    end
+    api_v1_status_reblogged_by_index_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/trends/links_controller.rb b/app/controllers/api/v1/trends/links_controller.rb
index 8ff3b364e..3ce20fb78 100644
--- a/app/controllers/api/v1/trends/links_controller.rb
+++ b/app/controllers/api/v1/trends/links_controller.rb
@@ -18,13 +18,11 @@ class Api::V1::Trends::LinksController < Api::BaseController
   end
 
   def set_links
-    @links = begin
-      if enabled?
-        links_from_trends.offset(offset_param).limit(limit_param(DEFAULT_LINKS_LIMIT))
-      else
-        []
-      end
-    end
+    @links = if enabled?
+               links_from_trends.offset(offset_param).limit(limit_param(DEFAULT_LINKS_LIMIT))
+             else
+               []
+             end
   end
 
   def links_from_trends
diff --git a/app/controllers/api/v1/trends/statuses_controller.rb b/app/controllers/api/v1/trends/statuses_controller.rb
index c275d5fc8..3aab92477 100644
--- a/app/controllers/api/v1/trends/statuses_controller.rb
+++ b/app/controllers/api/v1/trends/statuses_controller.rb
@@ -16,13 +16,11 @@ class Api::V1::Trends::StatusesController < Api::BaseController
   end
 
   def set_statuses
-    @statuses = begin
-      if enabled?
-        cache_collection(statuses_from_trends.offset(offset_param).limit(limit_param(DEFAULT_STATUSES_LIMIT)), Status)
-      else
-        []
-      end
-    end
+    @statuses = if enabled?
+                  cache_collection(statuses_from_trends.offset(offset_param).limit(limit_param(DEFAULT_STATUSES_LIMIT)), Status)
+                else
+                  []
+                end
   end
 
   def statuses_from_trends
diff --git a/app/controllers/api/v1/trends/tags_controller.rb b/app/controllers/api/v1/trends/tags_controller.rb
index 885a4ad7e..9dd9abdfe 100644
--- a/app/controllers/api/v1/trends/tags_controller.rb
+++ b/app/controllers/api/v1/trends/tags_controller.rb
@@ -18,13 +18,11 @@ class Api::V1::Trends::TagsController < Api::BaseController
   end
 
   def set_tags
-    @tags = begin
-      if enabled?
-        tags_from_trends.offset(offset_param).limit(limit_param(DEFAULT_TAGS_LIMIT))
-      else
-        []
-      end
-    end
+    @tags = if enabled?
+              tags_from_trends.offset(offset_param).limit(limit_param(DEFAULT_TAGS_LIMIT))
+            else
+              []
+            end
   end
 
   def tags_from_trends
diff --git a/app/controllers/api/v2/admin/accounts_controller.rb b/app/controllers/api/v2/admin/accounts_controller.rb
index b25831aa0..0c451f778 100644
--- a/app/controllers/api/v2/admin/accounts_controller.rb
+++ b/app/controllers/api/v2/admin/accounts_controller.rb
@@ -25,9 +25,7 @@ class Api::V2::Admin::AccountsController < Api::V1::Admin::AccountsController
   def translated_filter_params
     translated_params = filter_params.slice(*AccountFilter::KEYS)
 
-    if params[:permissions] == 'staff'
-      translated_params[:role_ids] = UserRole.that_can(:manage_reports).map(&:id)
-    end
+    translated_params[:role_ids] = UserRole.that_can(:manage_reports).map(&:id) if params[:permissions] == 'staff'
 
     translated_params
   end
diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb
index 40c38bc6d..83e784e4c 100644
--- a/app/controllers/auth/registrations_controller.rb
+++ b/app/controllers/auth/registrations_controller.rb
@@ -31,9 +31,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
 
   def update
     super do |resource|
-      if resource.saved_change_to_encrypted_password?
-        resource.clear_other_sessions(current_session.session_id)
-      end
+      resource.clear_other_sessions(current_session.session_id) if resource.saved_change_to_encrypted_password?
     end
   end
 
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index 16c18baa2..3183088e7 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -115,9 +115,7 @@ class Auth::SessionsController < Devise::SessionsController
   def home_paths(resource)
     paths = [about_path]
 
-    if single_user_mode? && resource.is_a?(User)
-      paths << short_account_path(username: resource.account)
-    end
+    paths << short_account_path(username: resource.account) if single_user_mode? && resource.is_a?(User)
 
     paths
   end
diff --git a/app/controllers/concerns/rate_limit_headers.rb b/app/controllers/concerns/rate_limit_headers.rb
index b8696df73..30702f00e 100644
--- a/app/controllers/concerns/rate_limit_headers.rb
+++ b/app/controllers/concerns/rate_limit_headers.rb
@@ -6,13 +6,11 @@ module RateLimitHeaders
   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
+        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
@@ -67,6 +65,6 @@ module RateLimitHeaders
   end
 
   def reset_period_offset
-    api_throttle_data[:period] - request_time.to_i % api_throttle_data[:period]
+    api_throttle_data[:period] - (request_time.to_i % api_throttle_data[:period])
   end
 end
diff --git a/app/controllers/concerns/two_factor_authentication_concern.rb b/app/controllers/concerns/two_factor_authentication_concern.rb
index c9477a1d4..3233e3e8d 100644
--- a/app/controllers/concerns/two_factor_authentication_concern.rb
+++ b/app/controllers/concerns/two_factor_authentication_concern.rb
@@ -81,13 +81,11 @@ module TwoFactorAuthenticationConcern
 
     @body_classes     = 'lighter'
     @webauthn_enabled = user.webauthn_enabled?
-    @scheme_type      = begin
-      if user.webauthn_enabled? && user_params[:otp_attempt].blank?
-        'webauthn'
-      else
-        'totp'
-      end
-    end
+    @scheme_type      = if user.webauthn_enabled? && user_params[:otp_attempt].blank?
+                          'webauthn'
+                        else
+                          'totp'
+                        end
 
     set_locale { render :two_factor }
   end
diff --git a/app/controllers/filters/statuses_controller.rb b/app/controllers/filters/statuses_controller.rb
index 4f63de7b6..86d11fcb9 100644
--- a/app/controllers/filters/statuses_controller.rb
+++ b/app/controllers/filters/statuses_controller.rb
@@ -43,9 +43,7 @@ class Filters::StatusesController < ApplicationController
   end
 
   def action_from_button
-    if params[:remove]
-      'remove'
-    end
+    'remove' if params[:remove]
   end
 
   def set_body_classes
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index 750e15fa3..4b747c9ad 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -58,7 +58,7 @@ class TagsController < ApplicationController
   def collection_presenter
     ActivityPub::CollectionPresenter.new(
       id: tag_url(@tag),
-      type: :ordered,
+      type: :ordered
     )
   end
 end
diff --git a/app/helpers/admin/dashboard_helper.rb b/app/helpers/admin/dashboard_helper.rb
index c21d41341..6096ff138 100644
--- a/app/helpers/admin/dashboard_helper.rb
+++ b/app/helpers/admin/dashboard_helper.rb
@@ -19,19 +19,17 @@ module Admin::DashboardHelper
   end
 
   def relevant_account_timestamp(account)
-    timestamp, exact = begin
-      if account.user_current_sign_in_at && account.user_current_sign_in_at < 24.hours.ago
-        [account.user_current_sign_in_at, true]
-      elsif account.user_current_sign_in_at
-        [account.user_current_sign_in_at, false]
-      elsif account.user_pending?
-        [account.user_created_at, true]
-      elsif account.last_status_at.present?
-        [account.last_status_at, true]
-      else
-        [nil, false]
-      end
-    end
+    timestamp, exact = if account.user_current_sign_in_at && account.user_current_sign_in_at < 24.hours.ago
+                         [account.user_current_sign_in_at, true]
+                       elsif account.user_current_sign_in_at
+                         [account.user_current_sign_in_at, false]
+                       elsif account.user_pending?
+                         [account.user_created_at, true]
+                       elsif account.last_status_at.present?
+                         [account.last_status_at, true]
+                       else
+                         [nil, false]
+                       end
 
     return '-' if timestamp.nil?
     return t('generic.today') unless exact
diff --git a/app/helpers/admin/trends/statuses_helper.rb b/app/helpers/admin/trends/statuses_helper.rb
index 214c1e2a6..79fee44dc 100644
--- a/app/helpers/admin/trends/statuses_helper.rb
+++ b/app/helpers/admin/trends/statuses_helper.rb
@@ -2,13 +2,11 @@
 
 module Admin::Trends::StatusesHelper
   def one_line_preview(status)
-    text = begin
-      if status.local?
-        status.text.split("\n").first
-      else
-        Nokogiri::HTML(status.text).css('html > body > *').first&.text
-      end
-    end
+    text = if status.local?
+             status.text.split("\n").first
+           else
+             Nokogiri::HTML(status.text).css('html > body > *').first&.text
+           end
 
     return '' if text.blank?
 
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 774643625..e0bf36cbc 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -217,9 +217,7 @@ module ApplicationHelper
       state_params[:moved_to_account] = current_account.moved_to_account
     end
 
-    if single_user_mode?
-      state_params[:owner] = Account.local.without_suspended.where('id > 0').first
-    end
+    state_params[:owner] = Account.local.without_suspended.where('id > 0').first if single_user_mode?
 
     json = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(state_params), serializer: InitialStateSerializer).to_json
     # rubocop:disable Rails/OutputSafety
diff --git a/app/helpers/branding_helper.rb b/app/helpers/branding_helper.rb
index ad7702aea..548c95411 100644
--- a/app/helpers/branding_helper.rb
+++ b/app/helpers/branding_helper.rb
@@ -23,14 +23,12 @@ module BrandingHelper
   end
 
   def render_symbol(version = :icon)
-    path = begin
-      case version
-      when :icon
-        'logo-symbol-icon.svg'
-      when :wordmark
-        'logo-symbol-wordmark.svg'
-      end
-    end
+    path = case version
+           when :icon
+             'logo-symbol-icon.svg'
+           when :wordmark
+             'logo-symbol-wordmark.svg'
+           end
 
     render(file: Rails.root.join('app', 'javascript', 'images', path)).html_safe # rubocop:disable Rails/OutputSafety
   end
diff --git a/app/helpers/domain_control_helper.rb b/app/helpers/domain_control_helper.rb
index ac60cad29..ffcf375ea 100644
--- a/app/helpers/domain_control_helper.rb
+++ b/app/helpers/domain_control_helper.rb
@@ -4,13 +4,11 @@ module DomainControlHelper
   def domain_not_allowed?(uri_or_domain)
     return if uri_or_domain.blank?
 
-    domain = begin
-      if uri_or_domain.include?('://')
-        Addressable::URI.parse(uri_or_domain).host
-      else
-        uri_or_domain
-      end
-    end
+    domain = if uri_or_domain.include?('://')
+               Addressable::URI.parse(uri_or_domain).host
+             else
+               uri_or_domain
+             end
 
     if whitelist_mode?
       !DomainAllow.allowed?(domain)
diff --git a/app/helpers/formatting_helper.rb b/app/helpers/formatting_helper.rb
index 05c003037..5b2ac1a2a 100644
--- a/app/helpers/formatting_helper.rb
+++ b/app/helpers/formatting_helper.rb
@@ -21,30 +21,26 @@ module FormattingHelper
   def rss_status_content_format(status)
     html = status_content_format(status)
 
-    before_html = begin
-      if status.spoiler_text?
-        tag.p do
-          tag.strong do
-            I18n.t('rss.content_warning', locale: available_locale_or_nil(status.language) || I18n.default_locale)
-          end
-
-          status.spoiler_text
-        end + tag.hr
-      end
-    end
-
-    after_html = begin
-      if status.preloadable_poll
-        tag.p do
-          safe_join(
-            status.preloadable_poll.options.map do |o|
-              tag.send(status.preloadable_poll.multiple? ? 'checkbox' : 'radio', o, disabled: true)
-            end,
-            tag.br
-          )
-        end
-      end
-    end
+    before_html = if status.spoiler_text?
+                    tag.p do
+                      tag.strong do
+                        I18n.t('rss.content_warning', locale: available_locale_or_nil(status.language) || I18n.default_locale)
+                      end
+
+                      status.spoiler_text
+                    end + tag.hr
+                  end
+
+    after_html = if status.preloadable_poll
+                   tag.p do
+                     safe_join(
+                       status.preloadable_poll.options.map do |o|
+                         tag.send(status.preloadable_poll.multiple? ? 'checkbox' : 'radio', o, disabled: true)
+                       end,
+                       tag.br
+                     )
+                   end
+                 end
 
     prerender_custom_emojis(
       safe_join([before_html, html, after_html]),
diff --git a/app/helpers/instance_helper.rb b/app/helpers/instance_helper.rb
index daacb535b..bedfe6f30 100644
--- a/app/helpers/instance_helper.rb
+++ b/app/helpers/instance_helper.rb
@@ -10,13 +10,11 @@ module InstanceHelper
   end
 
   def description_for_sign_up
-    prefix = begin
-      if @invite.present?
-        I18n.t('auth.description.prefix_invited_by_user', name: @invite.user.account.username)
-      else
-        I18n.t('auth.description.prefix_sign_up')
-      end
-    end
+    prefix = if @invite.present?
+               I18n.t('auth.description.prefix_invited_by_user', name: @invite.user.account.username)
+             else
+               I18n.t('auth.description.prefix_sign_up')
+             end
 
     safe_join([prefix, I18n.t('auth.description.suffix')], ' ')
   end
diff --git a/app/helpers/jsonld_helper.rb b/app/helpers/jsonld_helper.rb
index e5787fd47..24362b61e 100644
--- a/app/helpers/jsonld_helper.rb
+++ b/app/helpers/jsonld_helper.rb
@@ -26,15 +26,13 @@ module JsonLdHelper
   # The url attribute can be a string, an array of strings, or an array of objects.
   # The objects could include a mimeType. Not-included mimeType means it's text/html.
   def url_to_href(value, preferred_type = nil)
-    single_value = begin
-      if value.is_a?(Array) && !value.first.is_a?(String)
-        value.find { |link| preferred_type.nil? || ((link['mimeType'].presence || 'text/html') == preferred_type) }
-      elsif value.is_a?(Array)
-        value.first
-      else
-        value
-      end
-    end
+    single_value = if value.is_a?(Array) && !value.first.is_a?(String)
+                     value.find { |link| preferred_type.nil? || ((link['mimeType'].presence || 'text/html') == preferred_type) }
+                   elsif value.is_a?(Array)
+                     value.first
+                   else
+                     value
+                   end
 
     if single_value.nil? || single_value.is_a?(String)
       single_value
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index cc27840d0..ef08edbf8 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -165,11 +165,19 @@ export function submitCompose(routerHistory) {
     // API call.
     let media_attributes;
     if (statusId !== null) {
-      media_attributes = media.map(item => ({
-        id: item.get('id'),
-        description: item.get('description'),
-        focus: item.get('focus'),
-      }));
+      media_attributes = media.map(item => {
+        let focus;
+
+        if (item.getIn(['meta', 'focus'])) {
+          focus = `${item.getIn(['meta', 'focus', 'x']).toFixed(2)},${item.getIn(['meta', 'focus', 'y']).toFixed(2)}`;
+        }
+
+        return {
+          id: item.get('id'),
+          description: item.get('description'),
+          focus,
+        };
+      });
     }
 
     api(getState).request({
diff --git a/app/javascript/mastodon/components/autosuggest_input.js b/app/javascript/mastodon/components/autosuggest_input.js
index 8d2ddb411..f9616c581 100644
--- a/app/javascript/mastodon/components/autosuggest_input.js
+++ b/app/javascript/mastodon/components/autosuggest_input.js
@@ -51,7 +51,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
     searchTokens: PropTypes.arrayOf(PropTypes.string),
     maxLength: PropTypes.number,
     lang: PropTypes.string,
-    spellCheck: PropTypes.string,
+    spellCheck: PropTypes.bool,
   };
 
   static defaultProps = {
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 3e6c989ce..3e685efec 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -97,7 +97,7 @@
   "closed_registrations_modal.description": "لا يمكن إنشاء حساب على {domain} حاليا، ولكن على فكرة لست بحاجة إلى حساب على {domain} بذاته لاستخدام ماستدون.",
   "closed_registrations_modal.find_another_server": "ابحث على خادم آخر",
   "closed_registrations_modal.preamble": "ماستدون لامركزي، لذلك بغض النظر عن مكان إنشاء حسابك، سيكون بإمكانك المتابعة والتفاعل مع أي شخص على هذا الخادم. يمكنك حتى أن تستضيفه ذاتياً!",
-  "closed_registrations_modal.title": "تسجيل حساب في ماستدون",
+  "closed_registrations_modal.title": "إنشاء حساب على ماستدون",
   "column.about": "عن",
   "column.blocks": "المُستَخدِمون المَحظورون",
   "column.bookmarks": "الفواصل المرجعية",
@@ -232,7 +232,7 @@
   "empty_column.public": "لا يوجد أي شيء هنا! قم بنشر شيء ما للعامة، أو اتبع المستخدمين الآخرين المتواجدين على الخوادم الأخرى لملء خيط المحادثات",
   "error.unexpected_crash.explanation": "نظرا لوجود خطأ في التعليمات البرمجية أو مشكلة توافق مع المتصفّح، تعذر عرض هذه الصفحة بشكل صحيح.",
   "error.unexpected_crash.explanation_addons": "لا يمكن عرض هذه الصفحة بشكل صحيح. من المحتمل أن يكون هذا الخطأ بسبب إضافة متصفح أو أدوات ترجمة تلقائية.",
-  "error.unexpected_crash.next_steps": "حاول إعادة إنعاش الصفحة. إن لم تُحلّ المشكلة ، يمكنك دائمًا استخدام ماستدون عبر متصفّح آخر أو تطبيق أصلي.",
+  "error.unexpected_crash.next_steps": "حاول إعادة إنعاش الصفحة. إن لم تُحلّ المشكلة، يمكنك دائمًا استخدام ماستدون عبر متصفّح آخر أو تطبيق أصلي.",
   "error.unexpected_crash.next_steps_addons": "حاول تعطيلهم وإنعاش الصفحة. إن لم ينجح ذلك، يمكنك دائمًا استخدام ماستدون عبر متصفح آخر أو تطبيق أصلي.",
   "errors.unexpected_crash.copy_stacktrace": "انسخ تتبع الارتباطات إلى الحافظة",
   "errors.unexpected_crash.report_issue": "الإبلاغ عن خلل",
@@ -272,7 +272,7 @@
   "footer.keyboard_shortcuts": "اختصارات لوحة المفاتيح",
   "footer.privacy_policy": "سياسة الخصوصية",
   "footer.source_code": "الاطلاع على الشفرة المصدرية",
-  "footer.status": "Status",
+  "footer.status": "الحالة",
   "generic.saved": "تم الحفظ",
   "getting_started.heading": "استعدّ للبدء",
   "hashtag.column_header.tag_mode.all": "و {additional}",
@@ -291,10 +291,10 @@
   "home.column_settings.show_replies": "اعرض الردود",
   "home.hide_announcements": "إخفاء الإعلانات",
   "home.show_announcements": "إظهار الإعلانات",
-  "interaction_modal.description.favourite": "مع حساب في ماستدون، يمكنك تفضيل هذا المقال لإبلاغ الناشر بتقديرك وحفظه لاحقا.",
-  "interaction_modal.description.follow": "مع حساب في ماستدون، يمكنك متابعة {name} لتلقي مشاركاتهم في الصفحه الرئيسيه.",
-  "interaction_modal.description.reblog": "مع حساب في ماستدون، يمكنك تعزيز هذا المنشور لمشاركته مع متابعينك.",
-  "interaction_modal.description.reply": "مع حساب في ماستدون، يمكنك الرد على هذه المشاركة.",
+  "interaction_modal.description.favourite": "مع حساب في ماستدون، يمكنك إضافة هذا المنشور إلى مفضلتك لإبلاغ الناشر عن تقديرك وكذا للاحتفاظ به لوقت لاحق.",
+  "interaction_modal.description.follow": "مع حساب في ماستدون، يمكنك متابعة {name} وتلقي منشوراته على خيطك الرئيس.",
+  "interaction_modal.description.reblog": "مع حساب في ماستدون، يمكنك تعزيز هذا المنشور ومشاركته مع مُتابِعيك.",
+  "interaction_modal.description.reply": "مع حساب في ماستدون، يمكنك الرد على هذا المنشور.",
   "interaction_modal.on_another_server": "على خادم مختلف",
   "interaction_modal.on_this_server": "على هذا الخادم",
   "interaction_modal.other_server_instructions": "انسخ و الصق هذا الرابط في حقل البحث الخاص بك لتطبيق ماستدون المفضل لديك أو واجهة الويب لخادم ماستدون الخاص بك.",
@@ -509,7 +509,7 @@
   "report.statuses.title": "هل توجد مشاركات تدعم صحة هذا البلاغ؟",
   "report.submit": "إرسال",
   "report.target": "ابلغ عن {target}",
-  "report.thanks.take_action": "يمكنك هنا التحكم في ما يعرض لك على ماستدون:",
+  "report.thanks.take_action": "فيما يلي خياراتك للتحكم بما يُعرَض عليك في ماستدون:",
   "report.thanks.take_action_actionable": "في أثناء مراجعتنا للبلاغ، يمكنك اتخاذ إجراء ضد @{name}:",
   "report.thanks.title": "هل ترغب في مشاهدة هذا؟",
   "report.thanks.title_actionable": "شُكرًا لَكَ على الإبلاغ، سَوفَ نَنظُرُ فِي هَذَا الأمر.",
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index fcdabdc6c..bedfd9138 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -10,7 +10,7 @@
   "about.domain_blocks.suspended.title": "Suspendióse",
   "about.not_available": "Esta información nun ta disponible nesti sirvidor.",
   "about.powered_by": "Una rede social descentralizada que tien la teunoloxía de {mastodon}",
-  "about.rules": "Regles del sirvidor",
+  "about.rules": "Normes del sirvidor",
   "account.account_note_header": "Nota",
   "account.add_or_remove_from_list": "Amestar o quitar de les llistes",
   "account.badges.bot": "Robó",
@@ -46,7 +46,7 @@
   "account.media": "Multimedia",
   "account.mention": "Mentar a @{name}",
   "account.moved_to": "{name} indicó qu'agora la so cuenta nueva ye:",
-  "account.mute": "Mute @{name}",
+  "account.mute": "Desactivar los avisos de @{name}",
   "account.mute_notifications": "Desactivar los avisos de @{name}",
   "account.muted": "Muted",
   "account.open_original_page": "Abrir la páxina orixinal",
@@ -100,16 +100,16 @@
   "closed_registrations_modal.title": "Rexistru en Mastodon",
   "column.about": "Tocante a",
   "column.blocks": "Perfiles bloquiaos",
-  "column.bookmarks": "Bookmarks",
+  "column.bookmarks": "Marcadores",
   "column.community": "Llinia de tiempu llocal",
   "column.direct": "Mensaxes direutos",
   "column.directory": "Browse profiles",
   "column.domain_blocks": "Dominios bloquiaos",
-  "column.favourites": "Favourites",
+  "column.favourites": "Favoritos",
   "column.follow_requests": "Solicitúes de siguimientu",
-  "column.home": "Home",
+  "column.home": "Aniciu",
   "column.lists": "Llistes",
-  "column.mutes": "Muted users",
+  "column.mutes": "Perfiles colos avisos desactivaos",
   "column.notifications": "Avisos",
   "column.pins": "Artículos fixaos",
   "column.public": "Llinia de tiempu federada",
@@ -138,10 +138,10 @@
   "compose_form.poll.remove_option": "Quitar esta opción",
   "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.publish": "Publish",
-  "compose_form.publish_form": "Publish",
+  "compose_form.publish": "Espublizar",
+  "compose_form.publish_form": "Espublizar",
   "compose_form.publish_loud": "¡{publish}!",
-  "compose_form.save_changes": "Save changes",
+  "compose_form.save_changes": "Guardar los cambeos",
   "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}",
   "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}",
   "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}",
@@ -175,7 +175,7 @@
   "confirmations.unfollow.message": "¿De xuru que quies dexar de siguir a {name}?",
   "conversation.delete": "Delete conversation",
   "conversation.mark_as_read": "Mark as read",
-  "conversation.open": "View conversation",
+  "conversation.open": "Ver la conversación",
   "conversation.with": "Con {names}",
   "copypaste.copied": "Copióse",
   "copypaste.copy": "Copiar",
@@ -185,12 +185,12 @@
   "directory.recently_active": "Con actividá recién",
   "disabled_account_banner.account_settings": "Account settings",
   "disabled_account_banner.text": "Your account {disabledAccount} is currently disabled.",
-  "dismissable_banner.community_timeline": "These are the most recent public posts from people whose accounts are hosted by {domain}.",
+  "dismissable_banner.community_timeline": "Esta seición contién los artículos públicos más actuales de los perfiles agospiaos nel dominiu {domain}.",
   "dismissable_banner.dismiss": "Escartar",
   "dismissable_banner.explore_links": "Esta seición contién les noticies que se tán comentando puramente agora, nesti ya otros sirvidores de la rede descentralizada.",
   "dismissable_banner.explore_statuses": "Esta seición contién los artículos d'esti ya otros sirvidores de la rede descentralizada que tán ganando popularidá nesti sirvidor.",
   "dismissable_banner.explore_tags": "Esta seición contién les etiquetes que tán ganando popularidá ente les persones d'esti ya otros sirvidores de la rede descentralizada.",
-  "dismissable_banner.public_timeline": "Esta seición contién los artículos públicos más recientes de persones nesti ya otros sirvidores de la rede descentralizada qu'esti sirvidor conoz.",
+  "dismissable_banner.public_timeline": "Esta seición contién los artículos públicos más actuales de persones nesti ya otros sirvidores de la rede descentralizada qu'esti sirvidor conoz.",
   "embed.instructions": "Empotra esti artículu nel to sitiu web pente la copia del códigu d'abaxo.",
   "embed.preview": "Va apaecer asina:",
   "emoji_button.activity": "Actividá",
@@ -212,24 +212,24 @@
   "empty_column.account_timeline": "¡Equí nun hai nengún artículu!",
   "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "Entá nun bloquiesti a nengún perfil.",
-  "empty_column.bookmarked_statuses": "Entá nun tienes nengún artículu en Marcadores. Cuando amiestes unu, apaez equí.",
+  "empty_column.bookmarked_statuses": "Entá nun tienes nengún artículu en Marcadores. Cuando amiestes dalgún, apaez equí.",
   "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "Entá nun tienes nengún mensaxe direutu. Cuando unvies o recibas dalgún, apaecen equí.",
+  "empty_column.direct": "Entá nun tienes nengún mensaxe direutu. Cuando unvies o recibas dalgún, apaez equí.",
   "empty_column.domain_blocks": "Entá nun hai nengún dominiu bloquiáu.",
   "empty_column.explore_statuses": "Agora nun hai nada en tendencia. ¡Volvi equí dempués!",
-  "empty_column.favourited_statuses": "Entá nun marquesti nengún artículu como favoritu. Cuando marques unu, apaez equí.",
+  "empty_column.favourited_statuses": "Entá nun marquesti nengún artículu como favoritu. Cuando marques dalgún, apaez equí.",
   "empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.",
   "empty_column.follow_recommendations": "Paez que nun se puen xenerar suxerencies pa ti. Pues tentar d'usar la busca p'atopar perfiles que pues conocer o esplorar les etiquetes en tendencia.",
-  "empty_column.follow_requests": "Entá nun tienes nenguna solicitú de siguimientu. Cuando recibas una, apaez equí.",
+  "empty_column.follow_requests": "Entá nun tienes nenguna solicitú de siguimientu. Cuando recibas dalguna, apaez equí.",
   "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.",
   "empty_column.hashtag": "Entá nun hai nada con esta etiqueta.",
-  "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
-  "empty_column.home.suggestions": "See some suggestions",
+  "empty_column.home": "¡La to llinia de tiempu ta balera! Sigui a cuentes pa enllenala. {suggestions}",
+  "empty_column.home.suggestions": "Ver dalgunes suxerencies",
   "empty_column.list": "Entá nun hai nada nesta llista. Cuando los miembros d'esta llista espublicen artículos nuevos, apaecen equí.",
-  "empty_column.lists": "Entá nun tienes nenguna llista. Cuando crees una, apaez equí.",
-  "empty_column.mutes": "You haven't muted any users yet.",
-  "empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.",
-  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
+  "empty_column.lists": "Entá nun tienes nenguna llista. Cuando crees dalguna, apaez equí.",
+  "empty_column.mutes": "Entá nun tienes nengún perfil colos avisos desactivaos.",
+  "empty_column.notifications": "Entá nun tienes nengún avisu. Cuando otros perfiles interactúen contigo, apaez equí.",
+  "empty_column.public": "¡Equí nun hai nada! Escribi daqué públicamente o sigui a perfiles d'otros sirvidores pa enllenar esta seición",
   "error.unexpected_crash.explanation": "Pola mor d'un fallu nel códigu o un problema de compatibilidá del restolador, esta páxina nun se pudo amosar correutamente.",
   "error.unexpected_crash.explanation_addons": "Esta páxina nun se pudo amosar correutamente. Ye probable que dalgún complementu del restolador o dalguna ferramienta de traducción automática produxere esti error.",
   "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.",
@@ -259,7 +259,7 @@
   "filter_modal.select_filter.title": "Filter this post",
   "filter_modal.title.status": "Filter a post",
   "follow_recommendations.done": "Fecho",
-  "follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.",
+  "follow_recommendations.heading": "¡Sigui a perfiles que te prestaría ver nel feed personal! Equí tienes dalgunes suxerencies.",
   "follow_recommendations.lead": "Los artículos de los perfiles que sigas van apaecer n'orde cronolóxicu nel to feed d'aniciu. ¡Nun tengas mieu d'enquivocate, pues dexar de siguilos con facilidá en cualesquier momentu!",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Refugar",
@@ -312,7 +312,7 @@
   "keyboard_shortcuts.column": "Enfocar una columna",
   "keyboard_shortcuts.compose": "Enfocar l'área de composición",
   "keyboard_shortcuts.description": "Descripción",
-  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.direct": "Abrir la columna de mensaxes direutos",
   "keyboard_shortcuts.down": "Baxar na llista",
   "keyboard_shortcuts.enter": "Abrir un artículu",
   "keyboard_shortcuts.favourite": "Marcar un artículu como favoritu",
@@ -386,7 +386,7 @@
   "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.lists": "Llistes",
   "navigation_bar.logout": "Zarrar la sesión",
-  "navigation_bar.mutes": "Muted users",
+  "navigation_bar.mutes": "Perfiles colos avisos desactivaos",
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Artículos fixaos",
   "navigation_bar.preferences": "Preferencies",
@@ -420,7 +420,7 @@
   "notifications.column_settings.poll": "Resultaos de les encuestes:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Artículos compartíos:",
-  "notifications.column_settings.show": "Show in column",
+  "notifications.column_settings.show": "Amosar en columna",
   "notifications.column_settings.sound": "Reproducir un soníu",
   "notifications.column_settings.status": "Artículos nuevos:",
   "notifications.column_settings.unread_notifications.category": "Avisos ensin lleer",
@@ -457,7 +457,7 @@
   "privacy.direct.short": "Direct",
   "privacy.private.long": "Artículu visible namás pa los perfiles siguidores",
   "privacy.private.short": "Namás pa siguidores",
-  "privacy.public.long": "Visible for all",
+  "privacy.public.long": "Tol mundu pue ver l'artículu",
   "privacy.public.short": "Artículu públicu",
   "privacy.unlisted.long": "Artículu visible pa tol mundu mas escluyíu de les funciones de descubrimientu",
   "privacy.unlisted.short": "Unlisted",
@@ -467,11 +467,11 @@
   "regeneration_indicator.label": "Cargando…",
   "regeneration_indicator.sublabel": "Your home feed is being prepared!",
   "relative_time.days": "{number} d",
-  "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago",
-  "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago",
+  "relative_time.full.days": "Hai {number, plural, one {# día} other {# díes}}",
+  "relative_time.full.hours": "Hai {number, plural, one {# hora} other {# hores}}",
   "relative_time.full.just_now": "puramente agora",
-  "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago",
-  "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago",
+  "relative_time.full.minutes": "Hai {number, plural, one {# minutu} other {# minutos}}",
+  "relative_time.full.seconds": "Hai {number, plural, one {# segundu} other {# segundos}}",
   "relative_time.hours": "{number} h",
   "relative_time.just_now": "agora",
   "relative_time.minutes": "{number} m",
@@ -482,7 +482,7 @@
   "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.",
   "report.categories.other": "Other",
   "report.categories.spam": "Spam",
-  "report.categories.violation": "El conteníu incumple una o más regles del sirvidor",
+  "report.categories.violation": "El conteníu incumple una o más normes del sirvidor",
   "report.category.subtitle": "Escueyi la meyor opción",
   "report.category.title": "Dinos qué pasa con esti {type}",
   "report.category.title_account": "perfil",
@@ -495,18 +495,18 @@
   "report.mute_explanation": "You will not see their posts. They can still follow you and see your posts and will not know that they are muted.",
   "report.next": "Siguiente",
   "report.placeholder": "Comentarios adicionales",
-  "report.reasons.dislike": "I don't like it",
+  "report.reasons.dislike": "Nun me presta",
   "report.reasons.dislike_description": "Nun ye daqué que quiera ver",
   "report.reasons.other": "Ye daqué más",
   "report.reasons.other_description": "La incidencia nun s'axusta a les demás categoríes",
   "report.reasons.spam": "Ye spam",
-  "report.reasons.spam_description": "Malicious links, fake engagement, or repetitive replies",
-  "report.reasons.violation": "Incumple les regles del sirvidor",
-  "report.reasons.violation_description": "You are aware that it breaks specific rules",
+  "report.reasons.spam_description": "Contién enllaces maliciosos, conteníu fraudulentu o rempuestes repetitives",
+  "report.reasons.violation": "Incumple les normes del sirvidor",
+  "report.reasons.violation_description": "Yes consciente qu'incumple dalguna norma específica",
   "report.rules.subtitle": "Select all that apply",
-  "report.rules.title": "¿Qué regles s'incumplen?",
+  "report.rules.title": "¿Qué normes s'incumplen?",
   "report.statuses.subtitle": "Select all that apply",
-  "report.statuses.title": "Are there any posts that back up this report?",
+  "report.statuses.title": "¿Hai dalgún artículu qu'apoye esti informe?",
   "report.submit": "Unviar",
   "report.target": "Report {target}",
   "report.thanks.take_action": "Equí tienes les opciones pa controlar qué ves en Mastodon:",
@@ -515,7 +515,7 @@
   "report.thanks.title_actionable": "Thanks for reporting, we'll look into this.",
   "report.unfollow": "Dexar de siguir a @{name}",
   "report.unfollow_explanation": "Sigues a esta cuenta. Pa dexar de ver los sos artículos nel to feed d'aniciu, dexa de siguila.",
-  "report_notification.attached_statuses": "{count, plural, one {{count} post} other {{count} posts}} attached",
+  "report_notification.attached_statuses": "{count, plural, one {Axuntóse {count} artículu} other {Axuntáronse {count} artículos}}",
   "report_notification.categories.other": "Other",
   "report_notification.categories.spam": "Spam",
   "report_notification.categories.violation": "Rule violation",
@@ -545,9 +545,9 @@
   "sign_in_banner.create_account": "Crear una cuenta",
   "sign_in_banner.sign_in": "Aniciar la sesión",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts. You can also interact from your account on a different server.",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_domain": "Open moderation interface for {domain}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "Abrir la interfaz de moderación pa @{name}",
+  "status.admin_domain": "Abrir la interfaz de moderación pa «{domain}»",
+  "status.admin_status": "Abrir esti artículu na interfaz de moderación",
   "status.block": "Block @{name}",
   "status.bookmark": "Meter en Marcadores",
   "status.cancel_reblog_private": "Unboost",
@@ -555,7 +555,7 @@
   "status.copy": "Copiar l'enllaz al artículu",
   "status.delete": "Desaniciar",
   "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
+  "status.direct": "Unviar un mensaxe direutu a @{name}",
   "status.edit": "Edit",
   "status.edited": "Edited {date}",
   "status.edited_x_times": "Editóse {count, plural, one {{count} vegada} other {{count} vegaes}}",
@@ -567,7 +567,7 @@
   "status.history.created": "{name} creó {date}",
   "status.history.edited": "{name} editó {date}",
   "status.load_more": "Cargar más",
-  "status.media_hidden": "Media hidden",
+  "status.media_hidden": "Conteníu multimedia anubríu",
   "status.mention": "Mentar a @{name}",
   "status.more": "Más",
   "status.mute": "Desactivar los avisos de @{name}",
@@ -624,7 +624,7 @@
   "units.short.million": "{count} M",
   "units.short.thousand": "{count} mil",
   "upload_area.title": "Drag & drop to upload",
-  "upload_button.label": "Add images, a video or an audio file",
+  "upload_button.label": "Amestar ficheros multimedia",
   "upload_error.limit": "File upload limit exceeded.",
   "upload_error.poll": "La xuba de ficheros nun ta permitida coles encuestes.",
   "upload_form.audio_description": "Describe for people who are hard of hearing",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index cf5df140e..f357ed67d 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -272,7 +272,7 @@
   "footer.keyboard_shortcuts": "Клавишни комбинации",
   "footer.privacy_policy": "Политика за поверителност",
   "footer.source_code": "Преглед на изходния код",
-  "footer.status": "Status",
+  "footer.status": "Състояние",
   "generic.saved": "Запазено",
   "getting_started.heading": "Първи стъпки",
   "hashtag.column_header.tag_mode.all": "и {additional}",
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index e193919d1..84f8c70ac 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -3,23 +3,23 @@
   "about.contact": "Cysylltwch â:",
   "about.disclaimer": "Mae Mastodon yn feddalwedd rhydd, cod agored ac o dan hawlfraint Mastodon gGmbH.",
   "about.domain_blocks.no_reason_available": "Nid yw'r rheswm ar gael",
-  "about.domain_blocks.preamble": "Yn gyffredinol, mae Mastodon yn caniatáu i chi weld cynnwys gan unrhyw weinyddwr arall yn y ffederasiwn a rhyngweithio â hi. Dyma'r eithriadau a wnaed ar y gweinydd penodol hwn.",
-  "about.domain_blocks.silenced.explanation": "Yn gyffredinol, fyddwch chi ddim yn gweld proffiliau a chynnwys o'r gweinydd hwn, oni bai eich bod yn chwilio'n benodol amdano neu yn ymuno drwy ei ddilyn.",
+  "about.domain_blocks.preamble": "Fel rheol, mae Mastodon yn caniatáu i chi weld cynnwys gan unrhyw weinyddwr arall yn y ffederasiwn a rhyngweithio â hi. Dyma'r eithriadau a wnaed ar y gweinydd penodol hwn.",
+  "about.domain_blocks.silenced.explanation": "Fel rheol, fyddwch chi ddim yn gweld proffiliau a chynnwys o'r gweinydd hwn, oni bai eich bod yn chwilio'n benodol amdano neu yn ymuno drwy ei ddilyn.",
   "about.domain_blocks.silenced.title": "Cyfyngedig",
-  "about.domain_blocks.suspended.explanation": "Ni fydd data o'r gweinydd hwn yn cael ei brosesu, ei storio na'i gyfnewid, gan wneud unrhyw ryngweithio neu gyfathrebu gyda defnyddwyr o'r gweinydd hwn yn amhosibl.",
+  "about.domain_blocks.suspended.explanation": "Ni fydd data o'r gweinydd hwn yn cael ei brosesu, ei gadw na'i gyfnewid, gan wneud unrhyw ryngweithio neu gyfathrebu gyda defnyddwyr o'r gweinydd hwn yn amhosibl.",
   "about.domain_blocks.suspended.title": "Ataliwyd",
   "about.not_available": "Nid yw'r wybodaeth hon ar gael ar y gweinydd hwn.",
   "about.powered_by": "Cyfrwng cymdeithasol datganoledig sy'n cael ei yrru gan {mastodon}",
   "about.rules": "Rheolau'r gweinydd",
   "account.account_note_header": "Nodyn",
-  "account.add_or_remove_from_list": "Ychwanegu neu Dileu o'r rhestrau",
+  "account.add_or_remove_from_list": "Ychwanegu neu Ddileu o'r rhestrau",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grŵp",
   "account.block": "Blocio @{name}",
   "account.block_domain": "Blocio parth {domain}",
   "account.blocked": "Blociwyd",
   "account.browse_more_on_origin_server": "Pori mwy ar y proffil gwreiddiol",
-  "account.cancel_follow_request": "Tynnu nôl cais i ddilyn",
+  "account.cancel_follow_request": "Tynnu cais i ddilyn",
   "account.direct": "Neges breifat @{name}",
   "account.disable_notifications": "Stopiwch fy hysbysu pan fydd @{name} yn postio",
   "account.domain_blocked": "Parth wedi ei flocio",
@@ -100,14 +100,14 @@
   "closed_registrations_modal.title": "Ymgofrestru ar Mastodon",
   "column.about": "Ynghylch",
   "column.blocks": "Defnyddwyr a flociwyd",
-  "column.bookmarks": "Nodau tudalen",
+  "column.bookmarks": "Llyfrnodau",
   "column.community": "Ffrwd lleol",
   "column.direct": "Negeseuon preifat",
   "column.directory": "Pori proffiliau",
   "column.domain_blocks": "Parthau wedi'u blocio",
   "column.favourites": "Ffefrynnau",
   "column.follow_requests": "Ceisiadau dilyn",
-  "column.home": "Cartref",
+  "column.home": "Hafan",
   "column.lists": "Rhestrau",
   "column.mutes": "Defnyddwyr wedi'u tewi",
   "column.notifications": "Hysbysiadau",
@@ -145,8 +145,8 @@
   "compose_form.sensitive.hide": "Marcio cyfryngau fel eu bod yn sensitif",
   "compose_form.sensitive.marked": "Cyfryngau wedi'u marcio'n sensitif",
   "compose_form.sensitive.unmarked": "Nid yw'r cyfryngau wedi'u marcio'n sensitif",
-  "compose_form.spoiler.marked": "Testun wedi ei guddio gan rybudd",
-  "compose_form.spoiler.unmarked": "Nid yw'r testun wedi ei guddio",
+  "compose_form.spoiler.marked": "Dileu rhybudd cynnwys",
+  "compose_form.spoiler.unmarked": "Ychwanegu rhybudd cynnwys",
   "compose_form.spoiler_placeholder": "Ysgrifenwch eich rhybudd yma",
   "confirmation_modal.cancel": "Diddymu",
   "confirmations.block.block_and_report": "Rhwystro ac Adrodd",
@@ -179,7 +179,7 @@
   "conversation.with": "Gyda {names}",
   "copypaste.copied": "Wedi ei gopïo",
   "copypaste.copy": "Copïo",
-  "directory.federated": "O'r fydysawd cyfan",
+  "directory.federated": "O'r ffedysawd cyfan",
   "directory.local": "O {domain} yn unig",
   "directory.new_arrivals": "Defnyddwyr newydd",
   "directory.recently_active": "Ar-lein yn ddiweddar",
@@ -198,7 +198,7 @@
   "emoji_button.custom": "Cyfaddas",
   "emoji_button.flags": "Baneri",
   "emoji_button.food": "Bwyd & Diod",
-  "emoji_button.label": "Mewnosodwch emoji",
+  "emoji_button.label": "Mewnosod emoji",
   "emoji_button.nature": "Natur",
   "emoji_button.not_found": "Dim emojiau'n cydweddu i'w cael",
   "emoji_button.objects": "Gwrthrychau",
@@ -212,7 +212,7 @@
   "empty_column.account_timeline": "Dim postiadau yma!",
   "empty_column.account_unavailable": "Nid yw'r proffil ar gael",
   "empty_column.blocks": "Nid ydych wedi blocio unrhyw ddefnyddwyr eto.",
-  "empty_column.bookmarked_statuses": "Nid oes gennych unrhyw bostiad wedi'u cadw fel nodau tudalen eto. Pan fyddwch yn gosod nod tudalen i un, mi fydd yn ymddangos yma.",
+  "empty_column.bookmarked_statuses": "Nid oes gennych unrhyw bostiad wedi'u cadw fel llyfrnodau eto. Pan fyddwch yn gosod nod tudalen i un, mi fydd yn ymddangos yma.",
   "empty_column.community": "Mae'r ffrwd lleol yn wag. Beth am ysgrifennu rhywbeth cyhoeddus?",
   "empty_column.direct": "Does gennych unrhyw negeseuon preifat eto. Pan byddwch yn anfon neu derbyn un, bydd yn ymddangos yma.",
   "empty_column.domain_blocks": "Nid oes yna unrhyw barthau cuddiedig eto.",
@@ -371,7 +371,7 @@
   "mute_modal.indefinite": "Parhaus",
   "navigation_bar.about": "Ynghylch",
   "navigation_bar.blocks": "Defnyddwyr wedi eu blocio",
-  "navigation_bar.bookmarks": "Nodau tudalen",
+  "navigation_bar.bookmarks": "Llyfrnodau",
   "navigation_bar.community_timeline": "Ffrwd leol",
   "navigation_bar.compose": "Cyfansoddi post newydd",
   "navigation_bar.direct": "Negeseuon preifat",
@@ -549,7 +549,7 @@
   "status.admin_domain": "Agor rhyngwyneb cymedroli {domain}",
   "status.admin_status": "Agor y postiad hwn yn y rhyngwyneb cymedroli",
   "status.block": "Blocio @{name}",
-  "status.bookmark": "Nod Tudalen",
+  "status.bookmark": "Llyfrnodi",
   "status.cancel_reblog_private": "Dadhybu",
   "status.cannot_reblog": "Nid oes modd hybu'r postiad hwn",
   "status.copy": "Copïo dolen i'r post",
@@ -574,14 +574,14 @@
   "status.mute_conversation": "Tewi sgwrs",
   "status.open": "Ehangu'r post hwn",
   "status.pin": "Pinio ar y proffil",
-  "status.pinned": "Post wedi'i binio",
+  "status.pinned": "Postiad wedi'i binio",
   "status.read_more": "Darllen rhagor",
   "status.reblog": "Hybu",
   "status.reblog_private": "Hybu i'r gynulleidfa wreiddiol",
   "status.reblogged_by": "Hybodd {name}",
   "status.reblogs.empty": "Does neb wedi hybio'r post yma eto. Pan y bydd rhywun yn gwneud, byddent yn ymddangos yma.",
   "status.redraft": "Dileu ac ailddrafftio",
-  "status.remove_bookmark": "Tynnu Nod Tudalen",
+  "status.remove_bookmark": "Dileu llyfrnod",
   "status.replied_to": "Wedi ateb {name}",
   "status.reply": "Ateb",
   "status.replyAll": "Ateb i edefyn",
@@ -604,7 +604,7 @@
   "subscribed_languages.target": "Newid ieithoedd tanysgrifio {target}",
   "suggestions.dismiss": "Diystyru'r awgrym",
   "suggestions.header": "Efallai y bydd gennych ddiddordeb mewn…",
-  "tabs_bar.federated_timeline": "Ffedereiddiwyd",
+  "tabs_bar.federated_timeline": "Ffederasiwn",
   "tabs_bar.home": "Cartref",
   "tabs_bar.local_timeline": "Lleol",
   "tabs_bar.notifications": "Hysbysiadau",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index ff3f38c96..b34864cb0 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -39,7 +39,7 @@
   "account.follows_you": "Folgt dir",
   "account.go_to_profile": "Profil aufrufen",
   "account.hide_reblogs": "Geteilte Beiträge von @{name} verbergen",
-  "account.joined_short": "Beigetreten",
+  "account.joined_short": "Registriert",
   "account.languages": "Genutzte Sprachen überarbeiten",
   "account.link_verified_on": "Das Profil mit dieser E-Mail-Adresse wurde bereits am {date} bestätigt",
   "account.locked_info": "Die Privatsphäre dieses Kontos wurde auf „geschützt“ gesetzt. Die Person bestimmt manuell, wer ihrem Profil folgen darf.",
@@ -378,7 +378,7 @@
   "navigation_bar.discover": "Entdecken",
   "navigation_bar.domain_blocks": "Gesperrte Domains",
   "navigation_bar.edit_profile": "Profil bearbeiten",
-  "navigation_bar.explore": "Erforschen",
+  "navigation_bar.explore": "Entdecken",
   "navigation_bar.favourites": "Favoriten",
   "navigation_bar.filters": "Stummgeschaltete Wörter",
   "navigation_bar.follow_requests": "Follower-Anfragen",
@@ -523,7 +523,7 @@
   "search.placeholder": "Suche",
   "search.search_or_paste": "Suchen oder URL einfügen",
   "search_popout.search_format": "Erweiterte Suche",
-  "search_popout.tips.full_text": "Einfache Texteingabe gibt Beiträge, die du geschrieben, favorisiert und geteilt hast, zurück; außerdem auch Beiträge, in denen du erwähnt wurdest, aber auch passende Nutzernamen, Anzeigenamen oder Hashtags.",
+  "search_popout.tips.full_text": "Einfache Texteingabe gibt Beiträge, die du geschrieben, favorisiert und geteilt hast, zurück; außerdem auch Beiträge, in denen du erwähnt wurdest, aber auch passende Profilnamen, Anzeigenamen oder Hashtags.",
   "search_popout.tips.hashtag": "Hashtag",
   "search_popout.tips.status": "Beitrag",
   "search_popout.tips.text": "Einfache Texteingabe gibt Anzeigenamen, Profilnamen und Hashtags zurück",
@@ -567,7 +567,7 @@
   "status.history.created": "{name} erstellte {date}",
   "status.history.edited": "{name} bearbeitete {date}",
   "status.load_more": "Weitere laden",
-  "status.media_hidden": "{number, plural, one {Medium ausgeblendet} other {Medien ausgeblendet}}",
+  "status.media_hidden": "Inhalt verborgen",
   "status.mention": "@{name} im Beitrag erwähnen",
   "status.more": "Mehr",
   "status.mute": "@{name} stummschalten",
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index 5c41b7547..3d71f3c5c 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -128,7 +128,7 @@
   "compose.language.search": "Αναζήτηση γλωσσών...",
   "compose_form.direct_message_warning_learn_more": "Μάθετε περισσότερα",
   "compose_form.encryption_warning": "Οι δημοσιεύσεις στο Mastodon δεν είναι κρυπτογραφημένες από άκρο σε άκρο. Μην μοιράζεστε ευαίσθητες πληροφορίες μέσω του Mastodon.",
-  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
+  "compose_form.hashtag_warning": "Αυτή η δημοσίευση δεν θα εμφανίζεται κάτω από οποιαδήποτε ετικέτα καθώς δεν είναι δημόσια. Μόνο οι δημόσιες δημοσιεύσεις μπορούν να αναζητηθούν με ετικέτα.",
   "compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
   "compose_form.lock_disclaimer.lock": "κλειδωμένο",
   "compose_form.placeholder": "Τι σκέφτεσαι;",
@@ -221,7 +221,7 @@
   "empty_column.favourites": "Κανείς δεν έχει αγαπήσει αυτό το τουτ ακόμα. Μόλις το κάνει κάποια, θα εμφανιστούν εδώ.",
   "empty_column.follow_recommendations": "Φαίνεται ότι δεν υπάρχει καμία πρόταση για σένα. Μπορείς να κάνεις μια αναζήτηση για άτομα που μπορεί να γνωρίζεις ή για hashtags που τρεντάρουν.",
   "empty_column.follow_requests": "Δεν έχεις κανένα αίτημα παρακολούθησης ακόμα. Μόλις λάβεις κάποιο, θα εμφανιστεί εδώ.",
-  "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.",
+  "empty_column.followed_tags": "Δεν έχετε παρακολουθήσει ακόμα καμία ετικέτα. Όταν το κάνετε, θα εμφανιστούν εδώ.",
   "empty_column.hashtag": "Δεν υπάρχει ακόμα κάτι για αυτή την ετικέτα.",
   "empty_column.home": "Η τοπική σου ροή είναι κενή! Πήγαινε στο {public} ή κάνε αναζήτηση για να ξεκινήσεις και να γνωρίσεις άλλους χρήστες.",
   "empty_column.home.suggestions": "Ορίστε μερικές προτάσεις",
@@ -264,7 +264,7 @@
   "follow_request.authorize": "Ενέκρινε",
   "follow_request.reject": "Απέρριψε",
   "follow_requests.unlocked_explanation": "Παρόλο που ο λογαριασμός σου δεν είναι κλειδωμένος, οι διαχειριστές του {domain} θεώρησαν πως ίσως να θέλεις να ελέγξεις χειροκίνητα αυτά τα αιτήματα ακολούθησης.",
-  "followed_tags": "Followed hashtags",
+  "followed_tags": "Ετικέτες που ακολουθούνται",
   "footer.about": "Σχετικά με",
   "footer.directory": "Κατάλογος προφίλ",
   "footer.get_app": "Αποκτήστε την Εφαρμογή",
@@ -382,7 +382,7 @@
   "navigation_bar.favourites": "Αγαπημένα",
   "navigation_bar.filters": "Αποσιωπημένες λέξεις",
   "navigation_bar.follow_requests": "Αιτήματα ακολούθησης",
-  "navigation_bar.followed_tags": "Followed hashtags",
+  "navigation_bar.followed_tags": "Ετικέτες που ακολουθούνται",
   "navigation_bar.follows_and_followers": "Ακολουθείς και σε ακολουθούν",
   "navigation_bar.lists": "Λίστες",
   "navigation_bar.logout": "Αποσύνδεση",
@@ -544,7 +544,7 @@
   "server_banner.server_stats": "Στατιστικά διακομιστή:",
   "sign_in_banner.create_account": "Δημιουργία λογαριασμού",
   "sign_in_banner.sign_in": "Σύνδεση",
-  "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts. You can also interact from your account on a different server.",
+  "sign_in_banner.text": "Συνδεθείτε για να ακολουθήσετε προφίλ ή ετικέτες, αγαπήστε, μοιραστείτε και απαντήστε σε δημοσιεύσεις. Μπορείτε επίσης να αλληλεπιδράσετε από τον λογαριασμό σας σε διαφορετικό διακομιστή.",
   "status.admin_account": "Άνοιγμα λειτουργίας διαμεσολάβησης για τον/την @{name}",
   "status.admin_domain": "Άνοιγμα λειτουργίας διαμεσολάβησης για {domain}",
   "status.admin_status": "Άνοιγμα αυτής της δημοσίευσης στη λειτουργία διαμεσολάβησης",
@@ -599,7 +599,7 @@
   "status.uncached_media_warning": "Μη διαθέσιμα",
   "status.unmute_conversation": "Διέκοψε την αποσιώπηση της συζήτησης",
   "status.unpin": "Ξεκαρφίτσωσε από το προφίλ",
-  "subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.",
+  "subscribed_languages.lead": "Μόνο δημοσιεύσεις σε επιλεγμένες γλώσσες θα εμφανίζονται στην αρχική σας και θα εμφανίζονται χρονοδιαγράμματα μετά την αλλαγή. Επιλέξτε καμία για να λαμβάνετε δημοσιεύσεις σε όλες τις γλώσσες.",
   "subscribed_languages.save": "Αποθήκευση αλλαγών",
   "subscribed_languages.target": "Αλλαγή εγγεγραμμένων γλωσσών για {target}",
   "suggestions.dismiss": "Απόρριψη πρότασης",
diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json
index c37d8f62d..c1994b5f9 100644
--- a/app/javascript/mastodon/locales/es-AR.json
+++ b/app/javascript/mastodon/locales/es-AR.json
@@ -239,7 +239,7 @@
   "explore.search_results": "Resultados de búsqueda",
   "explore.suggested_follows": "Para vos",
   "explore.title": "Explorá",
-  "explore.trending_links": "Novedades",
+  "explore.trending_links": "Noticias",
   "explore.trending_statuses": "Mensajes",
   "explore.trending_tags": "Etiquetas",
   "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro no se aplica al contexto en el que accediste a este mensaje. Si querés que el mensaje sea filtrado también en este contexto, vas a tener que editar el filtro.",
diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json
index adcb3aae0..3b67c3d75 100644
--- a/app/javascript/mastodon/locales/fo.json
+++ b/app/javascript/mastodon/locales/fo.json
@@ -389,7 +389,7 @@
   "navigation_bar.mutes": "Doyvdir brúkarar",
   "navigation_bar.personal": "Persónligt",
   "navigation_bar.pins": "Festir postar",
-  "navigation_bar.preferences": "Sertokki",
+  "navigation_bar.preferences": "Stillingar",
   "navigation_bar.public_timeline": "Felags tíðarlinja",
   "navigation_bar.search": "Leita",
   "navigation_bar.security": "Trygd",
diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json
index 8355f2019..ca3dd0f2f 100644
--- a/app/javascript/mastodon/locales/gd.json
+++ b/app/javascript/mastodon/locales/gd.json
@@ -54,7 +54,7 @@
   "account.posts_with_replies": "Postaichean ’s freagairtean",
   "account.report": "Dèan gearan mu @{name}",
   "account.requested": "A’ feitheamh air aontachadh. Briog airson sgur dhen iarrtas leantainn",
-  "account.requested_follow": "{name} has requested to follow you",
+  "account.requested_follow": "Dh’iarr {name} ’gad leantainn",
   "account.share": "Co-roinn a’ phròifil aig @{name}",
   "account.show_reblogs": "Seall na brosnachaidhean o @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} phost} two {{counter} phost} few {{counter} postaichean} other {{counter} post}}",
@@ -128,7 +128,7 @@
   "compose.language.search": "Lorg cànan…",
   "compose_form.direct_message_warning_learn_more": "Barrachd fiosrachaidh",
   "compose_form.encryption_warning": "Chan eil crioptachadh ceann gu ceann air postaichean Mhastodon. Na co-roinn fiosrachadh dìomhair idir le Mastodon.",
-  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
+  "compose_form.hashtag_warning": "Cha nochd am post seo fon taga hais o nach eil e poblach. Cha ghabh ach postaichean poblach a lorg a-rèir an tagaichean hais.",
   "compose_form.lock_disclaimer": "Chan eil an cunntas agad {locked}. ’S urrainn do dhuine sam bith ’gad leantainn is na postaichean agad a tha ag amas air an luchd-leantainn agad a-mhàin a shealltainn.",
   "compose_form.lock_disclaimer.lock": "glaiste",
   "compose_form.placeholder": "Dè tha air d’ aire?",
@@ -221,7 +221,7 @@
   "empty_column.favourites": "Chan eil am post seo ’na annsachd aig duine sam bith fhathast. Nuair a nì daoine annsachd dheth, nochdaidh iad an-seo.",
   "empty_column.follow_recommendations": "Chan urrainn dhuinn dad a mholadh dhut. Cleachd gleus an luirg feuch an lorg thu daoine air a bheil thu eòlach no rùraich na tagaichean-hais a tha a’ treandadh.",
   "empty_column.follow_requests": "Chan eil iarrtas leantainn agad fhathast. Nuair a gheibh thu fear, nochdaidh e an-seo.",
-  "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.",
+  "empty_column.followed_tags": "Cha do lean thu taga hais sam bith fhathast. Nuair a leanas tu, nochdaidh iad an-seo.",
   "empty_column.hashtag": "Chan eil dad san taga hais seo fhathast.",
   "empty_column.home": "Tha loidhne-ama na dachaigh agad falamh! Lean barrachd dhaoine gus a lìonadh. {suggestions}",
   "empty_column.home.suggestions": "Faic moladh no dhà",
@@ -237,11 +237,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Cuir lethbhreac dhen stacktrace air an stòr-bhòrd",
   "errors.unexpected_crash.report_issue": "Dèan aithris air an duilgheadas",
   "explore.search_results": "Toraidhean an luirg",
-  "explore.suggested_follows": "For you",
+  "explore.suggested_follows": "Dhut-sa",
   "explore.title": "Rùraich",
-  "explore.trending_links": "News",
-  "explore.trending_statuses": "Posts",
-  "explore.trending_tags": "Hashtags",
+  "explore.trending_links": "Naidheachdan",
+  "explore.trending_statuses": "Postaichean",
+  "explore.trending_tags": "Tagaichean hais",
   "filter_modal.added.context_mismatch_explanation": "Chan eil an roinn-seòrsa criathraidh iom seo chaidh dhan cho-theacs san do dh’inntrig thu am post seo. Ma tha thu airson am post a chriathradh sa cho-theacs seo cuideachd, feumaidh tu a’ chriathrag a dheasachadh.",
   "filter_modal.added.context_mismatch_title": "Co-theacsa neo-iomchaidh!",
   "filter_modal.added.expired_explanation": "Dh’fhalbh an ùine air an roinn-seòrsa criathraidh seo agus feumaidh tu an ceann-là crìochnachaidh atharrachadh mus cuir thu an sàs i.",
@@ -264,7 +264,7 @@
   "follow_request.authorize": "Ùghdarraich",
   "follow_request.reject": "Diùlt",
   "follow_requests.unlocked_explanation": "Ged nach eil an cunntas agad glaiste, tha sgioba {domain} dhen bheachd gum b’ fheàirrde thu lèirmheas a dhèanamh air na h-iarrtasan leantainn o na cunntasan seo a làimh.",
-  "followed_tags": "Followed hashtags",
+  "followed_tags": "Tagaichean hais ’gan leantainn",
   "footer.about": "Mu dhèidhinn",
   "footer.directory": "Eòlaire nam pròifil",
   "footer.get_app": "Faigh an aplacaid",
@@ -272,7 +272,7 @@
   "footer.keyboard_shortcuts": "Ath-ghoiridean a’ mheur-chlàir",
   "footer.privacy_policy": "Poileasaidh prìobhaideachd",
   "footer.source_code": "Seall am bun-tùs",
-  "footer.status": "Status",
+  "footer.status": "Staid",
   "generic.saved": "Chaidh a shàbhaladh",
   "getting_started.heading": "Toiseach",
   "hashtag.column_header.tag_mode.all": "agus {additional}",
@@ -382,7 +382,7 @@
   "navigation_bar.favourites": "Na h-annsachdan",
   "navigation_bar.filters": "Faclan mùchte",
   "navigation_bar.follow_requests": "Iarrtasan leantainn",
-  "navigation_bar.followed_tags": "Followed hashtags",
+  "navigation_bar.followed_tags": "Tagaichean hais ’gan leantainn",
   "navigation_bar.follows_and_followers": "Dàimhean leantainn",
   "navigation_bar.lists": "Liostaichean",
   "navigation_bar.logout": "Clàraich a-mach",
@@ -544,9 +544,9 @@
   "server_banner.server_stats": "Stadastaireachd an fhrithealaiche:",
   "sign_in_banner.create_account": "Cruthaich cunntas",
   "sign_in_banner.sign_in": "Clàraich a-steach",
-  "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts. You can also interact from your account on a different server.",
+  "sign_in_banner.text": "Clàraich a-steach a leantainn phròifilean no thagaichean hais, a’ cur postaichean ris na h-annsachdan ’s ’gan co-roinneadh is freagairt dhaibh. ’S urrainn dhut gnìomh a ghabhail le cunntas o fhrithealaiche eile cuideachd.",
   "status.admin_account": "Fosgail eadar-aghaidh na maorsainneachd dha @{name}",
-  "status.admin_domain": "Open moderation interface for {domain}",
+  "status.admin_domain": "Fosgail eadar-aghaidh na maorsainneachd dha {domain}",
   "status.admin_status": "Fosgail am post seo ann an eadar-aghaidh na maorsainneachd",
   "status.block": "Bac @{name}",
   "status.bookmark": "Cuir ris na comharran-lìn",
@@ -563,7 +563,7 @@
   "status.favourite": "Cuir ris na h-annsachdan",
   "status.filter": "Criathraich am post seo",
   "status.filtered": "Criathraichte",
-  "status.hide": "Hide post",
+  "status.hide": "Falaich am post",
   "status.history.created": "Chruthaich {name} {date} e",
   "status.history.edited": "Dheasaich {name} {date} e",
   "status.load_more": "Luchdaich barrachd dheth",
@@ -595,7 +595,7 @@
   "status.show_more_all": "Seall barrachd dhen a h-uile",
   "status.show_original": "Seall an tionndadh tùsail",
   "status.translate": "Eadar-theangaich",
-  "status.translated_from_with": "Air eaar-theangachadh o {lang} le {provider}",
+  "status.translated_from_with": "Air eadar-theangachadh o {lang} le {provider}",
   "status.uncached_media_warning": "Chan eil seo ri fhaighinn",
   "status.unmute_conversation": "Dì-mhùch an còmhradh",
   "status.unpin": "Dì-phrìnich on phròifil",
diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json
index fc0efa7ea..3d6021b6e 100644
--- a/app/javascript/mastodon/locales/kab.json
+++ b/app/javascript/mastodon/locales/kab.json
@@ -1,6 +1,6 @@
 {
   "about.blocks": "Moderated servers",
-  "about.contact": "Contact:",
+  "about.contact": "Anermis:",
   "about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.",
   "about.domain_blocks.no_reason_available": "Reason not available",
   "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.",
diff --git a/app/javascript/mastodon/locales/my.json b/app/javascript/mastodon/locales/my.json
index 9086f0eec..d39ede21d 100644
--- a/app/javascript/mastodon/locales/my.json
+++ b/app/javascript/mastodon/locales/my.json
@@ -13,188 +13,188 @@
   "about.rules": "ဆာဗာစည်းမျဉ်းများ\n",
   "account.account_note_header": "မှတ်ချက်",
   "account.add_or_remove_from_list": "စာရင်းများမှ ထည့်ပါ သို့မဟုတ် ဖယ်ရှားပါ။\n",
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "စက်ရုပ်",
   "account.badges.group": "အုပ်စု",
   "account.block": "@{name} ကိုဘလော့မည်",
   "account.block_domain": " {domain} ဒိုမိန်းကိုပိတ်မည်",
   "account.blocked": "ဘလော့ထားသည်",
   "account.browse_more_on_origin_server": "မူရင်းပရိုဖိုင်တွင် ပိုမိုကြည့်ရှုပါ။",
-  "account.cancel_follow_request": "Withdraw follow request",
+  "account.cancel_follow_request": "ဖောလိုးပယ်ဖျက်ခြင်း",
   "account.direct": "@{name} ကိုတိုက်ရိုက်စာပို့မည်",
   "account.disable_notifications": "@{name} ပို့စ်တင်သည့်အခါ ကျွန်ုပ်ကို အသိပေးခြင်းရပ်ပါ။",
   "account.domain_blocked": "ဒိုမိန်း ပိတ်ပင်ထားခဲ့သည်\n",
   "account.edit_profile": "ကိုယ်ရေးမှတ်တမ်းပြင်ဆင်မည်",
   "account.enable_notifications": "@{name} ပို့စ်တင်သည့်အခါ ကျွန်ုပ်ကို အကြောင်းကြားပါ။",
-  "account.endorse": "Feature on profile",
+  "account.endorse": "အကောင့်ပရိုဖိုင်တွင်ဖော်ပြပါ",
   "account.featured_tags.last_status_at": "{date} တွင် နောက်ဆုံးပို့စ်",
-  "account.featured_tags.last_status_never": "No posts",
-  "account.featured_tags.title": "{name}'s featured hashtags",
+  "account.featured_tags.last_status_never": "ပို့စ်တင်ထားခြင်းမရှိပါ",
+  "account.featured_tags.title": "ဖော်ပြထားသောဟက်ရှ်တက်ခ်များ",
   "account.follow": "စောင့်ကြည့်မည်",
   "account.followers": "စောင့်ကြည့်သူများ",
   "account.followers.empty": "ဤသူကို စောင့်ကြည့်သူ မရှိသေးပါ။",
-  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.followers_counter": "{count, plural, one {{counter} ဖော်လိုဝါများ} other {{counter} ဖော်လိုဝါများ}}",
   "account.following": "စောင့်ကြည့်နေသည်",
-  "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
+  "account.following_counter": "{count, plural, one {{counter} ဖော်လိုလုပ်နေသည်} other {{counter} ဖော်လိုလုပ်နေသည်}}",
   "account.follows.empty": "ဤသူသည် မည်သူ့ကိုမျှ စောင့်ကြည့်ခြင်း မရှိသေးပါ။",
   "account.follows_you": "သင့်ကို စောင့်ကြည့်နေသည်",
   "account.go_to_profile": "ပရိုဖိုင်းသို့ သွားရန်",
   "account.hide_reblogs": "@{name} ၏ မျှဝေမှုကို ဝှက်ထားရန်",
   "account.joined_short": "ပူးပေါင်း",
-  "account.languages": "Change subscribed languages",
+  "account.languages": "ဘာသာစကားပြောင်းမည်",
   "account.link_verified_on": "ဤလင့်ခ်၏ ပိုင်ဆိုင်မှုကို {date} က စစ်ဆေးခဲ့သည်။",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.locked_info": "အကောင့်ကိုယ်ရေးကိုယ်တာကိုလော့ချထားသည်။အကောင့်ပိုင်ရှင်မှ ခွင့်ပြုချက်လိုအပ်သည်။",
   "account.media": "မီဒီယာ",
-  "account.mention": "Mention @{name}",
-  "account.moved_to": "{name} has indicated that their new account is now:",
-  "account.mute": "Mute @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
-  "account.open_original_page": "Open original page",
+  "account.mention": "{name}ကိုမန်းရှင်းထားသည်",
+  "account.moved_to": "{name} ၏အကောင့်အသစ်မှာ",
+  "account.mute": "{name}ကိုပိတ်ထားရန်",
+  "account.mute_notifications": "{name}ထံမှသတိပေးချက်",
+  "account.muted": "ပိတ်ထားရန်",
+  "account.open_original_page": "မူလစာမျက်နှာကိုဖွင့်ပါ",
   "account.posts": "ပို့စ်များ",
-  "account.posts_with_replies": "Posts and replies",
-  "account.report": "Report @{name}",
-  "account.requested": "Awaiting approval. Click to cancel follow request",
-  "account.requested_follow": "{name} has requested to follow you",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
-  "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
-  "account.unblock": "Unblock @{name}",
-  "account.unblock_domain": "Unblock domain {domain}",
-  "account.unblock_short": "Unblock",
-  "account.unendorse": "Don't feature on profile",
-  "account.unfollow": "Unfollow",
-  "account.unmute": "Unmute @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.unmute_short": "Unmute",
+  "account.posts_with_replies": "ပို့စ်နှင့် ရီပလိုင်းများ",
+  "account.report": "တိုင်ကြားမည်{name}",
+  "account.requested": "ခွင့်ပြုချက်စောင့်နေသည်။ ဖော်လိုးပယ်ဖျက်ရန်နှိပ်ပါ",
+  "account.requested_follow": "{name} မှသင့်ကိုဖော်လိုပြုလုပ်လိုသည်",
+  "account.share": "{name}၏ပရိုဖိုင်ကိုမျှဝေပါ",
+  "account.show_reblogs": "@{name} မှ မျှ၀ေမှုများကို ပြပါ\n",
+  "account.statuses_counter": "{count, plural, one {{counter} ပိုစ့်များ} other {{counter} ပိုစ့်များ}}",
+  "account.unblock": "{name} ကို ဘလော့ဖြုတ်မည်",
+  "account.unblock_domain": " {domain} ဒိုမိန်းကိုပြန်ဖွင့်မည်",
+  "account.unblock_short": "ဘလော့ဖြုတ်ရန်",
+  "account.unendorse": "အကောင့်ပရိုဖိုင်တွင်မဖော်ပြပါ",
+  "account.unfollow": "ဖောလိုးဖြုတ်မည်",
+  "account.unmute": "{name} ကို ပြန်ဖွင့်ရန်",
+  "account.unmute_notifications": "{name}ထံမှသတိပေးချက်ပြန်ဖွင့်မည်",
+  "account.unmute_short": "ပြန်ဖွင့်ရန်",
   "account_note.placeholder": "Click to add a note",
-  "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
-  "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
-  "admin.dashboard.retention.average": "Average",
-  "admin.dashboard.retention.cohort": "Sign-up month",
-  "admin.dashboard.retention.cohort_size": "New users",
-  "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
-  "alert.rate_limited.title": "Rate limited",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
-  "announcement.announcement": "Announcement",
-  "attachments_list.unprocessed": "(unprocessed)",
-  "audio.hide": "Hide audio",
-  "autosuggest_hashtag.per_week": "{count} per week",
-  "boost_modal.combo": "You can press {combo} to skip this next time",
-  "bundle_column_error.copy_stacktrace": "Copy error report",
-  "bundle_column_error.error.body": "The requested page could not be rendered. It could be due to a bug in our code, or a browser compatibility issue.",
-  "bundle_column_error.error.title": "Oh, no!",
-  "bundle_column_error.network.body": "There was an error when trying to load this page. This could be due to a temporary problem with your internet connection or this server.",
-  "bundle_column_error.network.title": "Network error",
-  "bundle_column_error.retry": "Try again",
-  "bundle_column_error.return": "Go back home",
-  "bundle_column_error.routing.body": "The requested page could not be found. Are you sure the URL in the address bar is correct?",
-  "bundle_column_error.routing.title": "404",
-  "bundle_modal_error.close": "Close",
-  "bundle_modal_error.message": "Something went wrong while loading this component.",
-  "bundle_modal_error.retry": "Try again",
-  "closed_registrations.other_server_instructions": "Since Mastodon is decentralized, you can create an account on another server and still interact with this one.",
-  "closed_registrations_modal.description": "Creating an account on {domain} is currently not possible, but please keep in mind that you do not need an account specifically on {domain} to use Mastodon.",
-  "closed_registrations_modal.find_another_server": "Find another server",
-  "closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!",
-  "closed_registrations_modal.title": "Signing up on Mastodon",
+  "admin.dashboard.daily_retention": "အကောင့်ဖွင့်ပြီးနောက် တစ်ရက်ပြီးတစ်ရက် အသုံးပြုသူ ထိန်းသိမ်းမှုနှုန်း",
+  "admin.dashboard.monthly_retention": "အကောင့်ဖွင့်ပြီးနောက် တစ်လအလိုက် အသုံးပြုသူ ထိန်းသိမ်းမှုနှုန်း",
+  "admin.dashboard.retention.average": "ပျမ်းမျှ",
+  "admin.dashboard.retention.cohort": "အကောင့်ပြုလုပ်မှုလ",
+  "admin.dashboard.retention.cohort_size": "အသုံးပြုသူအသစ်များ",
+  "alert.rate_limited.message": " {retry_time, time, medium}ပြီးနောက် ထပ်စမ်းကြည့်ပါ",
+  "alert.rate_limited.title": "နှုန်းထားကန့်သတ်ထားသည်။\n",
+  "alert.unexpected.message": "မမျှော်လင့်ထားသော အမှားတစ်ခု ဖြစ်ပွားခဲ့သည်။",
+  "alert.unexpected.title": "အယ်!",
+  "announcement.announcement": "ကြေငြာချက်",
+  "attachments_list.unprocessed": "(မလုပ်ဆောင်ရသေး)",
+  "audio.hide": "အသံပိတ်မည်",
+  "autosuggest_hashtag.per_week": "တစ်ပတ်လျှင် {count}\n",
+  "boost_modal.combo": "ဤအရာကို နောက်တစ်ကြိမ်ကျော်ရန် {combo} ကိုနှိပ်နိုင်သည်။",
+  "bundle_column_error.copy_stacktrace": "စာကူးရာတွင်ပြဿနာရှိသည်",
+  "bundle_column_error.error.body": "ဤစာမျက်နှာကို ဖော်ပြရာတွင် ပြဿနာရှိနေသည်",
+  "bundle_column_error.error.title": "မှားနေသည်",
+  "bundle_column_error.network.body": "ဒီစာမျက်နှာအား ဖွင့်လို့မရပါ။ အင်တာနက်ကွန်နက်ရှင် (သို့) ဆာဗာ ပြဿနာဖြစ်နေသည်။",
+  "bundle_column_error.network.title": "အင်တာနက်ကွန်ယက် ပြဿနာ",
+  "bundle_column_error.retry": "ထပ်ကြိုးစားပါ",
+  "bundle_column_error.return": "Homeကိုပြန်သွားမည်",
+  "bundle_column_error.routing.body": "ရှာနေသောအရာမှာမရှိပါ။ URL မှန်မမှန်ပြန်စစ်ပေးပါ",
+  "bundle_column_error.routing.title": "လေးသုံညလေး",
+  "bundle_modal_error.close": "ပိတ်ပါ",
+  "bundle_modal_error.message": "ဤဝက်ဘ်စာမျက်နှာအား ဖွင့်နေစဥ် အမှားတစ်ခု ဖြစ်ပေါ်ခဲ့သည်။",
+  "bundle_modal_error.retry": "ထပ်မံကြိုးစားပါ",
+  "closed_registrations.other_server_instructions": "Mastodon ကို ဗဟိုချုပ်ကိုင်မှု လျှော့ချထားသောကြောင့် သင်သည် အခြားဆာဗာတစ်ခုပေါ်တွင် အကောင့်တစ်ခု ဖန်တီးနိုင်ပြီး ဤတစ်ခုနှင့် အပြန်အလှန် တုံ့ပြန်ဆဲဖြစ်သည်။",
+  "closed_registrations_modal.description": "{domain} တွင် အကောင့်တစ်ခုဖန်တီးခြင်းသည် လောလောဆယ်မဖြစ်နိုင်ပါ၊ သို့သော် Mastodon ကိုအသုံးပြုရန်အတွက် သင်သည် {domain} တွင် အထူးအကောင့်တစ်ခုမလိုအပ်ကြောင်း ကျေးဇူးပြု၍ သတိရပါ။",
+  "closed_registrations_modal.find_another_server": "အခြားဆာဗာကိုရှာပါ။",
+  "closed_registrations_modal.preamble": "Mastodon ကို ဗဟိုချုပ်ကိုင်မှု လျှော့ချထားသောကြောင့် သင့်အကောင့်ကို မည်သည့်နေရာတွင်ပင် ဖန်တီးပါစေ၊ သင်သည် ဤဆာဗာပေါ်ရှိ မည်သူမဆိုနှင့် လိုက်လျောညီထွေ တုံ့ပြန်နိုင်မည်ဖြစ်သည်။ သင်ကိုယ်တိုင်ပင် လက်ခံဆောင်ရွက်ပေးနိုင်သည်။",
+  "closed_registrations_modal.title": "Mastodon တွင်အကောင့်ပြုလုပ်ပါ။\n",
   "column.about": "အကြောင်း",
-  "column.blocks": "Blocked users",
-  "column.bookmarks": "Bookmarks",
-  "column.community": "Local timeline",
-  "column.direct": "Direct messages",
-  "column.directory": "Browse profiles",
-  "column.domain_blocks": "Blocked domains",
-  "column.favourites": "Favourites",
-  "column.follow_requests": "Follow requests",
-  "column.home": "Home",
-  "column.lists": "Lists",
-  "column.mutes": "Muted users",
+  "column.blocks": "ဘလော့ထားသောအကောင့်များ",
+  "column.bookmarks": "မှတ်တမ်းများ",
+  "column.community": "ဒေသတွင်း အချိန်ဇယား",
+  "column.direct": "တိုက်ရိုက် မက်ဆေ့ခ်ျများ",
+  "column.directory": "ပရိုဖိုင်များကို ရှာဖွေမည်\n",
+  "column.domain_blocks": "  ဒိုမိန်းကိုပိတ်မည်",
+  "column.favourites": "အကြိုက်ဆုံးများ",
+  "column.follow_requests": "တောင်းဆိုချက်များကိုလိုက်နာပါ။",
+  "column.home": "ပင်မစာမျက်နှာ",
+  "column.lists": "စာရင်းများ",
+  "column.mutes": "မပေါ်အောင်ပိတ်ထားသောအသုံးပြုသူများ",
   "column.notifications": "အသိပေးချက်များ",
   "column.pins": "Pinned post",
-  "column.public": "Federated timeline",
-  "column_back_button.label": "Back",
-  "column_header.hide_settings": "Hide settings",
-  "column_header.moveLeft_settings": "Move column to the left",
-  "column_header.moveRight_settings": "Move column to the right",
-  "column_header.pin": "Pin",
-  "column_header.show_settings": "Show settings",
-  "column_header.unpin": "Unpin",
+  "column.public": "အားလုံးဖတ်နိုင်သောအချိန်ဇယား",
+  "column_back_button.label": "နောက်သို့",
+  "column_header.hide_settings": "ဆက်တင်များကို ဖျောက်ပါ။",
+  "column_header.moveLeft_settings": "ကော်လံကို ဘယ်ဘက်သို့ ရွှေ့ပါ။",
+  "column_header.moveRight_settings": "ကော်လံကို ညာဘက်သို့ ရွှေ့ပါ။",
+  "column_header.pin": "ထိပ်တွင်တွဲထားမည်",
+  "column_header.show_settings": "ဆက်တင်များကို ပြပါ။",
+  "column_header.unpin": "မတွဲတော့ပါ",
   "column_subheading.settings": "ဆက်တင်များ",
   "community.column_settings.local_only": "Local only",
   "community.column_settings.media_only": "Media only",
   "community.column_settings.remote_only": "Remote only",
-  "compose.language.change": "Change language",
-  "compose.language.search": "Search languages...",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "compose.language.change": "ဘာသာစကား ပြောင်းမည်",
+  "compose.language.search": "ဘာသာစကားကိုရှာမည်",
+  "compose_form.direct_message_warning_learn_more": "ထပ်သိရှိလိုသည်",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts 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.lock_disclaimer.lock": "locked",
+  "compose_form.hashtag_warning": "ဤပို့စ်သည် အများသူငှာမဟုတ်သောကြောင့် မည်သည့် hashtag အောက်တွင် ဖော်ပြမည်မဟုတ်ပါ။ အများသူငှာ ပို့စ်များကိုသာ hashtag ဖြင့် ရှာဖွေနိုင်သည်။",
+  "compose_form.lock_disclaimer": "သင့်အကောင့်ကို {သော့ခတ်မထားပါ}။ သင့်နောက်လိုက်-သီးသန့်ပို့စ်များကို ကြည့်ရှုရန် မည်သူမဆို သင့်အား လိုက်ကြည့်နိုင်ပါသည်။",
+  "compose_form.lock_disclaimer.lock": "သော့ခတ်ထားမယ်",
   "compose_form.placeholder": "What is on your mind?",
-  "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.publish": "Publish",
-  "compose_form.publish_form": "Publish",
+  "compose_form.poll.add_option": "ရွေးချယ်မှုထပ်မံပေါင်းထည့်ပါ",
+  "compose_form.poll.duration": "စစ်တမ်းကြာချိန်",
+  "compose_form.poll.option_placeholder": "ရွေးချယ်မှု {number}\n",
+  "compose_form.poll.remove_option": "ဤရွေးချယ်မှုကို ဖယ်ထုတ်ပါ",
+  "compose_form.poll.switch_to_multiple": "စစ်တမ်းတွင်တစ်ခုထပ်ပိုသောဆန္ဒပြုချက်လက်ခံမည်",
+  "compose_form.poll.switch_to_single": "စစ်တမ်းတွင် တစ်ခုကိုသာရွေးချယ်ခွင့်ပြုမည်",
+  "compose_form.publish": "ပို့စ်တင်မည်",
+  "compose_form.publish_form": "ပို့စ်တင်မည်",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.save_changes": "Save changes",
+  "compose_form.save_changes": "ပြောင်းလဲမှုများကို သိမ်းဆည်းပါ",
   "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}",
   "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}",
   "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
-  "compose_form.spoiler_placeholder": "Write your warning here",
-  "confirmation_modal.cancel": "Cancel",
-  "confirmations.block.block_and_report": "Block & Report",
-  "confirmations.block.confirm": "Block",
-  "confirmations.block.message": "Are you sure you want to block {name}?",
-  "confirmations.cancel_follow_request.confirm": "Withdraw request",
-  "confirmations.cancel_follow_request.message": "Are you sure you want to withdraw your request to follow {name}?",
-  "confirmations.delete.confirm": "Delete",
+  "compose_form.spoiler_placeholder": "သတိပေးစာကိုဤနေရာတွင်ရေးပါ",
+  "confirmation_modal.cancel": "ပယ်ဖျက်မည်",
+  "confirmations.block.block_and_report": "ဘလော့ပြီး တိုင်ကြားမည်",
+  "confirmations.block.confirm": "ဘလော့မည်",
+  "confirmations.block.message": "အကောင့်မှ ထွက်ရန် သေချာပါသလား?",
+  "confirmations.cancel_follow_request.confirm": "ပန်ကြားချက်ကို ပယ်ဖျက်မည်",
+  "confirmations.cancel_follow_request.message": "{name} ကိုဖော်လိုပယ်ဖျက်ရန် သေချာပါသလား။",
+  "confirmations.delete.confirm": "ဖျက်မည်",
   "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.discard_edit_media.confirm": "Discard",
+  "confirmations.delete_list.confirm": "ဖျက်မည်",
+  "confirmations.delete_list.message": "ဖျက်ရန် သေချာပါသလား?",
+  "confirmations.discard_edit_media.confirm": "ဖယ်ထုတ်ပါ",
   "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?",
   "confirmations.domain_block.confirm": "Hide 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?",
-  "confirmations.mute.confirm": "Mute",
-  "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.",
-  "confirmations.mute.message": "Are you sure you want to mute {name}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
+  "confirmations.domain_block.message": "{domain} တစ်ခုလုံးကို ဘလော့လုပ်ရန် တကယ် သေချာပါသလား? များသောအားဖြင့် အနည်းစုကို ပစ်မှတ်ထား ဘလော့လုပ်ခြင်းသည် လုံလောက်ပါသည်။ ထို ဒိုမိန်းမှ အကြောင်းအရာ တစ်ခုမှ မြင်ရမည်မဟုတ်သည့်အပြင် ထို ဒိုမိန်းတွင်ရှိသော သင်၏ စောင့်ကြည့်သူများပါ ဖယ်ရှားပစ်မည်ဖြစ်သည်။",
+  "confirmations.logout.confirm": "အကောင့်မှထွက်မည်",
+  "confirmations.logout.message": "အကောင့်မှ ထွက်ရန် သေချာပါသလား?",
+  "confirmations.mute.confirm": "ပိတ်ထားရန်",
+  "confirmations.mute.explanation": "၎င်းသည် ၎င်းတို့ထံမှ ပို့စ်များနှင့် ၎င်းတို့ကို ဖော်ပြထားသော ပို့စ်များကို ဖျောက်ထားမည်ဖြစ်ပြီး၊ သို့သော် ၎င်းတို့သည် သင့်ပို့စ်များကို မြင်နိုင်ပြီး သင့်အား လိုက်ကြည့်နိုင်စေမည်ဖြစ်သည်။",
+  "confirmations.mute.message": "{name} ကို မမြင်လိုသည်မှာ သေချာပါသလား။ ",
+  "confirmations.redraft.confirm": "ဖျက်ပြီး ပြန်လည်ရေးမည်။",
   "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.reply.confirm": "စာပြန်မည်",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
-  "confirmations.unfollow.confirm": "Unfollow",
-  "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}",
-  "copypaste.copied": "Copied",
-  "copypaste.copy": "Copy",
+  "confirmations.reply.message": "စာပြန်လျှင်ယခင်စာများကိုအလိုအလျောက်ပျက်သွားစေမည်။ ဆက်လက်လုပ်ဆောင်မည်လား?",
+  "confirmations.unfollow.confirm": "ဖောလိုးဖြုတ်မည်",
+  "confirmations.unfollow.message": "{name}ကိုဖောလိုးဖြုတ်မည်",
+  "conversation.delete": "ဤစကားပြောဆိုမှုကို ဖျက်ပစ်မည်",
+  "conversation.mark_as_read": "ဖတ်ပြီးသားအဖြစ်မှတ်ထားပါ",
+  "conversation.open": "Conversation ကိုကြည့်မည်",
+  "conversation.with": "{အမည်များ} ဖြင့်",
+  "copypaste.copied": "ကူယူပြီးပါပြီ",
+  "copypaste.copy": "ကူးယူပါ",
   "directory.federated": "From known fediverse",
-  "directory.local": "From {domain} only",
-  "directory.new_arrivals": "New arrivals",
-  "directory.recently_active": "Recently active",
-  "disabled_account_banner.account_settings": "Account settings",
-  "disabled_account_banner.text": "Your account {disabledAccount} is currently disabled.",
+  "directory.local": "{domain} မှသာလျှင်\n",
+  "directory.new_arrivals": "အသစ်ရောက်ရှိမှုများ",
+  "directory.recently_active": "မကြာသေးခင်က ဖွင့်ထားသော",
+  "disabled_account_banner.account_settings": "အကောင့်ဆက်တင်များ",
+  "disabled_account_banner.text": "{disabledAccount} သည်လတ်တလောပိတ်ခံထားရသည်",
   "dismissable_banner.community_timeline": "These are the most recent public posts from people whose accounts are hosted by {domain}.",
-  "dismissable_banner.dismiss": "Dismiss",
-  "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
-  "dismissable_banner.explore_statuses": "These posts from this and other servers in the decentralized network are gaining traction on this server right now.",
-  "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
+  "dismissable_banner.dismiss": "ပယ်ရန်",
+  "dismissable_banner.explore_links": "ဤသတင်းများကို ယခုအချိန်တွင် ဗဟိုချုပ်ကိုင်မှုလျှော့ချထားသော ကွန်ရက်၏ အခြားဆာဗာများမှ လူများက ပြောဆိုနေကြပါသည်။",
+  "dismissable_banner.explore_statuses": "ဤစာများနှင့် ဗဟိုချုပ်ကိုင်မှုလျှော့ချထားသော ကွန်ရက်ရှိ အခြားဆာဗာများမှ ဤပို့စ်များသည် ယခုဆာဗာပေါ်တွင် ဆွဲဆောင်မှု ရှိလာပါသည်။",
+  "dismissable_banner.explore_tags": "ဤ hashtag များသည် ယခုအချိန်တွင် ဗဟိုချုပ်ကိုင်မှုလျှော့ချထားသော ကွန်ရက်၏ အခြားဆာဗာများပေါ်ရှိ လူများကြားတွင် ဆွဲဆောင်မှုရှိလာပါသည်",
   "dismissable_banner.public_timeline": "These are the most recent public posts from people on this and other servers of the decentralized network that this server knows about.",
   "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.clear": "Clear",
+  "emoji_button.clear": "ရှင်းလင်းမည်",
   "emoji_button.custom": "Custom",
   "emoji_button.flags": "Flags",
   "emoji_button.food": "Food & Drink",
@@ -211,11 +211,11 @@
   "empty_column.account_suspended": "Account suspended",
   "empty_column.account_timeline": "No posts found",
   "empty_column.account_unavailable": "Profile unavailable",
-  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.blocks": "ပိတ်ထားသောအကောင့်များမရှိသေးပါ",
   "empty_column.bookmarked_statuses": "You don't have any bookmarked posts 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 blocked domains yet.",
+  "empty_column.domain_blocks": "သင်ပိတ်ထားသော ဒိုမိန်းမရှိသေးပါ",
   "empty_column.explore_statuses": "Nothing is trending right now. Check back later!",
   "empty_column.favourited_statuses": "You don't have any favourite posts yet. When you favourite one, it will show up here.",
   "empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.",
@@ -224,11 +224,11 @@
   "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.",
   "empty_column.hashtag": "There is nothing in this hashtag yet.",
   "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
-  "empty_column.home.suggestions": "See some suggestions",
+  "empty_column.home.suggestions": "ဆက်လက်ဖတ်ရှုမည်",
   "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. When other people interact with you, you will see it here.",
+  "empty_column.lists": "သင့်တွင် List မရှိသေးပါ။ List အသစ်ဖွင့်လျှင် ဤနေရာတွင်ကြည့်ရှုနိုင်မည်",
+  "empty_column.mutes": "ပိတ်ထားသောအကောင့်များမရှိသေးပါ",
+  "empty_column.notifications": "သတိပေးချက်မရှိသေးပါ။ သတိပေးချက်အသစ်ရှိလျှင် ဤနေရာတွင်ကြည့်ရှုနိုင်သည်",
   "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.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.",
@@ -237,11 +237,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
-  "explore.suggested_follows": "For you",
-  "explore.title": "Explore",
-  "explore.trending_links": "News",
-  "explore.trending_statuses": "Posts",
-  "explore.trending_tags": "Hashtags",
+  "explore.suggested_follows": "သင့်အတွက်",
+  "explore.title": "စူးစမ်းရန်",
+  "explore.trending_links": "သတင်းများ",
+  "explore.trending_statuses": "ပို့စ်တင်မယ်",
+  "explore.trending_tags": "ဟက်ရှ်တက်များ",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -252,7 +252,7 @@
   "filter_modal.added.short_explanation": "This post has been added to the following filter category: {title}.",
   "filter_modal.added.title": "Filter added!",
   "filter_modal.select_filter.context_mismatch": "does not apply to this context",
-  "filter_modal.select_filter.expired": "expired",
+  "filter_modal.select_filter.expired": "သက်တမ်းကုန်သွားပါပြီ",
   "filter_modal.select_filter.prompt_new": "New category: {name}",
   "filter_modal.select_filter.search": "Search or create",
   "filter_modal.select_filter.subtitle": "Use an existing category or create a new one",
@@ -265,16 +265,16 @@
   "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.",
   "followed_tags": "Followed hashtags",
-  "footer.about": "About",
+  "footer.about": "အကြောင်း",
   "footer.directory": "Profiles directory",
   "footer.get_app": "Get the app",
   "footer.invite": "Invite people",
   "footer.keyboard_shortcuts": "Keyboard shortcuts",
   "footer.privacy_policy": "Privacy policy",
-  "footer.source_code": "View source code",
-  "footer.status": "Status",
-  "generic.saved": "Saved",
-  "getting_started.heading": "Getting started",
+  "footer.source_code": "မူရင်းကုဒ်အားကြည့်ရှုမည်",
+  "footer.status": "အခြေအနေ",
+  "generic.saved": "သိမ်းဆည်းထားပြီး",
+  "getting_started.heading": "စတင်မည်",
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
@@ -296,7 +296,7 @@
   "interaction_modal.description.reblog": "With an account on Mastodon, you can boost this post to share it with your own followers.",
   "interaction_modal.description.reply": "With an account on Mastodon, you can respond to this post.",
   "interaction_modal.on_another_server": "On a different server",
-  "interaction_modal.on_this_server": "On this server",
+  "interaction_modal.on_this_server": "ဤဆာဗာတွင်",
   "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.",
   "interaction_modal.preamble": "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.",
   "interaction_modal.title.favourite": "Favourite {name}'s post",
@@ -311,7 +311,7 @@
   "keyboard_shortcuts.boost": "to boost",
   "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": "ဖော်ပြချက်",
   "keyboard_shortcuts.direct": "to open direct messages column",
   "keyboard_shortcuts.down": "to move down in the list",
   "keyboard_shortcuts.enter": "to open status",
@@ -320,7 +320,7 @@
   "keyboard_shortcuts.federated": "to open federated timeline",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
   "keyboard_shortcuts.home": "to open home timeline",
-  "keyboard_shortcuts.hotkey": "Hotkey",
+  "keyboard_shortcuts.hotkey": "သော့ချက်",
   "keyboard_shortcuts.legend": "to display this legend",
   "keyboard_shortcuts.local": "to open local timeline",
   "keyboard_shortcuts.mention": "to mention author",
@@ -340,39 +340,39 @@
   "keyboard_shortcuts.toot": "to start a brand new post",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
-  "lightbox.close": "Close",
+  "lightbox.close": "ပိတ်ပါ",
   "lightbox.compress": "Compress image view box",
-  "lightbox.expand": "Expand image view box",
-  "lightbox.next": "Next",
+  "lightbox.expand": "ပုံကိုဖွင့်ပါ",
+  "lightbox.next": "ရှေ့သို့",
   "lightbox.previous": "Previous",
   "limited_account_hint.action": "Show profile anyway",
   "limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
-  "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": "စာရင်းထဲသို့ထည့်ပါ",
+  "lists.account.remove": "စာရင်းမှ ဖယ်ရှားလိုက်ပါ။",
+  "lists.delete": "စာရင်းကိုဖျက်ပါ",
+  "lists.edit": "စာရင်းကိုပြင်ဆင်ပါ",
+  "lists.edit.submit": "ခေါင်းစဥ် ပြောင်းလဲရန်",
+  "lists.new.create": "စာရင်းသွင်းပါ",
+  "lists.new.title_placeholder": "စာရင်းသစ်ခေါင်းစဥ်",
   "lists.replies_policy.followed": "Any followed user",
-  "lists.replies_policy.list": "Members of the list",
-  "lists.replies_policy.none": "No one",
+  "lists.replies_policy.list": "စာရင်းထဲမှ အဖွဲ့ဝင်များ",
+  "lists.replies_policy.none": "တစ်ယောက်မှမရှိပါ",
   "lists.replies_policy.title": "Show replies to:",
-  "lists.search": "Search among people you follow",
-  "lists.subheading": "Your lists",
+  "lists.search": "မိမိဖောလိုးထားသူများမှရှာဖွေမည်",
+  "lists.subheading": "သင့်၏စာရင်းများ",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
-  "loading_indicator.label": "Loading...",
+  "loading_indicator.label": "လုပ်ဆောင်နေသည်…",
   "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
-  "missing_indicator.label": "Not found",
-  "missing_indicator.sublabel": "This resource could not be found",
-  "moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.",
-  "mute_modal.duration": "Duration",
-  "mute_modal.hide_notifications": "Hide notifications from this user?",
-  "mute_modal.indefinite": "Indefinite",
+  "missing_indicator.label": "မတွေ့ပါ",
+  "missing_indicator.sublabel": "ရှာဖွေနေသည်ကိုမတွေ့ပါ",
+  "moved_to_account_banner.text": "{movedToAccount} အကောင့်သို့ပြောင်းလဲထားသဖြင့် {disabledAccount} အကောင့်မှာပိတ်ထားသည်",
+  "mute_modal.duration": "ကြာချိန်",
+  "mute_modal.hide_notifications": "ဤအကောင့်မှသတိပေးချက်များကိုပိတ်မလား?",
+  "mute_modal.indefinite": "ရေတွက်လို့မရပါ",
   "navigation_bar.about": "အကြောင်း",
-  "navigation_bar.blocks": "Blocked users",
-  "navigation_bar.bookmarks": "Bookmarks",
-  "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.blocks": "ဘလော့ထားသောအကောင့်များ",
+  "navigation_bar.bookmarks": "မှတ်ထားသည်များ",
+  "navigation_bar.community_timeline": "ဒေသစံတော်ချိန်",
   "navigation_bar.compose": "Compose new post",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
@@ -400,24 +400,24 @@
   "notification.follow": "{name} followed you",
   "notification.follow_request": "{name} has requested to follow you",
   "notification.mention": "{name} mentioned you",
-  "notification.own_poll": "Your poll has ended",
-  "notification.poll": "A poll you have voted in has ended",
+  "notification.own_poll": "စစ်တမ်းကောက်မှု ပြီးဆုံးပါပြီ",
+  "notification.poll": "သင်ပါဝင်ခဲ့သော စစ်တမ်းပြီးပါပြီ",
   "notification.reblog": "{name} boosted your status",
   "notification.status": "{name} just posted",
   "notification.update": "{name} edited a post",
-  "notifications.clear": "Clear notifications",
-  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+  "notifications.clear": "အသိပေးချက်များအား ရှင်းလင်းပါ",
+  "notifications.clear_confirmation": "သတိပေးချက်အားလုံးကို အပြီးတိုင်ဖယ်ရှားမည်",
   "notifications.column_settings.admin.report": "New reports:",
   "notifications.column_settings.admin.sign_up": "New sign-ups:",
-  "notifications.column_settings.alert": "Desktop notifications",
-  "notifications.column_settings.favourite": "Favourites:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
+  "notifications.column_settings.alert": "Desktop သတိပေးချက်များ",
+  "notifications.column_settings.favourite": "ကြိုက်နှစ်သက်မှုများ",
+  "notifications.column_settings.filter_bar.advanced": "ခေါင်းစဥ်အားလုံးများကိုဖော်ပြပါ",
   "notifications.column_settings.filter_bar.category": "Quick filter bar",
   "notifications.column_settings.filter_bar.show_bar": "Show filter bar",
   "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.poll": "စစ်တမ်းရလဒ်",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Boosts:",
   "notifications.column_settings.show": "Show in column",
@@ -426,14 +426,14 @@
   "notifications.column_settings.unread_notifications.category": "Unread notifications",
   "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications",
   "notifications.column_settings.update": "Edits:",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.filter.polls": "Poll results",
+  "notifications.filter.all": "အားလုံး",
+  "notifications.filter.boosts": "အားပေးမည်",
+  "notifications.filter.favourites": "ကြိုက်နှစ်သက်မှုများ",
+  "notifications.filter.follows": "ဖောလိုးမည်",
+  "notifications.filter.mentions": " မန်းရှင်းမည်",
+  "notifications.filter.polls": "စစ်တမ်းရလဒ်",
   "notifications.filter.statuses": "Updates from people you follow",
-  "notifications.grant_permission": "Grant permission.",
+  "notifications.grant_permission": "ခွင့်ပြုချက်ပေးမည်",
   "notifications.group": "{count} notifications",
   "notifications.mark_as_read": "Mark every notification as read",
   "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request",
@@ -443,19 +443,19 @@
   "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.",
   "notifications_permission_banner.title": "Never miss a thing",
   "picture_in_picture.restore": "Put it back",
-  "poll.closed": "Closed",
-  "poll.refresh": "Refresh",
+  "poll.closed": "ပိတ်သွားပြီ",
+  "poll.refresh": "ပြန်ဖွင့်မည်",
   "poll.total_people": "{count, plural, one {# person} other {# people}}",
   "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
-  "poll.vote": "Vote",
-  "poll.voted": "You voted for this answer",
+  "poll.vote": "မဲပေးမည်",
+  "poll.voted": "သင်ဤအဖြေကိုမဲပေးခဲ့သည်",
   "poll.votes": "{votes, plural, one {# vote} other {# votes}}",
-  "poll_button.add_poll": "Add a poll",
-  "poll_button.remove_poll": "Remove poll",
+  "poll_button.add_poll": "စစ်တမ်းကောက်မည်",
+  "poll_button.remove_poll": "စစ်တမ်းပယ်ဖျက်မည်",
   "privacy.change": "Adjust status privacy",
-  "privacy.direct.long": "Visible for mentioned users only",
+  "privacy.direct.long": "မန်းရှင်းခေါ်သူသီးသန့်",
   "privacy.direct.short": "Direct",
-  "privacy.private.long": "Visible for followers only",
+  "privacy.private.long": "ဖော်လိုးလုပ်သူသီးသန့်",
   "privacy.private.short": "Followers-only",
   "privacy.public.long": "Visible for all",
   "privacy.public.short": "Public",
@@ -476,28 +476,28 @@
   "relative_time.just_now": "now",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
-  "relative_time.today": "today",
-  "reply_indicator.cancel": "Cancel",
-  "report.block": "Block",
+  "relative_time.today": "ယနေ့",
+  "reply_indicator.cancel": "ပယ်ဖျက်မည်",
+  "report.block": "ဘလော့မည်",
   "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.",
-  "report.categories.other": "Other",
-  "report.categories.spam": "Spam",
-  "report.categories.violation": "Content violates one or more server rules",
-  "report.category.subtitle": "Choose the best match",
+  "report.categories.other": "အခြား",
+  "report.categories.spam": "ပြင်ပစာများ",
+  "report.categories.violation": "ဤစာတွင် သတ်မှတ်ထားသောစည်းကမ်းများကို ဖောက်ဖျက်သောအကြောင်းအရာပါဝင်နေသည်",
+  "report.category.subtitle": "အကိုက်ညီဆုံးကိုရွေးချယ်ပါ",
   "report.category.title": "Tell us what's going on with this {type}",
   "report.category.title_account": "ကိုယ်ရေးမှတ်တမ်း",
-  "report.category.title_status": "post",
-  "report.close": "Done",
-  "report.comment.title": "Is there anything else you think we should know?",
-  "report.forward": "Forward to {target}",
-  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
-  "report.mute": "Mute",
+  "report.category.title_status": "ပို့စ်",
+  "report.close": "ပြီးပြီ",
+  "report.comment.title": "မိမိထင်မြင်ယူဆချက်များကိုဖော်ပြပေးပါ",
+  "report.forward": "{target} သို့တစ်ဆင့်ပို့ပေးမည်",
+  "report.forward_hint": "ဤအကောင့်မှာတစ်ခြားဆာဗာမှဖြစ်သည်။ အမည်မသိတိုင်းကြားချက်ဖွင့်လိုပါသလား?",
+  "report.mute": "ပိတ်ထားရန်",
   "report.mute_explanation": "You will not see their posts. They can still follow you and see your posts and will not know that they are muted.",
-  "report.next": "Next",
+  "report.next": "ရှေ့သို့",
   "report.placeholder": "Type or paste additional comments",
-  "report.reasons.dislike": "I don't like it",
-  "report.reasons.dislike_description": "It is not something you want to see",
-  "report.reasons.other": "It's something else",
+  "report.reasons.dislike": "မကြိုက်ပါ",
+  "report.reasons.dislike_description": "ပိုမိုမြင်လိုသည်ရှိပါသလား",
+  "report.reasons.other": "တစ်ခုခုဖြစ်နေသည်",
   "report.reasons.other_description": "The issue does not fit into other categories",
   "report.reasons.spam": "It's spam",
   "report.reasons.spam_description": "Malicious links, fake engagement, or repetitive replies",
@@ -520,19 +520,19 @@
   "report_notification.categories.spam": "Spam",
   "report_notification.categories.violation": "Rule violation",
   "report_notification.open": "Open report",
-  "search.placeholder": "Search",
-  "search.search_or_paste": "Search or paste URL",
+  "search.placeholder": "ရှာဖွေရန်",
+  "search.search_or_paste": "URL ရိုက်ထည့်ပါ သို့မဟုတ် ရှာဖွေပါ",
   "search_popout.search_format": "Advanced search format",
   "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
-  "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "status",
+  "search_popout.tips.hashtag": "ဟက်ရှ်တက်ခ်",
+  "search_popout.tips.status": "ပို့စ်",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
-  "search_popout.tips.user": "user",
-  "search_results.accounts": "People",
-  "search_results.all": "All",
+  "search_popout.tips.user": "အသုံးပြုသူ",
+  "search_results.accounts": "လူပုဂ္ဂိုလ်",
+  "search_results.all": "အားလုံး",
   "search_results.hashtags": "ဟက်ရှ်တက်များ",
-  "search_results.nothing_found": "Could not find anything for these search terms",
-  "search_results.statuses": "Posts",
+  "search_results.nothing_found": "ရှာဖွေလိုသောအရာမရှိပါ",
+  "search_results.statuses": "ပို့စ်တင်မယ်",
   "search_results.statuses_fts_disabled": "Searching posts by their content is not enabled on this Mastodon server.",
   "search_results.title": "Search for {q}",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
@@ -548,7 +548,7 @@
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
-  "status.block": "Block @{name}",
+  "status.block": "@{name} ကိုဘလော့မည်",
   "status.bookmark": "Bookmark",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
@@ -560,10 +560,10 @@
   "status.edited": "Edited {date}",
   "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}",
   "status.embed": "Embed",
-  "status.favourite": "Favourite",
+  "status.favourite": "ကြိုက်နှစ်သက်မှုများ",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide post",
+  "status.hide": "ပို့စ်ကိုပိတ်ထားမည်",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
@@ -572,7 +572,7 @@
   "status.more": "More",
   "status.mute": "Mute @{name}",
   "status.mute_conversation": "Mute conversation",
-  "status.open": "Expand this status",
+  "status.open": "ပို့စ်ကိုချဲ့ထွင်မည်",
   "status.pin": "Pin on profile",
   "status.pinned": "Pinned post",
   "status.read_more": "Read more",
@@ -626,14 +626,14 @@
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
-  "upload_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_error.poll": "စစ်တမ်းနှင့်အတူဖိုင်များတင်ခွင့်မပြုပါ",
+  "upload_form.audio_description": "အကြားအာရုံချို့ယွင်းသော ခက်ခဲသောသူများအတွက် ဖော်ပြထားသည်",
+  "upload_form.description": "အမြင်အာရုံချို့ယွင်းသော ခက်ခဲသောသူများအတွက် ဖော်ပြထားသည်",
   "upload_form.description_missing": "No description added",
   "upload_form.edit": "Edit",
   "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
-  "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
+  "upload_form.video_description": "အမြင်အာရုံနှင့်အကြားအာရုံ ချို့ယွင်းသော ခက်ခဲသောသူများအတွက် ဖော်ပြထားသည်",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
   "upload_modal.applying": "Applying…",
@@ -644,7 +644,7 @@
   "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
   "upload_modal.preparing_ocr": "Preparing OCR…",
   "upload_modal.preview_label": "Preview ({ratio})",
-  "upload_progress.label": "Uploading…",
+  "upload_progress.label": "တင်နေသည်...",
   "upload_progress.processing": "Processing…",
   "video.close": "Close video",
   "video.download": "Download file",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 02804f0f6..f2e4a365e 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -65,7 +65,7 @@
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Dessilenciar @{name}",
   "account.unmute_notifications": "Mostrar notificações de @{name}",
-  "account.unmute_short": "Dessilenciar",
+  "account.unmute_short": "Desativar silêncio",
   "account_note.placeholder": "Nota pessoal sobre este perfil aqui",
   "admin.dashboard.daily_retention": "Taxa de retenção de usuários por dia, após a inscrição",
   "admin.dashboard.monthly_retention": "Taxa de retenção de usuários por mês, após a inscrição",
@@ -82,7 +82,7 @@
   "autosuggest_hashtag.per_week": "{count} por semana",
   "boost_modal.combo": "Pressione {combo} para pular isso na próxima vez",
   "bundle_column_error.copy_stacktrace": "Copiar relatório do erro",
-  "bundle_column_error.error.body": "A página solicitada não pode ser renderizada. Pode ser devido a um erro em nosso código ou um problema de compatibilidade do navegador.",
+  "bundle_column_error.error.body": "A página solicitada não pôde ser renderizada. Pode ser devido a um erro no nosso código, ou um problema de compatibilidade do seu navegador.",
   "bundle_column_error.error.title": "Ah, não!",
   "bundle_column_error.network.body": "Ocorreu um erro ao tentar carregar esta página. Isso pode ser devido a um problema temporário com sua conexão de internet ou deste servidor.",
   "bundle_column_error.network.title": "Erro de rede",
diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json
index 683924c70..787727d56 100644
--- a/app/javascript/mastodon/locales/ro.json
+++ b/app/javascript/mastodon/locales/ro.json
@@ -54,7 +54,7 @@
   "account.posts_with_replies": "Postări și răspunsuri",
   "account.report": "Raportează pe @{name}",
   "account.requested": "Se așteaptă aprobarea. Apasă pentru a anula cererea de urmărire",
-  "account.requested_follow": "{name} has requested to follow you",
+  "account.requested_follow": "{name} A cerut să vă urmărească",
   "account.share": "Distribuie profilul lui @{name}",
   "account.show_reblogs": "Arată impulsurile de la @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -128,7 +128,7 @@
   "compose.language.search": "Căutare limbi…",
   "compose_form.direct_message_warning_learn_more": "Află mai multe",
   "compose_form.encryption_warning": "Postările pe Mastodon nu sunt criptate în ambele părți. Nu împărtășiți nici o informație sensibilă pe Mastodon.",
-  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
+  "compose_form.hashtag_warning": "Această postare nu va fi listată sub niciun hashtag, deoarece nu este publică. Doar postările publice pot fi căutate de hashtag.",
   "compose_form.lock_disclaimer": "Contul tău nu este {locked}. Oricine se poate abona la tine pentru a îți vedea postările numai pentru abonați.",
   "compose_form.lock_disclaimer.lock": "privat",
   "compose_form.placeholder": "La ce te gândești?",
@@ -221,7 +221,7 @@
   "empty_column.favourites": "Momentan nimeni nu a adăugat această postare la favorite. Când cineva o va face, va apărea aici.",
   "empty_column.follow_recommendations": "Se pare că nu am putut genera nicio sugestie pentru tine. Poți încerca funcția de căutare pentru a căuta persoane pe care le cunoști, sau poți explora tendințele.",
   "empty_column.follow_requests": "Momentan nu ai nicio cerere de abonare. Când vei primi una, va apărea aici.",
-  "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.",
+  "empty_column.followed_tags": "Încă nu urmăriți niciun harstag -uri. Când o vei face, vor apărea aici.",
   "empty_column.hashtag": "Acest hashtag încă nu a fost folosit.",
   "empty_column.home": "Nu există nimic în cronologia ta! Abonează-te la mai multe persoane pentru a o umple. {suggestions}",
   "empty_column.home.suggestions": "Vezi sugestiile",
@@ -237,11 +237,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiere stacktrace în clipboard",
   "errors.unexpected_crash.report_issue": "Raportează o problemă",
   "explore.search_results": "Rezultatele căutării",
-  "explore.suggested_follows": "For you",
+  "explore.suggested_follows": "Pentru tine",
   "explore.title": "Explorează",
-  "explore.trending_links": "News",
-  "explore.trending_statuses": "Posts",
-  "explore.trending_tags": "Hashtags",
+  "explore.trending_links": "Noutăți",
+  "explore.trending_statuses": "Postări",
+  "explore.trending_tags": "Hastaguri",
   "filter_modal.added.context_mismatch_explanation": "Această categorie de filtre nu se aplică în contextul în care ați accesat acestă postare. Dacă doriți ca postarea să fie filtrată și în acest context, va trebui să editați filtrul.",
   "filter_modal.added.context_mismatch_title": "Nepotrivire contextuală!",
   "filter_modal.added.expired_explanation": "Această categorie de filtre a expirat, va trebui să modifici data de expirare pentru ca aceasta să se aplice.",
@@ -264,7 +264,7 @@
   "follow_request.authorize": "Acceptă",
   "follow_request.reject": "Respinge",
   "follow_requests.unlocked_explanation": "Chiar dacă contul tău nu este blocat, personalul {domain} a considerat că ai putea prefera să consulți manual cererile de abonare de la aceste conturi.",
-  "followed_tags": "Followed hashtags",
+  "followed_tags": "Hastaguri urmărite",
   "footer.about": "Despre",
   "footer.directory": "Catalogul de profiluri",
   "footer.get_app": "Obține aplicația",
@@ -382,7 +382,7 @@
   "navigation_bar.favourites": "Favorite",
   "navigation_bar.filters": "Cuvinte ignorate",
   "navigation_bar.follow_requests": "Cereri de abonare",
-  "navigation_bar.followed_tags": "Followed hashtags",
+  "navigation_bar.followed_tags": "Hashtag-uri urmărite",
   "navigation_bar.follows_and_followers": "Abonamente și abonați",
   "navigation_bar.lists": "Liste",
   "navigation_bar.logout": "Deconectare",
@@ -544,7 +544,7 @@
   "server_banner.server_stats": "Statisticile serverului:",
   "sign_in_banner.create_account": "Creează-ți un cont",
   "sign_in_banner.sign_in": "Conectează-te",
-  "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts. You can also interact from your account on a different server.",
+  "sign_in_banner.text": "Conectează-te pentru a te abona la profiluri și haștaguri, pentru a aprecia, distribui și a răspunde postărilor, sau interacționează folosindu-ți contul de pe un alt server.",
   "status.admin_account": "Deschide interfața de moderare pentru @{name}",
   "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Deschide această stare în interfața de moderare",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index ba50e846a..03c237a64 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -218,7 +218,7 @@
   "empty_column.domain_blocks": "Žiadne domény ešte niesú skryté.",
   "empty_column.explore_statuses": "Momentálne nie je nič trendové. Pozrite sa neskôr!",
   "empty_column.favourited_statuses": "Nemáš obľúbené ešte žiadne príspevky. Keď si nejaký obľúbiš, bude zobrazený práve tu.",
-  "empty_column.favourites": "Tento toot si ešte nikto neobľúbil. Ten kto si ho obľúbi, bude zobrazený tu.",
+  "empty_column.favourites": "Ešte si tento príspevok nikto neobľúbil. Keď si ho niekto obľúbi, bude zobrazený tu.",
   "empty_column.follow_recommendations": "Zdá sa že pre Vás nemohli byť vygenerované žiadne návrhy. Môžete skúsiť použiť vyhľadávanie aby ste našli ľudi ktorých poznáte, alebo preskúmať trendujúce heštegy.",
   "empty_column.follow_requests": "Ešte nemáš žiadne požiadavky o následovanie. Keď nejaké dostaneš, budú tu zobrazené.",
   "empty_column.followed_tags": "Ešte nenasleduješ žiadne haštagy. Keď tak urobíš, zobrazia sa tu.",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 1e8dd8051..405e526bb 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -152,7 +152,7 @@
   "confirmations.block.block_and_report": "封鎖並檢舉",
   "confirmations.block.confirm": "封鎖",
   "confirmations.block.message": "您確定要封鎖 {name} ?",
-  "confirmations.cancel_follow_request.confirm": "收回請求",
+  "confirmations.cancel_follow_request.confirm": "收回跟隨請求",
   "confirmations.cancel_follow_request.message": "您確定要收回跟隨 {name} 的請求嗎?",
   "confirmations.delete.confirm": "刪除",
   "confirmations.delete.message": "您確定要刪除這則嘟文?",
diff --git a/app/javascript/mastodon/utils/notifications.js b/app/javascript/mastodon/utils/notifications.js
index 7634cac21..3cdf7caea 100644
--- a/app/javascript/mastodon/utils/notifications.js
+++ b/app/javascript/mastodon/utils/notifications.js
@@ -3,7 +3,7 @@
 
 const checkNotificationPromise = () => {
   try {
-    // eslint-disable-next-line promise/catch-or-return
+    // eslint-disable-next-line promise/catch-or-return, promise/valid-params
     Notification.requestPermission().then();
   } catch(e) {
     return false;
diff --git a/app/lib/activity_tracker.rb b/app/lib/activity_tracker.rb
index 6d3401b37..8829d8605 100644
--- a/app/lib/activity_tracker.rb
+++ b/app/lib/activity_tracker.rb
@@ -27,14 +27,12 @@ class ActivityTracker
     (start_at.to_date...end_at.to_date).map do |date|
       key = key_at(date.to_time(:utc))
 
-      value = begin
-        case @type
-        when :basic
-          redis.get(key).to_i
-        when :unique
-          redis.pfcount(key)
-        end
-      end
+      value = case @type
+              when :basic
+                redis.get(key).to_i
+              when :unique
+                redis.pfcount(key)
+              end
 
       [date, value]
     end
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index bda6e9c8b..eca446243 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -108,26 +108,24 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
   def process_status_params
     @status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: @account.followers_url)
 
-    @params = begin
-      {
-        uri: @status_parser.uri,
-        url: @status_parser.url || @status_parser.uri,
-        account: @account,
-        text: converted_object_type? ? converted_text : (@status_parser.text || ''),
-        language: @status_parser.language,
-        spoiler_text: converted_object_type? ? '' : (@status_parser.spoiler_text || ''),
-        created_at: @status_parser.created_at,
-        edited_at: @status_parser.edited_at && @status_parser.edited_at != @status_parser.created_at ? @status_parser.edited_at : nil,
-        override_timestamps: @options[:override_timestamps],
-        reply: @status_parser.reply,
-        sensitive: @account.sensitized? || @status_parser.sensitive || false,
-        visibility: @status_parser.visibility,
-        thread: replied_to_status,
-        conversation: conversation_from_uri(@object['conversation']),
-        media_attachment_ids: process_attachments.take(4).map(&:id),
-        poll: process_poll,
-      }
-    end
+    @params = {
+      uri: @status_parser.uri,
+      url: @status_parser.url || @status_parser.uri,
+      account: @account,
+      text: converted_object_type? ? converted_text : (@status_parser.text || ''),
+      language: @status_parser.language,
+      spoiler_text: converted_object_type? ? '' : (@status_parser.spoiler_text || ''),
+      created_at: @status_parser.created_at,
+      edited_at: @status_parser.edited_at && @status_parser.edited_at != @status_parser.created_at ? @status_parser.edited_at : nil,
+      override_timestamps: @options[:override_timestamps],
+      reply: @status_parser.reply,
+      sensitive: @account.sensitized? || @status_parser.sensitive || false,
+      visibility: @status_parser.visibility,
+      thread: replied_to_status,
+      conversation: conversation_from_uri(@object['conversation']),
+      media_attachment_ids: process_attachments.take(4).map(&:id),
+      poll: process_poll,
+    }
   end
 
   def process_audience
@@ -327,7 +325,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
   def resolve_thread(status)
     return unless status.reply? && status.thread.nil? && Request.valid_url?(in_reply_to_uri)
 
-    ThreadResolveWorker.perform_async(status.id, in_reply_to_uri, { 'request_id' => @options[:request_id]})
+    ThreadResolveWorker.perform_async(status.id, in_reply_to_uri, { 'request_id' => @options[:request_id] })
   end
 
   def fetch_replies(status)
@@ -338,7 +336,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     return unless replies.nil?
 
     uri = value_or_id(collection)
-    ActivityPub::FetchRepliesWorker.perform_async(status.id, uri, { 'request_id' => @options[:request_id]}) unless uri.nil?
+    ActivityPub::FetchRepliesWorker.perform_async(status.id, uri, { 'request_id' => @options[:request_id] }) unless uri.nil?
   end
 
   def conversation_from_uri(uri)
diff --git a/app/lib/activitypub/forwarder.rb b/app/lib/activitypub/forwarder.rb
index 4206b9d82..b01d63e58 100644
--- a/app/lib/activitypub/forwarder.rb
+++ b/app/lib/activitypub/forwarder.rb
@@ -28,13 +28,11 @@ class ActivityPub::Forwarder
   end
 
   def signature_account_id
-    @signature_account_id ||= begin
-      if in_reply_to_local?
-        in_reply_to.account_id
-      else
-        reblogged_by_account_ids.first
-      end
-    end
+    @signature_account_id ||= if in_reply_to_local?
+                                in_reply_to.account_id
+                              else
+                                reblogged_by_account_ids.first
+                              end
   end
 
   def inboxes
diff --git a/app/lib/activitypub/linked_data_signature.rb b/app/lib/activitypub/linked_data_signature.rb
index f90adaf6c..61759649a 100644
--- a/app/lib/activitypub/linked_data_signature.rb
+++ b/app/lib/activitypub/linked_data_signature.rb
@@ -27,9 +27,7 @@ class ActivityPub::LinkedDataSignature
     document_hash  = hash(@json.without('signature'))
     to_be_verified = options_hash + document_hash
 
-    if creator.keypair.public_key.verify(OpenSSL::Digest.new('SHA256'), Base64.decode64(signature), to_be_verified)
-      creator
-    end
+    creator if creator.keypair.public_key.verify(OpenSSL::Digest.new('SHA256'), Base64.decode64(signature), to_be_verified)
   end
 
   def sign!(creator, sign_with: nil)
diff --git a/app/lib/activitypub/parser/media_attachment_parser.rb b/app/lib/activitypub/parser/media_attachment_parser.rb
index 656be84b7..56b8b23f8 100644
--- a/app/lib/activitypub/parser/media_attachment_parser.rb
+++ b/app/lib/activitypub/parser/media_attachment_parser.rb
@@ -50,9 +50,7 @@ class ActivityPub::Parser::MediaAttachmentParser
     components = begin
       blurhash = @json['blurhash']
 
-      if blurhash.present? && /^[\w#$%*+,-.:;=?@\[\]^{|}~]+$/.match?(blurhash)
-        Blurhash.components(blurhash)
-      end
+      Blurhash.components(blurhash) if blurhash.present? && /^[\w#$%*+,-.:;=?@\[\]^{|}~]+$/.match?(blurhash)
     end
 
     components.present? && components.none? { |comp| comp > 5 }
diff --git a/app/lib/admin/metrics/dimension/software_versions_dimension.rb b/app/lib/admin/metrics/dimension/software_versions_dimension.rb
index 816615f99..9ab3776c9 100644
--- a/app/lib/admin/metrics/dimension/software_versions_dimension.rb
+++ b/app/lib/admin/metrics/dimension/software_versions_dimension.rb
@@ -58,12 +58,10 @@ class Admin::Metrics::Dimension::SoftwareVersionsDimension < Admin::Metrics::Dim
   end
 
   def redis_info
-    @redis_info ||= begin
-      if redis.is_a?(Redis::Namespace)
-        redis.redis.info
-      else
-        redis.info
-      end
-    end
+    @redis_info ||= if redis.is_a?(Redis::Namespace)
+                      redis.redis.info
+                    else
+                      redis.info
+                    end
   end
 end
diff --git a/app/lib/admin/metrics/dimension/space_usage_dimension.rb b/app/lib/admin/metrics/dimension/space_usage_dimension.rb
index 5867c5bab..cc8560890 100644
--- a/app/lib/admin/metrics/dimension/space_usage_dimension.rb
+++ b/app/lib/admin/metrics/dimension/space_usage_dimension.rb
@@ -59,12 +59,10 @@ class Admin::Metrics::Dimension::SpaceUsageDimension < Admin::Metrics::Dimension
   end
 
   def redis_info
-    @redis_info ||= begin
-      if redis.is_a?(Redis::Namespace)
-        redis.redis.info
-      else
-        redis.info
-      end
-    end
+    @redis_info ||= if redis.is_a?(Redis::Namespace)
+                      redis.redis.info
+                    else
+                      redis.info
+                    end
   end
 end
diff --git a/app/lib/extractor.rb b/app/lib/extractor.rb
index ead4cdddd..540bbe1a9 100644
--- a/app/lib/extractor.rb
+++ b/app/lib/extractor.rb
@@ -8,12 +8,10 @@ module Extractor
   module_function
 
   def extract_entities_with_indices(text, options = {}, &block)
-    entities = begin
-      extract_urls_with_indices(text, options) +
-        extract_hashtags_with_indices(text, check_url_overlap: false) +
-        extract_mentions_or_lists_with_indices(text) +
-        extract_extra_uris_with_indices(text)
-    end
+    entities = extract_urls_with_indices(text, options) +
+               extract_hashtags_with_indices(text, check_url_overlap: false) +
+               extract_mentions_or_lists_with_indices(text) +
+               extract_extra_uris_with_indices(text)
 
     return [] if entities.empty?
 
@@ -29,7 +27,7 @@ module Extractor
 
     text.scan(Account::MENTION_RE) do |screen_name, _|
       match_data = $LAST_MATCH_INFO
-      after      = $'
+      after      = ::Regexp.last_match.post_match
 
       unless Twitter::TwitterText::Regex[:end_mention_match].match?(after)
         _, domain = screen_name.split('@')
@@ -64,7 +62,7 @@ module Extractor
       match_data     = $LAST_MATCH_INFO
       start_position = match_data.char_begin(1) - 1
       end_position   = match_data.char_end(1)
-      after          = $'
+      after          = ::Regexp.last_match.post_match
 
       if %r{\A://}.match?(after)
         hash_text.match(/(.+)(https?\Z)/) do |matched|
diff --git a/app/lib/importer/statuses_index_importer.rb b/app/lib/importer/statuses_index_importer.rb
index 5b5153d5c..b0721c2e0 100644
--- a/app/lib/importer/statuses_index_importer.rb
+++ b/app/lib/importer/statuses_index_importer.rb
@@ -24,13 +24,11 @@ class Importer::StatusesIndexImporter < Importer::BaseImporter
           # is called before rendering the data and we need to filter based
           # on the results of the filter, so this filtering happens here instead
           bulk.map! do |entry|
-            new_entry = begin
-              if entry[:index] && entry.dig(:index, :data, 'searchable_by').blank?
-                { delete: entry[:index].except(:data) }
-              else
-                entry
-              end
-            end
+            new_entry = if entry[:index] && entry.dig(:index, :data, 'searchable_by').blank?
+                          { delete: entry[:index].except(:data) }
+                        else
+                          entry
+                        end
 
             if new_entry[:index]
               indexed += 1
diff --git a/app/lib/link_details_extractor.rb b/app/lib/link_details_extractor.rb
index 2e0672abe..74a7d0f3b 100644
--- a/app/lib/link_details_extractor.rb
+++ b/app/lib/link_details_extractor.rb
@@ -232,26 +232,24 @@ class LinkDetailsExtractor
   end
 
   def structured_data
-    @structured_data ||= begin
-      # Some publications have more than one JSON-LD definition on the page,
-      # and some of those definitions aren't valid JSON either, so we have
-      # to loop through here until we find something that is the right type
-      # and doesn't break
-      document.xpath('//script[@type="application/ld+json"]').filter_map do |element|
-        json_ld = element.content&.gsub(CDATA_JUNK_PATTERN, '')
+    # Some publications have more than one JSON-LD definition on the page,
+    # and some of those definitions aren't valid JSON either, so we have
+    # to loop through here until we find something that is the right type
+    # and doesn't break
+    @structured_data ||= document.xpath('//script[@type="application/ld+json"]').filter_map do |element|
+      json_ld = element.content&.gsub(CDATA_JUNK_PATTERN, '')
 
-        next if json_ld.blank?
+      next if json_ld.blank?
 
-        structured_data = StructuredData.new(html_entities.decode(json_ld))
+      structured_data = StructuredData.new(html_entities.decode(json_ld))
 
-        next unless structured_data.valid?
+      next unless structured_data.valid?
 
-        structured_data
-      rescue Oj::ParseError, EncodingError
-        Rails.logger.debug { "Invalid JSON-LD in #{@original_url}" }
-        next
-      end.first
-    end
+      structured_data
+    rescue Oj::ParseError, EncodingError
+      Rails.logger.debug { "Invalid JSON-LD in #{@original_url}" }
+      next
+    end.first
   end
 
   def document
diff --git a/app/lib/rate_limiter.rb b/app/lib/rate_limiter.rb
index 0e2c9a894..4a0b35b08 100644
--- a/app/lib/rate_limiter.rb
+++ b/app/lib/rate_limiter.rb
@@ -48,7 +48,7 @@ class RateLimiter
     {
       '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),
+      'X-RateLimit-Reset' => (now + (@period - (now.to_i % @period))).iso8601(6),
     }
   end
 
diff --git a/app/lib/request.rb b/app/lib/request.rb
index 0508169dc..be6a69b3f 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -215,26 +215,24 @@ class Request
         addr_by_socket = {}
 
         addresses.each do |address|
-          begin
-            check_private_address(address, host)
+          check_private_address(address, host)
 
-            sock     = ::Socket.new(address.is_a?(Resolv::IPv6) ? ::Socket::AF_INET6 : ::Socket::AF_INET, ::Socket::SOCK_STREAM, 0)
-            sockaddr = ::Socket.pack_sockaddr_in(port, address.to_s)
+          sock     = ::Socket.new(address.is_a?(Resolv::IPv6) ? ::Socket::AF_INET6 : ::Socket::AF_INET, ::Socket::SOCK_STREAM, 0)
+          sockaddr = ::Socket.pack_sockaddr_in(port, address.to_s)
 
-            sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
+          sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
 
-            sock.connect_nonblock(sockaddr)
+          sock.connect_nonblock(sockaddr)
 
-            # If that hasn't raised an exception, we somehow managed to connect
-            # immediately, close pending sockets and return immediately
-            socks.each(&:close)
-            return sock
-          rescue IO::WaitWritable
-            socks << sock
-            addr_by_socket[sock] = sockaddr
-          rescue => e
-            outer_e = e
-          end
+          # If that hasn't raised an exception, we somehow managed to connect
+          # immediately, close pending sockets and return immediately
+          socks.each(&:close)
+          return sock
+        rescue IO::WaitWritable
+          socks << sock
+          addr_by_socket[sock] = sockaddr
+        rescue => e
+          outer_e = e
         end
 
         until socks.empty?
@@ -279,9 +277,7 @@ class Request
       end
 
       def private_address_exceptions
-        @private_address_exceptions = begin
-          (ENV['ALLOWED_PRIVATE_ADDRESSES'] || '').split(',').map { |addr| IPAddr.new(addr) }
-        end
+        @private_address_exceptions = (ENV['ALLOWED_PRIVATE_ADDRESSES'] || '').split(',').map { |addr| IPAddr.new(addr) }
       end
     end
   end
diff --git a/app/lib/status_finder.rb b/app/lib/status_finder.rb
index 22ced8bf8..1a7f2fe69 100644
--- a/app/lib/status_finder.rb
+++ b/app/lib/status_finder.rb
@@ -27,8 +27,6 @@ class StatusFinder
   end
 
   def verify_action!
-    unless recognized_params[:action] == 'show'
-      raise ActiveRecord::RecordNotFound
-    end
+    raise ActiveRecord::RecordNotFound unless recognized_params[:action] == 'show'
   end
 end
diff --git a/app/lib/translation_service/deepl.rb b/app/lib/translation_service/deepl.rb
index 537fd24c0..151d33d90 100644
--- a/app/lib/translation_service/deepl.rb
+++ b/app/lib/translation_service/deepl.rb
@@ -29,7 +29,7 @@ class TranslationService::DeepL < TranslationService
 
   def request(text, source_language, target_language)
     req = Request.new(:post, endpoint_url, form: { text: text, source_lang: source_language&.upcase, target_lang: target_language, tag_handling: 'html' })
-    req.add_headers('Authorization': "DeepL-Auth-Key #{@api_key}")
+    req.add_headers(Authorization: "DeepL-Auth-Key #{@api_key}")
     req
   end
 
diff --git a/app/lib/webfinger.rb b/app/lib/webfinger.rb
index 7c0c10c33..42ddef47b 100644
--- a/app/lib/webfinger.rb
+++ b/app/lib/webfinger.rb
@@ -99,7 +99,7 @@ class Webfinger
   end
 
   def standard_url
-    if @domain.end_with? ".onion"
+    if @domain.end_with? '.onion'
       "http://#{@domain}/.well-known/webfinger?resource=#{@uri}"
     else
       "https://#{@domain}/.well-known/webfinger?resource=#{@uri}"
@@ -107,7 +107,7 @@ class Webfinger
   end
 
   def host_meta_url
-    if @domain.end_with? ".onion"
+    if @domain.end_with? '.onion'
       "http://#{@domain}/.well-known/host-meta"
     else
       "https://#{@domain}/.well-known/host-meta"
diff --git a/app/models/account.rb b/app/models/account.rb
index f4631e938..bd623cff9 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -313,9 +313,7 @@ class Account < ApplicationRecord
 
         previous = old_fields.find { |item| item['value'] == attr[:value] }
 
-        if previous && previous['verified_at'].present?
-          attr[:verified_at] = previous['verified_at']
-        end
+        attr[:verified_at] = previous['verified_at'] if previous && previous['verified_at'].present?
 
         fields << attr
       end
@@ -459,13 +457,12 @@ class Account < ApplicationRecord
       return [] if text.blank?
 
       text.scan(MENTION_RE).map { |match| match.first.split('@', 2) }.uniq.filter_map do |(username, domain)|
-        domain = begin
-          if TagManager.instance.local_domain?(domain)
-            nil
-          else
-            TagManager.instance.normalize_domain(domain)
-          end
-        end
+        domain = if TagManager.instance.local_domain?(domain)
+                   nil
+                 else
+                   TagManager.instance.normalize_domain(domain)
+                 end
+
         EntityCache.instance.mention(username, domain)
       end
     end
diff --git a/app/models/account/field.rb b/app/models/account/field.rb
index 4db4cac30..98c29726d 100644
--- a/app/models/account/field.rb
+++ b/app/models/account/field.rb
@@ -25,13 +25,11 @@ class Account::Field < ActiveModelSerializers::Model
   end
 
   def value_for_verification
-    @value_for_verification ||= begin
-      if account.local?
-        value
-      else
-        extract_url_from_html
-      end
-    end
+    @value_for_verification ||= if account.local?
+                                  value
+                                else
+                                  extract_url_from_html
+                                end
   end
 
   def verifiable?
diff --git a/app/models/account_statuses_cleanup_policy.rb b/app/models/account_statuses_cleanup_policy.rb
index 49adc6ad0..14ce00abb 100644
--- a/app/models/account_statuses_cleanup_policy.rb
+++ b/app/models/account_statuses_cleanup_policy.rb
@@ -122,9 +122,7 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
       # may need to be deleted, so we'll have to start again.
       redis.del("account_cleanup:#{account.id}")
     end
-    if EXCEPTION_THRESHOLDS.map { |name| attribute_change_to_be_saved(name) }.compact.any? { |old, new| old.present? && (new.nil? || new > old) }
-      redis.del("account_cleanup:#{account.id}")
-    end
+    redis.del("account_cleanup:#{account.id}") if EXCEPTION_THRESHOLDS.map { |name| attribute_change_to_be_saved(name) }.compact.any? { |old, new| old.present? && (new.nil? || new > old) }
   end
 
   def validate_local_account
@@ -141,9 +139,7 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
     # has switched to snowflake IDs significantly over 2 years ago anyway.
     snowflake_id = Mastodon::Snowflake.id_at(min_status_age.seconds.ago, with_random: false)
 
-    if max_id.nil? || snowflake_id < max_id
-      max_id = snowflake_id
-    end
+    max_id = snowflake_id if max_id.nil? || snowflake_id < max_id
 
     Status.where(Status.arel_table[:id].lteq(max_id))
   end
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
index bce0d6e17..1ce28f5c8 100644
--- a/app/models/admin/account_action.rb
+++ b/app/models/admin/account_action.rb
@@ -166,13 +166,11 @@ class Admin::AccountAction
   end
 
   def reports
-    @reports ||= begin
-      if type == 'none'
-        with_report? ? [report] : []
-      else
-        Report.where(target_account: target_account).unresolved
-      end
-    end
+    @reports ||= if type == 'none'
+                   with_report? ? [report] : []
+                 else
+                   Report.where(target_account: target_account).unresolved
+                 end
   end
 
   def warning_preset
diff --git a/app/models/announcement.rb b/app/models/announcement.rb
index 4b2cb4c6d..898bf3efa 100644
--- a/app/models/announcement.rb
+++ b/app/models/announcement.rb
@@ -54,13 +54,11 @@ class Announcement < ApplicationRecord
   end
 
   def statuses
-    @statuses ||= begin
-      if status_ids.nil?
-        []
-      else
-        Status.where(id: status_ids, visibility: [:public, :unlisted])
-      end
-    end
+    @statuses ||= if status_ids.nil?
+                    []
+                  else
+                    Status.where(id: status_ids, visibility: [:public, :unlisted])
+                  end
   end
 
   def tags
diff --git a/app/models/backup.rb b/app/models/backup.rb
index d242fd62c..277b9395b 100644
--- a/app/models/backup.rb
+++ b/app/models/backup.rb
@@ -18,5 +18,5 @@ class Backup < ApplicationRecord
   belongs_to :user, inverse_of: :backups
 
   has_attached_file :dump
-  do_not_validate_attachment_file_type :dump
+  validates_attachment_content_type :dump, content_type: /\Aapplication/
 end
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index de8bf338f..325619774 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -151,9 +151,7 @@ module AccountInteractions
     remove_potential_friendship(other_account)
 
     # When toggling a mute between hiding and allowing notifications, the mute will already exist, so the find_or_create_by! call will return the existing Mute without updating the hide_notifications attribute. Therefore, we check that hide_notifications? is what we want and set it if it isn't.
-    if mute.hide_notifications? != notifications
-      mute.update!(hide_notifications: notifications)
-    end
+    mute.update!(hide_notifications: notifications) if mute.hide_notifications? != notifications
 
     mute
   end
diff --git a/app/models/concerns/account_merging.rb b/app/models/concerns/account_merging.rb
index 8161761fb..41071633d 100644
--- a/app/models/concerns/account_merging.rb
+++ b/app/models/concerns/account_merging.rb
@@ -21,11 +21,9 @@ module AccountMerging
 
     owned_classes.each do |klass|
       klass.where(account_id: other_account.id).find_each do |record|
-        begin
-          record.update_attribute(:account_id, id)
-        rescue ActiveRecord::RecordNotUnique
-          next
-        end
+        record.update_attribute(:account_id, id)
+      rescue ActiveRecord::RecordNotUnique
+        next
       end
     end
 
@@ -36,11 +34,9 @@ module AccountMerging
 
     target_classes.each do |klass|
       klass.where(target_account_id: other_account.id).find_each do |record|
-        begin
-          record.update_attribute(:target_account_id, id)
-        rescue ActiveRecord::RecordNotUnique
-          next
-        end
+        record.update_attribute(:target_account_id, id)
+      rescue ActiveRecord::RecordNotUnique
+        next
       end
     end
 
diff --git a/app/models/concerns/expireable.rb b/app/models/concerns/expireable.rb
index 4d902abcb..c64fc7d80 100644
--- a/app/models/concerns/expireable.rb
+++ b/app/models/concerns/expireable.rb
@@ -17,7 +17,7 @@ module Expireable
     end
 
     def expires_in=(interval)
-      self.expires_at = interval.present? ? interval.to_i.seconds.from_now : nil 
+      self.expires_at = interval.present? ? interval.to_i.seconds.from_now : nil
       @expires_in     = interval
     end
 
diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb
index 7d54e9d6d..b0aa5be6f 100644
--- a/app/models/concerns/omniauthable.rb
+++ b/app/models/concerns/omniauthable.rb
@@ -56,9 +56,7 @@ module Omniauthable
       user = User.new(user_params_from_auth(email, auth))
 
       begin
-        if /\A#{URI::DEFAULT_PARSER.make_regexp(%w(http https))}\z/.match?(auth.info.image)
-          user.account.avatar_remote_url = auth.info.image
-        end
+        user.account.avatar_remote_url = auth.info.image if /\A#{URI::DEFAULT_PARSER.make_regexp(%w(http https))}\z/.match?(auth.info.image)
       rescue Mastodon::UnexpectedResponseError
         user.account.avatar_remote_url = nil
       end
diff --git a/app/models/concerns/paginable.rb b/app/models/concerns/paginable.rb
index 62e39f671..b76e78c1e 100644
--- a/app/models/concerns/paginable.rb
+++ b/app/models/concerns/paginable.rb
@@ -4,7 +4,7 @@ module Paginable
   extend ActiveSupport::Concern
 
   included do
-    scope :paginate_by_max_id, ->(limit, max_id = nil, since_id = nil) {
+    scope :paginate_by_max_id, lambda { |limit, max_id = nil, since_id = nil|
       query = order(arel_table[:id].desc).limit(limit)
       query = query.where(arel_table[:id].lt(max_id)) if max_id.present?
       query = query.where(arel_table[:id].gt(since_id)) if since_id.present?
@@ -14,7 +14,7 @@ module Paginable
     # Differs from :paginate_by_max_id in that it gives the results immediately following min_id,
     # whereas since_id gives the items with largest id, but with since_id as a cutoff.
     # Results will be in ascending order by id.
-    scope :paginate_by_min_id, ->(limit, min_id = nil, max_id = nil) {
+    scope :paginate_by_min_id, lambda { |limit, min_id = nil, max_id = nil|
       query = reorder(arel_table[:id]).limit(limit)
       query = query.where(arel_table[:id].gt(min_id)) if min_id.present?
       query = query.where(arel_table[:id].lt(max_id)) if max_id.present?
diff --git a/app/models/concerns/pam_authenticable.rb b/app/models/concerns/pam_authenticable.rb
index 6169d4dfa..f97f986a4 100644
--- a/app/models/concerns/pam_authenticable.rb
+++ b/app/models/concerns/pam_authenticable.rb
@@ -42,13 +42,11 @@ module PamAuthenticable
     def self.pam_get_user(attributes = {})
       return nil unless attributes[:email]
 
-      resource = begin
-        if Devise.check_at_sign && !attributes[:email].index('@')
-          joins(:account).find_by(accounts: { username: attributes[:email] })
-        else
-          find_by(email: attributes[:email])
-        end
-      end
+      resource = if Devise.check_at_sign && !attributes[:email].index('@')
+                   joins(:account).find_by(accounts: { username: attributes[:email] })
+                 else
+                   find_by(email: attributes[:email])
+                 end
 
       if resource.nil?
         resource = new(email: attributes[:email], agreement: true)
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb
index 10a0e5102..3a56e4f2a 100644
--- a/app/models/email_domain_block.rb
+++ b/app/models/email_domain_block.rb
@@ -69,13 +69,11 @@ class EmailDomainBlock < ApplicationRecord
 
     def extract_uris(domain_or_domains)
       Array(domain_or_domains).map do |str|
-        domain = begin
-          if str.include?('@')
-            str.split('@', 2).last
-          else
-            str
-          end
-        end
+        domain = if str.include?('@')
+                   str.split('@', 2).last
+                 else
+                   str
+                 end
 
         Addressable::URI.new.tap { |u| u.host = domain.strip } if domain.present?
       rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index 62a96528d..d692891d8 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -93,13 +93,11 @@ class Form::AdminSettings
     define_method(key) do
       return instance_variable_get("@#{key}") if instance_variable_defined?("@#{key}")
 
-      stored_value = begin
-        if UPLOAD_KEYS.include?(key)
-          SiteUpload.where(var: key).first_or_initialize(var: key)
-        else
-          Setting.public_send(key)
-        end
-      end
+      stored_value = if UPLOAD_KEYS.include?(key)
+                       SiteUpload.where(var: key).first_or_initialize(var: key)
+                     else
+                       Setting.public_send(key)
+                     end
 
       instance_variable_set("@#{key}", stored_value)
     end
diff --git a/app/models/form/custom_emoji_batch.rb b/app/models/form/custom_emoji_batch.rb
index f4fa84c10..484415f90 100644
--- a/app/models/form/custom_emoji_batch.rb
+++ b/app/models/form/custom_emoji_batch.rb
@@ -36,13 +36,11 @@ class Form::CustomEmojiBatch
   def update!
     custom_emojis.each { |custom_emoji| authorize(custom_emoji, :update?) }
 
-    category = begin
-      if category_id.present?
-        CustomEmojiCategory.find(category_id)
-      elsif category_name.present?
-        CustomEmojiCategory.find_or_create_by!(name: category_name)
-      end
-    end
+    category = if category_id.present?
+                 CustomEmojiCategory.find(category_id)
+               elsif category_name.present?
+                 CustomEmojiCategory.find_or_create_by!(name: category_name)
+               end
 
     custom_emojis.each do |custom_emoji|
       custom_emoji.update(category_id: category&.id)
diff --git a/app/models/notification.rb b/app/models/notification.rb
index bbc63c1c0..01155c363 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -87,13 +87,11 @@ class Notification < ApplicationRecord
 
   class << self
     def browserable(types: [], exclude_types: [], from_account_id: nil)
-      requested_types = begin
-        if types.empty?
-          TYPES
-        else
-          types.map(&:to_sym) & TYPES
-        end
-      end
+      requested_types = if types.empty?
+                          TYPES
+                        else
+                          types.map(&:to_sym) & TYPES
+                        end
 
       requested_types -= exclude_types.map(&:to_sym)
 
diff --git a/app/models/remote_follow.rb b/app/models/remote_follow.rb
index 911c06713..10715ac97 100644
--- a/app/models/remote_follow.rb
+++ b/app/models/remote_follow.rb
@@ -36,13 +36,11 @@ class RemoteFollow
 
     username, domain = value.strip.gsub(/\A@/, '').split('@')
 
-    domain = begin
-      if TagManager.instance.local_domain?(domain)
-        nil
-      else
-        TagManager.instance.normalize_domain(domain)
-      end
-    end
+    domain = if TagManager.instance.local_domain?(domain)
+               nil
+             else
+               TagManager.instance.normalize_domain(domain)
+             end
 
     [username, domain].compact.join('@')
   rescue Addressable::URI::InvalidURIError
diff --git a/app/models/status.rb b/app/models/status.rb
index 4e4d960a4..c17921333 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -104,12 +104,12 @@ class Status < ApplicationRecord
   scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) }
   scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
   scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).where('accounts.domain IS NULL OR accounts.domain NOT IN (?)', account.excluded_from_timeline_domains) }
-  scope :tagged_with_all, ->(tag_ids) {
+  scope :tagged_with_all, lambda { |tag_ids|
     Array(tag_ids).map(&:to_i).reduce(self) do |result, id|
       result.joins("INNER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}")
     end
   }
-  scope :tagged_with_none, ->(tag_ids) {
+  scope :tagged_with_none, lambda { |tag_ids|
     where('NOT EXISTS (SELECT * FROM statuses_tags forbidden WHERE forbidden.status_id = statuses.id AND forbidden.tag_id IN (?))', tag_ids)
   }
 
@@ -415,13 +415,12 @@ class Status < ApplicationRecord
       return [] if text.blank?
 
       text.scan(FetchLinkCardService::URL_PATTERN).map(&:second).uniq.filter_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 = if TagManager.instance.local_url?(url)
+                   ActivityPub::TagManager.instance.uri_to_resource(url, Status)
+                 else
+                   EntityCache.instance.status(url)
+                 end
+
         status&.distributable? ? status : nil
       end
     end
diff --git a/app/models/status_edit.rb b/app/models/status_edit.rb
index c2330c04f..18095b4e6 100644
--- a/app/models/status_edit.rb
+++ b/app/models/status_edit.rb
@@ -52,14 +52,12 @@ class StatusEdit < ApplicationRecord
   def ordered_media_attachments
     return @ordered_media_attachments if defined?(@ordered_media_attachments)
 
-    @ordered_media_attachments = begin
-      if ordered_media_attachment_ids.nil?
-        []
-      else
-        map = status.media_attachments.index_by(&:id)
-        ordered_media_attachment_ids.map.with_index { |media_attachment_id, index| PreservedMediaAttachment.new(media_attachment: map[media_attachment_id], description: media_descriptions[index]) }
-      end
-    end
+    @ordered_media_attachments = if ordered_media_attachment_ids.nil?
+                                   []
+                                 else
+                                   map = status.media_attachments.index_by(&:id)
+                                   ordered_media_attachment_ids.map.with_index { |media_attachment_id, index| PreservedMediaAttachment.new(media_attachment: map[media_attachment_id], description: media_descriptions[index]) }
+                                 end
   end
 
   def proper
diff --git a/app/models/system_key.rb b/app/models/system_key.rb
index f17db7c2d..1be399dd6 100644
--- a/app/models/system_key.rb
+++ b/app/models/system_key.rb
@@ -14,7 +14,7 @@ class SystemKey < ApplicationRecord
 
   before_validation :set_key
 
-  scope :expired, ->(now = Time.now.utc) { where(arel_table[:created_at].lt(now - ROTATION_PERIOD * 3)) }
+  scope :expired, ->(now = Time.now.utc) { where(arel_table[:created_at].lt(now - (ROTATION_PERIOD * 3))) }
 
   class << self
     def current_key
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 47a05d00a..98001d60a 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -49,7 +49,7 @@ class Tag < ApplicationRecord
   scope :listable, -> { where(listable: [true, nil]) }
   scope :trendable, -> { Setting.trendable_by_default ? where(trendable: [true, nil]) : where(trendable: true) }
   scope :not_trendable, -> { where(trendable: false) }
-  scope :recently_used, ->(account) {
+  scope :recently_used, lambda { |account|
                           joins(:statuses)
                             .where(statuses: { id: account.statuses.select(:id).limit(1000) })
                             .group(:id).order(Arel.sql('count(*) desc'))
diff --git a/app/models/trends/links.rb b/app/models/trends/links.rb
index 8808b3ab6..c94f7c023 100644
--- a/app/models/trends/links.rb
+++ b/app/models/trends/links.rb
@@ -113,13 +113,11 @@ class Trends::Links < Trends::Base
       max_score = preview_card.max_score
       max_score = 0 if max_time.nil? || max_time < (at_time - options[:max_score_cooldown])
 
-      score = begin
-        if expected > observed || observed < options[:threshold]
-          0
-        else
-          ((observed - expected)**2) / expected
-        end
-      end
+      score = if expected > observed || observed < options[:threshold]
+                0
+              else
+                ((observed - expected)**2) / expected
+              end
 
       if score > max_score
         max_score = score
@@ -129,13 +127,11 @@ class Trends::Links < Trends::Base
         preview_card.update_columns(max_score: max_score, max_score_at: max_time)
       end
 
-      decaying_score = begin
-        if max_score.zero? || !valid_locale?(preview_card.language)
-          0
-        else
-          max_score * (0.5**((at_time.to_f - max_time.to_f) / options[:max_score_halflife].to_f))
-        end
-      end
+      decaying_score = if max_score.zero? || !valid_locale?(preview_card.language)
+                         0
+                       else
+                         max_score * (0.5**((at_time.to_f - max_time.to_f) / options[:max_score_halflife].to_f))
+                       end
 
       [decaying_score, preview_card]
     end
diff --git a/app/models/trends/statuses.rb b/app/models/trends/statuses.rb
index 14a05e6d8..d4d5b1c24 100644
--- a/app/models/trends/statuses.rb
+++ b/app/models/trends/statuses.rb
@@ -99,21 +99,17 @@ class Trends::Statuses < Trends::Base
       expected  = 1.0
       observed  = (status.reblogs_count + status.favourites_count).to_f
 
-      score = begin
-        if expected > observed || observed < options[:threshold]
-          0
-        else
-          ((observed - expected)**2) / expected
-        end
-      end
-
-      decaying_score = begin
-        if score.zero? || !eligible?(status)
-          0
-        else
-          score * (0.5**((at_time.to_f - status.created_at.to_f) / options[:score_halflife].to_f))
-        end
-      end
+      score = if expected > observed || observed < options[:threshold]
+                0
+              else
+                ((observed - expected)**2) / expected
+              end
+
+      decaying_score = if score.zero? || !eligible?(status)
+                         0
+                       else
+                         score * (0.5**((at_time.to_f - status.created_at.to_f) / options[:score_halflife].to_f))
+                       end
 
       [decaying_score, status]
     end
diff --git a/app/models/trends/tag_filter.rb b/app/models/trends/tag_filter.rb
index 3b142efc4..46b747819 100644
--- a/app/models/trends/tag_filter.rb
+++ b/app/models/trends/tag_filter.rb
@@ -13,13 +13,11 @@ class Trends::TagFilter
   end
 
   def results
-    scope = begin
-      if params[:status] == 'pending_review'
-        Tag.unscoped
-      else
-        trending_scope
-      end
-    end
+    scope = if params[:status] == 'pending_review'
+              Tag.unscoped
+            else
+              trending_scope
+            end
 
     params.each do |key, value|
       next if key.to_s == 'page'
diff --git a/app/models/trends/tags.rb b/app/models/trends/tags.rb
index 19ade52ba..931532990 100644
--- a/app/models/trends/tags.rb
+++ b/app/models/trends/tags.rb
@@ -63,13 +63,11 @@ class Trends::Tags < Trends::Base
       max_score = tag.max_score
       max_score = 0 if max_time.nil? || max_time < (at_time - options[:max_score_cooldown])
 
-      score = begin
-        if expected > observed || observed < options[:threshold]
-          0
-        else
-          ((observed - expected)**2) / expected
-        end
-      end
+      score = if expected > observed || observed < options[:threshold]
+                0
+              else
+                ((observed - expected)**2) / expected
+              end
 
       if score > max_score
         max_score = score
diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb
index 6e46573ae..dfaadf5cc 100644
--- a/app/models/web/push_subscription.rb
+++ b/app/models/web/push_subscription.rb
@@ -53,25 +53,21 @@ class Web::PushSubscription < ApplicationRecord
   def associated_user
     return @associated_user if defined?(@associated_user)
 
-    @associated_user = begin
-      if user_id.nil?
-        session_activation.user
-      else
-        user
-      end
-    end
+    @associated_user = if user_id.nil?
+                         session_activation.user
+                       else
+                         user
+                       end
   end
 
   def associated_access_token
     return @associated_access_token if defined?(@associated_access_token)
 
-    @associated_access_token = begin
-      if access_token_id.nil?
-        find_or_create_access_token.token
-      else
-        access_token.token
-      end
-    end
+    @associated_access_token = if access_token_id.nil?
+                                 find_or_create_access_token.token
+                               else
+                                 access_token.token
+                               end
   end
 
   class << self
diff --git a/app/models/webauthn_credential.rb b/app/models/webauthn_credential.rb
index 7d423e38d..48abfc1d4 100644
--- a/app/models/webauthn_credential.rb
+++ b/app/models/webauthn_credential.rb
@@ -18,5 +18,5 @@ class WebauthnCredential < ApplicationRecord
   validates :external_id, uniqueness: true
   validates :nickname, uniqueness: { scope: :user_id }
   validates :sign_count,
-            numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 2**63 - 1 }
+            numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: (2**63) - 1 }
 end
diff --git a/app/presenters/tag_relationships_presenter.rb b/app/presenters/tag_relationships_presenter.rb
index c3bdbaf07..52e24314b 100644
--- a/app/presenters/tag_relationships_presenter.rb
+++ b/app/presenters/tag_relationships_presenter.rb
@@ -4,12 +4,10 @@ class TagRelationshipsPresenter
   attr_reader :following_map
 
   def initialize(tags, current_account_id = nil, **options)
-    @following_map = begin
-      if current_account_id.nil?
-        {}
-      else
-        TagFollow.select(:tag_id).where(tag_id: tags.map(&:id), account_id: current_account_id).each_with_object({}) { |f, h| h[f.tag_id] = true }.merge(options[:following_map] || {})
-      end
-    end
+    @following_map = if current_account_id.nil?
+                       {}
+                     else
+                       TagFollow.select(:tag_id).where(tag_id: tags.map(&:id), account_id: current_account_id).each_with_object({}) { |f, h| h[f.tag_id] = true }.merge(options[:following_map] || {})
+                     end
   end
 end
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index 8243a103f..938ede6bb 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -24,7 +24,6 @@ class InitialStateSerializer < ActiveModel::Serializer
     }
   end
 
-  # rubocop:disable Metrics/AbcSize
   def meta
     store = {
       streaming_api_base_url: Rails.configuration.x.streaming_api_base_url,
@@ -79,9 +78,7 @@ class InitialStateSerializer < ActiveModel::Serializer
     store[:disabled_account_id] = object.disabled_account.id.to_s if object.disabled_account
     store[:moved_to_account_id] = object.moved_to_account.id.to_s if object.moved_to_account
 
-    if Rails.configuration.x.single_user_mode
-      store[:owner] = object.owner&.id&.to_s
-    end
+    store[:owner] = object.owner&.id&.to_s if Rails.configuration.x.single_user_mode
 
     store
   end
diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb
index b95a61e89..e6c8fe4b2 100644
--- a/app/serializers/rest/account_serializer.rb
+++ b/app/serializers/rest/account_serializer.rb
@@ -16,6 +16,8 @@ class REST::AccountSerializer < ActiveModel::Serializer
   attribute :silenced, key: :limited, if: :silenced?
   attribute :noindex, if: :local?
 
+  attribute :memorial, if: :memorial?
+
   class AccountDecorator < SimpleDelegator
     def self.model_name
       Account.model_name
@@ -128,6 +130,10 @@ class REST::AccountSerializer < ActiveModel::Serializer
     object.silenced?
   end
 
+  def memorial
+    object.memorial?
+  end
+
   def roles
     if object.suspended? || object.user.nil?
       []
@@ -140,7 +146,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
     object.user_prefers_noindex?
   end
 
-  delegate :suspended?, :silenced?, :local?, to: :object
+  delegate :suspended?, :silenced?, :local?, :memorial?, to: :object
 
   def moved_and_not_nested?
     object.moved?
diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb
index c97db9c5f..41adaed80 100644
--- a/app/serializers/rest/instance_serializer.rb
+++ b/app/serializers/rest/instance_serializer.rb
@@ -96,9 +96,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
   end
 
   def registrations_message
-    if Setting.closed_registrations_message.present?
-      markdown.render(Setting.closed_registrations_message)
-    end
+    markdown.render(Setting.closed_registrations_message) if Setting.closed_registrations_message.present?
   end
 
   def markdown
diff --git a/app/services/account_search_service.rb b/app/services/account_search_service.rb
index 85538870b..dfc3a45f8 100644
--- a/app/services/account_search_service.rb
+++ b/app/services/account_search_service.rb
@@ -32,15 +32,13 @@ class AccountSearchService < BaseService
 
     return @exact_match if defined?(@exact_match)
 
-    match = begin
-      if options[:resolve]
-        ResolveAccountService.new.call(query)
-      elsif domain_is_local?
-        Account.find_local(query_username)
-      else
-        Account.find_remote(query_username, query_domain)
-      end
-    end
+    match = if options[:resolve]
+              ResolveAccountService.new.call(query)
+            elsif domain_is_local?
+              Account.find_local(query_username)
+            else
+              Account.find_remote(query_username, query_domain)
+            end
 
     match = nil if !match.nil? && !account.nil? && options[:following] && !account.following?(match)
 
diff --git a/app/services/activitypub/fetch_featured_tags_collection_service.rb b/app/services/activitypub/fetch_featured_tags_collection_service.rb
index ab047a0f8..ff1a88aa1 100644
--- a/app/services/activitypub/fetch_featured_tags_collection_service.rb
+++ b/app/services/activitypub/fetch_featured_tags_collection_service.rb
@@ -22,14 +22,12 @@ class ActivityPub::FetchFeaturedTagsCollectionService < BaseService
     collection = fetch_collection(collection['first']) if collection['first'].present?
 
     while collection.is_a?(Hash)
-      items = begin
-        case collection['type']
-        when 'Collection', 'CollectionPage'
-          collection['items']
-        when 'OrderedCollection', 'OrderedCollectionPage'
-          collection['orderedItems']
-        end
-      end
+      items = case collection['type']
+              when 'Collection', 'CollectionPage'
+                collection['items']
+              when 'OrderedCollection', 'OrderedCollectionPage'
+                collection['orderedItems']
+              end
 
       break if items.blank?
 
diff --git a/app/services/activitypub/fetch_remote_actor_service.rb b/app/services/activitypub/fetch_remote_actor_service.rb
index 8908d21e2..e8992b845 100644
--- a/app/services/activitypub/fetch_remote_actor_service.rb
+++ b/app/services/activitypub/fetch_remote_actor_service.rb
@@ -56,9 +56,7 @@ class ActivityPub::FetchRemoteActorService < BaseService
     webfinger                            = webfinger!("acct:#{confirmed_username}@#{confirmed_domain}")
     @username, @domain                   = split_acct(webfinger.subject)
 
-    unless confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
-      raise Webfinger::RedirectError, "Too many webfinger redirects for URI #{@uri} (stopped at #{@username}@#{@domain})"
-    end
+    raise Webfinger::RedirectError, "Too many webfinger redirects for URI #{@uri} (stopped at #{@username}@#{@domain})" unless confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
 
     raise Error, "Webfinger response for #{@username}@#{@domain} does not loop back to #{@uri}" if webfinger.link('self', 'href') != @uri
   rescue Webfinger::RedirectError => e
diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb
index 936737bf6..aea80f078 100644
--- a/app/services/activitypub/fetch_remote_status_service.rb
+++ b/app/services/activitypub/fetch_remote_status_service.rb
@@ -9,13 +9,11 @@ class ActivityPub::FetchRemoteStatusService < BaseService
   # Should be called when uri has already been checked for locality
   def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil, expected_actor_uri: nil, request_id: nil)
     @request_id = request_id || "#{Time.now.utc.to_i}-status-#{uri}"
-    @json = begin
-      if prefetched_body.nil?
-        fetch_resource(uri, id, on_behalf_of)
-      else
-        body_to_json(prefetched_body, compare_id: id ? uri : nil)
-      end
-    end
+    @json = if prefetched_body.nil?
+              fetch_resource(uri, id, on_behalf_of)
+            else
+              body_to_json(prefetched_body, compare_id: id ? uri : nil)
+            end
 
     return unless supported_context?
 
diff --git a/app/services/activitypub/fetch_replies_service.rb b/app/services/activitypub/fetch_replies_service.rb
index 18a27e851..4128df9ca 100644
--- a/app/services/activitypub/fetch_replies_service.rb
+++ b/app/services/activitypub/fetch_replies_service.rb
@@ -10,7 +10,7 @@ class ActivityPub::FetchRepliesService < BaseService
     @items = collection_items(collection_or_uri)
     return if @items.nil?
 
-    FetchReplyWorker.push_bulk(filtered_replies) { |reply_uri| [reply_uri, { 'request_id' => request_id}] }
+    FetchReplyWorker.push_bulk(filtered_replies) { |reply_uri| [reply_uri, { 'request_id' => request_id }] }
 
     @items
   end
diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb
index 1dc393e28..ac7372f74 100644
--- a/app/services/activitypub/process_status_update_service.rb
+++ b/app/services/activitypub/process_status_update_service.rb
@@ -80,9 +80,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
 
         # If a previously existing media attachment was significantly updated, mark
         # media attachments as changed even if none were added or removed
-        if media_attachment_parser.significantly_changes?(media_attachment)
-          @media_attachments_changed = true
-        end
+        @media_attachments_changed = true if media_attachment_parser.significantly_changes?(media_attachment)
 
         media_attachment.description          = media_attachment_parser.description
         media_attachment.focus                = media_attachment_parser.focus
diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb
index f07f407d8..68ccffc97 100644
--- a/app/services/backup_service.rb
+++ b/app/services/backup_service.rb
@@ -23,7 +23,7 @@ class BackupService < BaseService
     account.statuses.with_includes.reorder(nil).find_in_batches do |statuses|
       statuses.each do |status|
         item = serialize_payload(ActivityPub::ActivityPresenter.from_status(status), ActivityPub::ActivitySerializer, signer: @account, allow_local_only: true)
-        item.delete(:'@context')
+        item.delete(:@context)
 
         unless item[:type] == 'Announce' || item[:object][:attachment].blank?
           item[:object][:attachment].each do |attachment|
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index 4d55aa5e2..d5fa9af54 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -69,16 +69,14 @@ class FetchLinkCardService < BaseService
   end
 
   def parse_urls
-    urls = begin
-      if @status.local?
-        @status.text.scan(URL_PATTERN).map { |array| Addressable::URI.parse(array[1]).normalize }
-      else
-        document = Nokogiri::HTML(@status.text)
-        links    = document.css('a')
-
-        links.filter_map { |a| Addressable::URI.parse(a['href']) unless skip_link?(a) }.filter_map(&:normalize)
-      end
-    end
+    urls = if @status.local?
+             @status.text.scan(URL_PATTERN).map { |array| Addressable::URI.parse(array[1]).normalize }
+           else
+             document = Nokogiri::HTML(@status.text)
+             links = document.css('a')
+
+             links.filter_map { |a| Addressable::URI.parse(a['href']) unless skip_link?(a) }.filter_map(&:normalize)
+           end
 
     urls.reject { |uri| bad_url?(uri) }.first
   end
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 93a96667e..b3b279147 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -28,13 +28,11 @@ class ProcessMentionsService < BaseService
     @status.text = @status.text.gsub(Account::MENTION_RE) do |match|
       username, domain = Regexp.last_match(1).split('@')
 
-      domain = begin
-        if TagManager.instance.local_domain?(domain)
-          nil
-        else
-          TagManager.instance.normalize_domain(domain)
-        end
-      end
+      domain = if TagManager.instance.local_domain?(domain)
+                 nil
+               else
+                 TagManager.instance.normalize_domain(domain)
+               end
 
       mentioned_account = Account.find_remote(username, domain)
 
diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb
index 97f9f8e92..b73669f9d 100644
--- a/app/services/reblog_service.rb
+++ b/app/services/reblog_service.rb
@@ -20,13 +20,11 @@ class ReblogService < BaseService
 
     return reblog unless reblog.nil?
 
-    visibility = begin
-      if reblogged_status.hidden?
-        reblogged_status.visibility
-      else
-        options[:visibility] || account.user&.setting_default_privacy
-      end
-    end
+    visibility = if reblogged_status.hidden?
+                   reblogged_status.visibility
+                 else
+                   options[:visibility] || account.user&.setting_default_privacy
+                 end
 
     reblog = account.statuses.create!(reblog: reblogged_status, text: '', visibility: visibility, rate_limit: options[:with_rate_limit])
 
diff --git a/app/services/remove_from_followers_service.rb b/app/services/remove_from_followers_service.rb
index 3dac5467f..007d5b1fd 100644
--- a/app/services/remove_from_followers_service.rb
+++ b/app/services/remove_from_followers_service.rb
@@ -7,9 +7,7 @@ class RemoveFromFollowersService < BaseService
     source_account.passive_relationships.where(account_id: target_accounts).find_each do |follow|
       follow.destroy
 
-      if source_account.local? && !follow.account.local? && follow.account.activitypub?
-        create_notification(follow)
-      end
+      create_notification(follow) if source_account.local? && !follow.account.local? && follow.account.activitypub?
     end
   end
 
diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb
index 1ba372cd6..abe1534a5 100644
--- a/app/services/resolve_account_service.rb
+++ b/app/services/resolve_account_service.rb
@@ -71,13 +71,11 @@ class ResolveAccountService < BaseService
       @username, @domain = uri.strip.gsub(/\A@/, '').split('@')
     end
 
-    @domain = begin
-      if TagManager.instance.local_domain?(@domain)
-        nil
-      else
-        TagManager.instance.normalize_domain(@domain)
-      end
-    end
+    @domain = if TagManager.instance.local_domain?(@domain)
+                nil
+              else
+                TagManager.instance.normalize_domain(@domain)
+              end
 
     @uri = [@username, @domain].compact.join('@')
   end
@@ -96,9 +94,7 @@ class ResolveAccountService < BaseService
     @webfinger         = webfinger!("acct:#{confirmed_username}@#{confirmed_domain}")
     @username, @domain = split_acct(@webfinger.subject)
 
-    unless confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
-      raise Webfinger::RedirectError, "Too many webfinger redirects for URI #{uri} (stopped at #{@username}@#{@domain})"
-    end
+    raise Webfinger::RedirectError, "Too many webfinger redirects for URI #{uri} (stopped at #{@username}@#{@domain})" unless confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
   rescue Webfinger::GoneError
     @gone = true
   end
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 1a76cbb38..93b72fa0c 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -37,9 +37,7 @@ class SearchService < BaseService
   def perform_statuses_search!
     definition = parsed_query.apply(StatusesIndex.filter(term: { searchable_by: @account.id }))
 
-    if @options[:account_id].present?
-      definition = definition.filter(term: { account_id: @options[:account_id] })
-    end
+    definition = definition.filter(term: { account_id: @options[:account_id] }) if @options[:account_id].present?
 
     if @options[:min_id].present? || @options[:max_id].present?
       range      = {}
diff --git a/app/validators/domain_validator.rb b/app/validators/domain_validator.rb
index 6e4a854ff..3a951f9a7 100644
--- a/app/validators/domain_validator.rb
+++ b/app/validators/domain_validator.rb
@@ -4,13 +4,11 @@ class DomainValidator < ActiveModel::EachValidator
   def validate_each(record, attribute, value)
     return if value.blank?
 
-    domain = begin
-      if options[:acct]
-        value.split('@').last
-      else
-        value
-      end
-    end
+    domain = if options[:acct]
+               value.split('@').last
+             else
+               value
+             end
 
     record.errors.add(attribute, I18n.t('domain_validator.invalid_domain')) unless compliant?(domain)
   end
diff --git a/app/validators/existing_username_validator.rb b/app/validators/existing_username_validator.rb
index 1c5596821..45de4f4a4 100644
--- a/app/validators/existing_username_validator.rb
+++ b/app/validators/existing_username_validator.rb
@@ -4,16 +4,14 @@ class ExistingUsernameValidator < ActiveModel::EachValidator
   def validate_each(record, attribute, value)
     return if value.blank?
 
-    usernames_and_domains = begin
-      value.split(',').map do |str|
-        username, domain = str.strip.gsub(/\A@/, '').split('@', 2)
-        domain = nil if TagManager.instance.local_domain?(domain)
+    usernames_and_domains = value.split(',').map do |str|
+      username, domain = str.strip.gsub(/\A@/, '').split('@', 2)
+      domain = nil if TagManager.instance.local_domain?(domain)
 
-        next if username.blank?
+      next if username.blank?
 
-        [str, username, domain]
-      end.compact
-    end
+      [str, username, domain]
+    end.compact
 
     usernames_with_no_accounts = usernames_and_domains.filter_map do |(str, username, domain)|
       str unless Account.find_remote(username, domain)
diff --git a/app/validators/import_validator.rb b/app/validators/import_validator.rb
index cbad56df6..782baf5d6 100644
--- a/app/validators/import_validator.rb
+++ b/app/validators/import_validator.rb
@@ -35,13 +35,11 @@ class ImportValidator < ActiveModel::Validator
   def validate_following_import(import, row_count)
     base_limit = FollowLimitValidator.limit_for_account(import.account)
 
-    limit = begin
-      if import.overwrite?
-        base_limit
-      else
-        base_limit - import.account.following_count
-      end
-    end
+    limit = if import.overwrite?
+              base_limit
+            else
+              base_limit - import.account.following_count
+            end
 
     import.errors.add(:data, I18n.t('users.follow_limit_reached', limit: base_limit)) if row_count > limit
   end
diff --git a/app/workers/backup_worker.rb b/app/workers/backup_worker.rb
index 7b0b52844..df933142a 100644
--- a/app/workers/backup_worker.rb
+++ b/app/workers/backup_worker.rb
@@ -9,12 +9,10 @@ class BackupWorker
     backup_id = msg['args'].first
 
     ActiveRecord::Base.connection_pool.with_connection do
-      begin
-        backup = Backup.find(backup_id)
-        backup.destroy
-      rescue ActiveRecord::RecordNotFound
-        true
-      end
+      backup = Backup.find(backup_id)
+      backup.destroy
+    rescue ActiveRecord::RecordNotFound
+      true
     end
   end
 
diff --git a/app/workers/concerns/exponential_backoff.rb b/app/workers/concerns/exponential_backoff.rb
index f2b931e33..7626b2151 100644
--- a/app/workers/concerns/exponential_backoff.rb
+++ b/app/workers/concerns/exponential_backoff.rb
@@ -5,7 +5,7 @@ module ExponentialBackoff
 
   included do
     sidekiq_retry_in do |count|
-      15 + 10 * (count**4) + rand(10 * (count**4))
+      15 + (10 * (count**4)) + rand(10 * (count**4))
     end
   end
 end
diff --git a/app/workers/post_process_media_worker.rb b/app/workers/post_process_media_worker.rb
index 24201101c..996d5def9 100644
--- a/app/workers/post_process_media_worker.rb
+++ b/app/workers/post_process_media_worker.rb
@@ -9,13 +9,11 @@ class PostProcessMediaWorker
     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
+      media_attachment = MediaAttachment.find(media_attachment_id)
+      media_attachment.processing = :failed
+      media_attachment.save
+    rescue ActiveRecord::RecordNotFound
+      true
     end
 
     Sidekiq.logger.error("Processing media attachment #{media_attachment_id} failed with #{msg['error_message']}")
diff --git a/app/workers/scheduler/follow_recommendations_scheduler.rb b/app/workers/scheduler/follow_recommendations_scheduler.rb
index 57f78170e..04008a9d9 100644
--- a/app/workers/scheduler/follow_recommendations_scheduler.rb
+++ b/app/workers/scheduler/follow_recommendations_scheduler.rb
@@ -19,13 +19,11 @@ class Scheduler::FollowRecommendationsScheduler
     fallback_recommendations = FollowRecommendation.order(rank: :desc).limit(SET_SIZE)
 
     Trends.available_locales.each do |locale|
-      recommendations = begin
-        if AccountSummary.safe.filtered.localized(locale).exists? # We can skip the work if no accounts with that language exist
-          FollowRecommendation.localized(locale).order(rank: :desc).limit(SET_SIZE).map { |recommendation| [recommendation.account_id, recommendation.rank] }
-        else
-          []
-        end
-      end
+      recommendations = if AccountSummary.safe.filtered.localized(locale).exists? # We can skip the work if no accounts with that language exist
+                          FollowRecommendation.localized(locale).order(rank: :desc).limit(SET_SIZE).map { |recommendation| [recommendation.account_id, recommendation.rank] }
+                        else
+                          []
+                        end
 
       # Use language-agnostic results if there are not enough language-specific ones
       missing = SET_SIZE - recommendations.size
diff --git a/config.ru b/config.ru
index d7295e476..5e071f530 100644
--- a/config.ru
+++ b/config.ru
@@ -1,5 +1,5 @@
 # frozen_string_literal: true
 # This file is used by Rack-based servers to start the application.
 
-require ::File.expand_path('config/environment', __dir__)
+require File.expand_path('config/environment', __dir__)
 run Rails.application
diff --git a/config/locales/activerecord.de.yml b/config/locales/activerecord.de.yml
index 7e49ed1e1..fc46d0918 100644
--- a/config/locales/activerecord.de.yml
+++ b/config/locales/activerecord.de.yml
@@ -11,7 +11,7 @@ de:
         locale: Sprache
         password: Passwort
       user/account:
-        username: Benutzername
+        username: Profilname
       user/invite_request:
         text: Begründung
     errors:
@@ -43,12 +43,12 @@ de:
               blocked: verwendet einen unerlaubten E-Mail-Anbieter
               unreachable: scheint nicht zu existieren
             role_id:
-              elevated: kann nicht höher als Ihre aktuelle Rolle sein
+              elevated: kann nicht höher als deine derzeitige Rolle sein
         user_role:
           attributes:
             permissions_as_keys:
               dangerous: enthält Berechtigungen, welche nicht sicher sind für die Basisrolle
-              elevated: kann nicht Berechtigungen beinhalten, die deine aktuelle Rolle nicht besitzt
+              elevated: kann keine Berechtigungen enthalten, die deine aktuelle Rolle nicht besitzt
               own_role: kann nicht mit deiner aktuellen Rolle geändert werden
             position:
               elevated: kann nicht höher sein als deine aktuelle Rolle
diff --git a/config/locales/activerecord.el.yml b/config/locales/activerecord.el.yml
index b285e457a..4eae3b6a0 100644
--- a/config/locales/activerecord.el.yml
+++ b/config/locales/activerecord.el.yml
@@ -21,6 +21,14 @@ el:
             username:
               invalid: μόνο γράμματα, αριθμοί και κάτω παύλες
               reserved: είναι δεσμευμένο
+        admin/webhook:
+          attributes:
+            url:
+              invalid: δεν είναι έγκυρο URL
+        doorkeeper/application:
+          attributes:
+            website:
+              invalid: δεν είναι έγκυρο URL
         import:
           attributes:
             data:
@@ -34,9 +42,14 @@ el:
             email:
               blocked: χρησιμοποιεί μη επιτρεπόμενο πάροχο e-mail
               unreachable: δεν φαίνεται να υπάρχει
+            role_id:
+              elevated: δεν μπορεί να είναι μεγαλύτερο από τον τρέχοντα ρόλο σας
         user_role:
           attributes:
             permissions_as_keys:
+              dangerous: προσθήκη δικαιωμάτων που δεν είναι ασφαλή για τον βασικό ρόλο
+              elevated: δεν είναι δυνατή η προσθήκη δικαιωμάτων που ο τρέχων ρόλος σας δεν κατέχει
               own_role: δεν μπορεί να αλλάξει με τον τρέχοντα ρόλο σας
             position:
+              elevated: δεν μπορεί να είναι μεγαλύτερο από τον τρέχοντα ρόλο σας
               own_role: δεν μπορεί να αλλάξει με τον τρέχοντα ρόλο σας
diff --git a/config/locales/activerecord.my.yml b/config/locales/activerecord.my.yml
index 6aba9d49b..d5044bb6c 100644
--- a/config/locales/activerecord.my.yml
+++ b/config/locales/activerecord.my.yml
@@ -19,9 +19,37 @@ my:
         account:
           attributes:
             username:
-              invalid: အက္ခရာစာလုံး၊ ဂဏန်းနံပါတ်နှင့်underscores သာပါရမည်
-              reserved: အသုံးပြုပြီးဖြစ်သည်
+              invalid: တွင် အက္ခရာစာလုံး၊ ဂဏန်းနံပါတ်နှင့်underscores သာပါရမည်
+              reserved: သည် အသုံးပြုပြီးဖြစ်သည်
+        admin/webhook:
+          attributes:
+            url:
+              invalid: သည် မှန်ကန်သော URL မဟုတ်ပါ
+        doorkeeper/application:
+          attributes:
+            website:
+              invalid: သည် မှန်ကန်သော URL မဟုတ်ပါ
+        import:
+          attributes:
+            data:
+              malformed: သည် ပုံမှန်မဟုတ်ပါ
+        status:
+          attributes:
+            reblog:
+              taken: ပို့စ်တည်ရှိနှင့်ပြီးဖြစ်သည်
         user:
           attributes:
             email:
-              unreachable: တည်ရှိပုံ မပေါ်ပါ
+              blocked: တွင် ခွင့်မပြုထားသော အီးမေးလ်ထောက်ပံ့သူပါဝင်နေသည်။
+              unreachable: သည် တည်ရှိပုံ မပေါ်ပါ
+            role_id:
+              elevated: သင့်လက်ရှိအခန်းကဏ္ဍထက်ပို၍ မမြှင့်တင်နိုင်ပါ
+        user_role:
+          attributes:
+            permissions_as_keys:
+              dangerous: အခြေခံအခန်းကဏ္ဍအတွက် လုံခြုံမှုမရှိသော ခွင့်ပြုချက်များပါဝင်နေသည်
+              elevated: သင့်လက်ရှိအခန်းကဏ္ဍမပိုင်ဆိုင်သော ခွင့်ပြုချက်များမပါဝင်ပါ
+              own_role: သင့်လက်ရှိအခန်းကဏ္ဍဖြင့် ပြောင်းလဲ၍မရနိုင်ပါ
+            position:
+              elevated: သင့်လက်ရှိအခန်းကဏ္ဍထက်ပို၍ မမြှင့်တင်နိုင်ပါ
+              own_role: သင့်လက်ရှိအခန်းကဏ္ဍဖြင့် ပြောင်းလဲ၍မရနိုင်ပါ
diff --git a/config/locales/activerecord.zh-TW.yml b/config/locales/activerecord.zh-TW.yml
index 002ca9519..4b8e5e4de 100644
--- a/config/locales/activerecord.zh-TW.yml
+++ b/config/locales/activerecord.zh-TW.yml
@@ -4,7 +4,7 @@ zh-TW:
     attributes:
       poll:
         expires_at: 截止時間
-        options: 選擇
+        options: 選項
       user:
         agreement: 服務同意書
         email: 電子郵件地址
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index ad2797592..e9a7c3374 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -1,7 +1,7 @@
 ---
 ar:
   about:
-    about_mastodon_html: 'شبكة التواصل الإجتماعية المستقبَليّة: مِن دون إعلانات ، غير خاضعة لرقابة الشركات ، تصميم أخلاقي ولامركزية! بياناتكم مِلك لكم مع ماستدون!'
+    about_mastodon_html: 'شبكة التواصل الاجتماعية المستقبَليّة: مِن دون إعلانات، وغير خاضعة لرقابة الشركات، ذات تصميم أخلاقي ولامركزية! بياناتكم مِلك لكم مع ماستدون!'
     contact_missing: لم يتم تعيينه
     contact_unavailable: غير متوفر
     hosted_on: ماستدون مُستضاف على %{domain}
@@ -359,6 +359,13 @@ ar:
         other: "<strong>%{count}</strong> تقارير معلقة"
         two: "<strong>%{count}</strong> مستخدمين معلقين"
         zero: "<strong>%{count}</strong> وسماً معلقاً"
+      pending_reports_html:
+        few: "<strong>%{count}</strong> تقارير قيد الإنتظار"
+        many: "<strong>%{count}</strong> تقريرًا قيد الإنتظار"
+        one: "<strong>%{count}</strong> تقرير واحد قيد الإنتظار"
+        other: "<strong>%{count}</strong> تقرير قيد الانتظار"
+        two: "<strong>%{count}</strong> تقريران قيد الانتظار"
+        zero: "<strong>%{count}</strong> تقارير قيد الانتظار"
       resolved_reports: تقارير تم حلها
       software: البرنامج
       sources: مصادر التسجيل
@@ -582,7 +589,9 @@ ar:
         mark_as_sensitive_description_html: سيتم تحديد الوسائط في المناشير المبلّغ عنها على أنها محتوى حساس وسيتم تسجيل إنذار لمساعدتك في التعامل المستقبلي مع أي مخالفة جديدة من نفس الحساب.
         other_description_html: عرض المزيد من الخيارات للتحكم في االحسابات وتخصيص التواصل مع الحسابات المُبلّغ عنها.
         resolve_description_html: ولن يُتخذ أي إجراء ضد الحساب المبلّغ عنه، ولن تسلَّط عليه أية عقوبة، وسوف يُغلق التقرير.
+        silence_description_html: الحساب سيظهر فقط لمن يتابعه أو قام بالبحث عنه بشكل مباشر مما يخفض إمكانية رؤيته بشكل شبه كامل. يمكنك دائما التراجع عن هذا الإجراء. تُغلَق كافة الإبلاغات عن هذا الحساب.
       actions_description_html: تحديد الإجراءات التي يتعين اتخاذها لحل هذا التبليغ. إذا اتخذت إجراء عقابيا ضد الحساب المبلغ عنه، فسيتم إرسال إشعار بالبريد الإلكتروني إليهم، إلا عندما يتم تحديد فئة <strong>البريد المزعج.</strong>
+      actions_description_remote_html: حدّد الإجراءات التي يتعين اتخاذها لحل هذا التقرير. هذا سيؤثر فقط على كيفية اتصال <strong>خادمك</strong> بهذا الحساب البعيد والتعامل مع محتوياته.
       add_to_report: أضف المزيد إلى التقرير
       are_you_sure: هل أنت متأكد ؟
       assign_to_self: عين لي
@@ -624,6 +633,8 @@ ar:
       statuses: المحتوى المبلغ عنه
       statuses_description_html: سيشار إلى المحتوى المخالف في الاتصال بالحساب المبلغ عنه
       summary:
+        action_preambles:
+          suspend_html: 'أنت على وشك <strong>تعليق</strong> حساب <strong>@%{acct}</strong>. هذا سوف:'
         actions:
           delete_html: إزالة المنشورات المُخالِفة
           mark_as_sensitive_html: تصنيف وسائط المنشورات المُخالفة كحساسة
@@ -657,6 +668,13 @@ ar:
       edit: تعديل رتبة '%{name}' '
       everyone: الصلاحيات الافتراضية
       everyone_full_description_html: هذا هو <strong>الدور الأساسي</strong> الذي يحمله <strong>جميع المستخدمين</strong>، حتى أولئك الذين ليس لديهم دور معين. جميع الأدوار الأخرى ترث الأذونات منه.
+      permissions_count:
+        few: "%{count} تصريحات"
+        many: "%{count} تصريحًا"
+        one: تصريح واحد %{count}
+        other: "%{count} تصريح"
+        two: تصريحان %{count}
+        zero: لا تصريح %{count}
       privileges:
         administrator: مدير
         administrator_description: المستخدمين الذين لديهم هذا التصريح سيتجاوزون جميع التصاريح
@@ -716,7 +734,7 @@ ar:
         preamble: تخصيص واجهة الويب لماستدون.
         title: المظهر
       branding:
-        preamble: العلامة التجارية للخادم الخاص بك تميزه عن الخوادم الأخرى في الشبكة. يمكن عرض هذه المعلومات عبر مجموعة متنوعة من البيئات، مثل واجهة الويب لماستدون, التطبيقات الأصلية، في معاينات الرابط على مواقع الويب الأخرى وداخل تطبيقات الرسائل، وما إلى ذلك. ولهذا السبب، من الأفضل إبقاء هذه المعلومات واضحة وقصيرة وموجزة.
+        preamble: العلامة التجارية لخادمك الخاص تميزه عن الخوادم الأخرى في الشبكة. يمكن عرض هذه المعلومات عبر مجموعة متنوعة من البيئات، مثل واجهة الويب لماستدون، في التطبيقات الأصلية، في معاينات الروابط على مواقع الويب الأخرى وضمن تطبيقات الرسائل، وما إلى ذلك. ولهذا السبب، من الأفضل إبقاء هذه المعلومات واضحة وقصيرة وموجزة.
         title: العلامة
       content_retention:
         preamble: التحكم في كيفية تخزين المحتوى الذي ينشئه المستخدم في ماستدون.
@@ -726,7 +744,7 @@ ar:
         title: عدم السماح مبدئيا لمحركات البحث بفهرسة الملفات التعريفية للمستخدمين
       discovery:
         follow_recommendations: اتبع التوصيات
-        preamble: تصفح المحتوى المثير للاهتمام أمر مهم في إستقبال المستخدمين الجدد الذين قد لا يعرفون أي شخص ماستدون. التحكم في كيفية عمل ميزات الاكتشاف المختلفة على الخادم الخاص بك.
+        preamble: يُعد إتاحة رؤية المحتوى المثير للاهتمام أمرًا ضروريًا لجذب مستخدمين جدد قد لا يعرفون أي شخص في Mastodon. تحكم في كيفية عمل ميزات الاكتشاف المختلفة على خادمك الخاص.
         profile_directory: دليل الصفحات التعريفية
         public_timelines: الخيوط الزمنية العامة
         publish_discovered_servers: نشر الخوادم المكتشَفة
@@ -953,7 +971,7 @@ ar:
     description:
       prefix_invited_by_user: يدعوك @%{name} للاتحاق بخادم ماستدون هذا!
       prefix_sign_up: أنشئ حسابًا على ماستدون اليوم!
-      suffix: بفضل حساب ، ستكون قادرا على متابعة الأشخاص ونشر تحديثات وتبادل رسائل مع مستخدمين مِن أي خادم Mastodon وأكثر!
+      suffix: بفضل حساب، ستكون قادرا على متابعة أشخاص ونشر تحديثات وتبادل رسائل مع مستخدمين مِن أي خادم Mastodon وأكثر!
     didnt_get_confirmation: لم تتلق تعليمات التأكيد ؟
     dont_have_your_security_key: ليس لديك مفتاح الأمان الخاص بك؟
     forgot_password: نسيت كلمة المرور ؟
@@ -1153,6 +1171,13 @@ ar:
         other: "%{count} كلمة مفتاحية"
         two: كلمتان مفتاحيتان %{count}
         zero: "%{count} كلمة مفتاحية"
+      statuses:
+        few: "%{count} منشورات"
+        many: "%{count} منشورًا"
+        one: "%{count} منشور واحد"
+        other: "%{count} منشور"
+        two: "%{count} منشوران اثنان"
+        zero: "%{count} منشورات"
       title: عوامل التصفية
     new:
       save: حفظ عامل التصفية الجديد
diff --git a/config/locales/ast.yml b/config/locales/ast.yml
index c7d09ddf0..d4e3fe20e 100644
--- a/config/locales/ast.yml
+++ b/config/locales/ast.yml
@@ -18,11 +18,15 @@ ast:
     account_moderation_notes:
       create: Dexar la nota
     accounts:
+      add_email_domain_block: Bloquiar el dominiu de corréu electrónicu
+      approved_msg: Aprobóse correutamente la solicitú de rexistru de «%{username}»
       avatar: Avatar
       by_domain: Dominiu
+      confirming: En confirmación
       disabled: Conxelóse
       display_name: Nome visible
       domain: Dominiu
+      edit: Editar
       email: Direición de corréu electrónicu
       followers: Siguidores
       header: Testera
@@ -32,15 +36,18 @@ ast:
         local: Llocal
         remote: Remotu
         title: Llugar
+      login_status: Estáu del aniciu de la sesión
       moderation:
         pending: Pendiente
       most_recent_activity: L'actividá más recién
       most_recent_ip: La IP más recién
       perform_full_suspension: Suspender
       protocol: Protocolu
+      rejected_msg: Refugóse correutamente la solicitú de rexistru de «%{username}»
       resend_confirmation:
         already_confirmed: Esti perfil xá ta confirmáu
         send: Volver unviar el mensaxe de confirmación
+        success: "¡El mensaxe de confirmación unvióse correutamente!"
       role: Rol
       search: Buscar
       search_same_email_domain: Otros perfiles col mesmu dominiu de corréu electrónicu
@@ -60,6 +67,7 @@ ast:
         confirm_user_html: "%{name} confirmó la direición de corréu electrónicu del perfil %{target}"
         create_account_warning_html: "%{name} unvió una alvertencia a %{target}"
         create_announcement_html: "%{name} creó l'anunciu «%{target}»"
+        create_custom_emoji_html: "%{name} xubió un fustaxe nuevu «%{target}»"
         create_domain_allow_html: "%{name} permitió la federación col dominiu %{target}"
         create_domain_block_html: "%{name} bloquió'l dominiu %{target}"
         create_user_role_html: "%{name} creó'l rol «%{target}»"
@@ -72,6 +80,7 @@ ast:
         enable_custom_emoji_html: "%{name} activó'l fustaxe «%{target}»"
         reject_user_html: "%{name} refugó'l rexistru de: %{target}"
         remove_avatar_user_html: "%{name} quitó l'avatar de: %{target}"
+        resend_user_html: "%{name} volvió unviar el mensaxe de confirmación pa: %{target}"
         unblock_email_account_html: "%{name} desbloquió la direición de corréu electrónicu de: %{target}"
         update_announcement_html: "%{name} anovó l'anunciu «%{target}»"
         update_custom_emoji_html: "%{name} anovó'l fustaxe «%{target}»"
@@ -138,6 +147,7 @@ ast:
       space: Usu del espaciu
       title: Panel
       top_languages: Les llingües más actives
+      top_servers: Los sirvidores más activos
       website: Sitiu web
     disputes:
       appeals:
@@ -159,6 +169,7 @@ ast:
     export_domain_allows:
       no_file: Nun se seleicionó nengún ficheru
     follow_recommendations:
+      description_html: "<strong>La recomendación de cuentes ayuda a que los perfiles nuevos atopen aína conteníu interesante</strong>. Cuando una cuenta nun interactuó abondo con otros perfiles como pa formar recomendaciones personalizaes, estes cuentes van ser les que se recomienden. Recalcúlense caldía a partir d'un mecíu de cuentes con más actividá recién ya mayor númberu de siguidores llocales pa una llingua determinada."
       language: Pa la llingua
       status: Estáu
       title: Recomendación de cuentes
@@ -173,6 +184,16 @@ ast:
           suspend: Suspender
         policy: Política
         reason: Motivu públicu
+        title: Polítiques del conteníu
+      dashboard:
+        instance_accounts_dimension: Les cuentes más siguíes
+        instance_accounts_measure: cuentes atroxaes
+        instance_followers_measure: siguidores de nueso ellí
+        instance_follows_measure: siguidores de so equí
+        instance_languages_dimension: Les llingües más usaes
+        instance_media_attachments_measure: ficheros multimedia atroxaos
+        instance_reports_measure: informes d'esa instancia
+        instance_statuses_measure: artículos atroxaos
       empty: Nun s'atopó nengún dominiu.
       known_accounts:
         one: "%{count} cuenta conocida"
@@ -180,6 +201,10 @@ ast:
       private_comment: Comentariu priváu
       public_comment: Comentariu públicu
       title: Federación
+      total_reported: Informes d'esa instancia
+    invites:
+      deactivate_all: Desactivalo too
+      title: Invitaciones
     ip_blocks:
       expires_in:
         '1209600': 2 selmanes
@@ -215,6 +240,7 @@ ast:
       quick_actions_description_html: 'Toma una aición rápida o baxa pa ver el conteníu del que s''informó:'
       report: 'Informe #%{id}'
       reported_by: Perfil qu'informó
+      resolved: Resolvióse
       resolved_msg: "¡L'informe resolvióse correutamente!"
       skip_to_actions: Saltar a les aiciones
       status: Estáu
@@ -246,7 +272,7 @@ ast:
         manage_invites: Xestionar les invitaciones
         manage_reports: Xestionar los informes
         manage_roles: Xestionar los roles
-        manage_rules: Xestionar les regles
+        manage_rules: Xestionar les normes
         manage_settings: Xestionar la configuración
         manage_taxonomies: Xestionar les taxonomíes
         manage_users: Xestionar los perfiles
@@ -255,11 +281,11 @@ ast:
         view_devops: DevOps
       title: Roles
     rules:
-      add_new: Amestar la regla
-      title: Regles del sirvidor
+      add_new: Amestar la norma
+      title: Normes del sirvidor
     settings:
       about:
-        manage_rules: Xestionar les regles del sirvidor
+        manage_rules: Xestionar les normes del sirvidor
         title: Tocante a
       appearance:
         preamble: Personaliza la interfaz web de Mastodon.
@@ -271,7 +297,12 @@ ast:
         preamble: Controla cómo s'atroxa'l conteníu xeneráu polos perfiles en Mastodon.
         title: Retención del conteníu
       discovery:
+        follow_recommendations: Recomendación de cuentes
+        preamble: L'apaición de conteníu interesante ye fundamental p'atrayer persones nueves que nun conozan nada de Mastodon. Controla'l funcionamientu de delles funciones de descubrimientu d'esti sirvidor.
+        profile_directory: Direutoriu de perfiles
         public_timelines: Llinies de tiempu públiques
+        publish_discovered_servers: Espublizamientu de sirvidores descubiertos
+        publish_statistics: Espublizamientu d'estadístiques
         title: Descubrimientu
         trends: Tendencies
       domain_blocks:
@@ -290,6 +321,7 @@ ast:
     site_uploads:
       delete: Desaniciar el ficheru xubíu
     statuses:
+      back_to_account: Volver a la páxina de la cuenta
       language: Llingua
       metadata: Metadatos
       original_status: Artículu orixinal
@@ -307,18 +339,30 @@ ast:
         message_html: Nun se pudo conectar con Elasticsearch. Revisa que tea n'execución o desactiva la busca de testos completos
     title: Alministración
     trends:
+      allow: Permitir
+      disallow: Refugar
       links:
+        disallow: Refugar l'enllaz
         title: Enllaces en tendencia
       only_allowed: Namás lo permitío
       pending_review: Revisión pendiente
+      preview_card_providers:
+        title: Espublizadores
       statuses:
+        allow: Permitir l'artículu
+        disallow: Refugar l'artículu
         title: Artículos en tendencia
       tags:
         current_score: 'Puntuación total: %{score}'
         dashboard:
           tag_accounts_measure: usos únicos
+          tag_languages_dimension: Les llingües más usaes
+          tag_servers_dimension: Los sirvidores más destacaos
+          tag_servers_measure: sirvidores diferentes
+          tag_uses_measure: usos en total
         listable: Pue suxerise
         no_tag_selected: Nun camudó nenguna etiqueta darréu que nun se seleicionó nenguna
+        not_trendable: Nun apaez nes tendencies
         not_usable: Nun se pue usar
         title: Etiquetes en tendencia
         usable: Pue usase
@@ -372,6 +416,8 @@ ast:
       guide_link_text: tol mundu pue collaborar.
     sensitive_content: Conteníu sensible
     toot_layout: Distribución de los artículos
+  application_mailer:
+    notification_preferences: Camudar les preferencies de los mensaxes de corréu electrónicu
   applications:
     created: L'aplicación creóse correutamente
     regenerate_token: Volver xenerar el pase d'accesu
@@ -380,6 +426,8 @@ ast:
     your_token: El pase d'accesu
   auth:
     change_password: Contraseña
+    confirmations:
+      wrong_email_hint: Si la direición de corréu electrónicu nun ye correuta, pues camudala na configuración de la cuenta.
     delete_account: Desaniciu de la cuenta
     delete_account_html: Si quies desaniciar la cuenta, pues facelo <a href="%{path}">equí</a>. Va pidísete que confirmes l'aición.
     description:
@@ -390,15 +438,19 @@ ast:
     login: Aniciar la sesión
     logout: Zarrar la sesión
     migrate_account: Cambéu de cuenta
+    migrate_account_html: Si quies redirixir esta cuenta a otra diferente, pues <a href="%{path}">configurar esta opción equí</a>.
     privacy_policy_agreement_html: Lleí ya acepto la <a href="%{privacy_policy_path}" target="_blank">política de privacidá</a>
     providers:
       cas: CAS
       saml: SAML
     register: Rexistrase
     registration_closed: "%{instance} nun acepta cuentes nueves"
+    resend_confirmation: Volver unviar les instrucciones de confirmación
     security: Seguranza
     setup:
+      email_below_hint_html: Si la direición de corréu electrónicu ye incorreuta, pues camudala equí ya recibir un mensaxes de confirmación nuevu.
       email_settings_hint_html: Unvióse'l mensaxe de confirmación a %{email}. Si la direición de corréu electrónicu nun ye correuta, pues camudala na configuración de la cuenta.
+      title: Configuración
     sign_in:
       preamble_html: Anicia la sesión colos tos datos d'accesu en <strong>%{domain}</strong>. Si la cuenta ta agospiada n'otru sirvidor, nun vas ser a aniciar la sesión equí.
       title: Aniciu de la sesión en «%{domain}»
@@ -512,6 +564,8 @@ ast:
         one: "%{count} artículu"
         other: "%{count} artículos"
       title: Peñeres
+    new:
+      title: Amestar una peñera
   footer:
     trending_now: En tendencia
   generic:
@@ -522,6 +576,7 @@ ast:
     all_matching_items_selected_html:
       one: Seleicionóse <strong>%{count}</strong> elementu que concasa cola busca.
       other: Seleicionáronse <strong>%{count}</strong> elementos que concasen cola busca.
+    changes_saved_msg: "¡Los cambeos guardáronse correutamente!"
     copy: Copiar
     delete: Desaniciar
     deselect: Deseleicionar too
@@ -529,6 +584,8 @@ ast:
     save_changes: Guardar los cambeos
     today: güei
   imports:
+    errors:
+      over_rows_processing_limit: contién más de %{count} fileres
     modes:
       merge: Mecíu
       merge_long: Caltién los rexistros esistentes ya amiesta otros nuevos
@@ -537,8 +594,10 @@ ast:
     preface: Pues importar los datos qu'esportares dende otru sirvidor, como la llista de perfiles bloquiaos o que sigas.
     types:
       blocking: Llista de perfiles bloquiaos
+      bookmarks: Marcadores
       domain_blocking: Llista de dominios bloquiaos
       following: Llista de siguidores
+      muting: Llista de perfiles colos avisos desactivaos
     upload: Xubir
   invites:
     expired: Caducó
@@ -555,8 +614,11 @@ ast:
     max_uses:
       one: 1 usu
       other: "%{count} usos"
+    prompt: Xenera ya comparti enllaces con otres persones pa conceder l'accesu a esti sirvidor
     table:
       expires_at: Data de caducidá
+      uses: Usos
+    title: Invitación
   lists:
     errors:
       limit: Algamesti la cantidá máxima de llistes
@@ -564,6 +626,7 @@ ast:
     authentication_methods:
       password: contraseña
       webauthn: llaves de seguranza
+    successful_sign_in_html: Anicióse correutamente la sesión col métodu «%{method}» dende %{ip} (%{browser})
   media_attachments:
     validations:
       images_and_video: Nun se pue axuntar nengún videu a un artículu que xá contién imáxenes
@@ -572,6 +635,7 @@ ast:
     errors:
       missing_also_known_as: nun ye un nomatu d'esta cuenta
       move_to_self: nun pue ser la cuenta actual
+    incoming_migrations_html: Pa migrar d'otra cuenta a esta, primero tienes de <a href="%{path}">crear un nomatu de cuenta</a>.
     warning:
       followers: Esta aición va mover tolos siguidores de la cuenta actual a la nueva
   notification_mailer:
@@ -583,6 +647,7 @@ ast:
       subject: "%{name} marcó'l to artículu como favoritu"
     follow:
       body: "¡Agora %{name} siguete!"
+      subject: "%{name} ta siguiéndote"
     follow_request:
       body: "%{name} solicitó siguite"
       title: Solicitú de siguimientu nueva
@@ -596,6 +661,7 @@ ast:
     update:
       subject: "%{name} editó un artículu"
   notifications:
+    email_events: Unviu d'avisos per corréu electrónicu
     email_events_hint: 'Seleiciona los eventos de los que quies recibir avisos:'
     other_settings: Configuración d'otros avisos
   number:
@@ -614,7 +680,7 @@ ast:
     instructions_html: "<strong>Escania esti códigu QR con Google Authenticator o otra aplicación asemeyada nel móvil</strong>. Dende agora, esa aplicación va xenerar los pases que tienes d'introducir cuando anicies la sesión."
     manual_instructions: 'Si nun pues escaniar el códigu QR ya tienes d''introducilu manualmente, equí tienes el secretu en testu ensin formatu:'
     setup: Configurar
-    wrong_code: "¡El códigu introducíu nun yera válidu! ¿La hora del sirvidor y la del preséu son correutes?"
+    wrong_code: "¡El códigu introducíu nun yera válidu! ¿La hora del sirvidor ya la del preséu son correutes?"
   pagination:
     next: Siguiente
     truncate: "&hellip;"
@@ -625,6 +691,8 @@ ast:
       invalid_choice: La opción de votu escoyida nun esiste
       too_many_options: nun pue contener más de %{max} elementos
   preferences:
+    other: Otres preferencies
+    posting_defaults: Configuración predeterminada del espublizamientu d'artículos
     public_timelines: Llinies de tiempu públiques
   privacy_policy:
     title: Política de privacidá
@@ -633,6 +701,8 @@ ast:
     followers: Siguidores
     last_active: Última actividá
     most_recent: Lo más recién
+    mutual: Mutua
+    primary: Principal
     relationship: Rellación
     remove_selected_follows: Dexar de siguir a los perfiles seleicionaos
   scheduled_statuses:
@@ -726,6 +796,7 @@ ast:
     title: "%{name}: «%{quote}»"
     visibilities:
       direct: Mensaxe direutu
+      private: Namás siguidores
       public_long: Tol mundu pue velos
       unlisted_long: Tol mundu pue velos, mas nun apaecen nes llinies de tiempu públiques
   statuses_cleanup:
@@ -777,7 +848,7 @@ ast:
         suspend: Cuenta suspendida
     welcome:
       edit_profile_action: Configurar el perfil
-      edit_profile_step: Pues personalizar el perfil pente la xuba d'una semeya, el cambéu del nome visible y muncho más. Tamién, si lo prefieres, pues revisar los perfiles nuevos enantes de que puedan siguite.
+      edit_profile_step: Pues personalizar el perfil pente la xuba d'una semeya, el cambéu del nome visible ya muncho más. Tamién, si lo prefieres, pues revisar los perfiles nuevos enantes de que puedan siguite.
       explanation: Equí tienes dalgunos conseyos pa que comiences
       final_action: Comenzar a espublizar
       subject: Afáyate en Mastodon
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index 9127790bc..cdcf6158b 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -441,6 +441,7 @@ bg:
         private_comment_description_html: 'За по-лесно проследяване откъде идват внесените блокирания, те ще се създадат със следния личен коментар: <q>%{comment}</q>'
         private_comment_template: Внесено от %{source} на %{date}
         title: Внос на блокирания на домейни
+      invalid_domain_block: 'Едно или повече блокирания на домейн са прескочени поради следнате грешки: %{error}'
       new:
         title: Внос на блокирания на домейни
       no_file: Няма избран файл
@@ -589,6 +590,7 @@ bg:
       comment:
         none: Нищо
       comment_description_html: 'За да предостави повече информация, %{name} написа:'
+      confirm_action: Потвърждаване на модераторско действие срещу @%{acct}
       created_at: Докладвано
       delete_and_resolve: Изтриване на публикациите
       forwarded: Препратено
@@ -617,9 +619,15 @@ bg:
       status: Състояние
       statuses: Докладвано съдържание
       statuses_description_html: Непристойно съдържание ще бъде цитирано в комуникацията с докладвания акаунт
+      summary:
+        actions:
+          delete_html: Премахване на обидните публикации
+        close_report: Отбелязване на доклад №%{id} като решен
+        warning_placeholder: Незадължителни допълнителни причини за модераторско действие.
       target_origin: Произход на докладвания акаунт
       title: Доклади
       unassign: Освобождаване
+      unknown_action_msg: 'Незнайно деяние: %{action}'
       unresolved: Неразрешено
       updated_at: Обновено
       view_profile: Преглед на профила
@@ -943,6 +951,8 @@ bg:
   auth:
     apply_for_account: Заявка за акаунт
     change_password: Парола
+    confirmations:
+      wrong_email_hint: Ако този адрес на е-поща не е правилен, то може да го промените в настройки на акаунта.
     delete_account: Изтриване на акаунта
     delete_account_html: Ако желаете да изтриете акаунта си, може <a href="%{path}">да сторите това тук</a>. Ще ви се поиска потвърждение.
     description:
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index 52d1aa202..f870413a5 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -189,7 +189,7 @@ cy:
         create_account_warning: Creu Rhybydd
         create_announcement: Creu Cyhoeddiad
         create_canonical_email_block: Creu Bloc E-bost
-        create_custom_emoji: Creu Emoji Cyfaddas
+        create_custom_emoji: Creu Emoji Addasedig
         create_domain_allow: Creu Caniatáu Parth
         create_domain_block: Creu Gwaharddiad Parth
         create_email_domain_block: Creu Gwaharddiad Parth E-bost
@@ -199,7 +199,7 @@ cy:
         demote_user: Diraddio Defnyddiwr
         destroy_announcement: Dileu Cyhoeddiad
         destroy_canonical_email_block: Dileu Bloc E-bost
-        destroy_custom_emoji: Dileu Emoji Cyfaddas
+        destroy_custom_emoji: Dileu Emoji Addasedig
         destroy_domain_allow: Dileu Caniatáu Parth
         destroy_domain_block: Dileu Gwaharddiad Parth
         destroy_email_domain_block: Dileu gwaharddiad parth e-bost
@@ -209,10 +209,10 @@ cy:
         destroy_unavailable_domain: Dileu Parth Ddim ar Gael
         destroy_user_role: Dinistrio Rôl
         disable_2fa_user: Diffodd 2FA
-        disable_custom_emoji: Analluogi Emoji Cyfaddas
+        disable_custom_emoji: Analluogi Emoji Addasedig
         disable_sign_in_token_auth_user: Analluogi Dilysu Tocyn E-bost ar gyfer Defnyddiwr
         disable_user: Analluogi Defnyddiwr
-        enable_custom_emoji: Alluogi Emoji Cyfaddas
+        enable_custom_emoji: Galluogi Emoji Addasedig
         enable_sign_in_token_auth_user: Galluogi Dilysu Tocyn E-bost ar gyfer Defnyddiwr
         enable_user: Galluogi Defnyddiwr
         memorialize_account: Cofadeilio Cyfrif
@@ -233,7 +233,7 @@ cy:
         unsilence_account: Dad-gyfyngu Cyfrif
         unsuspend_account: Tynnu Ataliad Cyfrif Dros Dro
         update_announcement: Diweddaru Cyhoeddiad
-        update_custom_emoji: Diweddaru Emoji Cyfaddas
+        update_custom_emoji: Diweddaru Emoji Addasedig
         update_domain_block: Diweddaru'r Blocio Parth
         update_ip_block: Diweddaru rheol IP
         update_status: Diweddaru Postiad
@@ -1204,7 +1204,7 @@ cy:
       request: Gofynn am eich archif
       size: Maint
     blocks: Rydych chi'n blocio
-    bookmarks: Nodau Tudalen
+    bookmarks: Llyfrnodau
     csv: CSV
     domain_blocks: Blociau parth
     lists: Rhestrau
@@ -1324,7 +1324,7 @@ cy:
     success: Llwythwyd eich data yn llwyddiannus a bydd yn cael ei brosesu mewn da bryd
     types:
       blocking: Rhestr blocio
-      bookmarks: Nodau Tudalen
+      bookmarks: Llyfrnodau
       domain_blocking: Rhestr rhwystro parth
       following: Rhestr ddilynion
       muting: Rhestr tewi
@@ -1686,8 +1686,8 @@ cy:
     keep_pinned_hint: Nid yw'n dileu unrhyw un o'ch postiadau wedi'u pinio
     keep_polls: Cadw arolygon
     keep_polls_hint: Nid yw'n dileu unrhyw un o'ch arolygon
-    keep_self_bookmark: Cadw y postiadau wedi'u cadw fel nodau tudalen
-    keep_self_bookmark_hint: Nid yw'n dileu eich postiadau eich hun os ydych wedi rhoi nod tudalen arnyn nhw
+    keep_self_bookmark: Cadw y postiadau wedi'u cadw fel llyfrnodau
+    keep_self_bookmark_hint: Nid yw'n dileu eich postiadau eich hun os ydych wedi rhoi llyfrnodau arnyn nhw
     keep_self_fav: Cadw'r postiadau yr oeddech yn eu ffefrynnu
     keep_self_fav_hint: Nid yw'n dileu eich postiadau eich hun os ydych wedi eu ffefrynnu
     min_age:
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 605eb8e73..6944b54e4 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -77,7 +77,7 @@ de:
       invite_request_text: Begründung für das Beitreten
       invited_by: Eingeladen von
       ip: IP-Adresse
-      joined: Beigetreten
+      joined: Registriert
       location:
         all: Alle
         local: Lokal
@@ -392,7 +392,7 @@ de:
         create: Sperre einrichten
         hint: Die Domainsperre wird nicht verhindern, dass Konteneinträge in der Datenbank erstellt werden, sondern rückwirkend und automatisch alle Moderationsmethoden auf diese Konten anwenden.
         severity:
-          desc_html: "<strong>Stummschaltung</strong> wird die Beiträge von Konten unter dieser Domain für alle unsichtbar machen, die den Konten nicht folgen. Eine <strong>Sperre</strong> wird alle Inhalte, Medien und Profildaten für Konten dieser Domain von deinem Server entfernen. Verwende <strong>keine,</strong> um nur Mediendateien abzulehnen."
+          desc_html: "<strong>Stummschaltung</strong> wird die Beiträge von Konten unter dieser Domain für alle unsichtbar machen, die den Konten nicht folgen. Eine <strong>Sperre</strong> wird alle Inhalte, Medien und Profildaten für Konten dieser Domain von deinem Server entfernen. Verwende <strong>keine</strong>, um nur Mediendateien abzulehnen."
           noop: Kein
           silence: Stummschaltung
           suspend: Sperren
@@ -680,7 +680,7 @@ de:
         manage_custom_emojis: Eigene Emojis verwalten
         manage_custom_emojis_description: Erlaubt es Benutzer*innen, eigene Emojis auf dem Server zu verwalten
         manage_federation: Föderation verwalten
-        manage_federation_description: Erlaubt Nutzer*innen, Domains anderer Mastodon-Server zu sperren oder zuzulassen – und die Zustellbarkeit zu steuern
+        manage_federation_description: Erlaubt Benutzer*innen, Domains anderer Mastodon-Server zu sperren oder zuzulassen – und die Zustellbarkeit zu steuern
         manage_invites: Einladungen verwalten
         manage_invites_description: Erlaubt es Benutzer*innen, Einladungslinks zu durchsuchen und zu deaktivieren
         manage_reports: Meldungen verwalten
diff --git a/config/locales/devise.ar.yml b/config/locales/devise.ar.yml
index 7b8820771..1d268a6d1 100644
--- a/config/locales/devise.ar.yml
+++ b/config/locales/devise.ar.yml
@@ -37,8 +37,8 @@ ar:
         title: تم تغيير كلمة السر
       reconfirmation_instructions:
         explanation: ندعوك لتأكيد العنوان الجديد قصد تعديله في بريدك.
-        extra: إن لم تكن صاحب هذا الطلب ، يُرجى عدم إعارة الاهتمام لهذه الرسالة. فعنوان البريد الإلكتروني المتعلق بحساب ماستدون سوف يبقى هو مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد تعديله.
-        subject: 'ماستدون: تأكيد كلمة السر الخاصة بـ %{instance}'
+        extra: إن لم تكن صاحب هذا الطلب، يُرجى عدم إعارة الاهتمام لهذه الرسالة. فعنوان البريد الإلكتروني المتعلق بحساب ماستدون سوف يبقى هو مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد تعديله.
+        subject: 'ماستدون: تأكيد عنوان البريد الإلكتروني الخاص بـ %{instance}'
         title: التحقق من عنوان البريد الإلكتروني
       reset_password_instructions:
         action: تغيير كلمة السر
diff --git a/config/locales/devise.ast.yml b/config/locales/devise.ast.yml
index f48c70e2d..2f84b51fb 100644
--- a/config/locales/devise.ast.yml
+++ b/config/locales/devise.ast.yml
@@ -15,10 +15,12 @@ ast:
       unconfirmed: Tienes de confirmar la direición de corréu electrónicu enantes de siguir.
     mailer:
       confirmation_instructions:
+        action: Verificar la direición de corréu electrónicu
         explanation: Creesti una cuenta en %{host} con esta direición de corréu electrónicu ya tas a un calcu d'activala. Si nun fixesti esta aición, inora esti mensaxe.
         explanation_when_pending: Solicitesti una invitación a %{host} con esta direición de corréu electrónicu. Namás que confirmes la direición de corréu electrónicu, vamos revisar la solicitú. Entrín ya non, pues aniciar la sesión pa camudar los detalles o desaniciar la cuenta, mas nun pues acceder a la mayoría de funciones hasta que la cuenta nun tea aprobada. Si se refuga la solicitú, nun ye necesario que faigas nada más o si, per otra parte, tu nun fixesti esta aición, inora esti mensaxe.
-        extra_html: Revisa tamién <a href="%{terms_path}">les regles del sirvidor</a> ya <a href="%{policy_path}">los nuesos términos del serviciu</a>.
+        extra_html: Revisa tamién <a href="%{terms_path}">les normes del sirvidor</a> ya <a href="%{policy_path}">los nuesos términos del serviciu</a>.
         subject: 'Mastodon: instrucciones de confirmación de «%{instance}»'
+        title: Verificación de la direición de corréu electrónicu
       email_changed:
         explanation: 'La direición de corréu electrónicu de la cuenta camudó a:'
         extra: Si nun camudesti la direición de corréu electrónicu, ye probable que daquién accediere a la cuenta. Camuda la contraseña agora mesmo o ponte en contautu cola alministración del sirvidor si nun yes a acceder a la cuenta.
diff --git a/config/locales/devise.my.yml b/config/locales/devise.my.yml
index 5e1fc6bee..6ae910da0 100644
--- a/config/locales/devise.my.yml
+++ b/config/locales/devise.my.yml
@@ -1 +1,58 @@
+---
 my:
+  devise:
+    confirmations:
+      confirmed: သင်၏ အီးမေးလ်လိပ်စာ အောင်မြင်စွာအတည်ပြုပြီးပါပြီ။
+    failure:
+      invalid: မှားယွင်းသော %{authentication_keys} သို့မဟုတ် စကားဝှက် ဖြစ်ပါသည်။
+      not_found_in_database: မှားယွင်းသော %{authentication_keys} သို့မဟုတ် စကားဝှက် ဖြစ်ပါသည်။
+    mailer:
+      confirmation_instructions:
+        action: အီးမေးလ်လိပ်စာကို အတည်ပြုပါ
+        action_with_app: အတည်ပြုပြီး %{app} သို့ပြန်သွားပါ
+        title: အီးမေးလ်လိပ်စာကို အတည်ပြုပါ
+      email_changed:
+        subject: 'Mastodon: အီးမေးလ်ပြောင်းလဲသွားပြီ'
+        title: အီးမေးလ်လိပ်စာအသစ်
+      password_change:
+        subject: 'Mastodon: စကားဝှက်ပြောင်းလဲသွားပြီ'
+        title: စကားဝှက်ပြောင်းလဲသွားပြီ
+      reconfirmation_instructions:
+        explanation: သင်၏အီးမေးလ်လိပ်စာပြောင်းရန် လိပ်စာအသစ်အတည်ပြုပါ။
+        subject: 'Mastodon: %{instance} အတွက်အီးမေးလ်အတည်ပြုပါ'
+        title: အီးမေးလ်လိပ်စာစစ်ဆေးပါ
+      reset_password_instructions:
+        action: စကားဝှက်ပြောင်းမည်
+        subject: 'Mastodon: စကားဝှက်ညွှန်ကြားချက် ပြန်လည်သတ်မှတ်မည်'
+        title: စကားဝှက်ပြန်လည်သတ်မှတ်မည်
+      two_factor_disabled:
+        subject: 'Mastodon: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ပိတ်ထားသည်'
+        title: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ပိတ်ထားသည်
+      two_factor_enabled:
+        subject: 'Mastodon: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ဖွင့်ထားသည်'
+        title: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ဖွင့်ထားသည်
+      two_factor_recovery_codes_changed:
+        title: နှစ်ဆင့်ခံလုံခြုံရေးစနစ် ပြန်လည်ရယူသည့်ကုဒ်နံပါတ်များ ပြောင်းလဲခဲ့သည်
+      webauthn_credential:
+        added:
+          explanation: ဖော်ပြပါလုံခြုံရေးသော့ချက်အား သင့်အကောင့်ထဲသို့ထည့်ပြီးပါပြီ
+          subject: 'Mastodon: လုံခြုံရေးသော့ချက်အသစ်'
+          title: လုံခြုံရေးသော့ချက်အသစ် ထည့်လိုက်ပါပြီ
+        deleted:
+          explanation: ဖော်ပြပါလုံခြုံရေးသော့ချက်အား သင့်အကောင့်ထဲမှဖျက်လိုက်ပါပြီ
+          subject: 'Mastodon: လုံခြုံရေးသော့ချက် ဖျက်လိုက်ပါပြီ'
+          title: လုံခြုံရေးသော့ချက်များထဲမှတစ်ခု ဖျက်လိုက်ပါပြီ
+      webauthn_disabled:
+        title: လုံခြုံရေးသော့ချက်များ ပိတ်ပြီးပါပြီ
+      webauthn_enabled:
+        title: လုံခြုံရေးသော့ချက်များ ဖွင့်ပြီးပါပြီ
+    registrations:
+      updated: သင့်အကောင့်အားအောင်မြင်စွာ ပြင်ဆင်ပြီးပါပြီ။
+    sessions:
+      already_signed_out: အောင်မြင်စွာအကောင့်မှထွက်ပြီးပါပြီ။
+      signed_in: အောင်မြင်စွာအကောင့်ဝင်ပြီးပါပြီ။
+      signed_out: အောင်မြင်စွာအကောင့်မှထွက်ပြီးပါပြီ။
+  errors:
+    messages:
+      expired: သည် သက်တမ်းကျော်လွန်သွားပြီ။ ကျေးဇူးပြု၍အသစ်တစ်ခု တောင်းဆိုပါ
+      not_found: ရှာမတွေ့ပါ
diff --git a/config/locales/devise.zh-TW.yml b/config/locales/devise.zh-TW.yml
index e500e1d9e..e3f5dee2a 100644
--- a/config/locales/devise.zh-TW.yml
+++ b/config/locales/devise.zh-TW.yml
@@ -49,15 +49,15 @@ zh-TW:
       two_factor_disabled:
         explanation: 您帳號的兩階段驗證已停用。現在只使用電子郵件及密碼登入。
         subject: Mastodon:已停用兩階段驗證
-        title: 已停用 2FA
+        title: 已停用兩階段驗證
       two_factor_enabled:
         explanation: 已對您的帳號啟用兩階段驗證。登入時將需要已配對的 TOTP 應用程式所產生之 Token。
         subject: Mastodon:已啟用兩階段驗證
-        title: 已啟用 2FA
+        title: 已啟用兩階段驗證
       two_factor_recovery_codes_changed:
         explanation: 之前的備用驗證碼已經失效,且已產生新的。
         subject: Mastodon:兩階段驗證備用驗證碼已經重新產生
-        title: 2FA 備用驗證碼已變更
+        title: 兩階段驗證備用驗證碼已變更
       unlock_instructions:
         subject: Mastodon:解鎖指引
       webauthn_credential:
diff --git a/config/locales/doorkeeper.ar.yml b/config/locales/doorkeeper.ar.yml
index 861a63eb4..b10f5dbeb 100644
--- a/config/locales/doorkeeper.ar.yml
+++ b/config/locales/doorkeeper.ar.yml
@@ -122,6 +122,7 @@ ar:
         admin/accounts: إدارة الحسابات
         admin/all: جميع المهام الإدارية
         admin/reports: إدارة التقارير
+        all: وصول كامل إلى حساب ماستدون الخاص بك
         blocks: تم حجبها
         bookmarks: الفواصل المرجعية
         conversations: المحادثات
diff --git a/config/locales/doorkeeper.ast.yml b/config/locales/doorkeeper.ast.yml
index 695f9e4b0..628de6524 100644
--- a/config/locales/doorkeeper.ast.yml
+++ b/config/locales/doorkeeper.ast.yml
@@ -23,6 +23,7 @@ ast:
         name: Nome
         new: Aplicación nueva
         scopes: Ámbitos
+        title: Les tos aplicaciones
       new:
         title: Aplicación nueva
       show:
@@ -66,11 +67,22 @@ ast:
         write: Accesu de namás escritura
       title:
         accounts: Cuentes
+        admin/accounts: Alministración de cuentes
         admin/all: Toles funciones alministratives
+        admin/reports: Alministración d'informes
+        all: Accesu completu a la cuenta de Mastodon
+        bookmarks: Marcadores
         conversations: Conversaciones
         crypto: Cifráu de puntu a puntu
+        favourites: Favoritos
         filters: Peñeres
+        lists: Llistes
+        media: Elementos multimedia
+        mutes: Perfiles colos avisos desativaos
         notifications: Avisos
+        reports: Informes
+        search: Busca
+        statuses: Artículos
     layouts:
       admin:
         nav:
@@ -97,6 +109,8 @@ ast:
       write: modifica los datos de les cuentes
       write:accounts: modifica los perfiles
       write:blocks: bloquia cuentes ya dominios
+      write:bookmarks: meter artículos en Marcadores
+      write:conversations: desaniciar ya desactivar los avisos de conversaciones
       write:favourites: artículos favoritos
       write:filters: crea peñeres
       write:follows: sigue a perfiles
diff --git a/config/locales/doorkeeper.cy.yml b/config/locales/doorkeeper.cy.yml
index f3da378cf..21a94acec 100644
--- a/config/locales/doorkeeper.cy.yml
+++ b/config/locales/doorkeeper.cy.yml
@@ -124,7 +124,7 @@ cy:
         admin/reports: Gweinyddu adroddiadau
         all: Mynediad llawn i'ch cyfrif Mastodon
         blocks: Blociau
-        bookmarks: Nodau Tudalen
+        bookmarks: Llyfrnodau
         conversations: Sgyrsiau
         crypto: Amgryptio o ben i ben
         favourites: Ffefrynnau
@@ -169,7 +169,7 @@ cy:
       read: darllen holl ddata eich cyfrif
       read:accounts: gweld gwybodaeth y cyfrif
       read:blocks: gweld eich blociau
-      read:bookmarks: gweld eich nodau tudalen
+      read:bookmarks: gweld eich llyfrnodau
       read:favourites: gweld eich ffefrynnau
       read:filters: gweld eich hidlwyr
       read:follows: gweld eich dilynwyr
@@ -182,7 +182,7 @@ cy:
       write: addasu holl ddata eich cyfrif
       write:accounts: addasu eich proffil
       write:blocks: blocio cyfrifon a parthau
-      write:bookmarks: gosod nod tudalen postiadau
+      write:bookmarks: llyfrnodi postiadau
       write:conversations: anwybyddu a dileu sgyrsiau
       write:favourites: hoff bostiadau
       write:filters: creu hidlwyr
diff --git a/config/locales/doorkeeper.el.yml b/config/locales/doorkeeper.el.yml
index 8084bb5b3..abb6ccd68 100644
--- a/config/locales/doorkeeper.el.yml
+++ b/config/locales/doorkeeper.el.yml
@@ -60,6 +60,8 @@ el:
       error:
         title: Εμφανίστηκε σφάλμα
       new:
+        prompt_html: Ο/Η %{client_name} θα ήθελε άδεια πρόσβασης στο λογαριασμό σας. Είναι μια εφαρμογή από τρίτους. <strong>Αν δεν το εμπιστεύεστε, τότε δεν πρέπει να το εξουσιοδοτήσετε.</strong>
+        review_permissions: Αναθεώρηση δικαιωμάτων
         title: Απαιτείται έγκριση
       show:
         title: Αντέγραψε αυτό τον κωδικό έγκρισης στην εφαρμογή.
@@ -69,8 +71,12 @@ el:
       confirmations:
         revoke: Σίγουρα;
       index:
+        authorized_at: Εξουσιοδοτήθηκε στις %{date}
+        description_html: Αυτές είναι εφαρμογές που μπορούν να έχουν πρόσβαση στο λογαριασμό σας χρησιμοποιώντας το API. Αν υπάρχουν εφαρμογές που δεν αναγνωρίζετε εδώ ή μια εφαρμογή δεν συμπεριφέρεται σωστά, μπορείτε να ανακαλέσετε την πρόσβασή της.
+        last_used_at: Τελευταία χρήση στις %{date}
         never_used: Ποτέ σε χρήση
         scopes: Δικαιώματα
+        superapp: Εσωτερική
         title: Οι εφαρμογές που έχεις εγκρίνει
     errors:
       messages:
@@ -117,11 +123,14 @@ el:
         admin/all: Όλες οι λειτουργίες διαχείρησης
         admin/reports: Διαχείριση αναφορών
         all: Πλήρης πρόσβαση στο λογαριασμό σας στο Mastodon
+        blocks: Αποκλεισμοί
         bookmarks: Σελιδοδείκτες
         conversations: Συνομιλίες
         crypto: Κρυπτογράφηση από άκρο σε άκρο
         favourites: Αγαπημένα
         filters: Φίλτρα
+        follow: Ακολουθείτε, σε Σίγαση και Αποκλεισμοί
+        follows: Ακολουθείτε
         lists: Λίστες
         media: Συνημμένα πολυμέσα
         mutes: Αποσιωπήσεις
@@ -140,9 +149,19 @@ el:
     scopes:
       admin:read: ανάγνωση δεδομένων στον διακομιστή
       admin:read:accounts: ανάγνωση ευαίσθητων πληροφοριών όλων των λογαριασμών
+      admin:read:canonical_email_blocks: ανάγνωση ευαίσθητων πληροφοριών όλων των αποκλεισμένων email
+      admin:read:domain_allows: ανάγνωση ευαίσθητων πληροφοριών όλων των επιτρεπόμενων τομέων
+      admin:read:domain_blocks: ανάγνωση ευαίσθητων πληροφοριών όλων των αποκλεισμένων τομέων
+      admin:read:email_domain_blocks: ανάγνωση ευαίσθητων πληροφοριών όλων των αποκλεισμένων τομέων email
+      admin:read:ip_blocks: ανάγνωση ευαίσθητων πληροφοριών όλων των αποκλεισμένων IP
       admin:read:reports: ανάγνωση ευαίσθητων πληροφοριών όλων των καταγγελιών και των καταγγελλομένων λογαριασμών
       admin:write: αλλαγή δεδομένων στον διακομιστή
       admin:write:accounts: εκτέλεση διαχειριστικών ενεργειών σε λογαριασμούς
+      admin:write:canonical_email_blocks: εκτέλεση ενεργειών διαχείρισης σε αποκλεισμένα email
+      admin:write:domain_allows: εκτέλεση ενεργειών διαχείρισης σε επιτρεπτούς τομείς
+      admin:write:domain_blocks: εκτέλεση ενεργειών διαχείρισης σε αποκλεισμένους τομείς
+      admin:write:email_domain_blocks: εκτελέστε ενέργειες διαχείρισης σε αποκλεισμένους τομείς email
+      admin:write:ip_blocks: εκτέλεση ενεργειών διαχείρισης σε αποκλεισμένες IP
       admin:write:reports: εκτέλεση διαχειριστικών ενεργειών σε καταγγελίες
       crypto: χρήση κρυπτογράφησης από άκρο σε άκρο
       follow: να αλλάζει τις σχέσεις με λογαριασμούς
diff --git a/config/locales/doorkeeper.gd.yml b/config/locales/doorkeeper.gd.yml
index 84621d300..f025a0c55 100644
--- a/config/locales/doorkeeper.gd.yml
+++ b/config/locales/doorkeeper.gd.yml
@@ -122,12 +122,14 @@ gd:
         admin/accounts: Rianachd nan cunntas
         admin/all: Gach gleus na rianachd
         admin/reports: Rianachd nan gearan
+        all: Làn-inntrigeadh dhan chunntas Mastodon agad
         blocks: Bacaidhean
         bookmarks: Comharran-lìn
         conversations: Còmhraidhean
         crypto: Crioptachadh o cheann gu ceann
         favourites: Annsachdan
         filters: Criathragan
+        follow: Leantainn, mùchaidhean is bacaidhean
         follows: Leantainn
         lists: Liostaichean
         media: Ceanglachain mheadhanan
@@ -147,9 +149,19 @@ gd:
     scopes:
       admin:read: dàta sam bith a leughadh air an fhrithealaiche
       admin:read:accounts: fiosrachadh dìomhair air a h-uile cunntas a leughadh
+      admin:read:canonical_email_blocks: fiosrachadh dìomhair air a h-uile bacadh puist-d gnàthach a leughadh
+      admin:read:domain_allows: fiosrachadh dìomhair air a h-uile cead àrainne a leughadh
+      admin:read:domain_blocks: fiosrachadh dìomhair air a h-uile bacadh àrainne a leughadh
+      admin:read:email_domain_blocks: fiosrachadh dìomhair air a h-uile bacadh àrainn puist-d a leughadh
+      admin:read:ip_blocks: fiosrachadh dìomhair air a h-uile bacadh IP a leughadh
       admin:read:reports: fiosrachadh dìomhair air a h-uile gearan is cunntasan a chaidh a ghearan mun dèidhinn a leughadh
       admin:write: dàta sam bith atharrachadh air an fhrithealaiche
       admin:write:accounts: gnìomhan na maorsainneachd a ghabhail air cunntasan
+      admin:write:canonical_email_blocks: gnìomhan na maorsainneachd a ghabhail air bacaidhean puist-d gnàthach
+      admin:write:domain_allows: gnìomhan na maorsainneachd a ghabhail air ceadan àrainn
+      admin:write:domain_blocks: gnìomhan na maorsainneachd a ghabhail air bacaidhean àrainne
+      admin:write:email_domain_blocks: gnìomhan na maorsainneachd a ghabhail air bacaidhean àrainn puist-d
+      admin:write:ip_blocks: gnìomhan na maorsainneachd a ghabhail air bacaidhean IP
       admin:write:reports: gnìomhan na maorsainneachd a ghabhail air gearanan
       crypto: crioptachadh o cheann gu ceann a chleachdadh
       follow: dàimhean chunntasan atharrachadh
diff --git a/config/locales/doorkeeper.my.yml b/config/locales/doorkeeper.my.yml
index 5e1fc6bee..b7697074c 100644
--- a/config/locales/doorkeeper.my.yml
+++ b/config/locales/doorkeeper.my.yml
@@ -1 +1,24 @@
+---
 my:
+  activerecord:
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              invalid_uri: သည် မှန်ကန်သော URI ဖြစ်ရမည်။
+              secured_uri: သည် HTTPS/SSL URI ဖြစ်ရမည်။
+  doorkeeper:
+    applications:
+      buttons:
+        cancel: ပယ်ဖျက်မည်
+        destroy: ဖျက်ဆီးမည်
+        edit: ပြင်မည်
+        submit: တင်သွင်းမည်
+      confirmations:
+        destroy: သေချာပါသလား?
+      help:
+        redirect_uri: URI တစ်ခုစီအတွက် လိုင်းတစ်ကြောင်းသုံးပါ
+      index:
+        delete: ဖျက်မည်
+        name: အမည်
diff --git a/config/locales/el.yml b/config/locales/el.yml
index d3ef048a9..903fcb8e1 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -12,6 +12,7 @@ el:
       one: Ακόλουθος
       other: Ακόλουθοι
     following: Ακολουθεί
+    instance_actor_flash: Αυτός ο λογαριασμός είναι εικονικός και χρησιμοποιείται για να αντιπροσωπεύει τον ίδιο τον εξυπηρετητή και όχι κάποιον μεμονωμένο χρήστη. Χρησιμοποιείται για ομοσπονδιακούς σκοπούς και δεν πρέπει να ανασταλεί.
     last_active: τελευταία ενεργός/ή
     link_verified_on: Η κυριότητα αυτού του συνδέσμου ελέγχθηκε στις %{date}
     nothing_here: Δεν υπάρχει τίποτα εδώ!
@@ -37,23 +38,27 @@ el:
       avatar: Αβατάρ
       by_domain: Τομέας
       change_email:
+        changed_msg: Το email άλλαξε επιτυχώς!
         current_email: Τρέχον email
         label: Αλλαγή email
         new_email: Νέο email
         submit: Αλλαγή email
         title: Αλλαγή email για %{username}
       change_role:
+        changed_msg: Ο ρόλος άλλαξε επιτυχώς!
         label: Αλλαγή ρόλου
         no_role: Κανένας ρόλος
         title: Αλλαγή ρόλου για %{username}
       confirm: Επιβεβαίωση
       confirmed: Επιβεβαιώθηκε
       confirming: Προς επιβεβαίωση
+      custom: Προσαρμοσμένο
       delete: Διαγραφή δεδομένων
       deleted: Διαγραμμένοι
       demote: Υποβίβαση
       destroyed_msg: Τα δεδομένα του/της %{username} εκκρεμούν για άμεση διαγραφή
       disable: Απενεργοποίηση
+      disable_sign_in_token_auth: Απενεργοποίηση επαλήθευσης μέσω email
       disable_two_factor_authentication: Απενεργοποίηση 2FA
       disabled: Απενεργοποιημένο
       display_name: Όνομα εμφάνισης
@@ -62,6 +67,7 @@ el:
       email: Email
       email_status: Κατάσταση email
       enable: Ενεργοποίηση
+      enable_sign_in_token_auth: Ενεργοποίηση ελέγχου ταυτότητας μέσω e-mail
       enabled: Ενεργοποιημένο
       enabled_msg: Επιτυχές ξεπάγωμα λογαριασμού του/της %{username}
       followers: Ακόλουθοι
@@ -98,6 +104,10 @@ el:
       not_subscribed: Άνευ συνδρομής
       pending: Εκκρεμεί έγκριση
       perform_full_suspension: Αναστολή
+      previous_strikes: Προηγούμενα παραπτώματα
+      previous_strikes_description_html:
+        one: Αυτός ο λογαριασμός έχει <strong>ένα</strong> παράπτωμα.
+        other: Αυτός ο λογαριασμός έχει <strong>%{count}</strong> παραπτώματα.
       promote: Προβίβασε
       protocol: Πρωτόκολλο
       public: Δημόσιο
@@ -123,6 +133,9 @@ el:
       search: Αναζήτηση
       search_same_email_domain: Άλλοι χρήστες με τον ίδιο τομέα e-mail
       search_same_ip: Υπόλοιποι χρήστες με την ίδια διεύθυνση IP
+      security_measures:
+        only_password: Μόνο κωδικός πρόσβασης
+        password_and_2fa: Κωδικός πρόσβασης και 2FA
       sensitive: Ευαίσθητο
       sensitized: σήμανση ως ευαίσθητο
       shared_inbox_url: URL κοινόχρηστων εισερχομένων
@@ -132,6 +145,7 @@ el:
       silence: Αποσιώπησε
       silenced: Αποσιωπημένοι
       statuses: Καταστάσεις
+      strikes: Προηγούμενα παραπτώματα
       subscribe: Εγγραφή
       suspend: Αναστολή
       suspended: Σε αναστολή
@@ -162,14 +176,17 @@ el:
         confirm_user: Επιβεβαίωση Χρήστη
         create_account_warning: Δημιουργία Προειδοποίησης
         create_announcement: Δημιουργία Ανακοίνωσης
+        create_canonical_email_block: Δημιουργία αποκλεισμού e-mail
         create_custom_emoji: Δημιουργία Προσαρμοσμένου Emoji
         create_domain_allow: Δημιουργία Επιτρεπτού Τομέα
         create_domain_block: Δημιουργία Αποκλεισμένου Τομέα
         create_email_domain_block: Δημουργία Αποκλεισμένου Τομέα email
         create_ip_block: Δημιουργία κανόνα IP
+        create_unavailable_domain: Δημιουργία Μη Διαθέσιμου Τομέα
         create_user_role: Δημιουργία ρόλου
         demote_user: Υποβιβασμός Χρήστη
         destroy_announcement: Διαγραφή Ανακοίνωσης
+        destroy_canonical_email_block: Διαγραφή Αποκλεισμού email
         destroy_custom_emoji: Διαγραφή Προσαρμοσμένου Emoji
         destroy_domain_allow: Διαγραφή Επιτρεπτού Τομέα
         destroy_domain_block: Διαγραφή Αποκλεισμού Τομέα
@@ -177,10 +194,14 @@ el:
         destroy_instance: Εκκαθάριση Τομέα
         destroy_ip_block: Διαγραφή κανόνα IP
         destroy_status: Διαγραφή Κατάστασης
+        destroy_unavailable_domain: Διαγραφή Μη Διαθέσιμου Τομέα
+        destroy_user_role: Καταστροφή Ρόλου
         disable_2fa_user: Απενεργοποίηση 2FA
         disable_custom_emoji: Απενεργοποίηση Προσαρμοσμένων Emoji
+        disable_sign_in_token_auth_user: Απενεργοποίηση Ελέγχου Ταυτότητας Μέσω E-mail για το Χρήστη
         disable_user: Απενεργοποίηση Χρήστη
         enable_custom_emoji: Ενεργοποίηση Προσαρμοσμένων Emoji
+        enable_sign_in_token_auth_user: Ενεργοποίηση Ελέγχου Ταυτότητας Μέσω E-mail για το Χρήστη
         enable_user: Ενεργοποίηση Χρήστη
         memorialize_account: Μετατροπή Λογαριασμού σε Αναμνηστικό
         promote_user: Προαγωγή Χρήστη
@@ -201,10 +222,21 @@ el:
         unsuspend_account: Άρση Αναστολής Λογαριασμού
         update_announcement: Ενημέρωση Ανακοίνωσης
         update_custom_emoji: Ενημέρωση Προσαρμοσμένου Emoji
+        update_domain_block: Ενημέρωση Αποκλεισμού Τομέα
+        update_ip_block: Ενημέρωση κανόνα IP
         update_status: Ενημέρωση Κατάστασης
         update_user_role: Ενημέρωση ρόλου
       actions:
+        approve_appeal_html: Ο/Η %{name} ενέκρινε την ένσταση της απόφασης των διαχειριστών από %{target}
         approve_user_html: "%{name} εγκρίθηκε εγγραφή από %{target}"
+        assigned_to_self_report_html: Ο/Η %{name} ανάθεσε την καταγγελία %{target} στον εαυτό του/της
+        change_email_user_html: Ο/Η %{name} άλλαξε τη διεύθυνση email του χρήστη %{target}
+        change_role_user_html: Ο/Η %{name} άλλαξε ρόλο του/της %{target}
+        confirm_user_html: Ο/Η %{name} επιβεβαίωσε τη διεύθυνση email του χρήστη %{target}
+        create_account_warning_html: Ο/Η %{name} έστειλε προειδοποίηση προς %{target}
+        create_announcement_html: Ο/Η %{name} δημιούργησε νέα ανακοίνωση %{target}
+        create_canonical_email_block_html: Ο/Η %{name} απέκλεισε e-mail με το hash %{target}
+        create_custom_emoji_html: Ο/Η %{name} ανέβασε νέο emoji %{target}
         destroy_email_domain_block_html: Ο/Η %{name} ξεμπλόκαρε το email domain %{target}
         destroy_instance_html: Ο/Η %{name} εκκαθάρισε τον τομέα %{target}
         destroy_ip_block_html: Ο/Η %{name} διέγραψε τον κανόνα για την IP %{target}
diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml
index 17fea7227..e624bb27e 100644
--- a/config/locales/en-GB.yml
+++ b/config/locales/en-GB.yml
@@ -226,6 +226,28 @@ en-GB:
         update_ip_block: Update IP rule
         update_status: Update Post
         update_user_role: Update Role
+      actions:
+        approve_appeal_html: "%{name} approved moderation decision appeal from %{target}"
+        approve_user_html: "%{name} approved sign-up from %{target}"
+        assigned_to_self_report_html: "%{name} assigned report %{target} to themselves"
+        change_email_user_html: "%{name} changed the e-mail address of user %{target}"
+        change_role_user_html: "%{name} changed role of %{target}"
+        confirm_user_html: "%{name} confirmed e-mail address of user %{target}"
+        create_account_warning_html: "%{name} sent a warning to %{target}"
+        create_announcement_html: "%{name} created new announcement %{target}"
+        create_canonical_email_block_html: "%{name} blocked e-mail with the hash %{target}"
+        create_custom_emoji_html: "%{name} uploaded new emoji %{target}"
+        create_domain_allow_html: "%{name} allowed federation with domain %{target}"
+        create_domain_block_html: "%{name} blocked domain %{target}"
+        create_email_domain_block_html: "%{name} blocked e-mail domain %{target}"
+        create_ip_block_html: "%{name} created rule for IP %{target}"
+        create_unavailable_domain_html: "%{name} stopped delivery to domain %{target}"
+        create_user_role_html: "%{name} created %{target} role"
+        demote_user_html: "%{name} demoted user %{target}"
+        destroy_announcement_html: "%{name} deleted announcement %{target}"
+        destroy_canonical_email_block_html: "%{name} unblocked e-mail with the hash %{target}"
+        destroy_custom_emoji_html: "%{name} deleted emoji %{target}"
+        destroy_domain_allow_html: "%{name} disallowed federation with domain %{target}"
     roles:
       categories:
         devops: DevOps
@@ -256,7 +278,20 @@ en-GB:
       explanation: The appeal of the strike against your account on %{strike_date} that you submitted on %{appeal_date} has been approved. Your account is once again in good standing.
       subject: Your appeal from %{date} has been approved
     warning:
+      explanation:
+        disable: You can no longer use your account, but your profile and other data remains intact. You can request a backup of your data, change account settings or delete your account.
+        mark_statuses_as_sensitive: Some of your posts have been marked as sensitive by the moderators of %{instance}. This means that people will need to tap the media in the posts before a preview is displayed. You can mark media as sensitive yourself when posting in the future.
+        sensitive: From now on, all your uploaded media files will be marked as sensitive and hidden behind a click-through warning.
+        silence: You can still use your account but only people who are already following you will see your posts on this server, and you may be excluded from various discovery features. However, others may still manually follow you.
+        suspend: You can no longer use your account, and your profile and other data are no longer accessible. You can still login to request a backup of your data until the data is fully removed in about 30 days, but we will retain some basic data to prevent you from evading the suspension.
+      reason: 'Reason:'
+      statuses: 'Posts cited:'
       subject:
+        delete_statuses: Your posts on %{acct} have been removed
+        disable: Your account %{acct} has been frozen
+        mark_statuses_as_sensitive: Your posts on %{acct} have been marked as sensitive
+        none: Warning for %{acct}
+        sensitive: Your posts on %{acct} will be marked as sensitive from now on
         silence: Your account %{acct} has been limited
         suspend: Your account %{acct} has been suspended
       title:
@@ -283,7 +318,14 @@ en-GB:
     otp_lost_help_html: If you lost access to both, you may get in touch with %{email}
     seamless_external_login: You are logged in via an external service, so password and e-mail settings are not available.
     signed_in_as: 'Signed in as:'
+  verification:
+    explanation_html: 'You can <strong>verify yourself as the owner of the links in your profile metadata</strong>. For that, the linked website must contain a link back to your Mastodon profile. The link back <strong>must</strong> have a <code>rel="me"</code> attribute. The text content of the link does not matter. Here is an example:'
+    verification: Verification
   webauthn_credentials:
+    add: Add new security key
+    create:
+      error: There was a problem adding your security key. Please try again.
+      success: Your security key was successfully added.
     delete: Delete
     delete_confirmation: Are you sure you want to delete this security key?
     description_html: If you enable <strong>security key authentication</strong>, logging in will require you to use one of your security keys.
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 39ff4236a..594a030b9 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -91,6 +91,7 @@ en:
       moderation:
         active: Active
         all: All
+        disabled: Disabled
         pending: Pending
         silenced: Limited
         suspended: Suspended
@@ -133,6 +134,7 @@ en:
       search: Search
       search_same_email_domain: Other users with the same e-mail domain
       search_same_ip: Other users with the same IP
+      security: Security
       security_measures:
         only_password: Only password
         password_and_2fa: Password and 2FA
@@ -427,6 +429,7 @@ en:
         resolve: Resolve domain
         title: Block new e-mail domain
       no_email_domain_block_selected: No e-mail domain blocks were changed as none were selected
+      not_permitted: Not permitted
       resolved_dns_records_hint_html: The domain name resolves to the following MX domains, which are ultimately responsible for accepting e-mail. Blocking an MX domain will block sign-ups from any e-mail address which uses the same MX domain, even if the visible domain name is different. <strong>Be careful not to block major e-mail providers.</strong>
       resolved_through_html: Resolved through %{domain}
       title: Blocked e-mail domains
@@ -473,6 +476,7 @@ en:
       content_policies:
         comment: Internal note
         description_html: You can define content policies that will be applied to all accounts from this domain and any of its subdomains.
+        limited_federation_mode_description_html: You can chose whether to allow federation with this domain.
         policies:
           reject_media: Reject media
           reject_reports: Reject reports
@@ -585,11 +589,13 @@ en:
       assign_to_self: Assign to me
       assigned: Assigned moderator
       by_target_domain: Domain of reported account
+      cancel: Cancel
       category: Category
       category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account
       comment:
         none: None
       comment_description_html: 'To provide more information, %{name} wrote:'
+      confirm: Confirm
       confirm_action: Confirm moderation action against @%{acct}
       created_at: Reported
       delete_and_resolve: Delete posts
@@ -792,6 +798,7 @@ en:
         suspend: "%{name} suspended %{target}'s account"
       appeal_approved: Appealed
       appeal_pending: Appeal pending
+      appeal_rejected: Appeal rejected
     system_checks:
       database_schema_check:
         message_html: There are pending database migrations. Please run them to ensure the application behaves as expected
@@ -827,6 +834,7 @@ en:
           other: Shared by %{count} people over the last week
         title: Trending links
         usage_comparison: Shared %{today} times today, compared to %{yesterday} yesterday
+      not_allowed_to_trend: Not allowed to trend
       only_allowed: Only allowed
       pending_review: Pending review
       preview_card_providers:
@@ -958,6 +966,7 @@ en:
   applications:
     created: Application successfully created
     destroyed: Application successfully deleted
+    logout: Logout
     regenerate_token: Regenerate access token
     token_regenerated: Access token successfully regenerated
     warning: Be very careful with this data. Never share it with anyone!
@@ -994,6 +1003,8 @@ en:
     resend_confirmation: Resend confirmation instructions
     reset_password: Reset password
     rules:
+      accept: Accept
+      back: Back
       preamble: These are set and enforced by the %{domain} moderators.
       title: Some ground rules.
     security: Security
@@ -1141,7 +1152,7 @@ en:
   featured_tags:
     add_new: Add new
     errors:
-      limit: You have already featured the maximum amount of hashtags
+      limit: You have already featured the maximum number of hashtags
     hint_html: "<strong>What are featured hashtags?</strong> They are displayed prominently on your public profile and allow people to browse your public posts specifically under those hashtags. They are a great tool for keeping track of creative works or long-term projects."
   filters:
     contexts:
@@ -1253,7 +1264,7 @@ en:
     title: Invite people
   lists:
     errors:
-      limit: You have reached the maximum amount of lists
+      limit: You have reached the maximum number of lists
   login_activities:
     authentication_methods:
       otp: two-factor authentication app
@@ -1574,7 +1585,7 @@ en:
       '7889238': 3 months
     min_age_label: Age threshold
     min_favs: Keep posts favourited at least
-    min_favs_hint: Doesn't delete any of your posts that has received at least this amount of favourites. Leave blank to delete posts regardless of their number of favourites
+    min_favs_hint: Doesn't delete any of your posts that has received at least this number of favourites. Leave blank to delete posts regardless of their number of favourites
     min_reblogs: Keep posts boosted at least
     min_reblogs_hint: Doesn't delete any of your posts that has been boosted at least this number of times. Leave blank to delete posts regardless of their number of boosts
   stream_entries:
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index cbff5c237..99011f819 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -420,7 +420,7 @@ fi:
       delete: Poista
       dns:
         types:
-          mx: MX tietue
+          mx: MX-tietue
       domain: Verkkotunnus
       new:
         create: Lisää verkkotunnus
@@ -785,7 +785,7 @@ fi:
       actions:
         delete_statuses: "%{name} poisti käyttäjän %{target} viestit"
         disable: "%{name} jäädytti %{target} tilin"
-        mark_statuses_as_sensitive: "%{name} merkitsi %{target} viestiä arkaluonteiseksi"
+        mark_statuses_as_sensitive: "%{name} merkitsi käyttäjän %{target} viestit arkaluonteisiksi"
         none: "%{name} lähetti varoituksen henkilölle %{target}"
         sensitive: "%{name} merkitsi käyttäjän %{target} tilin arkaluonteiseksi"
         silence: "%{name} rajoitti käyttäjän %{target} tilin"
@@ -876,12 +876,12 @@ fi:
       add_new: Lisää uusi
       delete: Poista
       edit_preset: Muokkaa varoituksen esiasetusta
-      empty: Et ole vielä määrittänyt yhtään varoitusesiasetusta.
-      title: Hallinnoi varoitusesiasetuksia
+      empty: Et ole vielä määrittänyt yhtäkään varoitusten esiasetusta.
+      title: Hallinnoi varoitusten esiasetuksia
     webhooks:
       add_new: Lisää päätepiste
       delete: Poista
-      description_html: A <strong>webhook</strong> mahdollistaa Mastodonin työntää <strong>reaaliaikaisia ilmoituksia</strong> valituista tapahtumista omaan sovellukseesi, joten sovelluksesi voi <strong>laukaista automaattisesti reaktioita</strong>.
+      description_html: "<strong>Webhook</strong> mahdollistaa Mastodonin työntää <strong>reaaliaikaisia ilmoituksia</strong> valituista tapahtumista omaan sovellukseesi, joten sovelluksesi voi <strong>laukaista automaattisesti reaktioita</strong>."
       disable: Poista käytöstä
       disabled: Ei käytössä
       edit: Muokkaa päätepistettä
@@ -976,7 +976,7 @@ fi:
     didnt_get_confirmation: Etkö saanut vahvistusohjeita?
     dont_have_your_security_key: Eikö sinulla ole suojausavainta?
     forgot_password: Unohditko salasanasi?
-    invalid_reset_password_token: Salasananpalautustunnus on virheellinen tai vanhentunut. Pyydä uusi.
+    invalid_reset_password_token: Salasanan palautustunnus on virheellinen tai vanhentunut. Pyydä uusi.
     link_to_otp: Syötä puhelimesi kaksivaiheinen koodi tai palautuskoodi
     link_to_webauth: Käytä suojausavaintasi
     log_in_with: Kirjaudu käyttäen
@@ -1036,7 +1036,7 @@ fi:
     prompt: Vahvista salasanasi jatkaaksesi
   crypto:
     errors:
-      invalid_key: ei ole kelvollinen Ed25519- tai Curve25519 -avain
+      invalid_key: ei ole kelvollinen Ed25519- tai Curve25519-avain
       invalid_signature: ei ole kelvollinen Ed25519-allekirjoitus
   date:
     formats:
@@ -1044,16 +1044,16 @@ fi:
       with_month_name: "%B %d, %Y"
   datetime:
     distance_in_words:
-      about_x_hours: "%{count} h"
+      about_x_hours: "%{count} t"
       about_x_months: "%{count} kk"
       about_x_years: "%{count} v"
       almost_x_years: "%{count} v"
       half_a_minute: Nyt
-      less_than_x_minutes: "%{count} m"
+      less_than_x_minutes: "%{count} min"
       less_than_x_seconds: Nyt
       over_x_years: "%{count} v"
       x_days: "%{count} pv"
-      x_minutes: "%{count} m"
+      x_minutes: "%{count} min"
       x_months: "%{count} kk"
       x_seconds: "%{count} s"
   deletes:
@@ -1127,14 +1127,14 @@ fi:
     archive_takeout:
       date: Päiväys
       download: Lataa arkisto
-      hint_html: Voit pyytää arkistoa omista <strong>tuuttauksistasi ja mediastasi</strong>. Vientitiedot ovat ActivityPub-muodossa, ja ne voi lukea millä tahansa yhteensopivalla ohjelmalla.
+      hint_html: Voit pyytää arkistoa omista <strong>viesteistä ja mediasta</strong>. Viedyt tiedot ovat ActivityPub-muodossa, ja ne voi lukea millä tahansa yhteensopivalla ohjelmalla. Voit pyytää arkistoa viikon välein.
       in_progress: Arkistoa kootaan...
       request: Pyydä arkisto
       size: Koko
     blocks: Estot
     bookmarks: Kirjanmerkit
     csv: CSV
-    domain_blocks: Verkkotunnus estetty
+    domain_blocks: Verkkotunnusten estot
     lists: Listat
     mutes: Mykistetyt
     storage: Media-arkisto
@@ -1153,11 +1153,11 @@ fi:
     edit:
       add_keyword: Lisää avainsana
       keywords: Avainsanat
-      statuses: Yksittäiset postaukset
-      statuses_hint_html: Tämä suodatin koskee yksittäisten postausten valintaa riippumatta siitä, vastaavatko ne alla olevia avainsanoja. <a href="%{path}">Tarkista tai poista viestit suodattimesta</a>.
+      statuses: Yksittäiset viestit
+      statuses_hint_html: Tämä suodatin koskee yksittäisten viestien valintaa riippumatta siitä, vastaavatko ne alla olevia avainsanoja. <a href="%{path}">Tarkista tai poista viestit suodattimesta</a>.
       title: Muokkaa suodatinta
     errors:
-      deprecated_api_multiple_keywords: Näitä parametreja ei voi muuttaa tästä sovelluksesta, koska ne koskevat useampaa kuin yhtä suodattimen avainsanaa. Käytä uudempaa sovellusta tai web-käyttöliittymää.
+      deprecated_api_multiple_keywords: Näitä parametreja ei voi muuttaa tästä sovelluksesta, koska ne koskevat useampaa kuin yhtä suodattimen avainsanaa. Käytä uudempaa sovellusta tai selainkäyttöliittymää.
       invalid_context: Ei sisältöä tai se on virheellinen
     index:
       contexts: Suodattimet %{contexts}
@@ -1193,7 +1193,7 @@ fi:
       one: "<strong>%{count}</strong> kohde tällä sivulla on valittu."
       other: Kaikki <strong>%{count}</strong> kohdetta tällä sivulla on valittu.
     all_matching_items_selected_html:
-      one: "<strong>%{count}</strong> tuotetta, joka vastaa hakuasi."
+      one: "<strong>%{count}</strong> kohde, joka vastaa hakuasi."
       other: Kaikki <strong>%{count}</strong> kohdetta, jotka vastaavat hakuasi.
     changes_saved_msg: Muutosten tallennus onnistui!
     copy: Kopioi
@@ -1203,7 +1203,7 @@ fi:
     order_by: Järjestä
     save_changes: Tallenna muutokset
     select_all_matching_items:
-      one: Valitse %{count} kohdetta, joka vastaa hakuasi.
+      one: Valitse %{count} kohde, joka vastaa hakuasi.
       other: Valitse kaikki %{count} kohdetta, jotka vastaavat hakuasi.
     today: tänään
     validation_errors:
@@ -1314,7 +1314,7 @@ fi:
       report:
         subject: "%{name} lähetti raportin"
       sign_up:
-        subject: "%{name} kirjautunut"
+        subject: "%{name} rekisteröityi"
     favourite:
       body: "%{name} tykkäsi tilastasi:"
       subject: "%{name} tykkäsi tilastasi"
@@ -1384,7 +1384,7 @@ fi:
       too_many_options: ei voi sisältää enempää kuin %{max} kohdetta
   preferences:
     other: Muut
-    posting_defaults: Julkaisujen oletusasetukset
+    posting_defaults: Viestien oletusasetukset
     public_timelines: Julkiset aikajanat
   privacy_policy:
     title: Tietosuojakäytäntö
@@ -1418,7 +1418,7 @@ fi:
     errors:
       invalid_rules: ei viittaa voimassa oleviin sääntöihin
   rss:
-    content_warning: 'Sisällön varoitus:'
+    content_warning: 'Sisältövaroitus:'
     descriptions:
       account: Julkiset viestit lähettäjältä @%{acct}
       tag: 'Julkiset viestit merkitty #%{hashtag}'
@@ -1481,7 +1481,7 @@ fi:
     export: Vie tietoja
     featured_tags: Esitellyt aihetunnisteet
     import: Tuo
-    import_and_export: Tuo / Vie
+    import_and_export: Tuo ja vie
     migrate: Tilin muutto muualle
     notifications: Ilmoitukset
     preferences: Ominaisuudet
@@ -1516,8 +1516,8 @@ fi:
     over_character_limit: merkkimäärän rajoitus %{max} ylitetty
     pin_errors:
       direct: Viestejä, jotka ovat näkyvissä vain mainituille käyttäjille, ei voi kiinnittää
-      limit: Olet jo kiinnittänyt suurimman mahdollisen määrän tuuttauksia
-      ownership: Muiden tuuttauksia ei voi kiinnittää
+      limit: Olet jo kiinnittänyt suurimman mahdollisen määrän viestejä
+      ownership: Muiden viestejä ei voi kiinnittää
       reblog: Tehostusta ei voi kiinnittää
     poll:
       total_people:
@@ -1663,7 +1663,7 @@ fi:
         suspend: Tilin käyttäminen jäädytetty
     welcome:
       edit_profile_action: Aseta profiili
-      edit_profile_step: Voit muokata profiiliasi lataamalla profiilikuvan, vaihtamalla näyttönimeä ja paljon muuta. Voit halutessasi arvioida uudet seuraajat ennen kuin he saavat seurata sinua.
+      edit_profile_step: Voit muokata profiiliasi lataamalla profiilikuvan, vaihtamalla näyttönimeä ja paljon muuta. Voit halutessasi arvioida uudet seuraajat, ennen kuin he saavat seurata sinua.
       explanation: Näillä vinkeillä pääset alkuun
       final_action: Ala julkaista
       final_step: 'Ala julkaista! Vaikkei sinulla olisi seuraajia, monet voivat nähdä julkiset viestisi esimerkiksi paikallisella aikajanalla ja aihetunnisteilla. Kannattaa myös esittäytyä! Käytä aihetunnistetta #esittely.'
@@ -1676,7 +1676,7 @@ fi:
     invalid_otp_token: Virheellinen kaksivaiheisen todentamisen koodi
     otp_lost_help_html: Jos sinulla ei ole pääsyä kumpaankaan, voit ottaa yhteyttä osoitteeseen %{email}
     seamless_external_login: Olet kirjautunut ulkoisen palvelun kautta, joten salasana- ja sähköpostiasetukset eivät ole käytettävissä.
-    signed_in_as: 'Kirjautunut henkilönä:'
+    signed_in_as: 'Kirjautunut tilillä:'
   verification:
     explanation_html: 'Voit <strong>vahvistaa olevasi profiilisi metatiedoissa olevien linkkien omistaja.</strong>. Tätä varten linkitetyn verkkosivuston täytyy sisältää linkki takaisin Mastodon-profiiliisi. Palauttavalla linkillä <strong>täytyy</strong> olla <code>rel="me"</code>-arvo. Linkin tekstisisällöllä ei ole merkitystä. Tässä on esimerkki:'
     verification: Vahvistus
diff --git a/config/locales/gd.yml b/config/locales/gd.yml
index 147ee6351..1091c52e1 100644
--- a/config/locales/gd.yml
+++ b/config/locales/gd.yml
@@ -122,6 +122,8 @@ gd:
       redownloaded_msg: Chaidh a’ phròifil aig %{username} on tùs
       reject: Diùlt
       rejected_msg: Chaidh an t-iarrtas clàraidh aig %{username} a dhiùltadh
+      remote_suspension_irreversible: Chaidh dàta a’ chunntais seo a sguabadh às gu buan.
+      remote_suspension_reversible_hint_html: Chaidh an cunntas a chur à rèim air an fhrithealaiche aca agus thèid an dàta aige a sguabadh às gu buan %{date}. Gus an dig an t-àm ud, ’s urrainn dhan fhrithealaiche chèin an cunntas aiseag fhathast gun droch bhuaidh sam bith air. Nam bu toigh leat gach dàta a’ chunntais a thoirt air falbh sa bhad, ’s urrainn dhut sin a dhèanamh gu h-ìosal.
       remove_avatar: Thoir air falbh an t-avatar
       remove_header: Thoir air falbh am bann-cinn
       removed_avatar_msg: Chaidh dealbh an avatar aig %{username} a thoirt air falbh
@@ -404,6 +406,7 @@ gd:
         create: Cruthaich bacadh
         hint: Cha chuir bacadh na h-àrainne crìoch air cruthachadh chunntasan san stòr-dàta ach cuiridh e dòighean maorsainneachd sònraichte an sàs gu fèin-obrachail air a h-uile dàta a tha aig na cunntasan ud.
         severity:
+          desc_html: Falaichidh an <strong>cuingeachadh</strong> postaichean o chunntasan na h-àrainne seo do dhuine sam bith nach ail a’ leantainn orra. Bheir an <strong>cur à rèim</strong> air falbh gach susbaint, meadhan is dàta pròifil aig cunntasan na h-àrainne seo on fhrithealaiche agad. Tagh <strong>Chan eil gin</strong> mur eil thu ach airson faidhlichean meadhain a dhiùltadh.
           noop: Chan eil gin
           silence: Cuingich
           suspend: Cuir à rèim
@@ -449,9 +452,12 @@ gd:
       no_file: Cha deach faidhle a thaghadh
     export_domain_blocks:
       import:
+        description_html: Tha thu an impis bacaidhean àrainne ion-phortadh. Dèan lèirmheas glè chùramach air an liosta seo, gu h-àraidh mur an do chruinnich thu fhèin an liosta seo.
         existing_relationships_warning: Dàimhean leantainn làithreach
+        private_comment_description_html: 'Airson do chuideachadh ach an tracaich thu cò às a thàinig bacaidhean a chaidh ion-phortadh, thèid am beachd prìobhaideach seo a chur ris na bacaidhean air an ion-phortadh: <q>%{comment}</q>'
         private_comment_template: Chaidh ion-phortadh o %{source} %{date}
         title: Ion-phortaich bacaidhean àrainne
+      invalid_domain_block: 'Chaidh leum a ghearradh thar bacadh àrainne no dhà ri linn mearachd: %{error}'
       new:
         title: Ion-phortaich bacaidhean àrainne
       no_file: Cha deach faidhle a thaghadh
@@ -594,7 +600,10 @@ gd:
         mark_as_sensitive_description_html: Thèid comharra an fhrionasachd a chur ris na meadhanan sna postaichean le gearan orra agus rabhadh a chlàradh gus do chuideachadh ach am bi thu nas teinne le droch-ghiùlan on aon chunntas sam àm ri teachd.
         other_description_html: Seall barrachd roghainnean airson giùlan a’ chunntais a stiùireadh agus an conaltradh leis a’ chunntas a chaidh gearan a dhèanamh mu dhèidhinn a ghnàthachadh.
         resolve_description_html: Cha dèid gnìomh sam bith a ghabhail an aghaidh a’ chunntais le gearan air agus thèid an gearan a dhùnadh gun rabhadh a chlàradh.
+        silence_description_html: Chan fhaic ach an fheadhainn a tha ’ga leantainn mu thràth no a lorgas a làimh e an cunntas seo agus cuingichidh seo uiread nan daoine a ruigeas e gu mòr. Gabhaidh seo a neo-dhèanamh uair sam bith. Dùinidh seo gach gearan mun chunntas seo.
+        suspend_description_html: Cha ghabh an cunntas seo agus an t-susbaint gu leòr aige inntrigeadh gus an dèid a sguabadh às air deireadh na sgeòil agus cha ghabh eadar-ghabhail a dhèanamh leis. Gabhaidh seo a neo-dhèanamh am broinn 30 latha. Dùinidh seo gach gearan mun chunntas seo.
       actions_description_html: Socraich dè a nì thu airson an gearan seo fhuasgladh. Ma chuireas tu peanas air a’ chunntas le gearan air, gheibh iad brath air a’ phost-d mura tagh thu an roinn-seòrsa <strong>Spama</strong>.
+      actions_description_remote_html: Cuir romhad dè an gnìomh a ghabhas tu airson an gearan seo fhuasgladh. Cha bheir seo buaidh ach air mar a làimhsicheas am frithealaiche <strong>agadsa</strong> an cunntas cèin seo is mar a nì e conaltradh leis.
       add_to_report: Cuir barrachd ris a’ ghearan
       are_you_sure: A bheil thu cinnteach?
       assign_to_self: Iomruin dhomh-sa
@@ -605,6 +614,7 @@ gd:
       comment:
         none: Chan eil gin
       comment_description_html: 'Airson barrachd fiosrachaidh a sholar, sgrìobh %{name}:'
+      confirm_action: Dearbh gnìomh na maorsainneachd an aghaidh @%{acct}
       created_at: Chaidh an gearan a dhèanamh
       delete_and_resolve: Sguab às na postaichean
       forwarded: Chaidh a shìneadh air adhart
@@ -621,6 +631,7 @@ gd:
         placeholder: Mìnich dè na ghnìomhan a chaidh a ghabhail no naidheachd sam bith eile mu dhèidhinn…
         title: Nòtaichean
       notes_description_html: Seall is sgrìobh nòtaichean do mhaoir eile is dhut fhèin san àm ri teachd
+      processed_msg: 'Chaidh gearan #%{id} a phròiseasadh'
       quick_actions_description_html: 'Gabh gnìomh luath no sgrolaich sìos a dh’fhaicinn susbaint a’ ghearain:'
       remote_user_placeholder: cleachdaiche cèin o %{instance}
       reopen: Fosgail an gearan a-rithist
@@ -633,9 +644,28 @@ gd:
       status: Staid
       statuses: Susbaint le gearan
       statuses_description_html: Thèid iomradh a thoirt air an t-susbaint oilbheumach sa chonaltradh leis a’ chunntas mun a chaidh an gearan a thogail
+      summary:
+        action_preambles:
+          delete_html: 'Tha thu an impis cuid de na postaichean aig <strong>@%{acct}</strong> a <strong>thoirt air falbh</strong>. Seo na thachras:'
+          mark_as_sensitive_html: 'Tha thu an impis <strong>comharra</strong> a chur gu bheil cuid de na postaichean aig <strong>@%{acct}</strong> <strong>frionasach</strong>. Seo na thachras:'
+          silence_html: 'Tha thu an impis an cunntas aig <strong>@%{acct}</strong> a <strong> chuingeachadh</strong>. Seo na thachras:'
+          suspend_html: 'Tha thu an impis an cunntas aig <strong>@%{acct}</strong> a <strong> chur à rèim</strong>. Seo na thachras:'
+        actions:
+          delete_html: Thoir air falbh na postaichean oilbheumach
+          mark_as_sensitive_html: Cuir comharra gu bheil meadhanan nam postaichean oilbheumach frionasach
+          silence_html: Thèid cò ruigeas <strong>@%{acct}</strong> a chuingeachadh gu mòr air sgàth ’s nach fhaic ach an fheadhainn a bheil ’ga leantainn mu thràth no a tha a’ lorg na pròifil aca a làimh a’ phròifil is an t-susbaint aca.
+          suspend_html: Thèid <strong>@%{acct}</strong> a chur à rèim agus cha ghabh a’ phròifil is an t-susbaint aca a ruigsinn no eadar-ghabhail
+        close_report: 'Cuir comharra gun deach gearan #%{id} fhuasgladh'
+        close_reports_html: Cuir comharra gun deach <strong>gach</strong> gearan an aghaidh <strong>@%{acct}</strong> fhuasgladh
+        delete_data_html: Sguab às a’ phròifil ’s an t-susbaint aig <strong>@%{acct}</strong> an ceann 30 latha mura dèid an cur an gnìomh a-rithist roimhe sin
+        preview_preamble_html: 'Gheibh <strong>@%{acct}</strong> rabhadh leis an t-susbaint seo:'
+        record_strike_html: Clàraich rabhadh an aghaidh <strong>@%{acct}</strong> airson do chuideachadh ach am bi thu nas teinne le droch-ghiùlan on chunntas seo san àm ri teachd
+        send_email_html: Cuir post-d rabhaidh gu <strong>@%{acct}</strong>
+        warning_placeholder: Adhbharan roghainneil eile air gnìomh na maorsainneachd
       target_origin: Tùs cunntas a’ ghearain
       title: Gearanan
       unassign: Dì-iomruin
+      unknown_action_msg: 'Gnìomh nach aithne dhuinn: %{action}'
       unresolved: Gun fhuasgladh
       updated_at: Air ùrachadh
       view_profile: Seall a’ phròifil
@@ -726,11 +756,16 @@ gd:
       content_retention:
         preamble: Stiùirich mar a tha susbaint an luchd-cleachdaidh ’ga stòradh ann am Mastodon.
         title: Glèidheadh na susbaint
+      default_noindex:
+        desc_html: Bidh buaidh air a h-uile cleachdaiche nach do dh’atharraich an roghainn seo dhaibh fhèin
+        title: Thoir air falbh ro-aonta nan cleachdaichean air inneacsadh le einnseanan-luirg mar a’ bhun-roghainn
       discovery:
         follow_recommendations: Molaidhean leantainn
         preamble: Tha tighinn an uachdar susbainte inntinniche fìor-chudromach airson toiseach-tòiseachaidh an luchd-cleachdaidh ùr nach eil eòlach air duine sam bith air Mastodon, ma dh’fhaoidte. Stiùirich mar a dh’obraicheas gleusan an rannsachaidh air an fhrithealaiche agad.
         profile_directory: Eòlaire nam pròifil
         public_timelines: Loidhnichean-ama poblach
+        publish_discovered_servers: Foillsich na frithealaichean a chaidh a lorg
+        publish_statistics: Foillsich an stadastaireachd
         title: Rùrachadh
         trends: Treandaichean
       domain_blocks:
@@ -966,6 +1001,8 @@ gd:
   auth:
     apply_for_account: Iarr cunntas
     change_password: Facal-faire
+    confirmations:
+      wrong_email_hint: Mur eil an seòladh puist-d seo mar bu chòir, ’s urrainn dhut atharrachadh ann an roghainnean a’ chunntais.
     delete_account: Sguab às an cunntas
     delete_account_html: Nam bu mhiann leat an cunntas agad a sguabadh às, <a href="%{path}">nì thu an-seo e</a>. Thèid dearbhadh iarraidh ort.
     description:
@@ -1001,6 +1038,9 @@ gd:
       email_below_hint_html: Mur eil am post-d gu h-ìosal mar bu chòir, ’s urrainn dhut atharrachadh an-seo agus gheibh thu post-d dearbhaidh ùr.
       email_settings_hint_html: Chaidh am post-d dearbhaidh a chur gu %{email}. Mur eil an seòladh puist-d seo mar bu chòir, ’s urrainn dhut atharrachadh ann an roghainnean a’ chunntais.
       title: Suidheachadh
+    sign_in:
+      preamble_html: Clàraich a-steach le do theisteas <strong>%{domain}</strong>. Ma tha an cunntas agad ’ga òstadh air frithealaiche eile, chan urrainn dhut clàradh a-steach an-seo.
+      title: Clàraich a-steach gu %{domain}
     sign_up:
       preamble: Le cunntas air an fhrithealaiche Mastodon seo, ’s urrainn dhut neach sam bith a leantainn air an lìonra, ge b’ e càit a bheil an cunntas aca-san ’ga òstadh.
       title: Suidhicheamaid %{domain} dhut.
@@ -1406,6 +1446,9 @@ gd:
       unrecognized_emoji: "– chan aithne dhuinn an Emoji seo"
   relationships:
     activity: Gnìomhachd a’ chunntais
+    confirm_follow_selected_followers: A bheil thu cinnteach gu bheil thu airson an luchd-leantainn a thagh thu a leantainn?
+    confirm_remove_selected_followers: A bheil thu cinnteach gu bheil thu airson an luchd-leantainn a thagh thu a thoirt air falbh?
+    confirm_remove_selected_follows: A bheil thu cinnteach nach eil thu airson an fheadhainn a thagh thu a leantainn tuilleadh?
     dormant: Na thàmh
     follow_selected_followers: Lean an luchd-leantainn a thagh thu
     followers: Luchd-leantainn
diff --git a/config/locales/he.yml b/config/locales/he.yml
index bad6fd6fd..6c213c530 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -535,7 +535,7 @@ he:
       public_comment: תגובה פומבית
       purge: טיהור
       purge_description_html: אם יש יסוד להניח שדומיין זה מנותק לעד, ניתן למחוק את כל רשומות החשבונות והמידע המשוייך לדומיין זה משטח האפסון שלך. זה עשוי לקחת זמן מה.
-      title: שרתים מוכרים
+      title: שרתים בפדרציה
       total_blocked_by_us: חסום על ידינו
       total_followed_by_them: נעקב על ידם
       total_followed_by_us: נעקב על ידינו
diff --git a/config/locales/my.yml b/config/locales/my.yml
index 0a0826a65..3a86851c9 100644
--- a/config/locales/my.yml
+++ b/config/locales/my.yml
@@ -8,11 +8,18 @@ my:
       other: စောင့်ကြည့်သူ
     following: စောင့်ကြည့်နေသည်
     last_active: နောက်ဆုံးအသုံးပြုခဲ့သည့်အချိန်
+    nothing_here: ဤနေရာတွင် မည်သည့်အရာမျှမရှိပါ။
+    pin_errors:
+      following: သင်ထောက်ခံလိုသောလူနောက်သို့ စောင့်ကြည့်ပြီးသားဖြစ်နေပါမည်
     posts:
       other: ပို့စ်တင်မယ်
     posts_tab_heading: ပို့စ်များ
   admin:
+    account_moderation_notes:
+      create: မှတ်စုမှထွက်ရန်
     accounts:
+      add_email_domain_block: ဒိုမိန်းကိုပိတ်မည်
+      approve: အတည်ပြုပါ
       are_you_sure: သေချာပါသလား။
       avatar: ကိုယ်စားပြုရုပ်ပုံ
       by_domain: ဒိုမိန်း
@@ -23,6 +30,10 @@ my:
         new_email: အီးမေးလ်အသစ်
         submit: အီးမေးလ်ပြောင်းပါ။
         title: "%{username} အတွက် အီးမေးလ်ပြောင်းပါ"
+      change_role:
+        label: အခန်းကဏ္ဍ ပြောင်းလဲရန်
+        no_role: အခန်းကဏ္ဍမရှိ
+        title: "%{username} အတွက် အခန်းကဏ္ဍပြောင်းပါ"
       confirm: အတည်ပြု
       confirmed: အတည်ပြုပြီးပါပြီ
       confirming: အတည်ပြုနေသည်
@@ -30,28 +41,63 @@ my:
       delete: အချက်အလက်များဖျက်ပါ
       deleted: ဖျက်ပြီးပါပြီ
       disable_two_factor_authentication: 2FA ကို ပိတ်ပါ
+      display_name: ဖော်ပြမည့်အမည်
       domain: ဒိုမိန်း
       edit: ပြင်ဆင်ရန်
       email: အီးမေးလ်
+      email_status: အီးမေးလ်အခြေအနေ
+      enable_sign_in_token_auth: အီးမေးတိုကင် စစ်မှန်ကြောင်းအတည်ပြုချက်ကို ဖွင့်ပါ
       enabled: ဖွင့်ထားသည်
       followers: စောင့်ကြည့်သူများ
+      follows: စောင့်ကြည့်မယ်
+      header: မျက်နှာဖုံးပုံ
+      invited_by: ဖိတ်ခေါ်ထားသည်
       ip: IP
+      joined: စတင်ဝင်ရောက်သည့်နေ့
       location:
         all: အားလုံး
+        local: ပြည်တွင်း
         remote: အဝေးမှ
         title: တည်နေရာ
       login_status: အကောင့်ဝင်ရောက်မှုအခြေအနေ
       media_attachments: မီဒီယာ ပူးတွဲချက်များ
+      memorialize: အမှတ်တရအဖြစ် ပြောင်းပါ
       moderation:
+        active: လက်ရှိအသုံးပြုလျက်ရှိခြင်း
         all: အားလုံး
+        pending: ဆိုင်းငံ့ထားခြင်း
+        silenced: ကန့်သတ်ထားသော
+        suspended: ရပ်ဆိုင်းထားခြင်း
+        title: စိစစ်ခြင်း
+      moderation_notes: စိစစ်ခြင်းဆိုင်ရာမှတ်စုများ
+      most_recent_activity: နောက်ဆုံးအသုံးပြုခဲ့သည့်အချိန်
+      most_recent_ip: အသုံးပြုလေ့ရှိသည့် IP လိပ်စာ
+      no_account_selected: မည်သည့်အကောင့်ကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ
+      perform_full_suspension: ရပ်ဆိုင်းရန်
+      promote: အထောက်အကူ
+      protocol: လုပ်ထုံးလုပ်နည်း
       public: အများမြင်
+      redownload: ပရိုဖိုင်ကို ပြန်လည်စတင်ရန်
+      redownloaded_msg: မူလမှစ၍ %{username} ၏ ပရိုဖိုင်ကို ပြန်လည်စတင်ပြီးပါပြီ
       reject: ဖယ်ရှားပါ
       remove_avatar: ကိုယ်စားပြုရုပ်ပုံကို ဖယ်ရှားပါ
+      remove_header: မျက်နှာဖုံးပုံ ဖယ်ရှားရန်
+      removed_avatar_msg: "%{username} ၏ ကိုယ်စားပြုရုပ်ပုံအား ဖယ်ရှားပြီးပါပြီ"
+      removed_header_msg: "%{username} ၏ မျက်နှာဖုံးပုံအား ဖယ်ရှားပြီးပါပြီ"
+      resend_confirmation:
+        already_confirmed: ဤအသုံးပြုသူကို အတည်ပြုပြီးပါပြီ
+        send: အတည်ပြုထားသောအီးမေးလ် ပြန်ပို့ပေးရန်
+        success: အတည်ပြုထားသောအီးမေးလ် ပို့ပြီးပါပြီ။
       reset: ပြန်သတ်မှတ်မည်
+      role: အခန်းကဏ္ဍ
       search: ရှာရန်
+      search_same_ip: IP တူတူ အသုံးပြုသော အခြားသူများ
       security_measures:
         only_password: စကားဝှက်ဖြင့်သာ
         password_and_2fa: စကားဝှက်နှင့် 2FA
+      show:
+        created_reports: ဆောင်ရွက်ခဲ့ပြီးသောအစီရင်ခံစာများ
+        targeted_reports: အခြားသူများမှဆောင်ရွက်ခဲ့သော အစီရင်ခံစာများ
       silence: ကန့်သတ်
       silenced: ကန့်သတ်ထားသည်
       statuses: ပို့စ်များ
@@ -59,22 +105,48 @@ my:
       suspend: ရပ်ဆိုင်းပါ
       suspended: ရပ်ဆိုင်းထားသည်
       title: အကောင့်များ
+      unblock_email: အီးမေးလ်ကိုပြန်ဖွင့်မည်
+      unblocked_email_msg: " %{username} အီးမေးလ်ကိုပြန်ဖွင့်လိုက်ပါပြီ"
       unsubscribe: စာရင်းမှထွက်ရန်
       unsuspended_msg: "%{username} ၏ အကောင့်ကို ရပ်ဆိုင်းလိုက်ပါပြီ"
       username: အသုံးပြုသူအမည်
       web: ဝဘ်
     action_logs:
       action_types:
+        approve_user: အသုံးပြုသူကို အတည်ပြုရန်
+        change_email_user: အသုံးပြုသူအတွက် အီးမေးလ်ပြောင်းရန်
+        change_role_user: အသုံးပြုသူ၏ အခန်းကဏ္ဍကို ပြောင်းလဲရန်
+        confirm_user: အသုံးပြုသူကို လက်ခံရန်
         create_announcement: ကြေညာချက်ဖန်တီးပါ
         create_custom_emoji: စိတ်ကြိုက်အီမိုဂျီ ဖန်တီးပါ
+        create_ip_block: IP စည်းမျဉ်း ဖန်တီးရန်
+        create_user_role: အခန်းကဏ္ဍဖန်တီးပါ
+        destroy_announcement: ကြေညာချက်ကို ဖျက်ပါ
+        destroy_custom_emoji: စိတ်ကြိုက်အီမိုဂျီကို ဖျက်ရန်
+        destroy_ip_block: IP စည်းမျဉ်းကို ဖျက်ပါ
         destroy_status: Post ကို ဖျက်ပါ
+        destroy_unavailable_domain: အသုံးမပြုနိုင်သောဒိုမိန်းကို ဖျက်ပါ
         disable_2fa_user: 2FA ကို ပိတ်ပါ
         disable_custom_emoji: စိတ်ကြိုက်အီမိုဂျီကို ပိတ်ပါ
+        disable_user: အသုံးပြုသူကို ပိတ်ပါ
+        enable_custom_emoji: စိတ်ကြိုက်အီမိုဂျီကို ဖွင့်ပါ
+        enable_user: အသုံးပြုသူကို ဖွင့်ပါ
+        memorialize_account: အမှတ်တရအကောင့်
+        promote_user: အသုံးပြုသူ မြှင့်တင်ရန်
+        reject_user: အသုံးပြုသူ ဖယ်ရှားရန်
         remove_avatar_user: ကိုယ်စားပြုရုပ်ပုံကို ဖယ်ရှားပါ
         silence_account: အကောင့် ကန့်သတ်ပါ
         suspend_account: အကောင့် ရပ်ဆိုင်းပါ
+        update_announcement: ကြေညာချက်ပြင်ဆင်ရန်
+        update_custom_emoji: စိတ်ကြိုက်အီမိုဂျီကို ပြင်ဆင်ရန်
+        update_ip_block: IP စည်းမျဉ်း ပြင်ဆင်ရန်
         update_status: ပို့စ်ပြင်ဆင်ရန်
+        update_user_role: အခန်းကဏ္ဍပြင်ဆင်ရန်
+      actions:
+        destroy_custom_emoji_html: "%{name} ဖျက်လိုက်သော အီမိုဂျီ %{target}"
+        disable_custom_emoji_html: "%{name} ပိတ်ထားသောအီမိုဂျီ %{target}"
       deleted_account: အကောင့်ဖျက်ပြီးပါပြီ
+      empty: မှတ်တမ်းများ မတွေ့ပါ။
     announcements:
       destroyed_msg: ကြေညာချက် ဖျက်ပြီးပါပြီ
       edit:
@@ -91,7 +163,10 @@ my:
     custom_emojis:
       by_domain: ဒိုမိန်း
       copy: ကူးယူပါ
+      create_new_category: အမျိုးအစားအသစ်ဖန်တီးရန်
+      created_msg: အီမိုဂျီ ဖန်တီးပြီးပါပြီ။
       delete: ဖျက်ပါ
+      destroyed_msg: အီမိုဂျီ ဖျက်ပစ်လိုက်ပါပြီ။
       disable: ပိတ်ပါ
       disabled: ပိတ်ပြီးပါပြီ
       emoji: အီမိုဂျီ
@@ -103,11 +178,17 @@ my:
       new:
         title: စိတ်ကြိုက်အီမိုဂျီအသစ် ထည့်ပါ
       title: စိတ်ကြိုက်အီမိုဂျီများ
+      unlist: စာရင်းမသွင်းထားပါ
       unlisted: စာရင်းမသွင်းထားပါ
       update_failed_msg: ထိုအီမိုဂျီကို ပြင်ဆင်၍မရပါ
       updated_msg: အီမိုဂျီကို ပြင်ဆင်ပြီးပါပြီ။
+      upload: တင္ရန်
     dashboard:
+      active_users: လက်ရှိအသုံးပြုသူများ
+      media_storage: မီဒီယာသိုလှောင်မှု
       new_users: အသုံးပြုသူအသစ်များ
+      top_languages: လက်ရှိအသုံးများလျက်ရှိသည့် ဘာသာစကား
+      top_servers: လက်ရှိအသုံးများလျက်ရှိသည့် ဆာဗာများ
       website: ဝဘ်ဆိုဒ်
     domain_blocks:
       domain: ဒိုမိန်း
@@ -116,8 +197,13 @@ my:
           silence: ကန့်သတ်
           suspend: ရပ်ဆိုင်းပါ
       private_comment: သီးသန့်မှတ်ချက်
+      public_comment: အများမြင်မှတ်ချက်
     email_domain_blocks:
+      add_new: အသစ် ထည့်ပါ
       delete: ဖျက်ပါ
+      dns:
+        types:
+          mx: MX မှတ်တမ်း
       domain: ဒိုမိန်း
       new:
         create: ဒိုမိန်းထည့်ပါ
@@ -127,21 +213,29 @@ my:
       no_file: ဖိုင်ရွေးထားခြင်းမရှိပါ
     follow_recommendations:
       language: ဘာသာစကားအတွက်
+      status: အခြေအနေ
     instances:
       back_to_all: အားလုံး
       back_to_limited: ကန့်သတ်ထားသည်
+      confirm_purge: ဤဒိုမိန်းမှ အချက်အလက်များကို အပြီးတိုင်ဖျက်လိုသည်မှာ သေချာပါသလား။
       content_policies:
         policies:
+          reject_media: မီဒီယာဖယ်ရှားရန်
+          reject_reports: အစီရင်ခံစာများ ဖယ်ရှားရန်
           silence: ကန့်သတ်
+          suspend: ရပ်ဆိုင်းပါ
         policy: မူဝါဒ
       dashboard:
         instance_followers_measure: ကျွန်ုပ်တို့၏စောင့်ကြည့်သူများ အဲ့ဒီနေရာမှာပါ
         instance_follows_measure: သူတို့၏စောင့်ကြည့်သူများ ဒီနေရာမှာပါ
+        instance_languages_dimension: အသုံးများသည့်ဘာသာစကားများ
       delivery:
         all: အားလုံး
+        unavailable: မရရှိနိုင်ပါ
       moderation:
         all: အားလုံး
         limited: ကန့်သတ်ထားသော
+        title: စိစစ်ခြင်း
       private_comment: သီးသန့်မှတ်ချက်
       public_comment: အများမြင်မှတ်ချက်
       total_storage: မီဒီယာ ပူးတွဲချက်များ
@@ -149,33 +243,72 @@ my:
       filter:
         all: အားလုံး
         available: ရရှိနိုင်သော
+        title: စစ်ထုတ်ခြင်း
     ip_blocks:
+      add_new: စည်းမျဉ်းဖန်တီးပါ
+      created_msg: IP စည်းမျဉ်းအသစ် ထည့်သွင်းပြီးပါပြီ
       delete: ဖျက်ပါ
       expires_in:
-        '1209600': 2 weeks
-        '15778476': 6 months
-        '2629746': 1 month
-        '31556952': 1 year
-        '86400': 1 day
+        '1209600': ၂ ပတ်
+        '15778476': ၆ လ
+        '2629746': ၁ လ
+        '31556952': ၁ နှစ်
+        '86400': ၁ ရက်
         '94670856': ၃ နှစ်
+      new:
+        title: IP စည်းမျဉ်းအသစ်ဖန်တီးပါ
       title: IP စည်းမျဉ်းများ
+    relationships:
+      title: "%{acct} နှင့် ပတ်သက်မှု"
     relays:
       delete: ဖျက်ပါ
       disable: ပိတ်ပါ
       disabled: ပိတ်ထားသည်
       enable: ဖွင့်ပါ
       enabled: ဖွင့်ထားသည်
+      status: အခြေအနေ
     reports:
+      account:
+        notes:
+          other: "%{count} မှတ်စု"
+      are_you_sure: သေချာပါသလား။
+      assign_to_self: ကျွန်ုပ်ကို တာဝန်ပေးရန်
+      assigned: စိစစ်သူကို တာဝန်ပေးရန်
+      category: အမျိုးအစား
       delete_and_resolve: ပို့စ်များကို ဖျက်ပါ
-      view_profile: ပရိုဖိုင်ကိုကြည့်ရန်
+      notes:
+        create: မှတ်စုထည့်ရန်
+        create_and_unresolve: မှတ်စုဖြင့် ပြန်ဖွင့်ရန်
+        delete: ဖျက်ပါ
+        title: မှတ်စုများ
+      reopen: အစီရင်ခံစာပြန်ဖွင့်ရန်
+      report: "#%{id} အစီရင်ခံရန်"
+      resolved: ဖြေရှင်းပြီးပါပြီ
+      status: အခြေအနေ
+      summary:
+        actions:
+          suspend_html: "<strong>@%{acct}</strong> ကို ဆိုင်းငံ့ထားသောကြောင့် ပရိုဖိုင်နှင့် အကြောင်းအရာများအား ဝင်ရောက်ခွင့်မရှိတော့သဖြင့် အပြန်အလှန် တုံ့ပြန်၍ မရတော့ခြင်း"
+        delete_data_html: "<strong>@%{acct}</strong> ၏ ပရိုဖိုင်နှင့် အကြောင်းအရာများကို ဆိုင်းငံ့ထားခြင်းမရှိပါက ယခုမှ ရက်ပေါင်း ၃၀ အတွင်း ဖျက်ရန်"
+      updated_at: ပြင်ဆင်ပြီးပါပြီ
+      view_profile: ပရိုဖိုင်ကြည့်ရန်
     roles:
+      add_new: အခန်းကဏ္ဍထည့်ပါ
       categories:
         devops: DevOps
+        moderation: စိစစ်ခြင်း
       delete: ဖျက်ပါ
       permissions_count:
         other: "%{count} ခွင့်ပြုချက်"
       privileges:
+        administrator: စီမံသူ
+        delete_user_data: အသုံးပြုသူ၏အချက်အလက်ကို ဖျက်ပါ
+        invite_users: အသုံးပြုသူများကို ဖိတ်ခေါ်ရန်
+        invite_users_description: ဆာဗာသို့ လူသစ်များဖိတ်ခေါ်ရန်အတွက် အသုံးပြုသူအား ခွင့်ပြုရန်
         manage_announcements: ကြေညာချက်များကို စီမံပါ
+        manage_announcements_description: ဆာဗာပေါ်တွင် ကြေညာချက်များစီမံရန်အတွက် အသုံးပြုသူအား ခွင့်ပြုရန်
+        manage_reports: အစီရင်ခံစာများကို စီမံပါ
+        manage_roles: အခန်းကဏ္ဍများကို စီမံပါ
+        manage_rules: စည်းမျဉ်းများကို စီမံပါ
         manage_settings: သတ်မှတ်ချက်များကို စီမံပါ
         manage_users: အသုံးပြုသူများကို စီမံပါ
         view_devops: DevOps
@@ -185,17 +318,44 @@ my:
     settings:
       about:
         title: အကြောင်း
+      appearance:
+        title: ပုံပန်းသဏ္ဌာန်
+      discovery:
+        profile_directory: ပရိုဖိုင်လမ်းညွှန်
+      domain_blocks:
+        all: လူတိုင်း
+      title: ဆာဗာသတ်မှတ်ချက်များ
+    site_uploads:
+      delete: တင်ထားသောဖိုင်ဖျက်ရန်
     statuses:
       account: ရေးသားသူ
       back_to_account: အကောင့်စာမျက်နှာသို့ ပြန်သွားရန်
       deleted: ဖျက်ပြီးပါပြီ
+      favourites: အကြိုက်ဆုံးများ
       language: ဘာသာစကား
       media:
         title: မီဒီယာ
+      original_status: မူရင်းပို့စ်
+      title: အကောင့်ပို့စ်များ
+      with_media: မီဒီယာနှင့်အတူ
+    system_checks:
+      rules_check:
+        action: ဆာဗာစည်းမျဉ်းများကို စီမံရန်
     trends:
       allow: ခွင့်ပြု
+      approved: အတည်ပြုပြီးပါပြီ
       disallow: ခွင့်မပြု
+      rejected: ဖယ်ရှားပြီးပါပြီ
+      statuses:
+        allow: ပို့စ်တင်ခွင့်ပြုရန်
+        disallow: ပို့စ်ကို တင်ခွင့်မပြုရန်
       tags:
+        dashboard:
+          tag_languages_dimension: အသုံးများသည့်ဘာသာစကားများ
+          tag_servers_dimension: အသုံးများသည့်ဆာဗာများ
+          tag_servers_measure: မတူညီသောဆာဗာများ
+          tag_uses_measure: စုစုပေါင်းအသုံးပြုမှု
+        listable: အကြံပြုနိုင်ပါသည်
         not_usable: အသုံးမပြုနိုင်ပါ
         usable: အသုံးပြုနိုင်သည်
     warning_presets:
@@ -203,20 +363,38 @@ my:
       delete: ဖျက်ပါ
     webhooks:
       delete: ဖျက်ပါ
+      disable: ပိတ်ပါ
+      disabled: ပိတ်ထားသည်
       enable: ဖွင့်ပါ
+      enabled: လက်ရှိ
+      events: ပွဲအစီအစဉ်များ
+      status: အခြေအနေ
   appearance:
     localization:
       guide_link_text: လူတိုင်းပါဝင်ကူညီနိုင်ပါတယ်။
   application_mailer:
+    salutation: "%{name}"
+    view: ကြည့်ရှုရန် -
     view_profile: ပရိုဖိုင်ကိုကြည့်ရန်
     view_status: ပို့စ်ကိုကြည့်ရန်
+  applications:
+    created: အက်ပလီကေးရှင်းကို ဖန်တီးပြီးပါပြီ
   auth:
     change_password: စကားဝှက်
     delete_account: အကောင့်ဖျက်ပါ
+    description:
+      prefix_sign_up: ယနေ့တွင် Mastodon ၌ စာရင်းသွင်းလိုက်ပါ။
+    forgot_password: သင့်စကားဝှက် မေ့နေပါသလား။
+    log_in_with: ဖြင့် ဝင်ရောက်ပါ
+    login: အကောင့်ဝင်ရန်
     logout: ထွက်မယ်
+    migrate_account: အခြားအကောင့်တစ်ခုသို့ ရွှေ့ရန်
     providers:
       cas: CAS
       saml: SAML
+    register: အကောင့်ဖွင့်ရန်
+    registration_closed: "%{instance} သည် အဖွဲ့ဝင်အသစ်များကို လက်ခံထားခြင်းမရှိပါ"
+    security: လုံခြုံရေး
     set_new_password: စကားဝှက်အသစ် သတ်မှတ်ပါ။
     status:
       account_status: အကောင့်အခြေအနေ
@@ -224,6 +402,8 @@ my:
     follow: စောင့်ကြည့်မယ်
     follow_request: သင်သည် စောင့်ကြည့်မည် တောင်းဆိုချက်တစ်ခု ပေးပို့ထားသည်-
     post_follow:
+      close: သို့မဟုတ် သင်သည် ဤဝင်းဒိုးကို ပိတ်နိုင်သည်
+      return: အသုံးပြုသူ၏ ပရိုဖိုင်ကိုပြရန်
       web: ဝဘ်သို့ သွားပါ
     title: "%{acct} ကို စောင့်ကြည့်မယ်"
   challenge:
@@ -240,6 +420,7 @@ my:
       about_x_years: "%{count}y"
       almost_x_years: "%{count}y"
       half_a_minute: အခုလေးတင်
+      less_than_x_minutes: "%{count}m"
       less_than_x_seconds: အခုလေးတင်
       over_x_years: "%{count}y"
       x_days: "%{count}y"
@@ -253,6 +434,8 @@ my:
     strikes:
       status: "#%{id} ပို့စ်"
       title: "%{date} မှ %{action}"
+      title_actions:
+        none: သတိပေးချက်
   errors:
     '400': The request you submitted was invalid or malformed.
     '403': You don't have permission to view this page.
@@ -265,19 +448,32 @@ my:
     archive_takeout:
       date: ရက်စွဲ
       size: အရွယ်အစား
+    blocks: သင်ပိတ်ပင်ထားသည့်လူများစာရင်း
     csv: CSV
     lists: စာရင်းများ
+    storage: မီဒီယာသိုလှောင်မှု
   featured_tags:
     add_new: အသစ် ထည့်ပါ
   filters:
     contexts:
+      account: ပရိုဖိုင်များ
+      home: ပင်မနှင့် စာရင်းများ
       notifications: အကြောင်းကြားချက်များ
+      thread: စကားဝိုင်းများ
+    edit:
+      statuses: တစ်ဦးချင်းတင်ထားသောပို့စ်များ
+      title: စစ်ထုတ်ခြင်းကို ပြင်ဆင်ရန်
     index:
+      contexts: "%{contexts} ရှိ စစ်ထုတ်ထားမှုများ"
       delete: ဖျက်ပါ
+      empty: သင့်တွင် စစ်ထုတ်ထားခြင်းများ မရှိပါ။
       statuses:
         other: "%{count} ပို့စ်"
+      title: စစ်ထုတ်ခြင်းများ
   generic:
     all: အားလုံး
+    copy: ကူးယူပါ
+    delete: ဖျက်ပါ
     today: ယနေ့
   invites:
     expires_in:
@@ -287,6 +483,7 @@ my:
       '43200': ၁၂ နာရီ
       '604800': ၁ ပတ်
       '86400': ၁ ရက်
+    max_uses_prompt: အကန့်အသတ်မဲ့
   login_activities:
     authentication_methods:
       otp: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်အက်ပ်
@@ -295,8 +492,13 @@ my:
     validations:
       images_and_video: ရုပ်ပုံပါရှိပြီးသားပို့စ်တွင် ဗီဒီယို ပူးတွဲ၍မရပါ
   migrations:
+    acct: သို့ ပြောင်းရွှေ့ရန်
     errors:
       not_found: ရှာမတွေ့ပါ
+    proceed_with_move: စောင့်ကြည့်သူများကို ရွှေ့ရန်
+    warning:
+      only_redirect_html: တနည်းအားဖြင့် သင်သည် <a href="%{path}">သင့်ပရိုဖိုင်ပေါ်တွင် ပြန်ညွှန်းခြင်းကိုသာ ပြုလုပ်နိုင်သည်</a>။
+      redirect: သင့်လက်ရှိအကောင့်၏ပရိုဖိုင်ကို ပြန်လည်ညွှန်းပေးသည့်အသိပေးချက်ဖြင့် ပြင်ဆင်ပေးမည်ဖြစ်ပြီး ရှာဖွေမှုများမှ ဖယ်ထုတ်ပေးမည်ဖြစ်သည်
   notification_mailer:
     follow:
       title: စောင့်ကြည့်သူအသစ်
@@ -315,23 +517,75 @@ my:
           quadrillion: Q
           thousand: K
           trillion: T
+  otp_authentication:
+    enable: ဖွင့်ပါ
+  pagination:
+    truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: ဤစစ်တမ်းတွင် သင်ပါဝင်ပြီးဖြစ်သည်
+      duplicate_options: ထပ်တူညီသောအရာများပါဝင်နေသည်
+      duration_too_long: အလှမ်းဝေးလွန်းတယ်
+      duration_too_short: စောလွန်းတယ်
+      expired: စစ်တမ်းပြီးဆုံးသွားပါပြီ
+      invalid_choice: သင်ရွေးချယ်လိုသောအရာမှာ စစ်တမ်းတွင်မပါဝင်ပါ
+      over_character_limit: သတ်မှတ်ထားသောစာလုံးအရေအတွက် %{max} ထက်ပိုနေသည်
+      too_few_options: တစ်ခုထက်ပိုနေသည်
+      too_many_options: သတ်မှတ်ထားသောအရေအတွက် %{max} ကိုကျော်လွန်နေသည်
   privacy_policy:
     title: ကိုယ်ရေးအချက်အလက်မူဝါဒ
   relationships:
     followers: စောင့်ကြည့်သူများ
     following: စောင့်ကြည့်နေသည်
+    moved: ရွှေ့ပြီးပါပြီ
     mutual: အပြန်အလှန်စောင့်ကြည့်ထားခြင်း
+    status: အကောင့်အခြေအနေ
   sessions:
+    description: "%{platform} ပေါ်ရှိ %{browser}"
     platforms:
       ios: iOS
       linux: Linux
       mac: macOS
+    revoke: ပြန်ရုပ်သိမ်းရန်
   settings:
+    account: အကောင့်
+    account_settings: အကောင့်သတ်မှတ်ချက်များ
+    appearance: ပုံပန်းသဏ္ဌာန်
+    delete: အကောင့်ဖျက်သိမ်းခြင်း
     edit_profile: ပရိုဖိုင်ပြင်ဆင်ရန်
+    notifications: အသိပေးချက်များ
+    profile: ပရိုဖိုင်
+    relationships: စောင့်ကြည့်သူများနှင့် စောင့်ကြည့်စာရင်း
+    statuses_cleanup: အလိုအလျောက်ပို့စ်ဖျက်ခြင်း
+    two_factor_authentication: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်
   statuses:
+    attached:
+      description: ပူးတွဲပါ- %{attached}
+      image:
+        other: "%{count} ပုံ"
+      video:
+        other: "%{count} ဗီဒီယို"
+    edited_at_html: "%{date} ကို ပြင်ဆင်ပြီးပါပြီ"
+    open_in_web: ဝဘ်တွင် ဖွင့်ပါ
+    poll:
+      total_people:
+        other: "%{count} ယောက်"
+      total_votes:
+        other: မဲအရေအတွက် %{count} မဲ
+      vote: မဲပေးမည်
+    show_more: ပိုမိုပြရန်
+    show_newer: ပို့စ်အသစ်များပြရန်
+    show_older: ပို့စ်အဟောင်းများပြရန်
+    title: '%{name}: "%{quote}"'
     visibilities:
+      direct: တိုက်ရိုက်
+      private: စောင့်ကြည့်သူများသာ
+      private_long: စောင့်ကြည့်သူများကိုသာ ပြရန်
       public: အများမြင်
+      public_long: လူတိုင်းမြင်နိုင်ပါသည်
   statuses_cleanup:
+    keep_polls: စစ်တမ်းကိုဆက်လက်ထားမည်
+    keep_polls_hint: သင့်မှတ်တမ်းတစ်ခုမှ မပျက်ပါ
     min_age:
       '1209600': ၂ ပတ်
       '15778476': ၆ လ
@@ -341,11 +595,37 @@ my:
       '604800': ၁ ပတ်
       '63113904': ၂ နှစ်
       '7889238': ၃ လ
+  stream_entries:
+    pinned: ပင်တွဲထားသောပို့စ်
+  themes:
+    default: Mastodon (အနက်)
   time:
     formats:
+      default: "%b %d, %Y, %H:%M"
       month: "%b %Y"
       time: "%H:%M"
   two_factor_authentication:
+    add: ထည့်ရန်
     disable: 2FA ကို ပိတ်ပါ
+    edit: ပြင်ဆင်ရန်
     enabled: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ကို ဖွင့်ထားသည်
     enabled_success: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ကို ဖွင့်ပြီးပါပြီ
+    methods: နှစ်ဆင့်ခံလုံခြုံရေးနည်းလမ်းများ
+  user_mailer:
+    appeal_approved:
+      action: သင့်အကောင့်သို့ သွားပါ
+    suspicious_sign_in:
+      change_password: သင်၏ စကားဝှက်ပြောင်းလဲပါ
+    warning:
+      explanation:
+        disable: သင့်အကောင့်ကို အသုံးမပြုနိုင်တော့သော်လည်း သင့်ပရိုဖိုင်နှင့် အခြားအချက်အလက်များမှာ ကျန်ရှိနေမည်ဖြစ်သည်။ သင့်အချက်အလက်ကို မိတ္တူကူးရန်၊ အကောင့်သတ်မှတ်ချက်များကို ပြောင်းလဲရန် သို့မဟုတ် သင့်အကောင့်ဖျက်သိမ်းရန်တို့အတွက် အရန်သိမ်းဆည်းမှုအား သင် တောင်းဆိုနိုင်သည်။
+        suspend: သင့်အကောင့်ကို အသုံးမပြုနိုင်တော့သည့်အပြင် ပရိုဖိုင်နှင့် အခြားအချက်အလက်များကိုလည်း အသုံးပြု၍မရတော့ပါ။ သင့်အချက်အလက်ကို ရက်ပေါင်း ၃၀ ခန့်အတွင်း အပြည့်အဝ မဖယ်ရှားမချင်း အချက်အလက်များ အရန်ကူးယူရန်အတွက် အကောင့်သို့ ဝင်ရောက်နိုင်ပါသေးသည်။ သို့သော် အကောင့်ရပ်ဆိုင်းထားမှုရှောင်လွှဲခြင်းမှ ကာကွယ်ရန်အတွက် အခြေခံအချက်အလက်အချို့ကို ကျွန်ုပ်တို့ ထိန်းသိမ်းထားရပါမည်။
+      reason: အကြောင်းပြချက် -
+      subject:
+        none: "%{acct} အတွက် သတိပေးချက်"
+    welcome:
+      edit_profile_action: ပရိုဖိုင်ထည့်သွင်းရန်
+      edit_profile_step: ပရိုဖိုင်ဓာတ်ပုံတစ်ပုံ တင်ခြင်း၊ ဖော်ပြမည့်အမည် ပြောင်းလဲခြင်းနှင့် အခြားအရာများပြုလုပ်ခြင်းတို့ဖြင့် သင့်ပရိုဖိုင်ကို စိတ်ကြိုက်ပြင်ဆင်နိုင်ပါသည်။ စောင့်ကြည့်သူအသစ်များ သင့်ကိုစောင့်ကြည့်ခွင့်မပြုမီ ပြန်လည်သုံးသပ်ရန်အတွက် ဆုံးဖြတ်နိုင်ပါသည်။
+  webauthn_credentials:
+    delete: ဖျက်ရန်
+    registered_on: "%{date} တွင် စာရင်းသွင်းထားသည်"
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index d293f7539..d49a9b684 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -1225,7 +1225,7 @@ nl:
     types:
       blocking: Blokkeerlijst
       bookmarks: Bladwijzers
-      domain_blocking: Lijst met genegeerde servers
+      domain_blocking: Lijst met geblokkeerde domeinen
       following: Volglijst
       muting: Negeerlijst
     upload: Uploaden
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index a34d77f98..cbd35cd29 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -619,6 +619,8 @@ pt-BR:
           mark_as_sensitive_html: 'Você está prestes a <strong>marcar</strong> algumas das publicações de <strong>@%{acct}</strong> como <strong>sensíveis</strong>. Isso irá:'
           silence_html: 'Você está prestes a <strong>limitar</strong> <strong>a conta de @%{acct}</strong>. Isso irá:'
           suspend_html: 'Você está prestes a <strong>suspender</strong> <strong>a conta de @%{acct}</strong>. Isso irá:'
+        actions:
+          delete_html: Remover as publicações ofensivas
         close_report: 'Marcar denúncia #%{id} como resolvida'
         close_reports_html: Marcar <strong>todas</strong> as denúncias contra <strong>@%{acct}</strong> como resolvidas
         delete_data_html: Exclua o perfil e o conteúdo de <strong>@%{acct}</strong> daqui a 30 dias, a menos que a suspensão seja desfeita nesse meio tempo
diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml
index 21d9c277f..267d2292c 100644
--- a/config/locales/simple_form.ar.yml
+++ b/config/locales/simple_form.ar.yml
@@ -48,7 +48,7 @@ ar:
         phrase: سوف يتم العثور عليه مهما كان نوع النص أو حتى و إن كان داخل الويب فيه تحذير عن المحتوى
         scopes: ما هي المجالات المسموح بها في التطبيق ؟ إن قمت باختيار أعلى المجالات فيمكنك الاستغناء عن الخَيار اليدوي.
         setting_aggregate_reblogs: لا تقم بعرض المشارَكات الجديدة لمنشورات قد قُمتَ بمشاركتها سابقا (هذا الإجراء يعني المشاركات الجديدة فقط التي تلقيتَها)
-        setting_always_send_emails: عادة لن ترسل الإشعارات إلى بريدك الإلكتروني عندما تكون نشط على ماستدون
+        setting_always_send_emails: عادة لن تُرسَل إليك إشعارات البريد الإلكتروني عندما تكون نشطًا على ماستدون
         setting_default_sensitive: تُخفى الوسائط الحساسة تلقائيا ويمكن اظهارها عن طريق النقر عليها
         setting_display_media_default: إخفاء الوسائط المُعيَّنة كحساسة
         setting_display_media_hide_all: إخفاء كافة الوسائط دائمًا
@@ -73,6 +73,7 @@ ar:
           hide: إخفاء المحتويات التي تم تصفيتها، والتصرف كما لو أنها غير موجودة
           warn: إخفاء المحتوى الذي تم تصفيته خلف تحذير يذكر عنوان الفلتر
       form_admin_settings:
+        activity_api_enabled: عدد المنشورات المحلية و المستخدمين الناشطين و التسجيلات الأسبوعية الجديدة
         backups_retention_period: الاحتفاظ بأرشيف المستخدم الذي تم إنشاؤه لعدد محدد من الأيام.
         bootstrap_timeline_accounts: سيتم تثبيت هذه الحسابات على قمة التوصيات للمستخدمين الجدد.
         closed_registrations_message: ما سيعرض عند إغلاق التسجيلات
@@ -83,11 +84,12 @@ ar:
         profile_directory: دليل الملف الشخصي يسرد جميع المستخدمين الذين اختاروا الدخول ليكونوا قابلين للاكتشاف.
         require_invite_text: عندما تتطلب التسجيلات الموافقة اليدوية، اجعل إدخال النص "لماذا تريد الانضمام ؟" إلزاميا بدلا من اختياري
         site_contact_email: كيف يمكن للأشخاص أن يصلوا إليك للحصول على استفسارات قانونية أو استفسارات دعم.
-        site_contact_username: كيف يمكن للناس أن يصلوا إليك في ماستدون.
+        site_contact_username: كيف يمكن للناس أن يتصلوا بك في ماستدون.
         site_extended_description: أي معلومات إضافية قد تكون مفيدة للزوار والمستخدمين. يمكن تنظيمها مع بناء بنية Markdown.
         site_short_description: وصف قصير للمساعدة في التعرف على الخادم الخاص بك. من يقوم بتشغيله، ولمن ؟
         site_terms: استخدم سياسة الخصوصية الخاصة بك أو اتركها فارغة لاستخدام الافتراضي. يمكن هيكلتها مع بناء الجملة المصغرة مارك داون.
         site_title: كيف يمكن للناس الرجوع إلى الخادم الخاص بك إلى جانب اسم النطاق.
+        status_page_url: العنوان التشعبي حيث يمكن للناس رؤية صفحة حالة هذا الخادم عند حدوث عطب ما
         theme: الشكل الذي يشاهده الزوار الجدد و الغير مسجلين الدخول.
         thumbnail: عرض حوالي 2:1 صورة إلى جانب معلومات الخادم الخاص بك.
         timeline_preview: الزوار الذين سجلوا خروجهم سيكونون قادرين على تصفح أحدث المشاركات العامة المتاحة على الخادم.
@@ -247,11 +249,13 @@ ar:
         site_short_description: وصف الخادم
         site_terms: سياسة الخصوصية
         site_title: اسم الخادم
+        status_page_url: الرابط التشعبي لصفحة حالة الخادم
         theme: الحُلَّة الإفتراضية
         thumbnail: الصورة المصغرة للخادم
         timeline_preview: السماح بالوصول غير الموثق إلى الخيوط الزمنية العامة
         trendable_by_default: السماح للوسوم بالظهور على المتداوَلة دون مراجعة مسبقة
         trends: تمكين المتداوَلة
+        trends_as_landing_page: استخدام المُتداوَلة كصفحة ترحيب
       interactions:
         must_be_follower: حظر الإشعارات القادمة من حسابات لا تتبعك
         must_be_following: حظر الإشعارات القادمة من الحسابات التي لا تتابعها
diff --git a/config/locales/simple_form.ast.yml b/config/locales/simple_form.ast.yml
index 31501ed86..c17b3b898 100644
--- a/config/locales/simple_form.ast.yml
+++ b/config/locales/simple_form.ast.yml
@@ -7,6 +7,7 @@ ast:
       announcement:
         all_day: Al marcar la opción, namás apaecen les dates del intervalu de tiempu
         ends_at: Opcional. L'anunciu dexa de tar espublizáu na data qu'indiques
+        scheduled_at: Dexa esti campu como ta pa espublizar l'anunciu nel intre
         starts_at: Opcional. En casu de que l'anunciu tea arreyáu a un intervalu de tiempu específicu
         text: Pues usar la sintaxis de los artículos. Ten en cuenta l'espaciu que l'anunciu va ocupar na pantalla del usuariu/a
       defaults:
@@ -21,11 +22,16 @@ ast:
         locale: La llingua de la interfaz, los mensaxes per corréu electrónicu ya los avisos push
         locked: Controla manualmente quién pue siguite pente l'aprobación de les solicitúes de siguimientu
         password: Usa polo menos 8 caráuteres
+        setting_aggregate_reblogs: Nun amuesa los artículos compartíos nuevos que xá se compartieren de recién (namás afeuta a los artículos compartíos d'agora)
+        setting_always_send_emails: Los avisos nun se suelen unviar per corréu electrónicu si uses activamente Mastodon
+        setting_default_sensitive: El conteníu multimedia sensible anúbrese por defeutu ya pue amosase al calcar nelli
         setting_display_media_default: Anubrilu cuando se marque como sensible
         setting_display_media_hide_all: Anubrilu siempres
         setting_display_media_show_all: Amosalu siempres
         setting_hide_network: Les persones que sigas ya les que te sigan nun van apaecer nel to perfil
+        setting_noindex: Afeuta al perfil públicu ya a les páxines de los artículos
         setting_show_application: L'aplicación qu'uses pa espublizar apaez na vista detallada de los tos artículos
+        setting_use_blurhash: Los dilíos básense nos colores del conteníu multimedia anubríu mas desenfonca los detalles
         username: 'El nome d''usuariu va ser únicu en: %{domain}'
       featured_tag:
         name: 'Equí tán dalgunes de les etiquetes qu''usesti apocayá:'
@@ -40,6 +46,7 @@ ast:
         site_extended_description: Cualesquier tipu d'información adicional que pueda ser útil pa visitantes ya pa perfiles rexistraos. El testu pue estructurase cola sintaxis de Mastodon.
         site_short_description: Un descripción curtia qu'ayuda a identificar de forma única al sirvidor. ¿Quién lu lleva?, ¿pa quién ye?
         theme: L'estilu que los visitantes ya los perfiles nuevos usen.
+        trends: Les tendencies amuesen artículos, etiquetes ya noticies que tean ganando popularidá nesti sirvidor.
       form_challenge:
         current_password: Tas entrando a una área segura
       imports:
@@ -47,8 +54,10 @@ ast:
       invite_request:
         text: Esto va ayudanos a revisar la to solicitú
       ip_block:
-        comment: Opcional. Un recordatoriu de por qué amestesti esta regla.
+        comment: Opcional. Un recordatoriu de por qué amestesti esta norma.
         expires_in: Les direiciones IP son un recursu finitu, suelen compartise ya cambiar de manes. Por esti motivu, nun s'aconseyen los bloqueos indefiníos de direiciones IP.
+      user:
+        chosen_languages: Namás los artículos de les llingües que marques son los que van apaecer nes llinies de tiempu públiques
     labels:
       account:
         fields:
@@ -93,18 +102,26 @@ ast:
         phrase: Pallabra clave o fras
         setting_advanced_layout: Activar la interfaz web avanzada
         setting_aggregate_reblogs: Agrupar los artículos compartíos nes llinies de tiempu
+        setting_always_send_emails: Unviar siempres los avisos per corréu electrónicu
         setting_auto_play_gif: Reproducir automáticamente los GIFs
         setting_boost_modal: Amosar el diálogu de confirmación enantes de compartir un artículu
+        setting_crop_images: Recortar les imáxenes de los artículos ensin espander a la proporción 16:9
         setting_default_language: Llingua de los artículos
         setting_default_privacy: Privacidá de los artículos
+        setting_default_sensitive: Marcar siempres tol conteníu como sensible
         setting_delete_modal: Amosar el diálogu de confirmación enantes de desaniciar un artículu
+        setting_disable_swiping: Desactivar el movimientu de desplazamientu
         setting_display_media: Conteníu multimedia
+        setting_expand_spoilers: Espander siempres los artículos marcaos con alvertencies de conteníu
+        setting_hide_network: Anubrir les cuentes que sigas ya te sigan
+        setting_noindex: Arrenunciar a apaecer nos índices de los motores de busca
         setting_reduce_motion: Amenorgar el movimientu de les animaciones
         setting_show_application: Dicir les aplicaciones que s'usen pa unviar artículos
         setting_system_font_ui: Usar la fonte predeterminada del sistema
         setting_theme: Estilu del sitiu
         setting_trends: Amosar les tendencies de güei
         setting_unfollow_modal: Amosar el diálogu de confirmación enantes de dexar de siguir a daquién
+        setting_use_blurhash: Facer que'l conteníu multimedia anubríu tenga dilíos coloríos
         setting_use_pending_items: Mou lentu
         severity: Gravedá
         sign_in_token_attempt: Códigu de seguranza
@@ -129,6 +146,9 @@ ast:
         site_title: Nome del sirvidor
         theme: Estilu predetermináu
         thumbnail: Miniatura del sirvidor
+        timeline_preview: Permitir l'accesu ensin autenticar a les llinies de tiempu públiques
+        trendable_by_default: Permitir tendencies ensin revisión previa
+        trends: Activar les tendencies
       interactions:
         must_be_follower: Bloquiar los avisos de los perfiles que nun te siguen
         must_be_following: Bloquiar los avisos de los perfiles que nun sigues
@@ -146,15 +166,24 @@ ast:
         reblog: Daquién compartió'l to artículu
         report: Unvióse un informe nuevu
         trending_tag: Una tendencia rique una revisión
+      rule:
+        text: Norma
       tag:
+        listable: Permitir qu'esta etiqueta apaeza nes busques ya nes suxerencies
         name: Etiqueta
+        trendable: Permitir qu'esta etiqueta apaeza nes tendencies
+        usable: Permitir que los artículos usen esta etiqueta
       user:
         role: Rol
       user_role:
         name: Nome
         permissions_as_keys: Permisos
         position: Prioridá
+      webhook:
+        events: Eventos activos
     'no': Non
+    not_recommended: Nun s'aconseya
+    recommended: Aconséyase
     required:
       mark: "*"
     'yes': Sí
diff --git a/config/locales/simple_form.be.yml b/config/locales/simple_form.be.yml
index cdd1b3477..e5696a56f 100644
--- a/config/locales/simple_form.be.yml
+++ b/config/locales/simple_form.be.yml
@@ -87,6 +87,7 @@ be:
         site_short_description: Кароткае апісанне, каб дапамагчы адназначна ідэнтыфікаваць ваш сервер. Хто яго падтрымлівае, для каго ён?
         site_terms: Апішыце ўласную палітыку прыватнасці альбо пакіньце поле пустым, калі хочаце скарыстацца прадвызначанай. Можна карыстацца сінтаксісам Markdown каб структураваць тэкст.
         site_title: Як людзі могуць звяртацца да вашага серверу акрамя яго даменнага імя.
+        status_page_url: URL старонкі, дзе людзі могуць бачыць стан гэтага сервера падчас збою
         theme: Тэма, што бачаць новыя карыстальнікі ды наведвальнікі, якія выйшлі.
         thumbnail: Выява памерамі прыкладна 2:1, якая паказваецца побач з інфармацыяй пра ваш сервер.
         timeline_preview: Наведвальнікі, якія выйшлі, змогуць праглядаць апошнія публічныя допісы на серверы.
diff --git a/config/locales/simple_form.bg.yml b/config/locales/simple_form.bg.yml
index 94f7f5b3f..3ec5e19e1 100644
--- a/config/locales/simple_form.bg.yml
+++ b/config/locales/simple_form.bg.yml
@@ -40,7 +40,7 @@ bg:
         discoverable: Позволяване на странници да откриват вашия акаунт чрез препоръки, нашумели и други неща
         email: Ще ви се изпрати имейл за потвърждение
         fields: Може да добавите до 4 елемента в таблицата към профила си
-        header: PNG, GIF или JPG. До %{size}. Ще бъде смалена до %{dimensions} пиксела
+        header: PNG, GIF или JPG. До най-много %{size}. Ще се смали до %{dimensions} пиксела
         inbox_url: Копирайте URL адреса на заглавната страница на предаващия сървър, който искат да използвате
         irreversible: Филтрираните публикации ще изчезнат безвъзвратно, дори филтърът да бъде премахнат по-късно
         locale: Езикът на потребителския интерфейс, известиятата по имейл и насочените известия
@@ -82,8 +82,8 @@ bg:
         custom_css: Може да прилагате собствени стилове в уеб версията на Mastodon.
         mascot: Можете да заместите илюстрацията в разширения уеб интерфейс.
         media_cache_retention_period: Свалените мултимедийни файлове ще бъдат изтрити след посочения брой дни, когато броят е положително число, и ще бъдат свалени отново при поискване.
-        peers_api_enabled: Списък от домейни, с който сървърът се е свързал във fediverse. Тук не се включват данни за това дали федерирате с даден сървър, а само за това дали вашият сървър знае за него. Това се ползва от услуги, които събират статистики за федерацията в общия смисъл.
-        profile_directory: Указателят на профили съдържа всички потребители, които са се съгласили да бъдат откривани.
+        peers_api_enabled: Списък от имена на домейни, с които сървърът се е свързал във федивселената. Тук не се включват данни за това дали федерирате с даден сървър, а само за това дали сървърът ви знае за него. Това се ползва от услуги, събиращи статистика за федерацията в общия смисъл.
+        profile_directory: Указателят на профили вписва всички потребители, избрали да бъдат откриваеми.
         require_invite_text: Когато регистрацията изисква ръчно одобрение, текстовото поле за това "Защо желаете да се присъедините?" ще бъде задължително, вместо по желание
         site_contact_email: Как могат хората да се свържат с вас относно правни запитвания или помощ.
         site_contact_username: Как хората могат да ви достигнат в Mastodon.
@@ -91,11 +91,13 @@ bg:
         site_short_description: Кратък опис за помощ на неповторимата самоличност на сървъра ви. Кой го управлява, за кого е?
         site_terms: Използвайте собствени правила за поверителност или оставете празно, за да използвате тези по подразбиране. Може да се структурира с Markdown синтаксис.
         site_title: Как могат хората да наричат вашия сървър, освен името на домейна.
+        status_page_url: Адресът на страницата, където хората могат да видят състоянието на този сървър по време на прекъсване
         theme: Темата, която нови и невлезли потребители ще виждат.
         thumbnail: Изображение в резолюция около 2:1, показвана до информацията за вашия сървър.
         timeline_preview: Невлезлите потребители ще могат да преглеждат най-новите публични публикации, налични на сървъра.
         trendable_by_default: Прескачане на ръчния преглед на нашумяло съдържание. Отделни елементи могат да бъдат премахвани от нашумели в последствие.
-        trends: В секцията Нашумели се показват публикации, хаштагове и новини, набрали популярност на вашия сървър.
+        trends: В раздел „Налагащо се“ се показват публикации, хаштагове и новини, набрали популярност на сървъра ви.
+        trends_as_landing_page: Показване на налагащото се съдържание за излизащите потребители и посетители вместо на описа на този сървър. Изисква налагащото се да бъде включено.
       form_challenge:
         current_password: Влизате в сигурна зона
       imports:
@@ -211,7 +213,7 @@ bg:
         setting_show_application: Разкриване на приложението, изпращащо публикации
         setting_system_font_ui: Употреба на стандартния шрифт на системата
         setting_theme: Тема на сайта
-        setting_trends: Показване на днешните нашумели
+        setting_trends: Показване на днешното налагащо се
         setting_unfollow_modal: Показване на прозорче за потвърждение преди прекратяване следването на някого
         setting_use_blurhash: Показване на цветни преливки за скрита мултимедия
         setting_use_pending_items: Бавен режим
@@ -251,11 +253,13 @@ bg:
         site_short_description: Опис на сървъра
         site_terms: Политика за поверителност
         site_title: Име на сървъра
+        status_page_url: URL адрес на страница със състоянието
         theme: Стандартна тема
         thumbnail: Миниобраз на сървъра
         timeline_preview: Позволяване на неупълномощен достъп до публични часови оси
-        trendable_by_default: Без преглед на нашумели
+        trendable_by_default: Без преглед на налагащото се
         trends: Включване на налагащи се
+        trends_as_landing_page: Употреба на налагащото се като целева страница
       interactions:
         must_be_follower: Блокирай известия от не-последователи
         must_be_following: Блокиране на известия от неследваните
diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml
index 682928653..b7baf6aff 100644
--- a/config/locales/simple_form.de.yml
+++ b/config/locales/simple_form.de.yml
@@ -97,11 +97,11 @@ de:
         timeline_preview: Besucher*innen und ausgeloggte Benutzer*innen können die neuesten öffentlichen Beiträge dieses Servers aufrufen.
         trendable_by_default: Manuelles Überprüfen angesagter Inhalte überspringen. Einzelne Elemente können später noch aus den Trends entfernt werden.
         trends: Trends zeigen, welche Beiträge, Hashtags und Nachrichten auf deinem Server immer beliebter werden.
-        trends_as_landing_page: Dies zeigt nicht angemeldeten Personen Trendinhalte anstelle einer Beschreibung des Servers an. Erfordert, dass Trends aktiviert sind.
+        trends_as_landing_page: Zeigt Trendinhalte abgemeldeter Benutzer und Besucher anstelle einer Beschreibung dieses Servers an. Erfordert, dass Trends aktiviert sind.
       form_challenge:
         current_password: Du betrittst einen gesicherten Bereich
       imports:
-        data: CSV-Datei, exportiert von einem anderen Mastodon-Server
+        data: CSV-Datei, die aus einem anderen Mastodon-Server exportiert wurde
       invite_request:
         text: Dies wird uns bei der Überprüfung deiner Anmeldung behilflich sein
       ip_block:
@@ -138,9 +138,9 @@ de:
           name: Bezeichnung
           value: Inhalt
       account_alias:
-        acct: Betreiber des alten Kontos
+        acct: Adresse des alten Kontos
       account_migration:
-        acct: Betreiber des neuen Kontos
+        acct: Adresse des neuen Kontos
       account_warning_preset:
         text: Vorlagentext
         title: Titel
@@ -163,9 +163,9 @@ de:
         starts_at: Beginn der Ankündigung
         text: Ankündigung
       appeal:
-        text: Teile mit, warum diese Entscheidung zurückgenommen werden soll
+        text: Erkläre, warum diese Entscheidung rückgängig gemacht werden soll
       defaults:
-        autofollow: Lade ein, um deinem Konto zu folgen
+        autofollow: Meinem Profil automatisch folgen
         avatar: Profilbild
         bot: Dies ist ein Bot-Konto
         chosen_languages: Sprachen einschränken
@@ -183,16 +183,16 @@ de:
         honeypot: "%{label} (nicht ausfüllen)"
         inbox_url: Inbox-URL des Relais
         irreversible: Endgültig, nicht nur temporär ausblenden
-        locale: Sprache des Webinterface
+        locale: Sprache des Webinterfaces
         locked: Geschütztes Profil
-        max_uses: Maximale Anzahl der Nutzer
+        max_uses: Maximale Verwendungen
         new_password: Neues Passwort
         note: Über mich
         otp_attempt: Zwei-Faktor-Authentisierung
         password: Passwort
         phrase: Wort oder Formulierung
         setting_advanced_layout: Erweitertes Webinterface verwenden
-        setting_aggregate_reblogs: Boosts in der Timeline gruppieren
+        setting_aggregate_reblogs: Geteilte Beiträge in den Timelines gruppieren
         setting_always_send_emails: Benachrichtigungen immer senden
         setting_auto_play_gif: Animierte GIFs automatisch abspielen
         setting_boost_modal: Bestätigung vor dem Teilen einholen
@@ -280,7 +280,7 @@ de:
         appeal: wenn jemand einer Moderationsentscheidung widerspricht
         digest: Zusammenfassung senden
         favourite: wenn jemand meinen Beitrag favorisiert
-        follow: wenn mir jemand folgt
+        follow: wenn mir jemand Neues gefolgt ist
         follow_request: wenn mir jemand folgen möchte
         mention: wenn mich jemand erwähnt
         pending_account: wenn ein neues Konto überprüft werden muss
diff --git a/config/locales/simple_form.es.yml b/config/locales/simple_form.es.yml
index fc8c332e0..593416aca 100644
--- a/config/locales/simple_form.es.yml
+++ b/config/locales/simple_form.es.yml
@@ -91,12 +91,13 @@ es:
         site_short_description: Una breve descripción para ayudar a identificar su servidor de forma única. ¿Quién lo administra, a quién va dirigido?
         site_terms: Utiliza tu propia política de privacidad o déjala en blanco para usar la predeterminada Puede estructurarse con formato Markdown.
         site_title: Cómo puede referirse la gente a tu servidor además de por el nombre de dominio.
-        status_page_url: URL de la página donde la gente pueda ver el estado de este servidor durante la exclusión
+        status_page_url: URL de la página donde la gente puede ver el estado de este servidor durante una incidencia
         theme: El tema que los visitantes no registrados y los nuevos usuarios ven.
         thumbnail: Una imagen de aproximadamente 2:1 se muestra junto a la información de tu servidor.
         timeline_preview: Los visitantes no registrados podrán navegar por los mensajes públicos más recientes disponibles en el servidor.
         trendable_by_default: Omitir la revisión manual del contenido en tendencia. Los elementos individuales aún podrán eliminarse de las tendencias.
         trends: Las tendencias muestran qué mensajes, etiquetas y noticias están ganando tracción en tu servidor.
+        trends_as_landing_page: Mostrar contenido en tendencia para usuarios y visitantes en lugar de una descripción de este servidor. Requiere que las tendencias estén habilitadas.
       form_challenge:
         current_password: Estás entrando en un área segura
       imports:
@@ -252,11 +253,13 @@ es:
         site_short_description: Descripción del servidor
         site_terms: Política de Privacidad
         site_title: Nombre del servidor
+        status_page_url: URL de página de estado
         theme: Tema por defecto
         thumbnail: Miniatura del servidor
         timeline_preview: Permitir el acceso no autenticado a las líneas de tiempo públicas
         trendable_by_default: Permitir tendencias sin revisión previa
         trends: Habilitar tendencias
+        trends_as_landing_page: Usar tendencias como la página de inicio
       interactions:
         must_be_follower: Bloquear notificaciones de personas que no te siguen
         must_be_following: Bloquear notificaciones de personas que no sigues
diff --git a/config/locales/simple_form.gd.yml b/config/locales/simple_form.gd.yml
index 55df2370d..c86fc5a0c 100644
--- a/config/locales/simple_form.gd.yml
+++ b/config/locales/simple_form.gd.yml
@@ -18,6 +18,8 @@ gd:
           disable: Bac an cleachdaiche o chleachdadh a’ chunntais aca ach na sguab às no falaich an t-susbaint aca.
           none: Cleachd seo airson rabhadh a chur dhan chleachdaiche gun ghnìomh eile a ghabhail.
           sensitive: Èignich comharra gu bheil e frionasach air a h-uile ceanglachan meadhain a’ chleachdaiche seo.
+          silence: Bac an cleachdaiche o bhith a’ postadh le faicsinneachd poblach, falaich na postaichean aca agus brathan o na daoine nach eil ’ga leantainn. Dùinidh seo gach gearan mun chunntas seo.
+          suspend: Bac eadar-ghnìomh sam bith leis a’ chunntas seo agus sguab às an t-susbaint aige. Gabhaidh seo a neo-dhèanamh am broinn 30 latha. Dùinidh seo gach gearan mun chunntas seo.
         warning_preset_id: Roghainneil. ’S urrainn dhut teacsa gnàthaichte a chur ri deireadh an ro-sheata fhathast
       announcement:
         all_day: Nuair a bhios cromag ris, cha nochd ach cinn-latha na rainse-ama
@@ -72,6 +74,7 @@ gd:
           hide: Falaich an t-susbaint chriathraichte uile gu lèir mar nach robh i ann idir
           warn: Falaich an t-susbaint chriathraichte air cùlaibh rabhaidh a dh’innseas tiotal na criathraige
       form_admin_settings:
+        activity_api_enabled: Cunntasan nam postaichean a chaidh fhoillseachadh gu h-ionadail, nan cleachdaichean gnìomhach ’s nan clàraidhean ùra an am bucaidean seachdaineil
         backups_retention_period: Cùm na tasg-lannan a chaidh a ghintinn dhan luchd-cleachdaidh rè an àireamh de làithean a shònraich thu.
         bootstrap_timeline_accounts: Thèid na cunntasan seo a phrìneachadh air bàrr nam molaidhean leantainn dhan luchd-cleachdaidh ùr.
         closed_registrations_message: Thèid seo a shealltainn nuair a bhios an clàradh dùinte
@@ -79,6 +82,7 @@ gd:
         custom_css: "’S urrainn dhut stoidhlean gnàthaichte a chur an sàs air an tionndadh-lìn de Mhastodon."
         mascot: Tar-àithnidh seo an sgead-dhealbh san eadar-aghaidh-lìn adhartach.
         media_cache_retention_period: Thèid na faidhlichean meadhain air an luchdadh a-nuas a sguabadh às às dèidh an àireamh de làithean a shònraich thu nuair a bhios luach dearbh air agus an ath-luachdadh nuair a thèid an iarraidh an uairsin.
+        peers_api_enabled: Seo liosta de dh’ainmean àrainne ris an do thachair am frithealaiche seo sa cho-shaoghal. Chan eil dàta sam bith ’ga ghabhail a-staigh an-seo mu a bheil thu co-naisgte ri frithealaiche sònraichte gus nach eil ach dìreach gu bheil am frithealaiche agad eòlach air. Thèid seo a chleachdadh le seirbheisean a chruinnicheas stadastaireachd air a’ cho-nasgadh san fharsaingeachd.
         profile_directory: Seallaidh eòlaire nam pròifil liosta dhen luchd-cleachdaidh a dh’aontaich gun gabh an rùrachadh.
         require_invite_text: Nuair a bhios aontachadh a làimh riatanach dhan chlàradh, dèan an raon teacsa “Carson a bu mhiann leat ballrachd fhaighinn?” riatanach seach roghainneil
         site_contact_email: Mar a ruigear thu le ceistean laghail no taice.
@@ -87,11 +91,13 @@ gd:
         site_short_description: Tuairisgeul goirid a chuidicheas le aithneachadh sònraichte an fhrithealaiche agad. Cò leis is cò dha a tha e?
         site_terms: Cleachd am poileasaidh prìobhaideachd agad fhèin no fàg bàn e gus am fear bunaiteach a chleachdadh. ’S urrainn dhut structar a chur air le co-chàradh Markdown.
         site_title: An t-ainm a tha air an fhrithealaiche agad seach ainm àrainne.
+        status_page_url: URL duilleige far am faicear staid an fhrithealaiche seo nuair a bhios e sìos
         theme: An t-ùrlar a chì na h-aoighean gun chlàradh a-staigh agus an luchd-cleachdaidh ùr.
         thumbnail: Dealbh mu 2:1 a thèid a shealltainn ri taobh fiosrachadh an fhrithealaiche agad.
         timeline_preview: "’S urrainn dha na h-aoighean gun chlàradh a-staigh na postaichean poblach as ùire a tha ri fhaighinn air an fhrithealaiche a bhrabhsadh."
         trendable_by_default: Geàrr leum thar lèirmheas a làimh na susbainte a’ treandadh. Gabhaidh nithean fa leth a thoirt far nan treandaichean fhathast an uairsin.
         trends: Seallaidh na treandaichean na postaichean, tagaichean hais is naidheachdan a tha fèill mhòr orra air an fhrithealaiche agad.
+        trends_as_landing_page: Seall susbaint a’ treandadh dhan fheadhainn nach do chlàraich a-steach is do dh’aoighean seach tuairisgeul an fhrithealaiche seo. Feumaidh treandaichean a bhith an comas airson sin.
       form_challenge:
         current_password: Tha thu a’ tighinn a-steach gu raon tèarainte
       imports:
@@ -101,7 +107,7 @@ gd:
       ip_block:
         comment: Roghainneil. Cùm an cuimhne carson an do chuir thu an riaghailt seo ris.
         expires_in: Tha an uiread de sheòlaidhean IP cuingichte is thèid an co-roinneadh aig amannan agus an gluasad do chuideigin eile gu tric. Air an adhbhar seo, cha mholamaid bacadh IP gun chrìoch.
-        ip: Cuir a-steach seòladh IPv4 no IPv6. ’S urrainn dhut rainsean gu lèir a bhacadh le co-chàradh CIDR. Thoir an aire nach gluais thu thu fhèin a-mach!
+        ip: Cuir a-steach seòladh IPv4 no IPv6. ’S urrainn dhut rainsean gu lèir a bhacadh le co-chàradh CIDR. Thoir an aire nach glais thu thu fhèin a-mach!
         severities:
           no_access: Bac inntrigeadh dha na goireasan uile
           sign_up_block: Cha bhi ùr-chlàradh ceadaichte
@@ -227,6 +233,7 @@ gd:
           hide: Falaich uile gu lèir
           warn: Falaich le rabhadh
       form_admin_settings:
+        activity_api_enabled: Foillsich agragaid dhen stadastaireachd mu ghnìomhachd nan cleachdaichean san API
         backups_retention_period: Ùine glèidhidh aig tasg-lannan an luchd-cleachdaidh
         bootstrap_timeline_accounts: Mol na cunntasan seo do chleachdaichean ùra an-còmhnaidh
         closed_registrations_message: Teachdaireachd ghnàthaichte nuair nach eil clàradh ri fhaighinn
@@ -234,6 +241,7 @@ gd:
         custom_css: CSS gnàthaichte
         mascot: Suaichnean gnàthaichte (dìleabach)
         media_cache_retention_period: Ùine glèidhidh aig tasgadan nam meadhanan
+        peers_api_enabled: Foillsich liosta nam frithealaichean a chaidh a rùrachadh san API
         profile_directory: Cuir eòlaire nam pròifil an comas
         registrations_mode: Cò dh’fhaodas clàradh
         require_invite_text: Iarr adhbhar clàraidh
@@ -245,11 +253,13 @@ gd:
         site_short_description: Tuairisgeul an fhrithealaiche
         site_terms: Poileasaidh prìobhaideachd
         site_title: Ainm an fhrithealaiche
+        status_page_url: URL duilleag na staide
         theme: An t-ùrlar bunaiteach
         thumbnail: Dealbhag an fhrithealaiche
         timeline_preview: Ceadaich inntrigeadh gun ùghdarrachadh air na loidhnichean-ama phoblach
         trendable_by_default: Ceadaich treandaichean gun lèirmheas ro làimh
         trends: Cuir na treandaichean an comas
+        trends_as_landing_page: Cleachd na treandaichean ’nan duilleag-laighe
       interactions:
         must_be_follower: Bac na brathan nach eil o luchd-leantainn
         must_be_following: Bac na brathan o dhaoine nach lean thu
diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml
index 02e317ab6..92578cfd7 100644
--- a/config/locales/simple_form.pt-BR.yml
+++ b/config/locales/simple_form.pt-BR.yml
@@ -251,6 +251,7 @@ pt-BR:
         site_short_description: Descrição do servidor
         site_terms: Política de privacidade
         site_title: Nome do servidor
+        status_page_url: Endereço da página de status
         theme: Tema padrão
         thumbnail: Miniatura do servidor
         timeline_preview: Permitir acesso não autenticado às linhas do tempo públicas
diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml
index 855c40242..8c50b8e94 100644
--- a/config/locales/simple_form.zh-TW.yml
+++ b/config/locales/simple_form.zh-TW.yml
@@ -181,7 +181,7 @@ zh-TW:
         fields: 個人檔案詮釋資料
         header: 封面圖片
         honeypot: "%{label} (請勿填寫)"
-        inbox_url: 中繼收件匣的 URL
+        inbox_url: 中繼收件匣 URL
         irreversible: 放棄而非隱藏
         locale: 介面語言
         locked: 鎖定帳號
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index c453ee125..6ec3c0c7d 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -117,6 +117,7 @@ sk:
       redownloaded_msg: Úspešne obnovený profil %{username} z pôvodného
       reject: Zamietni
       rejected_msg: Úspešne zamietnutá prihláška %{username}
+      remote_suspension_irreversible: Údaje tohto účtu boli nenávratne zmazané.
       remove_avatar: Vymaž avatar
       remove_header: Vymaž záhlavie
       removed_avatar_msg: Úspešne odstránený obrázok avatara %{username}
@@ -508,13 +509,19 @@ sk:
         moderation: Moderácia
       delete: Vymaž
       edit: Uprav postavenie %{name}
+      everyone: Východzie oprávnenia
       privileges:
         administrator: Správca
         delete_user_data: Vymaž užívateľské dáta
         invite_users: Pozvi užívateľov
         manage_announcements: Spravuj oboznámenia
         manage_appeals: Spravuj námietky
+        manage_blocks: Spravuj blokovania
+        manage_federation: Spravuj federáciu
+        manage_reports: Spravuj hlásenia
         manage_roles: Spravuj postavenia
+        manage_rules: Spravuj pravidlá
+        manage_settings: Spravuj nastavenia
         manage_users: Spravuj užívateľov
       title: Postavenia
     rules:
@@ -1051,7 +1058,7 @@ sk:
       one: 'obsahoval nepovolený haštag: %{tags}'
       other: 'obsahoval nepovolené haštagy: %{tags}'
     errors:
-      in_reply_not_found: Príspevok, na ktorý sa snažíš odpovedať, už pravdepodobne neexistuje.
+      in_reply_not_found: Príspevok, na ktorý sa snažíš odpovedať, pravdepodobne neexistuje.
     open_in_web: Otvor v okne na webe
     over_character_limit: limit %{max} znakov bol presiahnutý
     pin_errors:
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 8081559db..a18385f59 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -709,7 +709,7 @@ th:
         preamble: ปรับแต่งส่วนติดต่อเว็บของ Mastodon
         title: ลักษณะที่ปรากฏ
       branding:
-        preamble: ตราสินค้าของเซิร์ฟเวอร์ของคุณสร้างความแตกต่างตราสินค้าของเซิร์ฟเวอร์ของคุณจากเซิร์ฟเวอร์อื่น ๆ ในเครือข่าย อาจแสดงข้อมูลนี้ข้ามสภาพแวดล้อมที่หลากหลาย เช่น ส่วนติดต่อเว็บของ Mastodon, แอปพลิเคชันเนทีฟ, ในการแสดงตัวอย่างลิงก์ในเว็บไซต์อื่น ๆ และภายในแอปการส่งข้อความ และอื่น ๆ ด้วยเหตุผลนี้ จึงเป็นการดีที่สุดที่จะทำให้ข้อมูลนี้ชัดเจน สั้น และกระชับ
+        preamble: ตราสินค้าของเซิร์ฟเวอร์ของคุณสร้างความแตกต่างของตราสินค้าจากเซิร์ฟเวอร์อื่น ๆ ในเครือข่าย อาจแสดงข้อมูลนี้ข้ามสภาพแวดล้อมที่หลากหลาย เช่น ส่วนติดต่อเว็บของ Mastodon, แอปพลิเคชันเนทีฟ, ในการแสดงตัวอย่างลิงก์ในเว็บไซต์อื่น ๆ และภายในแอปการส่งข้อความ และอื่น ๆ ด้วยเหตุผลนี้ จึงเป็นการดีที่สุดที่จะทำให้ข้อมูลนี้ชัดเจน สั้น และกระชับ
         title: ตราสินค้า
       content_retention:
         preamble: ควบคุมวิธีการจัดเก็บเนื้อหาที่ผู้ใช้สร้างขึ้นใน Mastodon
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index 97169cfde..c83dc2706 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -14,7 +14,7 @@ zh-TW:
     instance_actor_flash: 這個帳號是一個用來代表此伺服器的虛擬執行者,而非真實使用者。它用途為聯邦宇宙且不應被停權。
     last_active: 上次活躍時間
     link_verified_on: 此連結的所有權已在 %{date} 檢查過
-    nothing_here: 暫時沒有內容可供顯示!
+    nothing_here: 暫時沒有內容可供顯示!
     pin_errors:
       following: 您只能推薦您正在跟隨的使用者。
     posts:
@@ -25,15 +25,15 @@ zh-TW:
       action: 執行動作
       title: 對 %{acct} 執行站務動作
     account_moderation_notes:
-      create: 記錄
-      created_msg: 已新增管理備忘!
-      destroyed_msg: 成功刪除管理備忘!
+      create: 新增站務記錄
+      created_msg: 已成功新增管理備註!
+      destroyed_msg: 已成功刪除管理備註!
     accounts:
       add_email_domain_block: 將電子郵件網域加入黑名單
       approve: 批准
-      approved_msg: 成功審核了%{username} 的新帳號申請
+      approved_msg: 成功審核了 %{username} 的新帳號申請
       are_you_sure: 您確定嗎?
-      avatar: 頭像
+      avatar: 大頭貼
       by_domain: 站點
       change_email:
         changed_msg: 電子郵件已成功變更!
@@ -71,7 +71,7 @@ zh-TW:
       followers: 跟隨者
       follows: 正在跟隨
       header: 開頭
-      inbox_url: 收件箱 (Inbox) URL
+      inbox_url: 收件匣 (Inbox) URL
       invite_request_text: 加入原因
       invited_by: 邀請者
       ip: IP 位址
@@ -93,10 +93,10 @@ zh-TW:
         silenced: 受限的
         suspended: 已停權
         title: 站務
-      moderation_notes: 管理備忘
+      moderation_notes: 站務備註
       most_recent_activity: 最近活動
       most_recent_ip: 最近 IP 位址
-      no_account_selected: 未選取任何帳號,因此未變更
+      no_account_selected: 因未選取任何帳號,所以什麼事都沒發生
       no_limits_imposed: 未受限制
       no_role_assigned: 未指派角色
       not_subscribed: 未訂閱
@@ -112,7 +112,7 @@ zh-TW:
       redownload: 重新整理個人檔案
       redownloaded_msg: 成功重新載入%{username} 的個人檔案頁面
       reject: 拒絕
-      rejected_msg: 成功拒絕了%{username} 的新帳號申請
+      rejected_msg: 成功婉拒了 %{username} 的新帳號申請
       remote_suspension_irreversible: 此帳號之資料已被不可逆地刪除。
       remote_suspension_reversible_hint_html: 這個帳號已於此伺服器被停權,所有資料將會於 %{date} 被刪除。在此之前,遠端伺服器可以完全回復此的帳號。如果您想即時刪除這個帳號的資料,您可以在下面進行操作。
       remove_avatar: 取消大頭貼
@@ -122,7 +122,7 @@ zh-TW:
       resend_confirmation:
         already_confirmed: 此使用者已被確認
         send: 重新發送驗證信
-        success: 驗證信發送成功!
+        success: 驗證信發送成功!
       reset: 重設
       reset_password: 重設密碼
       resubscribe: 重新訂閱
@@ -132,10 +132,10 @@ zh-TW:
       search_same_ip: 其他有同個 IP 的使用者
       security_measures:
         only_password: 僅使用密碼
-        password_and_2fa: 密碼及二重因素驗證
+        password_and_2fa: 密碼及兩階段驗證 (2FA)
       sensitive: 敏感内容
       sensitized: 已標記為敏感內容
-      shared_inbox_url: 共享收件箱網址
+      shared_inbox_url: 共享收件匣 URL
       show:
         created_reports: 建立檢舉
         targeted_reports: 由其他人檢舉
@@ -252,7 +252,7 @@ zh-TW:
         destroy_status_html: "%{name} 刪除了 %{target} 的嘟文"
         destroy_unavailable_domain_html: "%{name} 恢復了對網域 %{target} 的發送"
         destroy_user_role_html: "%{name} 刪除了 %{target} 角色"
-        disable_2fa_user_html: "%{name} 停用了使用者 %{target} 的兩階段認證"
+        disable_2fa_user_html: "%{name} 停用了使用者 %{target} 的兩階段認證 (2FA) "
         disable_custom_emoji_html: "%{name} 停用了自訂表情符號 %{target}"
         disable_sign_in_token_auth_user_html: "%{name} 停用了 %{target} 之使用者電子郵件 token 驗證"
         disable_user_html: "%{name} 將使用者 %{target} 設定為禁止登入"
@@ -307,26 +307,26 @@ zh-TW:
     custom_emojis:
       assign_category: 指定分類
       by_domain: 站點
-      copied_msg: 成功將表情複製到本地
+      copied_msg: 成功建立 emoji 表情符號之本地備份
       copy: 複製
       copy_failed_msg: 無法將表情複製到本地
       create_new_category: 建立新分類
-      created_msg: 已新增表情符號!
+      created_msg: 已新增表情符號!
       delete: 刪除
-      destroyed_msg: 已刪除表情符號!
+      destroyed_msg: 已刪除表情符號!
       disable: 停用
       disabled: 已停用
-      disabled_msg: 已停用表情符號
+      disabled_msg: 已停用該表情符號
       emoji: 表情符號
       enable: 啟用
       enabled: 已啟用
-      enabled_msg: 已啟用表情符號
+      enabled_msg: 已啟用該表情符號
       image_hint: 檔案大小最大至 %{size} 之 PNG 或 GIF
       list: 列表
       listed: 已顯示
       new:
         title: 加入新的自訂表情符號
-      no_emoji_selected: 未選取任何 emoji,因此未變更
+      no_emoji_selected: 未選取任何 emoji,所以什麼事都沒發生
       not_permitted: 您無權執行此操作
       overwrite: 覆蓋
       shortcode: 短代碼
@@ -336,7 +336,7 @@ zh-TW:
       unlist: 不公開
       unlisted: 已隱藏
       update_failed_msg: 無法更新表情符號
-      updated_msg: 已更新表情符號!
+      updated_msg: 已更新表情符號!
       upload: 上傳新的表情符號
     dashboard:
       active_users: 活躍使用者
@@ -390,12 +390,12 @@ zh-TW:
           silence: 靜音
           suspend: 停權
         title: 新增封鎖站點
-      no_domain_block_selected: 因未選取項目,而未更改網域黑名單
+      no_domain_block_selected: 因未選取網域黑名單,所以什麼事都沒發生
       not_permitted: 您無權執行此操作
       obfuscate: 混淆網域名稱
       obfuscate_hint: 若啟用網域廣告列表限制,於列表部份混淆網域名稱
       private_comment: 私人留言
-      private_comment_hint: 請提供更多有關此站台限制的資訊以供版主作內部參考。
+      private_comment_hint: 請提供更多有關此站台限制的資訊以供管理員作內部參考。
       public_comment: 公開留言
       public_comment_hint: 如果您已經啟用站台限制列表的公告,請為一般大眾提供更多有關此站台限制的資訊。
       reject_media: 拒絕媒體檔案
@@ -418,7 +418,7 @@ zh-TW:
         create: 新增網域
         resolve: 解析網域
         title: 新增電子郵件黑名單項目
-      no_email_domain_block_selected: 因未選取項目,而未更改電子郵件網域黑名單
+      no_email_domain_block_selected: 因未選取電子郵件網域黑名單,所以什麼事都沒發生
       resolved_dns_records_hint_html: 網域名稱解析為以下 MX 網域,這些網域最終負責接收電子郵件。封鎖 MX 網域將會封鎖任何來自使用相同 MX 網域的電子郵件註冊,即便可見的域名是不同的也一樣。<strong>請注意,不要封鎖主要的電子郵件服務提供商。</strong>
       resolved_through_html: 透過 %{domain} 解析
       title: 電子郵件黑名單
@@ -439,7 +439,7 @@ zh-TW:
       no_file: 尚未選擇檔案
     follow_recommendations:
       description_html: |-
-        <strong>跟隨建議幫助新使用者們快速找到有趣的內容</strong>. 當使用者沒有與其他帳號有足夠多的互動以建立個人化跟隨建議時,這些帳號將會被推荐。這些帳號將基於某選定語言之高互動和高本地跟隨者數量帳號而
+        <strong>跟隨建議幫助新使用者們快速找到有趣的內容</strong>。當使用者沒有與其他帳號有足夠多的互動以建立個人化跟隨建議時,這些帳號將會被推薦。這些帳號將基於某選定語言之高互動和高本地跟隨者數量帳號而
         每日重新更新。
       language: 對於語言
       status: 狀態
@@ -532,7 +532,7 @@ zh-TW:
         '94670856': 3 年
       new:
         title: 建立新的 IP 規則
-      no_ip_block_selected: 因為沒有選擇任何 IP 規則,所以什麼事都沒發生
+      no_ip_block_selected: 因未選取任何 IP 規則,所以什麼事都沒發生
       title: IP 規則
     relationships:
       title: "%{acct} 的關係"
@@ -545,7 +545,7 @@ zh-TW:
       enable: 啟用
       enable_hint: 啟用後,您的伺服器將訂閱該中繼的所有公開文章,並將會此伺服器的公開文章發送給它。
       enabled: 已啟用
-      inbox_url: 中繼URL
+      inbox_url: 中繼 URL
       pending: 等待中繼站審核
       save_and_enable: 儲存並啟用
       setup: 設定中繼連結
@@ -553,8 +553,8 @@ zh-TW:
       status: 狀態
       title: 中繼
     report_notes:
-      created_msg: 檢舉記錄建立成功!
-      destroyed_msg: 檢舉記錄刪除成功!
+      created_msg: 檢舉備註建立成功!
+      destroyed_msg: 檢舉備註刪除成功!
     reports:
       account:
         notes:
@@ -573,7 +573,7 @@ zh-TW:
       add_to_report: 加入更多至報告
       are_you_sure: 您確定嗎?
       assign_to_self: 指派給自己
-      assigned: 指派負責人
+      assigned: 指派站務
       by_target_domain: 檢舉帳號之網域
       category: 分類
       category_description_html: 此帳號及/或被檢舉內容之原因會被引用在檢舉帳號通知中
@@ -590,13 +590,13 @@ zh-TW:
       mark_as_unresolved: 標記為「未解決」
       no_one_assigned: 沒有人
       notes:
-        create: 建立記錄
-        create_and_resolve: 建立記錄並標記為「已解決」
-        create_and_unresolve: 建立記錄並標記「未解決」
+        create: 新增備註
+        create_and_resolve: 新增備註並標記為「已解決」
+        create_and_unresolve: 新增備註並標記「未解決」
         delete: 刪除
         placeholder: 記錄已執行的動作,或其他相關的更新...
-        title: 註記
-      notes_description_html: 檢視及留下些給其他管理員和未來的自己的註記
+        title: 備註
+      notes_description_html: 檢視及留下些給其他管理員和未來的自己的備註
       processed_msg: '檢舉報告 #%{id} 已被成功處理'
       quick_actions_description_html: 採取一個快速行動,或者下捲以檢視檢舉內容:
       remote_user_placeholder: 來自 %{instance} 之遠端使用者
@@ -605,7 +605,7 @@ zh-TW:
       reported_account: 被檢舉使用者
       reported_by: 檢舉人
       resolved: 已解決
-      resolved_msg: 檢舉已處理!
+      resolved_msg: 檢舉報告已處理完成!
       skip_to_actions: 跳過行動
       status: 嘟文
       statuses: 被檢舉的內容
@@ -760,7 +760,7 @@ zh-TW:
       media:
         title: 媒體檔案
       metadata: 詮釋資料
-      no_status_selected: 因未選擇嘟文而未變更。
+      no_status_selected: 因未選取嘟文,所以什麼事都沒發生。
       open: 公開嘟文
       original_status: 原始嘟文
       reblogs: 轉嘟
@@ -782,7 +782,7 @@ zh-TW:
       appeal_pending: 申訴待審中
     system_checks:
       database_schema_check:
-        message_html: 有挂起的数据库迁移,请运行它们以确保应用程序按照预期运行。
+        message_html: 發現尚待處理的資料庫遷移 (database migration)。請執行它們以確保應用程式如期運行。
       elasticsearch_running_check:
         message_html: 無法連接 Elasticsearch。請檢查是否正在執行中,或者已關閉全文搜尋。
       elasticsearch_version_check:
@@ -807,9 +807,9 @@ zh-TW:
         description_html: 這些連結是正在被您伺服器上看到該嘟文之帳號大量分享。這些連結可以幫助您的使用者探索現在世界上正在發生的事情。除非您核准該發行者,連結將不被公開展示。您也可以核准或駁回個別連結。
         disallow: 不允許連結
         disallow_provider: 不允許發行者
-        no_link_selected: 未選取任何鏈結,因此未變更
+        no_link_selected: 因未選取任何鏈結,所以什麼事都沒發生
         publishers:
-          no_publisher_selected: 未選取任何發行者,因此未變更
+          no_publisher_selected: 因未選取任何發行者,所以什麼事都沒發生
         shared_by_over_week:
           other: 上週被 %{count} 名使用者分享
         title: 熱門連結
@@ -828,7 +828,7 @@ zh-TW:
         description_html: 這些是您伺服器上已知被正在大量分享及加入最愛之嘟文。這些嘟文能幫助您伺服器上舊雨新知發現更多帳號來跟隨。除非您核准該作者且作者允許他們的帳號被推薦至其他人,嘟文將不被公開展示。您可以核准或駁回個別嘟文。
         disallow: 不允許嘟文
         disallow_account: 不允許作者
-        no_status_selected: 未選取任何熱門嘟文,因此未變更
+        no_status_selected: 因未選取任何熱門嘟文,所以什麼事都沒發生
         not_discoverable: 嘟文作者選擇不被發現
         shared_by:
           other: 分享過或/及收藏過 %{friendly_count} 次
@@ -843,7 +843,7 @@ zh-TW:
           tag_uses_measure: 總使用次數
         description_html: 這些主題標籤正在您的伺服器上大量嘟文中出現。這些主題標籤能幫助您的使用者發現人們正集中討論的內容。除非您核准,主題標籤將不被公開展示。
         listable: 能被建議
-        no_tag_selected: 未選取任何主題標籤,因此未變更
+        no_tag_selected: 因未選取任何主題標籤,所以什麼事都沒發生
         not_listable: 不能被建議
         not_trendable: 不會登上熱門
         not_usable: 不可被使用
@@ -936,15 +936,15 @@ zh-TW:
     notification_preferences: 變更電子郵件設定
     salutation: "%{name}、"
     settings: 變更電子郵件設定︰%{link}
-    view: '進入瀏覽:'
+    view: 進入瀏覽:
     view_profile: 檢視個人檔案
     view_status: 檢視嘟文
   applications:
-    created: 已建立應用
-    destroyed: 已刪除應用
-    regenerate_token: 重設 token
-    token_regenerated: 已重設 token
-    warning: 警告,不要把它分享給任何人!
+    created: 已建立應用程式
+    destroyed: 已刪除應用程式
+    regenerate_token: 重新產生存取 token
+    token_regenerated: 已重新產生存取 token
+    warning: 警告,不要把它分享給任何人!
     your_token: 您的 access token
   auth:
     apply_for_account: 申請帳號
@@ -984,7 +984,7 @@ zh-TW:
     set_new_password: 設定新密碼
     setup:
       email_below_hint_html: 如果此電子郵件地址不正確,您可於此修改並接收郵件進行認證。
-      email_settings_hint_html: 請確認 e-mail 是否傳送到 %{email} 。如果不對的話,可以從帳號設定修改。
+      email_settings_hint_html: 請確認 e-mail 是否傳送至 %{email} 。如果電子郵件地址不正確的話,可以從帳號設定修改。
       title: 設定
     sign_in:
       preamble_html: 請登入您於 <strong>%{domain}</strong> 之帳號密碼。若您的帳號託管於其他伺服器,您將無法於此登入。
@@ -1174,7 +1174,7 @@ zh-TW:
       other: 已選取此頁面上 <strong>%{count}</strong> 個項目。
     all_matching_items_selected_html:
       other: 已選取符合您搜尋的 <strong>%{count}</strong> 個項目。
-    changes_saved_msg: 已成功儲存修改!
+    changes_saved_msg: 已成功儲存變更!
     copy: 複製
     delete: 刪除
     deselect: 取消選擇全部
@@ -1198,7 +1198,7 @@ zh-TW:
       overwrite: 覆蓋
       overwrite_long: 以新的紀錄覆蓋目前紀錄
     preface: 您可以在此匯入您在其他伺服器所匯出的資料檔,包括跟隨的使用者、封鎖的使用者名單。
-    success: 資料檔上傳成功,正在匯入,請稍候
+    success: 資料上傳成功,正在匯入,請稍候
     types:
       blocking: 您封鎖的使用者名單
       bookmarks: 書籤
@@ -1374,7 +1374,7 @@ zh-TW:
     confirm_remove_selected_followers: 您確定要移除這些選取的跟隨者嗎?
     confirm_remove_selected_follows: 您確定要移除這些選取的正在跟隨您的帳號嗎?
     dormant: 潛水中
-    follow_selected_followers: 跟隨所選的跟隨者
+    follow_selected_followers: 跟隨所選取的跟隨者
     followers: 跟隨者
     following: 跟隨中
     invited: 已邀請
@@ -1384,9 +1384,9 @@ zh-TW:
     mutual: 跟隨彼此
     primary: 主要
     relationship: 關係
-    remove_selected_domains: 從所選網域中移除所有跟隨者
-    remove_selected_followers: 移除所選的跟隨者
-    remove_selected_follows: 取消跟隨所選使用者
+    remove_selected_domains: 從所選取網域中移除所有跟隨者
+    remove_selected_followers: 移除所選取的跟隨者
+    remove_selected_follows: 取消跟隨所選取使用者
     status: 帳號狀態
   remote_follow:
     missing_resource: 無法找到資源
@@ -1566,7 +1566,7 @@ zh-TW:
       time: "%H:%M"
   two_factor_authentication:
     add: 新增
-    disable: 停用
+    disable: 停用兩階段驗證
     disabled_success: 已成功啟用兩階段驗證
     edit: 編輯
     enabled: 兩階段認證已啟用
diff --git a/config/routes.rb b/config/routes.rb
index f78d692b6..37d8dcd2e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -111,6 +111,8 @@ Rails.application.routes.draw do
 
   resource :inbox, only: [:create], module: :activitypub
 
+  get '/:encoded_at(*path)', to: redirect("/@%{path}"), constraints: { encoded_at: /%40/ }
+
   constraints(username: /[^@\/.]+/) do
     get '/@:username', to: 'accounts#show', as: :short_account
     get '/@:username/with_replies', to: 'accounts#show', as: :short_account_with_replies
diff --git a/db/migrate/20160305115639_add_devise_to_users.rb b/db/migrate/20160305115639_add_devise_to_users.rb
index 0e12e6053..fa1e521b2 100644
--- a/db/migrate/20160305115639_add_devise_to_users.rb
+++ b/db/migrate/20160305115639_add_devise_to_users.rb
@@ -2,7 +2,7 @@ class AddDeviseToUsers < ActiveRecord::Migration[4.2]
   def self.up
     change_table(:users) do |t|
       ## Database authenticatable
-      t.string :encrypted_password, null: false, default: ""
+      t.string :encrypted_password, null: false, default: ''
 
       ## Recoverable
       t.string   :reset_password_token
diff --git a/db/migrate/20161006213403_rails_settings_migration.rb b/db/migrate/20161006213403_rails_settings_migration.rb
index 9d565cb5c..02932610c 100644
--- a/db/migrate/20161006213403_rails_settings_migration.rb
+++ b/db/migrate/20161006213403_rails_settings_migration.rb
@@ -1,8 +1,8 @@
 MIGRATION_BASE_CLASS = if ActiveRecord::VERSION::MAJOR >= 5
-  ActiveRecord::Migration[5.0]
-else
-  ActiveRecord::Migration[4.2]
-end
+                         ActiveRecord::Migration[5.0]
+                       else
+                         ActiveRecord::Migration[4.2]
+                       end
 
 class RailsSettingsMigration < MIGRATION_BASE_CLASS
   def self.up
@@ -12,7 +12,7 @@ class RailsSettingsMigration < MIGRATION_BASE_CLASS
       t.references :target, null: false, polymorphic: true, index: { name: 'index_settings_on_target_type_and_target_id' }
       t.timestamps null: true
     end
-    add_index :settings, [ :target_type, :target_id, :var ], unique: true
+    add_index :settings, [:target_type, :target_id, :var], unique: true
   end
 
   def self.down
diff --git a/db/migrate/20161122163057_remove_unneeded_indexes.rb b/db/migrate/20161122163057_remove_unneeded_indexes.rb
index 3832b878d..12cc9c5b2 100644
--- a/db/migrate/20161122163057_remove_unneeded_indexes.rb
+++ b/db/migrate/20161122163057_remove_unneeded_indexes.rb
@@ -1,7 +1,7 @@
 class RemoveUnneededIndexes < ActiveRecord::Migration[5.0]
   def change
-    remove_index :notifications, name: "index_notifications_on_account_id"
-    remove_index :settings, name: "index_settings_on_target_type_and_target_id"
-    remove_index :statuses_tags, name: "index_statuses_tags_on_tag_id"
+    remove_index :notifications, name: 'index_notifications_on_account_id'
+    remove_index :settings, name: 'index_settings_on_target_type_and_target_id'
+    remove_index :statuses_tags, name: 'index_statuses_tags_on_tag_id'
   end
 end
diff --git a/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb b/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb
index 2c43210ba..39cd41c00 100644
--- a/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb
+++ b/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb
@@ -1,5 +1,5 @@
 class AddSpoilerTextToStatuses < ActiveRecord::Migration[5.0]
   def change
-    add_column :statuses, :spoiler_text, :text, default: "", null: false
+    add_column :statuses, :spoiler_text, :text, default: '', null: false
   end
 end
diff --git a/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb b/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb
index 60a287101..946e26ff2 100644
--- a/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb
+++ b/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb
@@ -1,7 +1,7 @@
 class AddVisibleInPickerToCustomEmoji < ActiveRecord::Migration[5.1]
   def change
-    safety_assured {
+    safety_assured do
       add_column :custom_emojis, :visible_in_picker, :boolean, default: true, null: false
-    }
+    end
   end
 end
diff --git a/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb b/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb
index 03f2591a8..ba67eee86 100644
--- a/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb
+++ b/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb
@@ -1,6 +1,6 @@
 class RemoveDuplicateIndexesInLists < ActiveRecord::Migration[5.1]
   def change
-    remove_index :list_accounts, name: "index_list_accounts_on_account_id"
-    remove_index :list_accounts, name: "index_list_accounts_on_list_id"
+    remove_index :list_accounts, name: 'index_list_accounts_on_account_id'
+    remove_index :list_accounts, name: 'index_list_accounts_on_list_id'
   end
 end
diff --git a/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
index b29e62803..a3f883fcb 100644
--- a/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
+++ b/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
@@ -4,9 +4,9 @@ class ImproveIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Mi
   disable_ddl_transaction!
 
   def change
-  #  These changes ware reverted by migration 20180514140000.
-  #  add_index :statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently
-  #  add_index :statuses, [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently
-  #  remove_index :statuses, column: [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106
+    #  These changes ware reverted by migration 20180514140000.
+    #  add_index :statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently
+    #  add_index :statuses, [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently
+    #  remove_index :statuses, column: [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106
   end
 end
diff --git a/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
index ccd2ec7ea..e23880bf5 100644
--- a/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
+++ b/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
@@ -5,11 +5,11 @@ class RevertIndexChangeOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecor
 
   def change
     safety_assured do
-      add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_name_exists?(:statuses, "index_statuses_20180106")
+      add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_name_exists?(:statuses, 'index_statuses_20180106')
     end
 
     # These index may not exists (see migration 20180514130000)
     remove_index :statuses, column: [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently if index_exists?(:statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)')
-    remove_index :statuses, column: [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently if index_exists?(:statuses, ["account_id", "id"], where: "(visibility = 3)")
+    remove_index :statuses, column: [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently if index_exists?(:statuses, ['account_id', 'id'], where: '(visibility = 3)')
   end
 end
diff --git a/db/migrate/20180528141303_fix_accounts_unique_index.rb b/db/migrate/20180528141303_fix_accounts_unique_index.rb
index 3e33e2cac..0b39f7107 100644
--- a/db/migrate/20180528141303_fix_accounts_unique_index.rb
+++ b/db/migrate/20180528141303_fix_accounts_unique_index.rb
@@ -106,21 +106,17 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2]
     # to check for (and skip past) uniqueness errors
     [Favourite, Follow, FollowRequest, Block, Mute].each do |klass|
       klass.where(account_id: duplicate_account.id).find_each do |record|
-        begin
-          record.update_attribute(:account_id, main_account.id)
-        rescue ActiveRecord::RecordNotUnique
-          next
-        end
+        record.update_attribute(:account_id, main_account.id)
+      rescue ActiveRecord::RecordNotUnique
+        next
       end
     end
 
     [Follow, FollowRequest, Block, Mute].each do |klass|
       klass.where(target_account_id: duplicate_account.id).find_each do |record|
-        begin
-          record.update_attribute(:target_account_id, main_account.id)
-        rescue ActiveRecord::RecordNotUnique
-          next
-        end
+        record.update_attribute(:target_account_id, main_account.id)
+      rescue ActiveRecord::RecordNotUnique
+        next
       end
     end
   end
diff --git a/db/migrate/20180617162849_remove_unused_indexes.rb b/db/migrate/20180617162849_remove_unused_indexes.rb
index 61add6385..9cd6b9164 100644
--- a/db/migrate/20180617162849_remove_unused_indexes.rb
+++ b/db/migrate/20180617162849_remove_unused_indexes.rb
@@ -1,7 +1,7 @@
 class RemoveUnusedIndexes < ActiveRecord::Migration[5.2]
   def change
-    remove_index :statuses, name: "index_statuses_on_conversation_id"
-    remove_index :users, name: "index_users_on_filtered_languages"
-    remove_index :backups, name: "index_backups_on_user_id"
+    remove_index :statuses, name: 'index_statuses_on_conversation_id'
+    remove_index :users, name: 'index_users_on_filtered_languages'
+    remove_index :backups, name: 'index_backups_on_user_id'
   end
 end
diff --git a/db/migrate/20180812173710_copy_status_stats.rb b/db/migrate/20180812173710_copy_status_stats.rb
index ff10c18d9..45eb9501c 100644
--- a/db/migrate/20180812173710_copy_status_stats.rb
+++ b/db/migrate/20180812173710_copy_status_stats.rb
@@ -19,7 +19,7 @@ class CopyStatusStats < ActiveRecord::Migration[5.2]
 
   def supports_upsert?
     version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i
-    version >= 90500
+    version >= 90_500
   end
 
   def up_fast
@@ -43,12 +43,10 @@ class CopyStatusStats < ActiveRecord::Migration[5.2]
     # We cannot use bulk INSERT or overarching transactions here because of possible
     # uniqueness violations that we need to skip over
     Status.unscoped.select('id, reblogs_count, favourites_count, created_at, updated_at').find_each do |status|
-      begin
-        params = [[nil, status.id], [nil, status.reblogs_count], [nil, status.favourites_count], [nil, status.created_at], [nil, status.updated_at]]
-        exec_insert('INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)', nil, params)
-      rescue ActiveRecord::RecordNotUnique
-        next
-      end
+      params = [[nil, status.id], [nil, status.reblogs_count], [nil, status.favourites_count], [nil, status.created_at], [nil, status.updated_at]]
+      exec_insert('INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)', nil, params)
+    rescue ActiveRecord::RecordNotUnique
+      next
     end
   end
 end
diff --git a/db/migrate/20181116173541_copy_account_stats.rb b/db/migrate/20181116173541_copy_account_stats.rb
index 8e27eb11b..f908575cb 100644
--- a/db/migrate/20181116173541_copy_account_stats.rb
+++ b/db/migrate/20181116173541_copy_account_stats.rb
@@ -19,7 +19,7 @@ class CopyAccountStats < ActiveRecord::Migration[5.2]
 
   def supports_upsert?
     version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i
-    version >= 90500
+    version >= 90_500
   end
 
   def up_fast
@@ -43,12 +43,10 @@ class CopyAccountStats < ActiveRecord::Migration[5.2]
     # We cannot use bulk INSERT or overarching transactions here because of possible
     # uniqueness violations that we need to skip over
     Account.unscoped.select('id, statuses_count, following_count, followers_count, created_at, updated_at').find_each do |account|
-      begin
-        params = [[nil, account.id], [nil, account[:statuses_count]], [nil, account[:following_count]], [nil, account[:followers_count]], [nil, account.created_at], [nil, account.updated_at]]
-        exec_insert('INSERT INTO account_stats (account_id, statuses_count, following_count, followers_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6)', nil, params)
-      rescue ActiveRecord::RecordNotUnique
-        next
-      end
+      params = [[nil, account.id], [nil, account[:statuses_count]], [nil, account[:following_count]], [nil, account[:followers_count]], [nil, account.created_at], [nil, account.updated_at]]
+      exec_insert('INSERT INTO account_stats (account_id, statuses_count, following_count, followers_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6)', nil, params)
+    rescue ActiveRecord::RecordNotUnique
+      next
     end
   end
 end
diff --git a/db/migrate/20190306145741_add_lock_version_to_polls.rb b/db/migrate/20190306145741_add_lock_version_to_polls.rb
index 5bb8cd3b4..c9fa471ad 100644
--- a/db/migrate/20190306145741_add_lock_version_to_polls.rb
+++ b/db/migrate/20190306145741_add_lock_version_to_polls.rb
@@ -21,4 +21,3 @@ class AddLockVersionToPolls < ActiveRecord::Migration[5.2]
     remove_column :polls, :lock_version
   end
 end
-
diff --git a/db/migrate/20190807135426_add_comments_to_domain_blocks.rb b/db/migrate/20190807135426_add_comments_to_domain_blocks.rb
index b660a71ad..79b9f0212 100644
--- a/db/migrate/20190807135426_add_comments_to_domain_blocks.rb
+++ b/db/migrate/20190807135426_add_comments_to_domain_blocks.rb
@@ -4,4 +4,3 @@ class AddCommentsToDomainBlocks < ActiveRecord::Migration[5.2]
     add_column :domain_blocks, :public_comment, :text
   end
 end
-
diff --git a/db/migrate/20200312162302_add_status_ids_to_announcements.rb b/db/migrate/20200312162302_add_status_ids_to_announcements.rb
index 42aa6513d..704d3773e 100644
--- a/db/migrate/20200312162302_add_status_ids_to_announcements.rb
+++ b/db/migrate/20200312162302_add_status_ids_to_announcements.rb
@@ -3,4 +3,3 @@ class AddStatusIdsToAnnouncements < ActiveRecord::Migration[5.2]
     add_column :announcements, :status_ids, :bigint, array: true
   end
 end
-
diff --git a/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb b/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb
index 1d6ba1fe9..59bb1b9e2 100644
--- a/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb
+++ b/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb
@@ -19,4 +19,3 @@ class RemoveDuplicatedIndexesPghero < ActiveRecord::Migration[5.2]
     add_index :markers, :user_id, name: :index_markers_on_user_id                                       unless index_exists?(:markers, :user_id, name: :index_markers_on_user_id)
   end
 end
-
diff --git a/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb b/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb
index 24d43a0bf..c5c80b795 100644
--- a/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb
+++ b/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb
@@ -6,7 +6,7 @@ class EncryptedMessageIdsToTimestampIds < ActiveRecord::Migration[5.2]
   end
 
   def down
-    execute("LOCK encrypted_messages")
+    execute('LOCK encrypted_messages')
     execute("SELECT setval('encrypted_messages_id_seq', (SELECT MAX(id) FROM encrypted_messages))")
     execute("ALTER TABLE encrypted_messages ALTER COLUMN id SET DEFAULT nextval('encrypted_messages_id_seq')")
   end
diff --git a/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb b/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb
index 652ce9752..b350ee9f2 100644
--- a/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb
+++ b/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb
@@ -16,7 +16,7 @@ class AddFixedLowercaseIndexToAccounts < ActiveRecord::Migration[5.2]
       add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true, algorithm: :concurrently
     rescue ActiveRecord::RecordNotUnique
       remove_index :accounts, name: 'index_accounts_on_username_and_domain_lower'
-      raise CorruptionError.new('index_accounts_on_username_and_domain_lower')
+      raise CorruptionError, 'index_accounts_on_username_and_domain_lower'
     end
 
     remove_index :accounts, name: 'old_index_accounts_on_username_and_domain_lower' if index_name_exists?(:accounts, 'old_index_accounts_on_username_and_domain_lower')
diff --git a/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb b/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb
index 5c6865b92..ccd65bf53 100644
--- a/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb
+++ b/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb
@@ -10,7 +10,7 @@ class MediaAttachmentIdsToTimestampIds < ActiveRecord::Migration[5.1]
   end
 
   def down
-    execute("LOCK media_attachments")
+    execute('LOCK media_attachments')
     execute("SELECT setval('media_attachments_id_seq', (SELECT MAX(id) FROM media_attachments))")
     execute("ALTER TABLE media_attachments ALTER COLUMN id SET DEFAULT nextval('media_attachments_id_seq')")
   end
diff --git a/db/migrate/20200628133322_create_account_notes.rb b/db/migrate/20200628133322_create_account_notes.rb
index 664727e60..022e0ff3a 100644
--- a/db/migrate/20200628133322_create_account_notes.rb
+++ b/db/migrate/20200628133322_create_account_notes.rb
@@ -10,4 +10,3 @@ class CreateAccountNotes < ActiveRecord::Migration[5.2]
     end
   end
 end
-
diff --git a/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb b/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb
index 39cd4cdea..40c582842 100644
--- a/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb
+++ b/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb
@@ -10,7 +10,7 @@ class AccountIdsToTimestampIds < ActiveRecord::Migration[5.1]
   end
 
   def down
-    execute("LOCK accounts")
+    execute('LOCK accounts')
     execute("SELECT setval('accounts_id_seq', (SELECT MAX(id) FROM accounts))")
     execute("ALTER TABLE accounts ALTER COLUMN id SET DEFAULT nextval('accounts_id_seq')")
   end
diff --git a/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb b/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb
index b3ee11d09..7f6a2c6dd 100644
--- a/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb
+++ b/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb
@@ -10,7 +10,7 @@ class AddCaseInsensitiveBtreeIndexToTags < ActiveRecord::Migration[5.2]
       safety_assured { execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)' }
     rescue ActiveRecord::StatementInvalid => e
       remove_index :tags, name: 'index_tags_on_name_lower_btree'
-      raise CorruptionError.new('index_tags_on_name_lower_btree') if e.is_a?(ActiveRecord::RecordNotUnique)
+      raise CorruptionError, 'index_tags_on_name_lower_btree' if e.is_a?(ActiveRecord::RecordNotUnique)
       raise e
     end
 
diff --git a/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb b/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb
index 28cfb6ef5..db168676a 100644
--- a/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb
+++ b/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb
@@ -17,4 +17,3 @@ class CreateAccountStatusesCleanupPolicies < ActiveRecord::Migration[6.1]
     end
   end
 end
-
diff --git a/db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb b/db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb
index 7ed34a3ef..eb437c86c 100644
--- a/db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb
+++ b/db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb
@@ -5,7 +5,7 @@ class FixCustomFilterKeywordsIdSeq < ActiveRecord::Migration[6.1]
 
   def up
     # 20220613110711 manually inserts items with set `id` in the database, but
-    # we also need to bump the sequence number, otherwise 
+    # we also need to bump the sequence number, otherwise
     safety_assured do
       execute <<-SQL.squish
         BEGIN;
diff --git a/jest.config.js b/jest.config.js
index 177e05f98..1eb143a59 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,9 +1,7 @@
-module.exports = {
-  'testEnvironment': 'jsdom',
-  'projects': [
-    '<rootDir>/app/javascript/mastodon',
-  ],
-  'testPathIgnorePatterns': [
+/** @type {import('jest').Config} */
+const config = {
+  testEnvironment: 'jsdom',
+  testPathIgnorePatterns: [
     '<rootDir>/node_modules/',
     '<rootDir>/vendor/',
     '<rootDir>/config/',
@@ -12,22 +10,17 @@ module.exports = {
     '<rootDir>/tmp/',
     '<rootDir>/app/javascript/themes/',
   ],
-  'setupFiles': [
-    'raf/polyfill',
-  ],
-  'setupFilesAfterEnv': [
-    '<rootDir>/app/javascript/mastodon/test_setup.js',
-  ],
-  'collectCoverageFrom': [
+  setupFiles: ['raf/polyfill'],
+  setupFilesAfterEnv: ['<rootDir>/app/javascript/mastodon/test_setup.js'],
+  collectCoverageFrom: [
     'app/javascript/mastodon/**/*.js',
     '!app/javascript/mastodon/features/emoji/emoji_compressed.js',
     '!app/javascript/mastodon/locales/locale-data/*.js',
     '!app/javascript/mastodon/service_worker/entry.js',
     '!app/javascript/mastodon/test_setup.js',
   ],
-  'coverageDirectory': '<rootDir>/coverage',
-  'moduleDirectories': [
-    '<rootDir>/node_modules',
-    '<rootDir>/app/javascript',
-  ],
+  coverageDirectory: '<rootDir>/coverage',
+  moduleDirectories: ['<rootDir>/node_modules', '<rootDir>/app/javascript'],
 };
+
+module.exports = config;
diff --git a/lib/cli.rb b/lib/cli.rb
index 35c00e736..157465c4b 100644
--- a/lib/cli.rb
+++ b/lib/cli.rb
@@ -121,7 +121,7 @@ module Mastodon
 
       prompt.warn('Do NOT interrupt this process...')
 
-      delete_account = ->(account) do
+      delete_account = lambda do |account|
         payload = ActiveModelSerializers::SerializableResource.new(
           account,
           serializer: ActivityPub::DeleteActorSerializer,
diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb
index 34afbc699..db379eb85 100644
--- a/lib/mastodon/accounts_cli.rb
+++ b/lib/mastodon/accounts_cli.rb
@@ -490,14 +490,12 @@ module Mastodon
         scope = Account.where(id: ::Follow.where(account: account).select(:target_account_id))
 
         scope.find_each do |target_account|
-          begin
-            UnfollowService.new.call(account, target_account)
-          rescue => e
-            progress.log pastel.red("Error processing #{target_account.id}: #{e}")
-          ensure
-            progress.increment
-            processed += 1
-          end
+          UnfollowService.new.call(account, target_account)
+        rescue => e
+          progress.log pastel.red("Error processing #{target_account.id}: #{e}")
+        ensure
+          progress.increment
+          processed += 1
         end
 
         BootstrapTimelineWorker.perform_async(account.id)
@@ -507,14 +505,12 @@ module Mastodon
         scope = Account.where(id: ::Follow.where(target_account: account).select(:account_id))
 
         scope.find_each do |target_account|
-          begin
-            UnfollowService.new.call(target_account, account)
-          rescue => e
-            progress.log pastel.red("Error processing #{target_account.id}: #{e}")
-          ensure
-            progress.increment
-            processed += 1
-          end
+          UnfollowService.new.call(target_account, account)
+        rescue => e
+          progress.log pastel.red("Error processing #{target_account.id}: #{e}")
+        ensure
+          progress.increment
+          processed += 1
         end
       end
 
diff --git a/lib/mastodon/cli_helper.rb b/lib/mastodon/cli_helper.rb
index a78a28e27..8704edd75 100644
--- a/lib/mastodon/cli_helper.rb
+++ b/lib/mastodon/cli_helper.rb
@@ -42,30 +42,28 @@ module Mastodon
 
         items.each do |item|
           futures << Concurrent::Future.execute(executor: pool) do
-            begin
-              if !progress.total.nil? && progress.progress + 1 > progress.total
-                # The number of items has changed between start and now,
-                # since there is no good way to predict the final count from
-                # here, just change the progress bar to an indeterminate one
-
-                progress.total = nil
-              end
-
-              progress.log("Processing #{item.id}") if options[:verbose]
-
-              result = ActiveRecord::Base.connection_pool.with_connection do
-                yield(item)
-              ensure
-                RedisConfiguration.pool.checkin if Thread.current[:redis]
-                Thread.current[:redis] = nil
-              end
-
-              aggregate.increment(result) if result.is_a?(Integer)
-            rescue => e
-              progress.log pastel.red("Error processing #{item.id}: #{e}")
+            if !progress.total.nil? && progress.progress + 1 > progress.total
+              # The number of items has changed between start and now,
+              # since there is no good way to predict the final count from
+              # here, just change the progress bar to an indeterminate one
+
+              progress.total = nil
+            end
+
+            progress.log("Processing #{item.id}") if options[:verbose]
+
+            result = ActiveRecord::Base.connection_pool.with_connection do
+              yield(item)
             ensure
-              progress.increment
+              RedisConfiguration.pool.checkin if Thread.current[:redis]
+              Thread.current[:redis] = nil
             end
+
+            aggregate.increment(result) if result.is_a?(Integer)
+          rescue => e
+            progress.log pastel.red("Error processing #{item.id}: #{e}")
+          ensure
+            progress.increment
           end
         end
 
diff --git a/lib/mastodon/domains_cli.rb b/lib/mastodon/domains_cli.rb
index 81ee53c18..f24a54e7e 100644
--- a/lib/mastodon/domains_cli.rb
+++ b/lib/mastodon/domains_cli.rb
@@ -139,7 +139,7 @@ module Mastodon
 
       pool = Concurrent::ThreadPoolExecutor.new(min_threads: 0, max_threads: options[:concurrency], idletime: 10, auto_terminate: true, max_queue: 0)
 
-      work_unit = ->(domain) do
+      work_unit = lambda do |domain|
         next if stats.key?(domain)
         next if options[:exclude_suspended] && domain.match?(blocked_domains)
 
diff --git a/lib/mastodon/emoji_cli.rb b/lib/mastodon/emoji_cli.rb
index a3e947909..feb77107f 100644
--- a/lib/mastodon/emoji_cli.rb
+++ b/lib/mastodon/emoji_cli.rb
@@ -49,7 +49,7 @@ module Mastodon
           next if filename.start_with?('._')
 
           shortcode    = [options[:prefix], filename, options[:suffix]].compact.join
-          custom_emoji = CustomEmoji.local.find_by("LOWER(shortcode) = ?", shortcode.downcase)
+          custom_emoji = CustomEmoji.local.find_by('LOWER(shortcode) = ?', shortcode.downcase)
 
           if custom_emoji && !options[:overwrite]
             skipped += 1
diff --git a/lib/mastodon/ip_blocks_cli.rb b/lib/mastodon/ip_blocks_cli.rb
index 5c38c1aca..08939c092 100644
--- a/lib/mastodon/ip_blocks_cli.rb
+++ b/lib/mastodon/ip_blocks_cli.rb
@@ -79,13 +79,11 @@ module Mastodon
       skipped   = 0
 
       addresses.each do |address|
-        ip_blocks = begin
-          if options[:force]
-            IpBlock.where('ip >>= ?', address)
-          else
-            IpBlock.where('ip <<= ?', address)
-          end
-        end
+        ip_blocks = if options[:force]
+                      IpBlock.where('ip >>= ?', address)
+                    else
+                      IpBlock.where('ip <<= ?', address)
+                    end
 
         if ip_blocks.empty?
           say("#{address} is not yet blocked", :yellow)
diff --git a/lib/mastodon/maintenance_cli.rb b/lib/mastodon/maintenance_cli.rb
index 85937da81..bb3802f56 100644
--- a/lib/mastodon/maintenance_cli.rb
+++ b/lib/mastodon/maintenance_cli.rb
@@ -13,8 +13,8 @@ module Mastodon
       true
     end
 
-    MIN_SUPPORTED_VERSION = 2019_10_01_213028 # rubocop:disable Style/NumericLiterals
-    MAX_SUPPORTED_VERSION = 2022_11_04_133904 # rubocop:disable Style/NumericLiterals
+    MIN_SUPPORTED_VERSION = 2019_10_01_213028
+    MAX_SUPPORTED_VERSION = 2022_11_04_133904
 
     # Stubs to enjoy ActiveRecord queries while not depending on a particular
     # version of the code/database
@@ -98,11 +98,9 @@ module Mastodon
 
         owned_classes.each do |klass|
           klass.where(account_id: other_account.id).find_each do |record|
-            begin
-              record.update_attribute(:account_id, id)
-            rescue ActiveRecord::RecordNotUnique
-              next
-            end
+            record.update_attribute(:account_id, id)
+          rescue ActiveRecord::RecordNotUnique
+            next
           end
         end
 
@@ -111,11 +109,9 @@ module Mastodon
 
         target_classes.each do |klass|
           klass.where(target_account_id: other_account.id).find_each do |record|
-            begin
-              record.update_attribute(:target_account_id, id)
-            rescue ActiveRecord::RecordNotUnique
-              next
-            end
+            record.update_attribute(:target_account_id, id)
+          rescue ActiveRecord::RecordNotUnique
+            next
           end
         end
 
@@ -209,7 +205,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring index_accounts_on_username_and_domain_lower…'
-      if ActiveRecord::Migrator.current_version < 20200620164023 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2020_06_20_164023
         ActiveRecord::Base.connection.add_index :accounts, 'lower (username), lower(domain)', name: 'index_accounts_on_username_and_domain_lower', unique: true
       else
         ActiveRecord::Base.connection.add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true
@@ -252,7 +248,7 @@ module Mastodon
         end
       end
 
-      if ActiveRecord::Migrator.current_version < 20220118183010 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_01_18_183010
         ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM users WHERE remember_token IS NOT NULL GROUP BY remember_token HAVING count(*) > 1").each do |row|
           users = User.where(id: row['ids'].split(',')).sort_by(&:updated_at).reverse.drop(1)
           @prompt.warn "Unsetting remember token for those accounts: #{users.map(&:account).map(&:acct).join(', ')}"
@@ -275,9 +271,9 @@ module Mastodon
       @prompt.say 'Restoring users indexes…'
       ActiveRecord::Base.connection.add_index :users, ['confirmation_token'], name: 'index_users_on_confirmation_token', unique: true
       ActiveRecord::Base.connection.add_index :users, ['email'], name: 'index_users_on_email', unique: true
-      ActiveRecord::Base.connection.add_index :users, ['remember_token'], name: 'index_users_on_remember_token', unique: true if ActiveRecord::Migrator.current_version < 20220118183010
+      ActiveRecord::Base.connection.add_index :users, ['remember_token'], name: 'index_users_on_remember_token', unique: true if ActiveRecord::Migrator.current_version < 2022_01_18_183010
 
-      if ActiveRecord::Migrator.current_version < 20220310060641 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_03_10_060641
         ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true
       else
         ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true, where: 'reset_password_token IS NOT NULL', opclass: :text_pattern_ops
@@ -340,7 +336,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring conversations indexes…'
-      if ActiveRecord::Migrator.current_version < 20220307083603 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_03_07_083603
         ActiveRecord::Base.connection.add_index :conversations, ['uri'], name: 'index_conversations_on_uri', unique: true
       else
         ActiveRecord::Base.connection.add_index :conversations, ['uri'], name: 'index_conversations_on_uri', unique: true, where: 'uri IS NOT NULL', opclass: :text_pattern_ops
@@ -457,7 +453,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring media_attachments indexes…'
-      if ActiveRecord::Migrator.current_version < 20220310060626 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_03_10_060626
         ActiveRecord::Base.connection.add_index :media_attachments, ['shortcode'], name: 'index_media_attachments_on_shortcode', unique: true
       else
         ActiveRecord::Base.connection.add_index :media_attachments, ['shortcode'], name: 'index_media_attachments_on_shortcode', unique: true, where: 'shortcode IS NOT NULL', opclass: :text_pattern_ops
@@ -490,7 +486,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring statuses indexes…'
-      if ActiveRecord::Migrator.current_version < 20220310060706 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_03_10_060706
         ActiveRecord::Base.connection.add_index :statuses, ['uri'], name: 'index_statuses_on_uri', unique: true
       else
         ActiveRecord::Base.connection.add_index :statuses, ['uri'], name: 'index_statuses_on_uri', unique: true, where: 'uri IS NOT NULL', opclass: :text_pattern_ops
@@ -512,7 +508,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring tags indexes…'
-      if ActiveRecord::Migrator.current_version < 20210421121431
+      if ActiveRecord::Migrator.current_version < 2021_04_21_121431
         ActiveRecord::Base.connection.add_index :tags, 'lower((name)::text)', name: 'index_tags_on_name_lower', unique: true
       else
         ActiveRecord::Base.connection.execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)'
@@ -601,11 +597,9 @@ module Mastodon
       owned_classes = [ConversationMute, AccountConversation]
       owned_classes.each do |klass|
         klass.where(conversation_id: duplicate_conv.id).find_each do |record|
-          begin
-            record.update_attribute(:account_id, main_conv.id)
-          rescue ActiveRecord::RecordNotUnique
-            next
-          end
+          record.update_attribute(:account_id, main_conv.id)
+        rescue ActiveRecord::RecordNotUnique
+          next
         end
       end
     end
@@ -629,47 +623,37 @@ module Mastodon
       owned_classes << Bookmark if ActiveRecord::Base.connection.table_exists?(:bookmarks)
       owned_classes.each do |klass|
         klass.where(status_id: duplicate_status.id).find_each do |record|
-          begin
-            record.update_attribute(:status_id, main_status.id)
-          rescue ActiveRecord::RecordNotUnique
-            next
-          end
-        end
-      end
-
-      StatusPin.where(account_id: main_status.account_id, status_id: duplicate_status.id).find_each do |record|
-        begin
           record.update_attribute(:status_id, main_status.id)
         rescue ActiveRecord::RecordNotUnique
           next
         end
       end
 
+      StatusPin.where(account_id: main_status.account_id, status_id: duplicate_status.id).find_each do |record|
+        record.update_attribute(:status_id, main_status.id)
+      rescue ActiveRecord::RecordNotUnique
+        next
+      end
+
       Status.where(in_reply_to_id: duplicate_status.id).find_each do |record|
-        begin
-          record.update_attribute(:in_reply_to_id, main_status.id)
-        rescue ActiveRecord::RecordNotUnique
-          next
-        end
+        record.update_attribute(:in_reply_to_id, main_status.id)
+      rescue ActiveRecord::RecordNotUnique
+        next
       end
 
       Status.where(reblog_of_id: duplicate_status.id).find_each do |record|
-        begin
-          record.update_attribute(:reblog_of_id, main_status.id)
-        rescue ActiveRecord::RecordNotUnique
-          next
-        end
+        record.update_attribute(:reblog_of_id, main_status.id)
+      rescue ActiveRecord::RecordNotUnique
+        next
       end
     end
 
     def merge_tags!(main_tag, duplicate_tag)
       [FeaturedTag].each do |klass|
         klass.where(tag_id: duplicate_tag.id).find_each do |record|
-          begin
-            record.update_attribute(:tag_id, main_tag.id)
-          rescue ActiveRecord::RecordNotUnique
-            next
-          end
+          record.update_attribute(:tag_id, main_tag.id)
+        rescue ActiveRecord::RecordNotUnique
+          next
         end
       end
     end
diff --git a/lib/mastodon/media_cli.rb b/lib/mastodon/media_cli.rb
index 24cc98964..fc70c8785 100644
--- a/lib/mastodon/media_cli.rb
+++ b/lib/mastodon/media_cli.rb
@@ -116,13 +116,11 @@ module Mastodon
 
         loop do
           objects = begin
-            begin
-              bucket.objects(start_after: last_key, prefix: prefix).limit(1000).map { |x| x }
-            rescue => e
-              progress.log(pastel.red("Error fetching list of files: #{e}"))
-              progress.log("If you want to continue from this point, add --start-after=#{last_key} to your command") if last_key
-              break
-            end
+            bucket.objects(start_after: last_key, prefix: prefix).limit(1000).map { |x| x }
+          rescue => e
+            progress.log(pastel.red("Error fetching list of files: #{e}"))
+            progress.log("If you want to continue from this point, add --start-after=#{last_key} to your command") if last_key
+            break
           end
 
           break if objects.empty?
@@ -277,9 +275,7 @@ module Mastodon
         exit(1)
       end
 
-      if options[:days].present?
-        scope = scope.where('media_attachments.id > ?', Mastodon::Snowflake.id_at(options[:days].days.ago, with_random: false))
-      end
+      scope = scope.where('media_attachments.id > ?', Mastodon::Snowflake.id_at(options[:days].days.ago, with_random: false)) if options[:days].present?
 
       processed, aggregate = parallelize_with_progress(scope) do |media_attachment|
         next if media_attachment.remote_url.blank? || (!options[:force] && media_attachment.file_file_name.present?)
diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb
index 2ab8150ec..5a252b351 100644
--- a/lib/mastodon/migration_helpers.rb
+++ b/lib/mastodon/migration_helpers.rb
@@ -289,8 +289,6 @@ module Mastodon
     # determines this method to be too complex while there's no way to make it
     # less "complex" without introducing extra methods (which actually will
     # make things _more_ complex).
-    #
-    # rubocop: disable Metrics/AbcSize
     def update_column_in_batches(table_name, column, value)
       if transaction_open?
         raise 'update_column_in_batches can not be run inside a transaction, ' \
@@ -573,7 +571,7 @@ module Mastodon
             o.conname as name,
             o.confdeltype as on_delete
           from pg_constraint o
-          left join pg_class f on f.oid = o.confrelid 
+          left join pg_class f on f.oid = o.confrelid
           left join pg_class c on c.oid = o.conrelid
           left join pg_class m on m.oid = o.conrelid
           where o.contype = 'f'
diff --git a/lib/mastodon/redis_config.rb b/lib/mastodon/redis_config.rb
index 3522fa11e..037ca5edc 100644
--- a/lib/mastodon/redis_config.rb
+++ b/lib/mastodon/redis_config.rb
@@ -46,6 +46,4 @@ REDIS_SIDEKIQ_PARAMS = {
   namespace: sidekiq_namespace,
 }.freeze
 
-if Rails.env.test?
-  ENV['REDIS_NAMESPACE'] = "mastodon_test#{ENV['TEST_ENV_NUMBER']}"
-end
+ENV['REDIS_NAMESPACE'] = "mastodon_test#{ENV['TEST_ENV_NUMBER']}" if Rails.env.test?
diff --git a/lib/mastodon/search_cli.rb b/lib/mastodon/search_cli.rb
index b206854ab..31e9a3d5a 100644
--- a/lib/mastodon/search_cli.rb
+++ b/lib/mastodon/search_cli.rb
@@ -43,13 +43,11 @@ module Mastodon
         exit(1)
       end
 
-      indices = begin
-        if options[:only]
-          options[:only].map { |str| "#{str.camelize}Index".constantize }
-        else
-          INDICES
-        end
-      end
+      indices = if options[:only]
+                  options[:only].map { |str| "#{str.camelize}Index".constantize }
+                else
+                  INDICES
+                end
 
       pool      = Concurrent::FixedThreadPool.new(options[:concurrency], max_queue: options[:concurrency] * 10)
       importers = indices.index_with { |index| "Importer::#{index.name}Importer".constantize.new(batch_size: options[:batch_size], executor: pool) }
diff --git a/lib/mastodon/upgrade_cli.rb b/lib/mastodon/upgrade_cli.rb
index 570b7e6fa..2b60f9eee 100644
--- a/lib/mastodon/upgrade_cli.rb
+++ b/lib/mastodon/upgrade_cli.rb
@@ -50,16 +50,14 @@ module Mastodon
             styles << :original unless styles.include?(:original)
 
             styles.each do |style|
-              success = begin
-                case Paperclip::Attachment.default_options[:storage]
-                when :s3
-                  upgrade_storage_s3(progress, attachment, style)
-                when :fog
-                  upgrade_storage_fog(progress, attachment, style)
-                when :filesystem
-                  upgrade_storage_filesystem(progress, attachment, style)
-                end
-              end
+              success = case Paperclip::Attachment.default_options[:storage]
+                        when :s3
+                          upgrade_storage_s3(progress, attachment, style)
+                        when :fog
+                          upgrade_storage_fog(progress, attachment, style)
+                        when :filesystem
+                          upgrade_storage_filesystem(progress, attachment, style)
+                        end
 
               upgraded = true if style == :original && success
 
diff --git a/lib/paperclip/attachment_extensions.rb b/lib/paperclip/attachment_extensions.rb
index d66a17623..7f82138aa 100644
--- a/lib/paperclip/attachment_extensions.rb
+++ b/lib/paperclip/attachment_extensions.rb
@@ -8,7 +8,7 @@ module Paperclip
 
     # monkey-patch to avoid unlinking too avoid unlinking source file too early
     # see https://github.com/kreeti/kt-paperclip/issues/64
-    def post_process_style(name, style) #:nodoc:
+    def post_process_style(name, style) # :nodoc:
       raise "Style #{name} has no processors defined." if style.processors.blank?
 
       intermediate_files = []
@@ -16,16 +16,16 @@ module Paperclip
       # if we're processing the original, close + unlink the source tempfile
       intermediate_files << original if name == :original
 
-      @queued_for_write[name] = style.processors.
-                                inject(original) do |file, processor|
+      @queued_for_write[name] = style.processors
+                                     .inject(original) do |file, processor|
         file = Paperclip.processor(processor).make(file, style.processor_options, self)
         intermediate_files << file unless file == original
         file
       end
 
       unadapted_file = @queued_for_write[name]
-      @queued_for_write[name] = Paperclip.io_adapters.
-                                for(@queued_for_write[name], @options[:adapter_options])
+      @queued_for_write[name] = Paperclip.io_adapters
+                                         .for(@queued_for_write[name], @options[:adapter_options])
       unadapted_file.close if unadapted_file.respond_to?(:close)
       @queued_for_write[name]
     rescue Paperclip::Errors::NotIdentifiedByImageMagickError => e
diff --git a/lib/paperclip/color_extractor.rb b/lib/paperclip/color_extractor.rb
index d3b8e1022..733dcba80 100644
--- a/lib/paperclip/color_extractor.rb
+++ b/lib/paperclip/color_extractor.rb
@@ -79,8 +79,8 @@ module Paperclip
     private
 
     def w3c_contrast(color1, color2)
-      luminance1 = color1.to_xyz.y * 0.01 + 0.05
-      luminance2 = color2.to_xyz.y * 0.01 + 0.05
+      luminance1 = (color1.to_xyz.y * 0.01) + 0.05
+      luminance2 = (color2.to_xyz.y * 0.01) + 0.05
 
       if luminance1 > luminance2
         luminance1 / luminance2
@@ -109,11 +109,11 @@ module Paperclip
 
         case max
         when r
-          h = (g - b) / d + (g < b ? 6.0 : 0)
+          h = ((g - b) / d) + (g < b ? 6.0 : 0)
         when g
-          h = (b - r) / d + 2.0
+          h = ((b - r) / d) + 2.0
         when b
-          h = (r - g) / d + 4.0
+          h = ((r - g) / d) + 4.0
         end
 
         h /= 6.0
@@ -126,9 +126,9 @@ module Paperclip
       t += 1 if t.negative?
       t -= 1 if t > 1
 
-      return (p + (q - p) * 6 * t) if t < 1 / 6.0
+      return (p + ((q - p) * 6 * t)) if t < 1 / 6.0
       return q if t < 1 / 2.0
-      return (p + (q - p) * (2 / 3.0 - t) * 6) if t < 2 / 3.0
+      return (p + ((q - p) * ((2 / 3.0) - t) * 6)) if t < 2 / 3.0
 
       p
     end
@@ -147,11 +147,11 @@ module Paperclip
         g = l.to_f
         b = l.to_f # achromatic
       else
-        q = l < 0.5 ? l * (s + 1) : l + s - l * s
-        p = 2 * l - q
-        r = hue_to_rgb(p, q, h + 1 / 3.0)
+        q = l < 0.5 ? l * (s + 1) : l + s - (l * s)
+        p = (2 * l) - q
+        r = hue_to_rgb(p, q, h + (1 / 3.0))
         g = hue_to_rgb(p, q, h)
-        b = hue_to_rgb(p, q, h - 1 / 3.0)
+        b = hue_to_rgb(p, q, h - (1 / 3.0))
       end
 
       [(r * 255).round, (g * 255).round, (b * 255).round]
@@ -161,13 +161,11 @@ module Paperclip
     def lighten_or_darken(color, by)
       hue, saturation, light = rgb_to_hsl(color.r, color.g, color.b)
 
-      light = begin
-        if light < 50
-          [100, light + by].min
-        else
-          [0, light - by].max
-        end
-      end
+      light = if light < 50
+                [100, light + by].min
+              else
+                [0, light - by].max
+              end
 
       ColorDiff::Color::RGB.new(*hsl_to_rgb(hue, saturation, light))
     end
diff --git a/lib/rails/engine_extensions.rb b/lib/rails/engine_extensions.rb
index 4e3767db9..1f5c2cd6c 100644
--- a/lib/rails/engine_extensions.rb
+++ b/lib/rails/engine_extensions.rb
@@ -3,7 +3,7 @@ module Rails
     # Rewrite task loading code to filter digitalocean.rake task
     def run_tasks_blocks(app)
       Railtie.instance_method(:run_tasks_blocks).bind_call(self, app)
-      paths["lib/tasks"].existent.reject { |ext| ext.end_with?('digitalocean.rake') }.sort.each { |ext| load(ext) }
+      paths['lib/tasks'].existent.reject { |ext| ext.end_with?('digitalocean.rake') }.sort.each { |ext| load(ext) }
     end
   end
 end
diff --git a/lib/sanitize_ext/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb
index 8da067585..330044379 100644
--- a/lib/sanitize_ext/sanitize_config.rb
+++ b/lib/sanitize_ext/sanitize_config.rb
@@ -60,13 +60,11 @@ class Sanitize
 
       current_node = env[:node]
 
-      scheme = begin
-        if current_node['href'] =~ Sanitize::REGEX_PROTOCOL
-          Regexp.last_match(1).downcase
-        else
-          :relative
-        end
-      end
+      scheme = if current_node['href'] =~ Sanitize::REGEX_PROTOCOL
+                 Regexp.last_match(1).downcase
+               else
+                 :relative
+               end
 
       current_node.replace(Nokogiri::XML::Text.new(current_node.text, current_node.document)) unless LINK_PROTOCOLS.include?(scheme)
     end
diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake
index ca939fd1f..e8a64b8fb 100644
--- a/lib/tasks/db.rake
+++ b/lib/tasks/db.rake
@@ -4,16 +4,14 @@ namespace :db do
   namespace :migrate do
     desc 'Setup the db or migrate depending on state of db'
     task setup: :environment do
-      begin
-        if ActiveRecord::Migrator.current_version.zero?
-          Rake::Task['db:migrate'].invoke
-          Rake::Task['db:seed'].invoke
-        end
-      rescue ActiveRecord::NoDatabaseError
-        Rake::Task['db:setup'].invoke
-      else
+      if ActiveRecord::Migrator.current_version.zero?
         Rake::Task['db:migrate'].invoke
+        Rake::Task['db:seed'].invoke
       end
+    rescue ActiveRecord::NoDatabaseError
+      Rake::Task['db:setup'].invoke
+    else
+      Rake::Task['db:migrate'].invoke
     end
   end
 
diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake
index 1184e5273..179a730bc 100644
--- a/lib/tasks/mastodon.rake
+++ b/lib/tasks/mastodon.rake
@@ -264,7 +264,7 @@ namespace :mastodon do
 
           env['S3_ENDPOINT'] = prompt.ask('Storj DCS endpoint URL:') do |q|
             q.required true
-            q.default "https://gateway.storjshare.io"
+            q.default 'https://gateway.storjshare.io'
             q.modify :strip
           end
 
@@ -286,13 +286,13 @@ namespace :mastodon do
             q.required true
             q.modify :strip
           end
-          
+
           linksharing_access_key = prompt.ask('Storj Linksharing access key (uplink share --register --public --readonly=true --disallow-lists --not-after=none sj://bucket):') do |q|
             q.required true
             q.modify :strip
           end
           env['S3_ALIAS_HOST'] = "link.storjshare.io/raw/#{linksharing_access_key}/#{env['S3_BUCKET']}"
-          
+
         when 'Google Cloud Storage'
           env['S3_ENABLED']             = 'true'
           env['S3_PROTOCOL']            = 'https'
diff --git a/lib/tasks/statistics.rake b/lib/tasks/statistics.rake
index 82f2b5416..440c309ce 100644
--- a/lib/tasks/statistics.rake
+++ b/lib/tasks/statistics.rake
@@ -13,7 +13,7 @@ namespace :mastodon do
       %w(Validators app/validators),
       %w(Workers app/workers),
     ].each do |name, dir|
-      ::STATS_DIRECTORIES << [name, Rails.root.join(dir)]
+      STATS_DIRECTORIES << [name, Rails.root.join(dir)]
     end
   end
 end
diff --git a/package.json b/package.json
index 5f3528cab..5e5397761 100644
--- a/package.json
+++ b/package.json
@@ -15,8 +15,8 @@
     "test:lint:js": "eslint --ext=js . --cache --report-unused-disable-directives",
     "test:lint:sass": "stylelint \"**/*.{css,scss}\" && prettier --check \"**/*.{css,scss}\"",
     "test:jest": "cross-env NODE_ENV=test jest",
-    "format": "prettier --write \"**/*.{json,yml}\"",
-    "format-check": "prettier --check \"**/*.{json,yml}\""
+    "format": "prettier --write .",
+    "format-check": "prettier --check ."
   },
   "repository": {
     "type": "git",
@@ -39,7 +39,7 @@
     "atrament": "0.2.4",
     "arrow-key-navigation": "^1.2.0",
     "autoprefixer": "^9.8.8",
-    "axios": "^1.3.2",
+    "axios": "^1.3.3",
     "babel-loader": "^8.3.0",
     "babel-plugin-lodash": "^3.3.4",
     "babel-plugin-preval": "^5.1.0",
@@ -117,7 +117,7 @@
     "requestidlecallback": "^0.3.0",
     "reselect": "^4.1.7",
     "rimraf": "^4.1.2",
-    "sass": "^1.58.0",
+    "sass": "^1.58.2",
     "sass-loader": "^10.2.0",
     "stacktrace-js": "^2.0.2",
     "stringz": "^2.1.0",
@@ -130,7 +130,7 @@
     "uuid": "^8.3.1",
     "webpack": "^4.46.0",
     "webpack-assets-manifest": "^4.0.6",
-    "webpack-bundle-analyzer": "^4.7.0",
+    "webpack-bundle-analyzer": "^4.8.0",
     "webpack-cli": "^3.3.12",
     "webpack-merge": "^5.8.0",
     "wicg-inert": "^3.1.2",
@@ -140,29 +140,29 @@
     "workbox-strategies": "^6.5.4",
     "workbox-webpack-plugin": "^6.5.4",
     "workbox-window": "^6.5.4",
-    "ws": "^8.12.0"
+    "ws": "^8.12.1"
   },
   "devDependencies": {
     "@babel/eslint-parser": "^7.19.1",
     "@testing-library/jest-dom": "^5.16.5",
     "@testing-library/react": "^12.1.5",
-    "babel-jest": "^29.4.1",
+    "babel-jest": "^29.4.3",
     "eslint": "^8.33.0",
     "eslint-plugin-import": "~2.27.5",
     "eslint-plugin-jsx-a11y": "~6.7.1",
     "eslint-plugin-promise": "~6.1.1",
     "eslint-plugin-react": "~7.32.2",
-    "jest": "^29.4.1",
-    "jest-environment-jsdom": "^29.4.1",
+    "jest": "^29.4.3",
+    "jest-environment-jsdom": "^29.4.3",
     "postcss-scss": "^4.0.6",
-    "prettier": "^2.8.3",
+    "prettier": "^2.8.4",
     "raf": "^3.4.1",
     "react-intl-translations-manager": "^5.0.3",
     "react-test-renderer": "^16.14.0",
     "stylelint": "^15.1.0",
-    "stylelint-config-standard-scss": "^7.0.0",
+    "stylelint-config-standard-scss": "^7.0.1",
     "webpack-dev-server": "^3.11.3",
-    "yargs": "^17.6.2"
+    "yargs": "^17.7.0"
   },
   "resolutions": {
     "kind-of": "^6.0.3"
diff --git a/spec/config/initializers/rack_attack_spec.rb b/spec/config/initializers/rack_attack_spec.rb
index 581021cb9..50d4505b7 100644
--- a/spec/config/initializers/rack_attack_spec.rb
+++ b/spec/config/initializers/rack_attack_spec.rb
@@ -32,25 +32,28 @@ describe Rack::Attack do
   describe 'throttle excessive sign-up requests by IP address' do
     context 'through the website' do
       let(:limit) { 25 }
-      let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } }
+      let(:request) { -> { post path, {}, 'REMOTE_ADDR' => remote_ip } }
 
       context 'for exact path' do
-        let(:path)  { '/auth' }
+        let(:path) { '/auth' }
+
         it_behaves_like 'throttled endpoint'
       end
 
       context 'for path with format' do
-        let(:path)  { '/auth.html' }
+        let(:path) { '/auth.html' }
+
         it_behaves_like 'throttled endpoint'
       end
     end
 
     context 'through the API' do
       let(:limit) { 5 }
-      let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } }
+      let(:request) { -> { post path, {}, 'REMOTE_ADDR' => remote_ip } }
 
       context 'for exact path' do
-        let(:path)  { '/api/v1/accounts' }
+        let(:path) { '/api/v1/accounts' }
+
         it_behaves_like 'throttled endpoint'
       end
 
@@ -67,15 +70,17 @@ describe Rack::Attack do
 
   describe 'throttle excessive sign-in requests by IP address' do
     let(:limit) { 25 }
-    let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } }
+    let(:request) { -> { post path, {}, 'REMOTE_ADDR' => remote_ip } }
 
     context 'for exact path' do
-      let(:path)  { '/auth/sign_in' }
+      let(:path) { '/auth/sign_in' }
+
       it_behaves_like 'throttled endpoint'
     end
 
     context 'for path with format' do
-      let(:path)  { '/auth/sign_in.html' }
+      let(:path) { '/auth/sign_in.html' }
+
       it_behaves_like 'throttled endpoint'
     end
   end
diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb
index defa8b2d3..db588156c 100644
--- a/spec/controllers/accounts_controller_spec.rb
+++ b/spec/controllers/accounts_controller_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe AccountsController, type: :controller do
   shared_examples 'cacheable response' do
     it 'does not set cookies' do
       expect(response.cookies).to be_empty
-      expect(response.headers['Set-Cookies']).to be nil
+      expect(response.headers['Set-Cookies']).to be_nil
     end
 
     it 'does not set sessions' do
diff --git a/spec/controllers/activitypub/collections_controller_spec.rb b/spec/controllers/activitypub/collections_controller_spec.rb
index f78d9abbf..4e35938db 100644
--- a/spec/controllers/activitypub/collections_controller_spec.rb
+++ b/spec/controllers/activitypub/collections_controller_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do
   shared_examples 'cacheable response' do
     it 'does not set cookies' do
       expect(response.cookies).to be_empty
-      expect(response.headers['Set-Cookies']).to be nil
+      expect(response.headers['Set-Cookies']).to be_nil
     end
 
     it 'does not set sessions' do
diff --git a/spec/controllers/activitypub/outboxes_controller_spec.rb b/spec/controllers/activitypub/outboxes_controller_spec.rb
index 74bf46a5e..d8d42b7ae 100644
--- a/spec/controllers/activitypub/outboxes_controller_spec.rb
+++ b/spec/controllers/activitypub/outboxes_controller_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
   shared_examples 'cacheable response' do
     it 'does not set cookies' do
       expect(response.cookies).to be_empty
-      expect(response.headers['Set-Cookies']).to be nil
+      expect(response.headers['Set-Cookies']).to be_nil
     end
 
     it 'does not set sessions' do
diff --git a/spec/controllers/activitypub/replies_controller_spec.rb b/spec/controllers/activitypub/replies_controller_spec.rb
index aee1a8b1a..394d4baab 100644
--- a/spec/controllers/activitypub/replies_controller_spec.rb
+++ b/spec/controllers/activitypub/replies_controller_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do
   shared_examples 'cacheable response' do
     it 'does not set cookies' do
       expect(response.cookies).to be_empty
-      expect(response.headers['Set-Cookies']).to be nil
+      expect(response.headers['Set-Cookies']).to be_nil
     end
 
     it 'does not set sessions' do
diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb
index 81d592ddd..48204b7b6 100644
--- a/spec/controllers/admin/accounts_controller_spec.rb
+++ b/spec/controllers/admin/accounts_controller_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe Admin::AccountsController, type: :controller do
         username: 'username',
         display_name: 'display name',
         email: 'local-part@domain',
-        ip: '0.0.0.42'
+        ip: '0.0.0.42',
       }
     end
 
diff --git a/spec/controllers/admin/change_email_controller_spec.rb b/spec/controllers/admin/change_email_controller_spec.rb
index cf8a27d39..0814f327d 100644
--- a/spec/controllers/admin/change_email_controller_spec.rb
+++ b/spec/controllers/admin/change_email_controller_spec.rb
@@ -9,8 +9,8 @@ RSpec.describe Admin::ChangeEmailsController, type: :controller do
     sign_in admin
   end
 
-  describe "GET #show" do
-    it "returns http success" do
+  describe 'GET #show' do
+    it 'returns http success' do
       user = Fabricate(:user)
 
       get :show, params: { account_id: user.account.id }
@@ -19,12 +19,12 @@ RSpec.describe Admin::ChangeEmailsController, type: :controller do
     end
   end
 
-  describe "GET #update" do
+  describe 'GET #update' do
     before do
       allow(UserMailer).to receive(:confirmation_instructions).and_return(double('email', deliver_later: nil))
     end
 
-    it "returns http success" do
+    it 'returns http success' do
       user = Fabricate(:user)
 
       previous_email = user.email
diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb
index 6231a09a2..ab3738fcd 100644
--- a/spec/controllers/admin/dashboard_controller_spec.rb
+++ b/spec/controllers/admin/dashboard_controller_spec.rb
@@ -8,10 +8,10 @@ describe Admin::DashboardController, type: :controller do
   describe 'GET #index' do
     before do
       allow(Admin::SystemCheck).to receive(:perform).and_return([
-        Admin::SystemCheck::Message.new(:database_schema_check),
-        Admin::SystemCheck::Message.new(:rules_check, nil, admin_rules_path),
-        Admin::SystemCheck::Message.new(:sidekiq_process_check, 'foo, bar'),
-      ])
+                                                                  Admin::SystemCheck::Message.new(:database_schema_check),
+                                                                  Admin::SystemCheck::Message.new(:rules_check, nil, admin_rules_path),
+                                                                  Admin::SystemCheck::Message.new(:sidekiq_process_check, 'foo, bar'),
+                                                                ])
       sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin'))
     end
 
diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb
index f432060d9..3b2fd6c5d 100644
--- a/spec/controllers/admin/domain_blocks_controller_spec.rb
+++ b/spec/controllers/admin/domain_blocks_controller_spec.rb
@@ -26,9 +26,9 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
           domain_blocks_attributes: {
             '0' => { enabled: '1', domain: 'example.com', severity: 'silence' },
             '1' => { enabled: '0', domain: 'mastodon.social', severity: 'suspend' },
-            '2' => { enabled: '1', domain: 'mastodon.online', severity: 'suspend' }
-          }
-        }
+            '2' => { enabled: '1', domain: 'mastodon.online', severity: 'suspend' },
+          },
+        },
       }
 
       expect(DomainBlockWorker).to have_received(:perform_async).exactly(2).times
diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb
index 4cd1524bf..4dcc277d9 100644
--- a/spec/controllers/admin/reports_controller_spec.rb
+++ b/spec/controllers/admin/reports_controller_spec.rb
@@ -4,6 +4,7 @@ describe Admin::ReportsController do
   render_views
 
   let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
+
   before do
     sign_in user, scope: :user
   end
diff --git a/spec/controllers/admin/resets_controller_spec.rb b/spec/controllers/admin/resets_controller_spec.rb
index aeb172318..64fe027fd 100644
--- a/spec/controllers/admin/resets_controller_spec.rb
+++ b/spec/controllers/admin/resets_controller_spec.rb
@@ -4,6 +4,7 @@ describe Admin::ResetsController do
   render_views
 
   let(:account) { Fabricate(:account) }
+
   before do
     sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user
   end
diff --git a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
index aae35ce38..5026ca327 100644
--- a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
@@ -35,7 +35,7 @@ describe Api::V1::Accounts::CredentialsController do
             source: {
               privacy: 'unlisted',
               sensitive: true,
-            }
+            },
           }
         end
 
@@ -70,7 +70,7 @@ describe Api::V1::Accounts::CredentialsController do
         it 'returns http success' do
           expect(response).to have_http_status(200)
         end
-     end
+      end
 
       describe 'with invalid data' do
         before do
diff --git a/spec/controllers/api/v1/admin/accounts_controller_spec.rb b/spec/controllers/api/v1/admin/accounts_controller_spec.rb
index 8d35b86cb..a4c509c60 100644
--- a/spec/controllers/api/v1/admin/accounts_controller_spec.rb
+++ b/spec/controllers/api/v1/admin/accounts_controller_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do
         it "returns the correct accounts (#{expected_results.inspect})" do
           json = body_as_json
 
-          expect(json.map { |a| a[:id].to_i }).to eq (expected_results.map { |symbol| send(symbol).id })
+          expect(json.map { |a| a[:id].to_i }).to eq(expected_results.map { |symbol| send(symbol).id })
         end
       end
     end
diff --git a/spec/controllers/api/v1/apps_controller_spec.rb b/spec/controllers/api/v1/apps_controller_spec.rb
index 70cd62d48..9ac7880a4 100644
--- a/spec/controllers/api/v1/apps_controller_spec.rb
+++ b/spec/controllers/api/v1/apps_controller_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe Api::V1::AppsController, type: :controller do
       end
 
       it 'creates an OAuth app' do
-        expect(Doorkeeper::Application.find_by(name: client_name)).to_not be nil
+        expect(Doorkeeper::Application.find_by(name: client_name)).to_not be_nil
       end
 
       it 'returns client ID and client secret' do
diff --git a/spec/controllers/api/v1/markers_controller_spec.rb b/spec/controllers/api/v1/markers_controller_spec.rb
index ba0f3c322..64ec18e59 100644
--- a/spec/controllers/api/v1/markers_controller_spec.rb
+++ b/spec/controllers/api/v1/markers_controller_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe Api::V1::MarkersController, type: :controller do
 
       it 'creates a marker' do
         expect(user.markers.first.timeline).to eq 'home'
-        expect(user.markers.first.last_read_id).to eq 69420
+        expect(user.markers.first.last_read_id).to eq 69_420
       end
     end
 
@@ -58,7 +58,7 @@ RSpec.describe Api::V1::MarkersController, type: :controller do
 
       it 'updates a marker' do
         expect(user.markers.first.timeline).to eq 'home'
-        expect(user.markers.first.last_read_id).to eq 70120
+        expect(user.markers.first.last_read_id).to eq 70_120
       end
     end
   end
diff --git a/spec/controllers/api/v1/push/subscriptions_controller_spec.rb b/spec/controllers/api/v1/push/subscriptions_controller_spec.rb
index 9487251e1..67f09da2d 100644
--- a/spec/controllers/api/v1/push/subscriptions_controller_spec.rb
+++ b/spec/controllers/api/v1/push/subscriptions_controller_spec.rb
@@ -20,7 +20,7 @@ describe Api::V1::Push::SubscriptionsController do
           p256dh: 'BEm_a0bdPDhf0SOsrnB2-ategf1hHoCnpXgQsFj5JCkcoMrMt2WHoPfEYOYPzOIs9mZE8ZUaD7VA5vouy0kEkr8=',
           auth: 'eH_C8rq2raXqlcBVDa1gLg==',
         },
-      }
+      },
     }.with_indifferent_access
   end
 
@@ -37,8 +37,8 @@ describe Api::V1::Push::SubscriptionsController do
           mention: false,
           poll: true,
           status: false,
-        }
-      }
+        },
+      },
     }.with_indifferent_access
   end
 
diff --git a/spec/controllers/api/v1/reports_controller_spec.rb b/spec/controllers/api/v1/reports_controller_spec.rb
index dbc64e704..78a72b95b 100644
--- a/spec/controllers/api/v1/reports_controller_spec.rb
+++ b/spec/controllers/api/v1/reports_controller_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Api::V1::ReportsController, type: :controller do
     let(:target_account) { status.account }
     let(:category) { nil }
     let(:forward) { nil }
-    let(:rule_ids){ nil }
+    let(:rule_ids) { nil }
 
     before do
       allow(AdminMailer).to receive(:new_report).and_return(double('email', deliver_later: nil))
diff --git a/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb b/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb
index 7cc77f430..4dcaba6bd 100644
--- a/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb
+++ b/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Api::V1::Statuses::FavouritedByAccountsController, type: :control
       it 'returns accounts who favorited the status' do
         get :index, params: { status_id: status.id, limit: 2 }
         expect(body_as_json.size).to eq 2
-      expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s])
+        expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s])
       end
 
       it 'does not return blocked users' do
diff --git a/spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb
index 8d4a6f91c..dc36d4ca0 100644
--- a/spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb
+++ b/spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Api::V1::Statuses::RebloggedByAccountsController, type: :controll
       it 'returns accounts who reblogged the status' do
         get :index, params: { status_id: status.id, limit: 2 }
         expect(body_as_json.size).to eq 2
-      expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s])
+        expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s])
       end
 
       it 'does not return blocked users' do
diff --git a/spec/controllers/api/v1/statuses_controller_spec.rb b/spec/controllers/api/v1/statuses_controller_spec.rb
index bd8b8013a..e4e6e172a 100644
--- a/spec/controllers/api/v1/statuses_controller_spec.rb
+++ b/spec/controllers/api/v1/statuses_controller_spec.rb
@@ -195,7 +195,7 @@ RSpec.describe Api::V1::StatusesController, type: :controller do
       end
 
       it 'removes the status' do
-        expect(Status.find_by(id: status.id)).to be nil
+        expect(Status.find_by(id: status.id)).to be_nil
       end
     end
 
diff --git a/spec/controllers/api/v1/streaming_controller_spec.rb b/spec/controllers/api/v1/streaming_controller_spec.rb
index 4ab409a54..9dbca0178 100644
--- a/spec/controllers/api/v1/streaming_controller_spec.rb
+++ b/spec/controllers/api/v1/streaming_controller_spec.rb
@@ -38,7 +38,7 @@ describe Api::V1::StreamingController do
         [:scheme, :path, :query, :fragment].each do |part|
           expect(redirect_to_uri.send(part)).to eq(request_uri.send(part)), "redirect target #{part}"
         end
-        expect(redirect_to_uri.host).to eq(@streaming_host), "redirect target host"
+        expect(redirect_to_uri.host).to eq(@streaming_host), 'redirect target host'
       end
     end
   end
diff --git a/spec/controllers/api/v1/suggestions_controller_spec.rb b/spec/controllers/api/v1/suggestions_controller_spec.rb
index 17f10b04f..7805b6b4f 100644
--- a/spec/controllers/api/v1/suggestions_controller_spec.rb
+++ b/spec/controllers/api/v1/suggestions_controller_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe Api::V1::SuggestionsController, type: :controller do
       json = body_as_json
 
       expect(json.size).to be >= 1
-      expect(json.map { |i| i[:id] }).to include *[bob, jeff].map { |i| i.id.to_s }
+      expect(json.map { |i| i[:id] }).to include(*[bob, jeff].map { |i| i.id.to_s })
     end
   end
 end
diff --git a/spec/controllers/api/v2/admin/accounts_controller_spec.rb b/spec/controllers/api/v2/admin/accounts_controller_spec.rb
index 2508a9e05..1477049a1 100644
--- a/spec/controllers/api/v2/admin/accounts_controller_spec.rb
+++ b/spec/controllers/api/v2/admin/accounts_controller_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe Api::V2::Admin::AccountsController, type: :controller do
         it "returns the correct accounts (#{expected_results.inspect})" do
           json = body_as_json
 
-          expect(json.map { |a| a[:id].to_i }).to eq (expected_results.map { |symbol| send(symbol).id })
+          expect(json.map { |a| a[:id].to_i }).to eq(expected_results.map { |symbol| send(symbol).id })
         end
       end
     end
diff --git a/spec/controllers/api/v2/filters/statuses_controller_spec.rb b/spec/controllers/api/v2/filters/statuses_controller_spec.rb
index 9740c1eb3..969b2ea73 100644
--- a/spec/controllers/api/v2/filters/statuses_controller_spec.rb
+++ b/spec/controllers/api/v2/filters/statuses_controller_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe Api::V2::Filters::StatusesController, type: :controller do
   end
 
   describe 'GET #show' do
-    let(:scopes)  { 'read:filters' }
+    let(:scopes) { 'read:filters' }
     let!(:status_filter) { Fabricate(:custom_filter_status, custom_filter: filter) }
 
     before do
@@ -90,7 +90,7 @@ RSpec.describe Api::V2::Filters::StatusesController, type: :controller do
   end
 
   describe 'DELETE #destroy' do
-    let(:scopes)  { 'write:filters' }
+    let(:scopes) { 'write:filters' }
     let(:status_filter) { Fabricate(:custom_filter_status, custom_filter: filter) }
 
     before do
diff --git a/spec/controllers/api/web/embeds_controller_spec.rb b/spec/controllers/api/web/embeds_controller_spec.rb
index a8fc1718f..345c317ba 100644
--- a/spec/controllers/api/web/embeds_controller_spec.rb
+++ b/spec/controllers/api/web/embeds_controller_spec.rb
@@ -6,6 +6,7 @@ describe Api::Web::EmbedsController do
   render_views
 
   let(:user) { Fabricate(:user) }
+
   before { sign_in user }
 
   describe 'POST #create' do
diff --git a/spec/controllers/api/web/push_subscriptions_controller_spec.rb b/spec/controllers/api/web/push_subscriptions_controller_spec.rb
index bda4a7661..9f027ede9 100644
--- a/spec/controllers/api/web/push_subscriptions_controller_spec.rb
+++ b/spec/controllers/api/web/push_subscriptions_controller_spec.rb
@@ -15,7 +15,7 @@ describe Api::Web::PushSubscriptionsController do
           p256dh: 'BEm_a0bdPDhf0SOsrnB2-ategf1hHoCnpXgQsFj5JCkcoMrMt2WHoPfEYOYPzOIs9mZE8ZUaD7VA5vouy0kEkr8=',
           auth: 'eH_C8rq2raXqlcBVDa1gLg==',
         },
-      }
+      },
     }
   end
 
@@ -32,8 +32,8 @@ describe Api::Web::PushSubscriptionsController do
           mention: false,
           poll: true,
           status: false,
-        }
-      }
+        },
+      },
     }
   end
 
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 2af12376d..e7d997192 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -27,7 +27,7 @@ describe ApplicationController, type: :controller do
       expect(response).to have_http_status(code)
     end
 
-    it "renders template for http" do
+    it 'renders template for http' do
       is_expected.to render_template("errors/#{code}", layout: 'error')
     end
   end
@@ -150,7 +150,7 @@ describe ApplicationController, type: :controller do
       end
 
       it 'does not store location for user if it is devise controller' do
-        @request.env["devise.mapping"] = Devise.mappings[:user]
+        @request.env['devise.mapping'] = Devise.mappings[:user]
         get 'create'
         expect(controller.stored_location_for(:user)).to be_nil
       end
diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb
index 0ebf6641f..7298bde00 100644
--- a/spec/controllers/auth/registrations_controller_spec.rb
+++ b/spec/controllers/auth/registrations_controller_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
   describe 'GET #edit' do
     it 'returns http success' do
-      request.env["devise.mapping"] = Devise.mappings[:user]
+      request.env['devise.mapping'] = Devise.mappings[:user]
       sign_in(Fabricate(:user))
       get :edit
       expect(response).to have_http_status(200)
@@ -41,7 +41,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
   describe 'GET #update' do
     it 'returns http success' do
-      request.env["devise.mapping"] = Devise.mappings[:user]
+      request.env['devise.mapping'] = Devise.mappings[:user]
       sign_in(Fabricate(:user), scope: :user)
       post :update
       expect(response).to have_http_status(200)
@@ -49,7 +49,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
     context 'when suspended' do
       it 'returns http forbidden' do
-        request.env["devise.mapping"] = Devise.mappings[:user]
+        request.env['devise.mapping'] = Devise.mappings[:user]
         sign_in(Fabricate(:user, account_attributes: { username: 'test', suspended_at: Time.now.utc }), scope: :user)
         post :update
         expect(response).to have_http_status(403)
@@ -59,7 +59,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
   describe 'GET #new' do
     before do
-      request.env["devise.mapping"] = Devise.mappings[:user]
+      request.env['devise.mapping'] = Devise.mappings[:user]
     end
 
     context do
@@ -92,7 +92,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
       I18n.locale = current_locale
     end
 
-    before { request.env["devise.mapping"] = Devise.mappings[:user] }
+    before { request.env['devise.mapping'] = Devise.mappings[:user] }
 
     context do
       around do |example|
@@ -103,7 +103,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
       subject do
         Setting.registrations_mode = 'open'
-        request.headers["Accept-Language"] = accept_language
+        request.headers['Accept-Language'] = accept_language
         post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
       end
 
@@ -129,7 +129,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
       subject do
         Setting.registrations_mode = 'open'
-        request.headers["Accept-Language"] = accept_language
+        request.headers['Accept-Language'] = accept_language
         post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'false' } }
       end
 
@@ -149,7 +149,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
       subject do
         Setting.registrations_mode = 'approved'
-        request.headers["Accept-Language"] = accept_language
+        request.headers['Accept-Language'] = accept_language
         post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
       end
 
@@ -176,9 +176,9 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
       subject do
         Setting.registrations_mode = 'approved'
-        request.headers["Accept-Language"] = accept_language
+        request.headers['Accept-Language'] = accept_language
         invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.ago)
-        post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code, agreement: 'true' } }
+        post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', invite_code: invite.code, agreement: 'true' } }
       end
 
       it 'redirects to setup' do
@@ -208,9 +208,9 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
         inviter = Fabricate(:user, confirmed_at: 2.days.ago)
         Setting.registrations_mode = 'approved'
         Setting.require_invite_text = true
-        request.headers["Accept-Language"] = accept_language
+        request.headers['Accept-Language'] = accept_language
         invite = Fabricate(:invite, user: inviter, max_uses: nil, expires_at: 1.hour.from_now)
-        post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code, agreement: 'true' } }
+        post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', invite_code: invite.code, agreement: 'true' } }
       end
 
       it 'redirects to setup' do
diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb
index d3db7aa1a..eb03dff50 100644
--- a/spec/controllers/auth/sessions_controller_spec.rb
+++ b/spec/controllers/auth/sessions_controller_spec.rb
@@ -54,7 +54,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
     context 'using PAM authentication', if: ENV['PAM_ENABLED'] == 'true' do
       context 'using a valid password' do
         before do
-          post :create, params: { user: { email: "pam_user1", password: '123456' } }
+          post :create, params: { user: { email: 'pam_user1', password: '123456' } }
         end
 
         it 'redirects to home' do
@@ -68,7 +68,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
 
       context 'using an invalid password' do
         before do
-          post :create, params: { user: { email: "pam_user1", password: 'WRONGPW' } }
+          post :create, params: { user: { email: 'pam_user1', password: 'WRONGPW' } }
         end
 
         it 'shows a login error' do
@@ -127,7 +127,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
 
         before do
           allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return(current_ip)
-          allow(UserMailer).to receive(:suspicious_sign_in).and_return(double('email', 'deliver_later!': nil))
+          allow(UserMailer).to receive(:suspicious_sign_in).and_return(double('email', deliver_later!: nil))
           user.update(current_sign_in_at: 1.month.ago)
           post :create, params: { user: { email: user.email, password: user.password } }
         end
@@ -194,7 +194,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
           post :create, params: { user: { email: user.email, password: user.password } }
         end
 
-        context "in single user mode" do
+        context 'in single user mode' do
           let(:single_user_mode) { true }
 
           it 'redirects to home' do
@@ -202,7 +202,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
           end
         end
 
-        context "in non-single user mode" do
+        context 'in non-single user mode' do
           let(:single_user_mode) { false }
 
           it "redirects back to the user's page" do
@@ -230,8 +230,8 @@ RSpec.describe Auth::SessionsController, type: :controller do
           end
 
           it 'renders two factor authentication page' do
-            expect(controller).to render_template("two_factor")
-            expect(controller).to render_template(partial: "_otp_authentication_form")
+            expect(controller).to render_template('two_factor')
+            expect(controller).to render_template(partial: '_otp_authentication_form')
           end
         end
 
@@ -246,8 +246,8 @@ RSpec.describe Auth::SessionsController, type: :controller do
           end
 
           it 'renders two factor authentication page' do
-            expect(controller).to render_template("two_factor")
-            expect(controller).to render_template(partial: "_otp_authentication_form")
+            expect(controller).to render_template('two_factor')
+            expect(controller).to render_template(partial: '_otp_authentication_form')
           end
         end
 
@@ -257,8 +257,8 @@ RSpec.describe Auth::SessionsController, type: :controller do
           end
 
           it 'renders two factor authentication page' do
-            expect(controller).to render_template("two_factor")
-            expect(controller).to render_template(partial: "_otp_authentication_form")
+            expect(controller).to render_template('two_factor')
+            expect(controller).to render_template(partial: '_otp_authentication_form')
           end
         end
 
@@ -339,11 +339,11 @@ RSpec.describe Auth::SessionsController, type: :controller do
             external_id: public_key_credential.id,
             public_key: public_key_credential.public_key,
             sign_count: '1000'
-           )
+          )
           user.webauthn_credentials.take
         end
 
-        let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http' }://#{Rails.configuration.x.web_domain}" }
+        let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" }
 
         let(:fake_client) { WebAuthn::FakeClient.new(domain) }
 
@@ -359,8 +359,8 @@ RSpec.describe Auth::SessionsController, type: :controller do
           end
 
           it 'renders webauthn authentication page' do
-            expect(controller).to render_template("two_factor")
-            expect(controller).to render_template(partial: "_webauthn_form")
+            expect(controller).to render_template('two_factor')
+            expect(controller).to render_template(partial: '_webauthn_form')
           end
         end
 
@@ -370,8 +370,8 @@ RSpec.describe Auth::SessionsController, type: :controller do
           end
 
           it 'renders webauthn authentication page' do
-            expect(controller).to render_template("two_factor")
-            expect(controller).to render_template(partial: "_webauthn_form")
+            expect(controller).to render_template('two_factor')
+            expect(controller).to render_template(partial: '_webauthn_form')
           end
         end
 
@@ -400,7 +400,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
 
   describe 'GET #webauthn_options' do
     context 'with WebAuthn and OTP enabled as second factor' do
-      let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http' }://#{Rails.configuration.x.web_domain}" }
+      let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" }
 
       let(:fake_client) { WebAuthn::FakeClient.new(domain) }
 
diff --git a/spec/controllers/authorize_interactions_controller_spec.rb b/spec/controllers/authorize_interactions_controller_spec.rb
index 44f52df69..e52103941 100644
--- a/spec/controllers/authorize_interactions_controller_spec.rb
+++ b/spec/controllers/authorize_interactions_controller_spec.rb
@@ -99,7 +99,6 @@ describe AuthorizeInteractionsController do
         allow(ResolveAccountService).to receive(:new).and_return(service)
         allow(service).to receive(:call).with('user@hostname').and_return(target_account)
 
-
         post :create, params: { acct: 'acct:user@hostname' }
 
         expect(account.following?(target_account)).to be true
diff --git a/spec/controllers/instance_actors_controller_spec.rb b/spec/controllers/instance_actors_controller_spec.rb
index f64a7d2ca..d6b4c793b 100644
--- a/spec/controllers/instance_actors_controller_spec.rb
+++ b/spec/controllers/instance_actors_controller_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe InstanceActorsController, type: :controller do
 
         it 'does not set cookies' do
           expect(response.cookies).to be_empty
-          expect(response.headers['Set-Cookies']).to be nil
+          expect(response.headers['Set-Cookies']).to be_nil
         end
 
         it 'does not set sessions' do
@@ -43,11 +43,13 @@ RSpec.describe InstanceActorsController, type: :controller do
 
       context 'without authorized fetch mode' do
         let(:authorized_fetch_mode) { false }
+
         it_behaves_like 'shared behavior'
       end
 
       context 'with authorized fetch mode' do
         let(:authorized_fetch_mode) { true }
+
         it_behaves_like 'shared behavior'
       end
     end
diff --git a/spec/controllers/intents_controller_spec.rb b/spec/controllers/intents_controller_spec.rb
index ddfd5ea36..394f7d512 100644
--- a/spec/controllers/intents_controller_spec.rb
+++ b/spec/controllers/intents_controller_spec.rb
@@ -4,6 +4,7 @@ RSpec.describe IntentsController, type: :controller do
   render_views
 
   let(:user) { Fabricate(:user) }
+
   before { sign_in user, scope: :user }
 
   describe 'GET #show' do
diff --git a/spec/controllers/oauth/authorized_applications_controller_spec.rb b/spec/controllers/oauth/authorized_applications_controller_spec.rb
index 901e538e9..885bfa35b 100644
--- a/spec/controllers/oauth/authorized_applications_controller_spec.rb
+++ b/spec/controllers/oauth/authorized_applications_controller_spec.rb
@@ -13,7 +13,7 @@ describe Oauth::AuthorizedApplicationsController do
     shared_examples 'stores location for user' do
       it 'stores location for user' do
         subject
-        expect(controller.stored_location_for(:user)).to eq "/oauth/authorized_applications"
+        expect(controller.stored_location_for(:user)).to eq '/oauth/authorized_applications'
       end
     end
 
diff --git a/spec/controllers/settings/applications_controller_spec.rb b/spec/controllers/settings/applications_controller_spec.rb
index 1292e9ff8..35ad4b2e7 100644
--- a/spec/controllers/settings/applications_controller_spec.rb
+++ b/spec/controllers/settings/applications_controller_spec.rb
@@ -37,7 +37,7 @@ describe Settings::ApplicationsController do
   end
 
   describe 'GET #new' do
-    it 'works' do
+    it 'returns http success' do
       get :new
       expect(response).to have_http_status(200)
     end
@@ -51,8 +51,8 @@ describe Settings::ApplicationsController do
             name: 'My New App',
             redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
             website: 'http://google.com',
-            scopes: 'read write follow'
-          }
+            scopes: 'read write follow',
+          },
         }
         response
       end
@@ -73,8 +73,8 @@ describe Settings::ApplicationsController do
             name: 'My New App',
             redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
             website: 'http://google.com',
-            scopes: [ 'read', 'write', 'follow' ]
-          }
+            scopes: ['read', 'write', 'follow'],
+          },
         }
         response
       end
@@ -95,8 +95,8 @@ describe Settings::ApplicationsController do
             name: '',
             redirect_uri: '',
             website: '',
-            scopes: []
-          }
+            scopes: [],
+          },
         }
       end
 
@@ -112,16 +112,16 @@ describe Settings::ApplicationsController do
 
   describe 'PATCH #update' do
     context 'success' do
-      let(:opts) {
+      let(:opts) do
         {
-          website: 'https://foo.bar/'
+          website: 'https://foo.bar/',
         }
-      }
+      end
 
       def call_update
         patch :update, params: {
           id: app.id,
-          doorkeeper_application: opts
+          doorkeeper_application: opts,
         }
         response
       end
@@ -144,8 +144,8 @@ describe Settings::ApplicationsController do
             name: '',
             redirect_uri: '',
             website: '',
-            scopes: []
-          }
+            scopes: [],
+          },
         }
       end
 
@@ -175,12 +175,13 @@ describe Settings::ApplicationsController do
 
   describe 'regenerate' do
     let(:token) { user.token_for_app(app) }
+
     before do
       expect(token).to_not be_nil
       post :regenerate, params: { id: app.id }
     end
 
-    it 'should create new token' do
+    it 'creates new token' do
       expect(user.token_for_app(app)).to_not eql(token)
     end
   end
diff --git a/spec/controllers/settings/imports_controller_spec.rb b/spec/controllers/settings/imports_controller_spec.rb
index b8caf5941..e50504cc5 100644
--- a/spec/controllers/settings/imports_controller_spec.rb
+++ b/spec/controllers/settings/imports_controller_spec.rb
@@ -7,8 +7,8 @@ RSpec.describe Settings::ImportsController, type: :controller do
     sign_in Fabricate(:user), scope: :user
   end
 
-  describe "GET #show" do
-    it "returns http success" do
+  describe 'GET #show' do
+    it 'returns http success' do
       get :show
       expect(response).to have_http_status(200)
     end
@@ -21,8 +21,8 @@ RSpec.describe Settings::ImportsController, type: :controller do
       post :create, params: {
         import: {
           type: 'following',
-          data: fixture_file_upload('imports.txt')
-        }
+          data: fixture_file_upload('imports.txt'),
+        },
       }
 
       expect(response).to redirect_to(settings_import_path)
@@ -34,8 +34,8 @@ RSpec.describe Settings::ImportsController, type: :controller do
       post :create, params: {
         import: {
           type: 'blocking',
-          data: fixture_file_upload('imports.txt')
-        }
+          data: fixture_file_upload('imports.txt'),
+        },
       }
 
       expect(response).to redirect_to(settings_import_path)
diff --git a/spec/controllers/settings/migrations_controller_spec.rb b/spec/controllers/settings/migrations_controller_spec.rb
index 35c5747a0..4ce153c9d 100644
--- a/spec/controllers/settings/migrations_controller_spec.rb
+++ b/spec/controllers/settings/migrations_controller_spec.rb
@@ -90,7 +90,7 @@ describe Settings::MigrationsController do
         end
       end
 
-      context 'when a recent migration already exists ' do
+      context 'when a recent migration already exists' do
         let(:acct) { Fabricate(:account, also_known_as: [ActivityPub::TagManager.instance.uri_for(user.account)]) }
 
         before do
diff --git a/spec/controllers/settings/preferences/notifications_controller_spec.rb b/spec/controllers/settings/preferences/notifications_controller_spec.rb
index 02180b383..a821052ed 100644
--- a/spec/controllers/settings/preferences/notifications_controller_spec.rb
+++ b/spec/controllers/settings/preferences/notifications_controller_spec.rb
@@ -25,7 +25,7 @@ describe Settings::Preferences::NotificationsController do
         user: {
           notification_emails: { follow: '1' },
           interactions: { must_be_follower: '0' },
-        }
+        },
       }
 
       expect(response).to redirect_to(settings_preferences_notifications_path)
diff --git a/spec/controllers/settings/preferences/other_controller_spec.rb b/spec/controllers/settings/preferences/other_controller_spec.rb
index 960378a01..dd7f01847 100644
--- a/spec/controllers/settings/preferences/other_controller_spec.rb
+++ b/spec/controllers/settings/preferences/other_controller_spec.rb
@@ -34,7 +34,7 @@ describe Settings::Preferences::OtherController do
         user: {
           setting_boost_modal: '1',
           setting_delete_modal: '0',
-        }
+        },
       }
 
       expect(response).to redirect_to(settings_preferences_other_path)
diff --git a/spec/controllers/settings/profiles_controller_spec.rb b/spec/controllers/settings/profiles_controller_spec.rb
index ee3aec815..fbbca8bb9 100644
--- a/spec/controllers/settings/profiles_controller_spec.rb
+++ b/spec/controllers/settings/profiles_controller_spec.rb
@@ -10,8 +10,8 @@ RSpec.describe Settings::ProfilesController, type: :controller do
     sign_in user, scope: :user
   end
 
-  describe "GET #show" do
-    it "returns http success" do
+  describe 'GET #show' do
+    it 'returns http success' do
       get :show
       expect(response).to have_http_status(200)
     end
diff --git a/spec/controllers/settings/sessions_controller_spec.rb b/spec/controllers/settings/sessions_controller_spec.rb
index 52b204a6a..0e312c5a6 100644
--- a/spec/controllers/settings/sessions_controller_spec.rb
+++ b/spec/controllers/settings/sessions_controller_spec.rb
@@ -5,6 +5,7 @@ describe Settings::SessionsController do
 
   let(:user) { Fabricate(:user) }
   let(:session_activation) { Fabricate(:session_activation, user: user) }
+
   before { sign_in user, scope: :user }
 
   describe 'DELETE #destroy' do
diff --git a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb
index 569c8322b..0b807b280 100644
--- a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb
+++ b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb
@@ -5,7 +5,6 @@ require 'rails_helper'
 describe Settings::TwoFactorAuthentication::ConfirmationsController do
   render_views
 
-
   shared_examples 'renders :new' do
     it 'renders the new view' do
       subject
diff --git a/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb
index fe53b4dfc..c3156c4e9 100644
--- a/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb
+++ b/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb
@@ -7,7 +7,7 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do
   render_views
 
   let(:user) { Fabricate(:user) }
-  let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http' }://#{Rails.configuration.x.web_domain}" }
+  let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" }
   let(:fake_client) { WebAuthn::FakeClient.new(domain) }
 
   def add_webauthn_credential(user)
@@ -137,7 +137,7 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do
             expect { get :options }.to_not change { user.webauthn_id }
           end
 
-          it "includes existing credentials in list of excluded credentials" do
+          it 'includes existing credentials in list of excluded credentials' do
             get :options
 
             excluded_credentials_ids = JSON.parse(response.body)['excludeCredentials'].map { |credential| credential['id'] }
diff --git a/spec/controllers/shares_controller_spec.rb b/spec/controllers/shares_controller_spec.rb
index d6de3016a..e365b356e 100644
--- a/spec/controllers/shares_controller_spec.rb
+++ b/spec/controllers/shares_controller_spec.rb
@@ -4,6 +4,7 @@ describe SharesController do
   render_views
 
   let(:user) { Fabricate(:user) }
+
   before { sign_in user }
 
   describe 'GTE #show' do
diff --git a/spec/controllers/statuses_cleanup_controller_spec.rb b/spec/controllers/statuses_cleanup_controller_spec.rb
index 924709260..347fe4027 100644
--- a/spec/controllers/statuses_cleanup_controller_spec.rb
+++ b/spec/controllers/statuses_cleanup_controller_spec.rb
@@ -8,8 +8,8 @@ RSpec.describe StatusesCleanupController, type: :controller do
     sign_in @user, scope: :user
   end
 
-  describe "GET #show" do
-    it "returns http success" do
+  describe 'GET #show' do
+    it 'returns http success' do
       get :show
       expect(response).to have_http_status(200)
     end
diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb
index 6ed5d4bbb..c8b503d68 100644
--- a/spec/controllers/statuses_controller_spec.rb
+++ b/spec/controllers/statuses_controller_spec.rb
@@ -8,7 +8,7 @@ describe StatusesController do
   shared_examples 'cacheable response' do
     it 'does not set cookies' do
       expect(response.cookies).to be_empty
-      expect(response.headers['Set-Cookies']).to be nil
+      expect(response.headers['Set-Cookies']).to be_nil
     end
 
     it 'does not set sessions' do
diff --git a/spec/controllers/well_known/host_meta_controller_spec.rb b/spec/controllers/well_known/host_meta_controller_spec.rb
index c02aa0d59..654bad406 100644
--- a/spec/controllers/well_known/host_meta_controller_spec.rb
+++ b/spec/controllers/well_known/host_meta_controller_spec.rb
@@ -9,12 +9,12 @@ describe WellKnown::HostMetaController, type: :controller do
 
       expect(response).to have_http_status(200)
       expect(response.media_type).to eq 'application/xrd+xml'
-      expect(response.body).to eq <<XML
-<?xml version="1.0" encoding="UTF-8"?>
-<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
-  <Link rel="lrdd" template="https://cb6e6126.ngrok.io/.well-known/webfinger?resource={uri}"/>
-</XRD>
-XML
+      expect(response.body).to eq <<~XML
+        <?xml version="1.0" encoding="UTF-8"?>
+        <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
+          <Link rel="lrdd" template="https://cb6e6126.ngrok.io/.well-known/webfinger?resource={uri}"/>
+        </XRD>
+      XML
     end
   end
 end
diff --git a/spec/controllers/well_known/nodeinfo_controller_spec.rb b/spec/controllers/well_known/nodeinfo_controller_spec.rb
index 36e85f20d..964a14706 100644
--- a/spec/controllers/well_known/nodeinfo_controller_spec.rb
+++ b/spec/controllers/well_known/nodeinfo_controller_spec.rb
@@ -27,8 +27,8 @@ describe WellKnown::NodeInfoController, type: :controller do
 
       json = body_as_json
 
-      expect({ "foo" => 0 }).not_to match_json_schema("nodeinfo_2.0")
-      expect(json).to match_json_schema("nodeinfo_2.0")
+      expect({ 'foo' => 0 }).not_to match_json_schema('nodeinfo_2.0')
+      expect(json).to match_json_schema('nodeinfo_2.0')
       expect(json[:version]).to eq '2.0'
       expect(json[:usage]).to be_a Hash
       expect(json[:software]).to be_a Hash
diff --git a/spec/fabricators/account_moderation_note_fabricator.rb b/spec/fabricators/account_moderation_note_fabricator.rb
index 9277af165..343a41fb1 100644
--- a/spec/fabricators/account_moderation_note_fabricator.rb
+++ b/spec/fabricators/account_moderation_note_fabricator.rb
@@ -1,4 +1,4 @@
 Fabricator(:account_moderation_note) do
-  content "MyText"
+  content 'MyText'
   account nil
 end
diff --git a/spec/fabricators/account_note_fabricator.rb b/spec/fabricators/account_note_fabricator.rb
index 1b061745a..285703b38 100644
--- a/spec/fabricators/account_note_fabricator.rb
+++ b/spec/fabricators/account_note_fabricator.rb
@@ -1,5 +1,5 @@
 Fabricator(:account_note) do
   account
   target_account { Fabricate(:account) }
-  comment        "User note text"
+  comment        'User note text'
 end
diff --git a/spec/fabricators/account_stat_fabricator.rb b/spec/fabricators/account_stat_fabricator.rb
index 2b06b4790..b1b47ffef 100644
--- a/spec/fabricators/account_stat_fabricator.rb
+++ b/spec/fabricators/account_stat_fabricator.rb
@@ -1,6 +1,6 @@
 Fabricator(:account_stat) do
   account         nil
-  statuses_count  ""
-  following_count ""
-  followers_count ""
+  statuses_count  ''
+  following_count ''
+  followers_count ''
 end
diff --git a/spec/fabricators/account_tag_stat_fabricator.rb b/spec/fabricators/account_tag_stat_fabricator.rb
index 9edb550be..7a4de07f6 100644
--- a/spec/fabricators/account_tag_stat_fabricator.rb
+++ b/spec/fabricators/account_tag_stat_fabricator.rb
@@ -1,3 +1,3 @@
 Fabricator(:account_tag_stat) do
-  accounts_count ""
+  accounts_count ''
 end
diff --git a/spec/fabricators/account_warning_preset_fabricator.rb b/spec/fabricators/account_warning_preset_fabricator.rb
index 6c0b87e7c..7e7c03cb8 100644
--- a/spec/fabricators/account_warning_preset_fabricator.rb
+++ b/spec/fabricators/account_warning_preset_fabricator.rb
@@ -1,3 +1,3 @@
 Fabricator(:account_warning_preset) do
-  text "MyText"
+  text 'MyText'
 end
diff --git a/spec/fabricators/admin_action_log_fabricator.rb b/spec/fabricators/admin_action_log_fabricator.rb
index 2f44e953d..474bef1bc 100644
--- a/spec/fabricators/admin_action_log_fabricator.rb
+++ b/spec/fabricators/admin_action_log_fabricator.rb
@@ -1,5 +1,5 @@
 Fabricator('Admin::ActionLog') do
   account nil
-  action  "MyString"
+  action  'MyString'
   target  nil
 end
diff --git a/spec/fabricators/canonical_email_block_fabricator.rb b/spec/fabricators/canonical_email_block_fabricator.rb
index a0b6e0d22..61afde3de 100644
--- a/spec/fabricators/canonical_email_block_fabricator.rb
+++ b/spec/fabricators/canonical_email_block_fabricator.rb
@@ -1,4 +1,4 @@
 Fabricator(:canonical_email_block) do
-  email "test@example.com"
+  email 'test@example.com'
   reference_account { Fabricate(:account) }
 end
diff --git a/spec/fabricators/conversation_account_fabricator.rb b/spec/fabricators/conversation_account_fabricator.rb
index f57ffd535..0fe7a494e 100644
--- a/spec/fabricators/conversation_account_fabricator.rb
+++ b/spec/fabricators/conversation_account_fabricator.rb
@@ -1,6 +1,6 @@
 Fabricator(:conversation_account) do
   account                 nil
   conversation            nil
-  participant_account_ids ""
+  participant_account_ids ''
   last_status             nil
 end
diff --git a/spec/fabricators/custom_emoji_category_fabricator.rb b/spec/fabricators/custom_emoji_category_fabricator.rb
index f593b95ed..119c343cf 100644
--- a/spec/fabricators/custom_emoji_category_fabricator.rb
+++ b/spec/fabricators/custom_emoji_category_fabricator.rb
@@ -1,3 +1,3 @@
 Fabricator(:custom_emoji_category) do
-  name "MyString"
+  name 'MyString'
 end
diff --git a/spec/fabricators/custom_filter_keyword_fabricator.rb b/spec/fabricators/custom_filter_keyword_fabricator.rb
index 0f101dcd1..201566cbe 100644
--- a/spec/fabricators/custom_filter_keyword_fabricator.rb
+++ b/spec/fabricators/custom_filter_keyword_fabricator.rb
@@ -1,4 +1,4 @@
 Fabricator(:custom_filter_keyword) do
   custom_filter
-  keyword       'discourse'
+  keyword 'discourse'
 end
diff --git a/spec/fabricators/domain_allow_fabricator.rb b/spec/fabricators/domain_allow_fabricator.rb
index 6226b1e20..6f62ce3b8 100644
--- a/spec/fabricators/domain_allow_fabricator.rb
+++ b/spec/fabricators/domain_allow_fabricator.rb
@@ -1,3 +1,3 @@
 Fabricator(:domain_allow) do
-  domain "MyString"
+  domain 'MyString'
 end
diff --git a/spec/fabricators/encrypted_message_fabricator.rb b/spec/fabricators/encrypted_message_fabricator.rb
index e65f66302..4de0d7add 100644
--- a/spec/fabricators/encrypted_message_fabricator.rb
+++ b/spec/fabricators/encrypted_message_fabricator.rb
@@ -3,6 +3,6 @@ Fabricator(:encrypted_message) do
   from_account
   from_device_id   { Faker::Number.number(digits: 5) }
   type             0
-  body             ""
-  message_franking ""
+  body             ''
+  message_franking ''
 end
diff --git a/spec/fabricators/identity_fabricator.rb b/spec/fabricators/identity_fabricator.rb
index bc832df9f..fcfb15518 100644
--- a/spec/fabricators/identity_fabricator.rb
+++ b/spec/fabricators/identity_fabricator.rb
@@ -1,5 +1,5 @@
 Fabricator(:identity) do
   user     nil
-  provider "MyString"
-  uid      "MyString"
+  provider 'MyString'
+  uid      'MyString'
 end
diff --git a/spec/fabricators/ip_block_fabricator.rb b/spec/fabricators/ip_block_fabricator.rb
index 31dc336e6..5bd018f9c 100644
--- a/spec/fabricators/ip_block_fabricator.rb
+++ b/spec/fabricators/ip_block_fabricator.rb
@@ -1,6 +1,6 @@
 Fabricator(:ip_block) do
-  ip         ""
-  severity   ""
-  expires_at "2020-10-08 22:20:37"
-  comment    "MyText"
-end
\ No newline at end of file
+  ip         ''
+  severity   ''
+  expires_at '2020-10-08 22:20:37'
+  comment    'MyText'
+end
diff --git a/spec/fabricators/list_fabricator.rb b/spec/fabricators/list_fabricator.rb
index c3db690fa..4ad29a386 100644
--- a/spec/fabricators/list_fabricator.rb
+++ b/spec/fabricators/list_fabricator.rb
@@ -1,4 +1,4 @@
 Fabricator(:list) do
   account
-  title "MyString"
+  title 'MyString'
 end
diff --git a/spec/fabricators/poll_vote_fabricator.rb b/spec/fabricators/poll_vote_fabricator.rb
index 51f9b006e..c06e61f67 100644
--- a/spec/fabricators/poll_vote_fabricator.rb
+++ b/spec/fabricators/poll_vote_fabricator.rb
@@ -1,5 +1,5 @@
 Fabricator(:poll_vote) do
   account
   poll
-  choice  0
+  choice 0
 end
diff --git a/spec/fabricators/relay_fabricator.rb b/spec/fabricators/relay_fabricator.rb
index 488913f77..d6255866c 100644
--- a/spec/fabricators/relay_fabricator.rb
+++ b/spec/fabricators/relay_fabricator.rb
@@ -1,4 +1,4 @@
 Fabricator(:relay) do
-  inbox_url "https://example.com/inbox"
+  inbox_url 'https://example.com/inbox'
   state :idle
 end
diff --git a/spec/fabricators/report_fabricator.rb b/spec/fabricators/report_fabricator.rb
index 2c7101e09..3011c49c6 100644
--- a/spec/fabricators/report_fabricator.rb
+++ b/spec/fabricators/report_fabricator.rb
@@ -1,6 +1,6 @@
 Fabricator(:report) do
   account
   target_account  { Fabricate(:account) }
-  comment         "You nasty"
+  comment         'You nasty'
   action_taken_at nil
 end
diff --git a/spec/fabricators/report_note_fabricator.rb b/spec/fabricators/report_note_fabricator.rb
index e139efffb..33f384074 100644
--- a/spec/fabricators/report_note_fabricator.rb
+++ b/spec/fabricators/report_note_fabricator.rb
@@ -1,5 +1,5 @@
 Fabricator(:report_note) do
   report
   account { Fabricate(:account) }
-  content "Test Content"
+  content 'Test Content'
 end
diff --git a/spec/fabricators/session_activation_fabricator.rb b/spec/fabricators/session_activation_fabricator.rb
index 526faaec2..a7fc3b017 100644
--- a/spec/fabricators/session_activation_fabricator.rb
+++ b/spec/fabricators/session_activation_fabricator.rb
@@ -1,4 +1,4 @@
 Fabricator(:session_activation) do
   user
-  session_id "MyString"
+  session_id 'MyString'
 end
diff --git a/spec/fabricators/status_edit_fabricator.rb b/spec/fabricators/status_edit_fabricator.rb
index 21b793747..0e5796b23 100644
--- a/spec/fabricators/status_edit_fabricator.rb
+++ b/spec/fabricators/status_edit_fabricator.rb
@@ -1,7 +1,7 @@
 Fabricator(:status_edit) do
   status                    nil
   account                   nil
-  text                      "MyText"
-  spoiler_text              "MyText"
+  text                      'MyText'
+  spoiler_text              'MyText'
   media_attachments_changed false
-end
\ No newline at end of file
+end
diff --git a/spec/fabricators/status_fabricator.rb b/spec/fabricators/status_fabricator.rb
index 04bbbcf4b..8a0a8aa55 100644
--- a/spec/fabricators/status_fabricator.rb
+++ b/spec/fabricators/status_fabricator.rb
@@ -1,6 +1,6 @@
 Fabricator(:status) do
   account
-  text "Lorem ipsum dolor sit amet"
+  text 'Lorem ipsum dolor sit amet'
 
   after_build do |status|
     status.uri = Faker::Internet.device_token if !status.account.local? && status.uri.nil?
diff --git a/spec/fabricators/status_stat_fabricator.rb b/spec/fabricators/status_stat_fabricator.rb
index 9c67fd404..feba9fbca 100644
--- a/spec/fabricators/status_stat_fabricator.rb
+++ b/spec/fabricators/status_stat_fabricator.rb
@@ -1,6 +1,6 @@
 Fabricator(:status_stat) do
   status_id        nil
-  replies_count    ""
-  reblogs_count    ""
-  favourites_count ""
+  replies_count    ''
+  reblogs_count    ''
+  favourites_count ''
 end
diff --git a/spec/fabricators/system_key_fabricator.rb b/spec/fabricators/system_key_fabricator.rb
index f808495e0..c744bb286 100644
--- a/spec/fabricators/system_key_fabricator.rb
+++ b/spec/fabricators/system_key_fabricator.rb
@@ -1,3 +1,2 @@
 Fabricator(:system_key) do
-
 end
diff --git a/spec/fabricators/user_fabricator.rb b/spec/fabricators/user_fabricator.rb
index 10ad2c53a..93ce07a74 100644
--- a/spec/fabricators/user_fabricator.rb
+++ b/spec/fabricators/user_fabricator.rb
@@ -1,7 +1,7 @@
 Fabricator(:user) do
   account      { Fabricate.build(:account, user: nil) }
   email        { sequence(:email) { |i| "#{i}#{Faker::Internet.email}" } }
-  password     "123456789"
+  password     '123456789'
   confirmed_at { Time.zone.now }
   agreement    true
 end
diff --git a/spec/fabricators/user_role_fabricator.rb b/spec/fabricators/user_role_fabricator.rb
index ed0a7dc1f..592b4edca 100644
--- a/spec/fabricators/user_role_fabricator.rb
+++ b/spec/fabricators/user_role_fabricator.rb
@@ -1,5 +1,5 @@
 Fabricator(:user_role) do
-  name        "MyString"
-  color       ""
+  name        'MyString'
+  color       ''
   permissions 0
 end
diff --git a/spec/features/log_in_spec.rb b/spec/features/log_in_spec.rb
index de1a6de03..5ae738ee2 100644
--- a/spec/features/log_in_spec.rb
+++ b/spec/features/log_in_spec.rb
@@ -2,21 +2,21 @@
 
 require 'rails_helper'
 
-feature 'Log in' do
+describe 'Log in' do
   include ProfileStories
 
-  given(:email)        { "test@example.com" }
-  given(:password)     { "password" }
-  given(:confirmed_at) { Time.zone.now }
+  subject { page }
+
+  let(:email)        { 'test@example.com' }
+  let(:password)     { 'password' }
+  let(:confirmed_at) { Time.zone.now }
 
-  background do
+  before do
     as_a_registered_user
     visit new_user_session_path
   end
 
-  subject { page }
-
-  scenario 'A valid email and password user is able to log in' do
+  it 'A valid email and password user is able to log in' do
     fill_in 'user_email', with: email
     fill_in 'user_password', with: password
     click_on I18n.t('auth.login')
@@ -24,7 +24,7 @@ feature 'Log in' do
     is_expected.to have_css('div.app-holder')
   end
 
-  scenario 'A invalid email and password user is not able to log in' do
+  it 'A invalid email and password user is not able to log in' do
     fill_in 'user_email', with: 'invalid_email'
     fill_in 'user_password', with: 'invalid_password'
     click_on I18n.t('auth.login')
@@ -33,9 +33,9 @@ feature 'Log in' do
   end
 
   context do
-    given(:confirmed_at) { nil }
+    let(:confirmed_at) { nil }
 
-    scenario 'A unconfirmed user is able to log in' do
+    it 'A unconfirmed user is able to log in' do
       fill_in 'user_email', with: email
       fill_in 'user_password', with: password
       click_on I18n.t('auth.login')
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index ec4f9a53f..d1c6919c1 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -2,25 +2,25 @@
 
 require 'rails_helper'
 
-feature 'Profile' do
+describe 'Profile' do
   include ProfileStories
 
-  given(:local_domain) { ENV['LOCAL_DOMAIN'] }
+  subject { page }
+
+  let(:local_domain) { ENV['LOCAL_DOMAIN'] }
 
-  background do
+  before do
     as_a_logged_in_user
     with_alice_as_local_user
   end
 
-  subject { page }
-
-  scenario 'I can view Annes public account' do
+  it 'I can view Annes public account' do
     visit account_path('alice')
 
     is_expected.to have_title("alice (@alice@#{local_domain})")
   end
 
-  scenario 'I can change my account' do
+  it 'I can change my account' do
     visit settings_profile_path
 
     fill_in 'Display name', with: 'Bob'
diff --git a/spec/helpers/accounts_helper_spec.rb b/spec/helpers/accounts_helper_spec.rb
index 2b35b23b7..1f412a39f 100644
--- a/spec/helpers/accounts_helper_spec.rb
+++ b/spec/helpers/accounts_helper_spec.rb
@@ -13,15 +13,15 @@ RSpec.describe AccountsHelper, type: :helper do
 
   describe '#display_name' do
     it 'uses the display name when it exists' do
-      account = Account.new(display_name: "Display", username: "Username")
+      account = Account.new(display_name: 'Display', username: 'Username')
 
-      expect(helper.display_name(account)).to eq "Display"
+      expect(helper.display_name(account)).to eq 'Display'
     end
 
     it 'uses the username when display name is nil' do
-      account = Account.new(display_name: nil, username: "Username")
+      account = Account.new(display_name: nil, username: 'Username')
 
-      expect(helper.display_name(account)).to eq "Username"
+      expect(helper.display_name(account)).to eq 'Username'
     end
   end
 
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 1dbd985bf..6502cfebf 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -5,8 +5,8 @@ describe ApplicationHelper do
     it 'returns active when on the current page' do
       allow(helper).to receive(:current_page?).and_return(true)
 
-      result = helper.active_nav_class("/test")
-      expect(result).to eq "active"
+      result = helper.active_nav_class('/test')
+      expect(result).to eq 'active'
     end
 
     it 'returns active when on a current page' do
@@ -14,14 +14,14 @@ describe ApplicationHelper do
       allow(helper).to receive(:current_page?).with('/test').and_return(true)
 
       result = helper.active_nav_class('/foo', '/test')
-      expect(result).to eq "active"
+      expect(result).to eq 'active'
     end
 
     it 'returns empty string when not on current page' do
       allow(helper).to receive(:current_page?).and_return(false)
 
-      result = helper.active_nav_class("/test")
-      expect(result).to eq ""
+      result = helper.active_nav_class('/test')
+      expect(result).to eq ''
     end
   end
 
@@ -82,6 +82,7 @@ describe ApplicationHelper do
       before do
         allow(helper).to receive(:user_signed_in?).and_return(true)
       end
+
       it 'does not show landing strip' do
         expect(helper.show_landing_strip?).to eq false
       end
diff --git a/spec/helpers/jsonld_helper_spec.rb b/spec/helpers/jsonld_helper_spec.rb
index 744a14f26..debee17f0 100644
--- a/spec/helpers/jsonld_helper_spec.rb
+++ b/spec/helpers/jsonld_helper_spec.rb
@@ -113,7 +113,7 @@ describe JsonLdHelper do
             {
               'type' => 'Mention',
               'href' => ['foo'],
-            }
+            },
           ],
         },
         'signature' => {
diff --git a/spec/lib/activitypub/activity/announce_spec.rb b/spec/lib/activitypub/activity/announce_spec.rb
index e9cd6c68c..461c3757b 100644
--- a/spec/lib/activitypub/activity/announce_spec.rb
+++ b/spec/lib/activitypub/activity/announce_spec.rb
@@ -82,10 +82,10 @@ RSpec.describe ActivityPub::Activity::Announce do
             content: 'Lorem ipsum',
             attributedTo: 'https://example.com/actor',
             to: {
-              'type': 'OrderedCollection',
-              'id': 'http://example.com/followers',
-              'first': 'http://example.com/followers?page=true',
-            }
+              type: 'OrderedCollection',
+              id: 'http://example.com/followers',
+              first: 'http://example.com/followers?page=true',
+            },
           }
         end
 
diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb
index 738e644c5..0bf51fb9f 100644
--- a/spec/lib/activitypub/activity/create_spec.rb
+++ b/spec/lib/activitypub/activity/create_spec.rb
@@ -252,10 +252,10 @@ RSpec.describe ActivityPub::Activity::Create do
             type: 'Note',
             content: 'Lorem ipsum',
             to: {
-              'type': 'OrderedCollection',
-              'id': 'http://example.com/followers',
-              'first': 'http://example.com/followers?page=true',
-            }
+              type: 'OrderedCollection',
+              id: 'http://example.com/followers',
+              first: 'http://example.com/followers?page=true',
+            },
           }
         end
 
@@ -454,7 +454,6 @@ RSpec.describe ActivityPub::Activity::Create do
         end
       end
 
-
       context 'with media attachments with long description' do
         let(:object_json) do
           {
@@ -733,7 +732,7 @@ RSpec.describe ActivityPub::Activity::Create do
                 replies: {
                   type: 'Collection',
                   totalItems: 3,
-                }
+                },
               },
             ],
           }
@@ -763,7 +762,7 @@ RSpec.describe ActivityPub::Activity::Create do
             id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
             type: 'Note',
             name: 'Yellow',
-            inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status)
+            inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status),
           }
         end
 
@@ -788,7 +787,7 @@ RSpec.describe ActivityPub::Activity::Create do
             id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
             type: 'Note',
             name: 'Yellow',
-            inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status)
+            inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status),
           }
         end
 
diff --git a/spec/lib/activitypub/activity/flag_spec.rb b/spec/lib/activitypub/activity/flag_spec.rb
index 2f2d13876..7890fd1e8 100644
--- a/spec/lib/activitypub/activity/flag_spec.rb
+++ b/spec/lib/activitypub/activity/flag_spec.rb
@@ -110,7 +110,7 @@ RSpec.describe ActivityPub::Activity::Flag do
 
   describe '#perform with a defined uri' do
     subject { described_class.new(json, sender) }
-    let (:flag_id) { 'http://example.com/reports/1' }
+    let(:flag_id) { 'http://example.com/reports/1' }
 
     before do
       subject.perform
diff --git a/spec/lib/extractor_spec.rb b/spec/lib/extractor_spec.rb
index dba4bd0bb..560617ed7 100644
--- a/spec/lib/extractor_spec.rb
+++ b/spec/lib/extractor_spec.rb
@@ -20,7 +20,7 @@ describe Extractor do
       text = '@screen_name'
       extracted = Extractor.extract_mentions_or_lists_with_indices(text)
       expect(extracted).to eq [
-        { screen_name: 'screen_name', indices: [ 0, 12 ] }
+        { screen_name: 'screen_name', indices: [0, 12] },
       ]
     end
 
@@ -44,19 +44,19 @@ describe Extractor do
     it 'does not exclude normal hash text before ://' do
       text = '#hashtag://'
       extracted = Extractor.extract_hashtags_with_indices(text)
-      expect(extracted).to eq [ { hashtag: 'hashtag', indices: [ 0, 8 ] } ]
+      expect(extracted).to eq [{ hashtag: 'hashtag', indices: [0, 8] }]
     end
 
     it 'excludes http://' do
       text = '#hashtaghttp://'
       extracted = Extractor.extract_hashtags_with_indices(text)
-      expect(extracted).to eq [ { hashtag: 'hashtag', indices: [ 0, 8 ] } ]
+      expect(extracted).to eq [{ hashtag: 'hashtag', indices: [0, 8] }]
     end
 
     it 'excludes https://' do
       text = '#hashtaghttps://'
       extracted = Extractor.extract_hashtags_with_indices(text)
-      expect(extracted).to eq [ { hashtag: 'hashtag', indices: [ 0, 8 ] } ]
+      expect(extracted).to eq [{ hashtag: 'hashtag', indices: [0, 8] }]
     end
 
     it 'yields hashtags if a block is given' do
diff --git a/spec/lib/fast_ip_map_spec.rb b/spec/lib/fast_ip_map_spec.rb
index c66f64828..78b3ddb05 100644
--- a/spec/lib/fast_ip_map_spec.rb
+++ b/spec/lib/fast_ip_map_spec.rb
@@ -4,7 +4,7 @@ require 'rails_helper'
 
 describe FastIpMap do
   describe '#include?' do
-    subject { described_class.new([IPAddr.new('20.4.0.0/16'), IPAddr.new('145.22.30.0/24'), IPAddr.new('189.45.86.3')])}
+    subject { described_class.new([IPAddr.new('20.4.0.0/16'), IPAddr.new('145.22.30.0/24'), IPAddr.new('189.45.86.3')]) }
 
     it 'returns true for an exact match' do
       expect(subject.include?(IPAddr.new('189.45.86.3'))).to be true
diff --git a/spec/lib/feed_manager_spec.rb b/spec/lib/feed_manager_spec.rb
index f2ab2570d..b25084938 100644
--- a/spec/lib/feed_manager_spec.rb
+++ b/spec/lib/feed_manager_spec.rb
@@ -423,7 +423,7 @@ RSpec.describe FeedManager do
 
       FeedManager.instance.merge_into_home(account, reblog.account)
 
-      expect(redis.zscore("feed:home:0", reblog.id)).to eq nil
+      expect(redis.zscore('feed:home:0', reblog.id)).to eq nil
     end
   end
 
diff --git a/spec/lib/link_details_extractor_spec.rb b/spec/lib/link_details_extractor_spec.rb
index 7ea867c61..7eb15ced3 100644
--- a/spec/lib/link_details_extractor_spec.rb
+++ b/spec/lib/link_details_extractor_spec.rb
@@ -39,17 +39,17 @@ RSpec.describe LinkDetailsExtractor do
     let(:original_url) { 'https://example.com/page.html' }
 
     context 'and is wrapped in CDATA tags' do
-      let(:html) { <<-HTML }
-<!doctype html>
-<html>
-<head>
-  <script type="application/ld+json">
-  //<![CDATA[
-  {"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"https://example.com/page.html","headline":"Foo","datePublished":"2022-01-31T19:53:00+00:00","url":"https://example.com/page.html","description":"Bar","author":{"@type":"Person","name":"Hoge"},"publisher":{"@type":"Organization","name":"Baz"}}
-  //]]>
-  </script>
-</head>
-</html>
+      let(:html) { <<~HTML }
+        <!doctype html>
+        <html>
+        <head>
+          <script type="application/ld+json">
+          //<![CDATA[
+          {"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"https://example.com/page.html","headline":"Foo","datePublished":"2022-01-31T19:53:00+00:00","url":"https://example.com/page.html","description":"Bar","author":{"@type":"Person","name":"Hoge"},"publisher":{"@type":"Organization","name":"Baz"}}
+          //]]>
+          </script>
+        </head>
+        </html>
       HTML
 
       describe '#title' do
@@ -78,57 +78,57 @@ RSpec.describe LinkDetailsExtractor do
     end
 
     context 'but the first tag is invalid JSON' do
-      let(:html) { <<-HTML }
-<!doctype html>
-<html>
-<body>
-  <script type="application/ld+json">
-    {
-      "@context":"https://schema.org",
-      "@type":"ItemList",
-      "url":"https://example.com/page.html",
-      "name":"Foo",
-      "description":"Bar"
-    },
-    {
-      "@context": "https://schema.org",
-      "@type": "BreadcrumbList",
-      "itemListElement":[
-        {
-          "@type":"ListItem",
-          "position":1,
-          "item":{
-            "@id":"https://www.example.com",
-            "name":"Baz"
-          }
-        }
-      ]
-    }
-  </script>
-  <script type="application/ld+json">
-    {
-      "@context":"https://schema.org",
-      "@type":"NewsArticle",
-      "mainEntityOfPage": {
-        "@type":"WebPage",
-        "@id": "http://example.com/page.html"
-      },
-      "headline": "Foo",
-      "description": "Bar",
-      "datePublished": "2022-01-31T19:46:00+00:00",
-      "author": {
-        "@type": "Organization",
-        "name": "Hoge"
-      },
-      "publisher": {
-        "@type": "NewsMediaOrganization",
-        "name":"Baz",
-        "url":"https://example.com/"
-      }
-    }
-  </script>
-</body>
-</html>
+      let(:html) { <<~HTML }
+        <!doctype html>
+        <html>
+        <body>
+          <script type="application/ld+json">
+            {
+              "@context":"https://schema.org",
+              "@type":"ItemList",
+              "url":"https://example.com/page.html",
+              "name":"Foo",
+              "description":"Bar"
+            },
+            {
+              "@context": "https://schema.org",
+              "@type": "BreadcrumbList",
+              "itemListElement":[
+                {
+                  "@type":"ListItem",
+                  "position":1,
+                  "item":{
+                    "@id":"https://www.example.com",
+                    "name":"Baz"
+                  }
+                }
+              ]
+            }
+          </script>
+          <script type="application/ld+json">
+            {
+              "@context":"https://schema.org",
+              "@type":"NewsArticle",
+              "mainEntityOfPage": {
+                "@type":"WebPage",
+                "@id": "http://example.com/page.html"
+              },
+              "headline": "Foo",
+              "description": "Bar",
+              "datePublished": "2022-01-31T19:46:00+00:00",
+              "author": {
+                "@type": "Organization",
+                "name": "Hoge"
+              },
+              "publisher": {
+                "@type": "NewsMediaOrganization",
+                "name":"Baz",
+                "url":"https://example.com/"
+              }
+            }
+          </script>
+        </body>
+        </html>
       HTML
 
       describe '#title' do
diff --git a/spec/lib/request_spec.rb b/spec/lib/request_spec.rb
index 8539944e2..e555a8b5a 100644
--- a/spec/lib/request_spec.rb
+++ b/spec/lib/request_spec.rb
@@ -43,7 +43,7 @@ describe Request do
       before { stub_request(:get, 'http://example.com') }
 
       it 'executes a HTTP request' do
-        expect { |block| subject.perform &block }.to yield_control
+        expect { |block| subject.perform(&block) }.to yield_control
         expect(a_request(:get, 'http://example.com')).to have_been_made.once
       end
 
@@ -54,18 +54,18 @@ describe Request do
         allow(resolver).to receive(:timeouts=).and_return(nil)
         allow(Resolv::DNS).to receive(:open).and_yield(resolver)
 
-        expect { |block| subject.perform &block }.to yield_control
+        expect { |block| subject.perform(&block) }.to yield_control
         expect(a_request(:get, 'http://example.com')).to have_been_made.once
       end
 
       it 'sets headers' do
-        expect { |block| subject.perform &block }.to yield_control
+        expect { |block| subject.perform(&block) }.to yield_control
         expect(a_request(:get, 'http://example.com').with(headers: subject.headers)).to have_been_made
       end
 
       it 'closes underlying connection' do
         expect_any_instance_of(HTTP::Client).to receive(:close)
-        expect { |block| subject.perform &block }.to yield_control
+        expect { |block| subject.perform(&block) }.to yield_control
       end
 
       it 'returns response which implements body_with_limit' do
diff --git a/spec/lib/settings/extend_spec.rb b/spec/lib/settings/extend_spec.rb
index 83ced4230..ea623137b 100644
--- a/spec/lib/settings/extend_spec.rb
+++ b/spec/lib/settings/extend_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Settings::Extend do
   describe '#settings' do
     it 'sets @settings as an instance of Settings::ScopedSettings' do
       user = Fabricate(:user)
-      expect(user.settings).to be_kind_of Settings::ScopedSettings
+      expect(user.settings).to be_a Settings::ScopedSettings
     end
   end
 end
diff --git a/spec/lib/status_filter_spec.rb b/spec/lib/status_filter_spec.rb
index a851014d9..287fe00de 100644
--- a/spec/lib/status_filter_spec.rb
+++ b/spec/lib/status_filter_spec.rb
@@ -32,6 +32,7 @@ describe StatusFilter do
 
     context 'with real account' do
       let(:account) { Fabricate(:account) }
+
       subject { described_class.new(status, account) }
 
       context 'when there are no connections' do
diff --git a/spec/lib/text_formatter_spec.rb b/spec/lib/text_formatter_spec.rb
index 52a9d2498..d4a3a6b59 100644
--- a/spec/lib/text_formatter_spec.rb
+++ b/spec/lib/text_formatter_spec.rb
@@ -223,7 +223,7 @@ RSpec.describe TextFormatter do
     end
 
     context 'given a URL containing unsafe code (XSS attack, visible part)' do
-      let(:text) { %q{http://example.com/b<del>b</del>} }
+      let(:text) { 'http://example.com/b<del>b</del>' }
 
       it 'does not include the HTML in the URL' do
         is_expected.to include '"http://example.com/b"'
@@ -235,7 +235,7 @@ RSpec.describe TextFormatter do
     end
 
     context 'given a URL containing unsafe code (XSS attack, invisible part)' do
-      let(:text) { %q{http://example.com/blahblahblahblah/a<script>alert("Hello")</script>} }
+      let(:text) { 'http://example.com/blahblahblahblah/a<script>alert("Hello")</script>' }
 
       it 'does not include the HTML in the URL' do
         is_expected.to include '"http://example.com/blahblahblahblah/a"'
diff --git a/spec/lib/webfinger_resource_spec.rb b/spec/lib/webfinger_resource_spec.rb
index 5c7f475d6..ee007da70 100644
--- a/spec/lib/webfinger_resource_spec.rb
+++ b/spec/lib/webfinger_resource_spec.rb
@@ -14,9 +14,9 @@ describe WebfingerResource do
       it 'raises with a route whose controller is not AccountsController' do
         resource = 'https://example.com/users/alice/other'
 
-        expect {
+        expect do
           WebfingerResource.new(resource).username
-        }.to raise_error(ActiveRecord::RecordNotFound)
+        end.to raise_error(ActiveRecord::RecordNotFound)
       end
 
       it 'raises with a route whose action is not show' do
@@ -29,17 +29,17 @@ describe WebfingerResource do
 
         expect(Rails.application.routes).to receive(:recognize_path).with(resource).and_return(recognized).at_least(:once)
 
-        expect {
+        expect do
           WebfingerResource.new(resource).username
-        }.to raise_error(ActiveRecord::RecordNotFound)
+        end.to raise_error(ActiveRecord::RecordNotFound)
       end
 
       it 'raises with a string that doesnt start with URL' do
         resource = 'website for http://example.com/users/alice/other'
 
-        expect {
+        expect do
           WebfingerResource.new(resource).username
-        }.to raise_error(WebfingerResource::InvalidRequest)
+        end.to raise_error(WebfingerResource::InvalidRequest)
       end
 
       it 'finds the username in a valid https route' do
@@ -68,9 +68,9 @@ describe WebfingerResource do
       it 'raises on a non-local domain' do
         resource = 'user@remote-host.com'
 
-        expect {
+        expect do
           WebfingerResource.new(resource).username
-        }.to raise_error(ActiveRecord::RecordNotFound)
+        end.to raise_error(ActiveRecord::RecordNotFound)
       end
 
       it 'finds username for a local domain' do
@@ -94,17 +94,17 @@ describe WebfingerResource do
       it 'raises on a non-local domain' do
         resource = 'acct:user@remote-host.com'
 
-        expect {
+        expect do
           WebfingerResource.new(resource).username
-        }.to raise_error(ActiveRecord::RecordNotFound)
+        end.to raise_error(ActiveRecord::RecordNotFound)
       end
 
       it 'raises on a nonsense domain' do
         resource = 'acct:user@remote-host@remote-hostess.remote.local@remote'
 
-        expect {
+        expect do
           WebfingerResource.new(resource).username
-        }.to raise_error(ActiveRecord::RecordNotFound)
+        end.to raise_error(ActiveRecord::RecordNotFound)
       end
 
       it 'finds the username for a local account if the domain is the local one' do
@@ -128,9 +128,9 @@ describe WebfingerResource do
       it 'raises InvalidRequest' do
         resource = 'df/:dfkj'
 
-        expect {
+        expect do
           WebfingerResource.new(resource).username
-        }.to raise_error(WebfingerResource::InvalidRequest)
+        end.to raise_error(WebfingerResource::InvalidRequest)
       end
     end
   end
diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb
index 29bdc349b..6746871a3 100644
--- a/spec/mailers/notification_mailer_spec.rb
+++ b/spec/mailers/notification_mailer_spec.rb
@@ -1,4 +1,4 @@
-require "rails_helper"
+require 'rails_helper'
 
 RSpec.describe NotificationMailer, type: :mailer do
   let(:receiver)       { Fabricate(:user) }
@@ -19,69 +19,69 @@ RSpec.describe NotificationMailer, type: :mailer do
     end
   end
 
-  describe "mention" do
+  describe 'mention' do
     let(:mention) { Mention.create!(account: receiver.account, status: foreign_status) }
     let(:mail) { NotificationMailer.mention(receiver.account, Notification.create!(account: receiver.account, activity: mention)) }
 
     include_examples 'localized subject', 'notification_mailer.mention.subject', name: 'bob'
 
-    it "renders the headers" do
-      expect(mail.subject).to eq("You were mentioned by bob")
+    it 'renders the headers' do
+      expect(mail.subject).to eq('You were mentioned by bob')
       expect(mail.to).to eq([receiver.email])
     end
 
-    it "renders the body" do
-      expect(mail.body.encoded).to match("You were mentioned by bob")
+    it 'renders the body' do
+      expect(mail.body.encoded).to match('You were mentioned by bob')
       expect(mail.body.encoded).to include 'The body of the foreign status'
     end
   end
 
-  describe "follow" do
+  describe 'follow' do
     let(:follow) { sender.follow!(receiver.account) }
     let(:mail) { NotificationMailer.follow(receiver.account, Notification.create!(account: receiver.account, activity: follow)) }
 
     include_examples 'localized subject', 'notification_mailer.follow.subject', name: 'bob'
 
-    it "renders the headers" do
-      expect(mail.subject).to eq("bob is now following you")
+    it 'renders the headers' do
+      expect(mail.subject).to eq('bob is now following you')
       expect(mail.to).to eq([receiver.email])
     end
 
-    it "renders the body" do
-      expect(mail.body.encoded).to match("bob is now following you")
+    it 'renders the body' do
+      expect(mail.body.encoded).to match('bob is now following you')
     end
   end
 
-  describe "favourite" do
+  describe 'favourite' do
     let(:favourite) { Favourite.create!(account: sender, status: own_status) }
     let(:mail) { NotificationMailer.favourite(own_status.account, Notification.create!(account: receiver.account, activity: favourite)) }
 
     include_examples 'localized subject', 'notification_mailer.favourite.subject', name: 'bob'
 
-    it "renders the headers" do
-      expect(mail.subject).to eq("bob favourited your post")
+    it 'renders the headers' do
+      expect(mail.subject).to eq('bob favourited your post')
       expect(mail.to).to eq([receiver.email])
     end
 
-    it "renders the body" do
-      expect(mail.body.encoded).to match("Your post was favourited by bob")
+    it 'renders the body' do
+      expect(mail.body.encoded).to match('Your post was favourited by bob')
       expect(mail.body.encoded).to include 'The body of the own status'
     end
   end
 
-  describe "reblog" do
+  describe 'reblog' do
     let(:reblog) { Status.create!(account: sender, reblog: own_status) }
     let(:mail) { NotificationMailer.reblog(own_status.account, Notification.create!(account: receiver.account, activity: reblog)) }
 
     include_examples 'localized subject', 'notification_mailer.reblog.subject', name: 'bob'
 
-    it "renders the headers" do
-      expect(mail.subject).to eq("bob boosted your post")
+    it 'renders the headers' do
+      expect(mail.subject).to eq('bob boosted your post')
       expect(mail.to).to eq([receiver.email])
     end
 
-    it "renders the body" do
-      expect(mail.body.encoded).to match("Your post was boosted by bob")
+    it 'renders the body' do
+      expect(mail.body.encoded).to match('Your post was boosted by bob')
       expect(mail.body.encoded).to include 'The body of the own status'
     end
   end
@@ -98,7 +98,7 @@ RSpec.describe NotificationMailer, type: :mailer do
     end
 
     it 'renders the body' do
-      expect(mail.body.encoded).to match("bob has requested to follow you")
+      expect(mail.body.encoded).to match('bob has requested to follow you')
     end
   end
 end
diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb
index 2ed33c1e4..9c22f60f1 100644
--- a/spec/mailers/user_mailer_spec.rb
+++ b/spec/mailers/user_mailer_spec.rb
@@ -90,7 +90,7 @@ describe UserMailer, type: :mailer do
 
     it 'renders warning notification' do
       receiver.update!(locale: nil)
-      expect(mail.body.encoded).to include I18n.t("user_mailer.warning.title.suspend", acct: receiver.account.acct)
+      expect(mail.body.encoded).to include I18n.t('user_mailer.warning.title.suspend', acct: receiver.account.acct)
       expect(mail.body.encoded).to include strike.text
     end
   end
diff --git a/spec/models/account/field_spec.rb b/spec/models/account/field_spec.rb
index 0ac9769bc..40bbee025 100644
--- a/spec/models/account/field_spec.rb
+++ b/spec/models/account/field_spec.rb
@@ -97,7 +97,7 @@ RSpec.describe Account::Field, type: :model do
           expect(subject.verifiable?).to be false
         end
       end
-      
+
       context 'for text which is blank' do
         let(:value) { '' }
 
@@ -149,7 +149,7 @@ RSpec.describe Account::Field, type: :model do
           expect(subject.verifiable?).to be false
         end
       end
-      
+
       context 'for text which is blank' do
         let(:value) { '' }
 
diff --git a/spec/models/account_alias_spec.rb b/spec/models/account_alias_spec.rb
index 27ec215aa..c48b804b2 100644
--- a/spec/models/account_alias_spec.rb
+++ b/spec/models/account_alias_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe AccountAlias, type: :model do
-
 end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index 6cd769dc8..763835618 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -3,6 +3,7 @@ require 'rails_helper'
 RSpec.describe Account, type: :model do
   context do
     let(:bob) { Fabricate(:account, username: 'bob') }
+
     subject { Fabricate(:account) }
 
     describe '#suspend!' do
@@ -344,9 +345,9 @@ RSpec.describe Account, type: :model do
     before do
       _missing = Fabricate(
         :account,
-        display_name: "Missing",
-        username: "missing",
-        domain: "missing.com"
+        display_name: 'Missing',
+        username: 'missing',
+        domain: 'missing.com'
       )
     end
 
@@ -404,58 +405,58 @@ RSpec.describe Account, type: :model do
     it 'finds accounts with matching display_name' do
       match = Fabricate(
         :account,
-        display_name: "Display Name",
-        username: "username",
-        domain: "example.com"
+        display_name: 'Display Name',
+        username: 'username',
+        domain: 'example.com'
       )
 
-      results = Account.search_for("display")
+      results = Account.search_for('display')
       expect(results).to eq [match]
     end
 
     it 'finds accounts with matching username' do
       match = Fabricate(
         :account,
-        display_name: "Display Name",
-        username: "username",
-        domain: "example.com"
+        display_name: 'Display Name',
+        username: 'username',
+        domain: 'example.com'
       )
 
-      results = Account.search_for("username")
+      results = Account.search_for('username')
       expect(results).to eq [match]
     end
 
     it 'finds accounts with matching domain' do
       match = Fabricate(
         :account,
-        display_name: "Display Name",
-        username: "username",
-        domain: "example.com"
+        display_name: 'Display Name',
+        username: 'username',
+        domain: 'example.com'
       )
 
-      results = Account.search_for("example")
+      results = Account.search_for('example')
       expect(results).to eq [match]
     end
 
     it 'limits by 10 by default' do
-      11.times.each { Fabricate(:account, display_name: "Display Name") }
-      results = Account.search_for("display")
+      11.times.each { Fabricate(:account, display_name: 'Display Name') }
+      results = Account.search_for('display')
       expect(results.size).to eq 10
     end
 
     it 'accepts arbitrary limits' do
-      2.times.each { Fabricate(:account, display_name: "Display Name") }
-      results = Account.search_for("display", limit: 1)
+      2.times.each { Fabricate(:account, display_name: 'Display Name') }
+      results = Account.search_for('display', limit: 1)
       expect(results.size).to eq 1
     end
 
     it 'ranks multiple matches higher' do
       matches = [
-        { username: "username", display_name: "username" },
-        { display_name: "Display Name", username: "username", domain: "example.com" },
+        { username: 'username', display_name: 'username' },
+        { display_name: 'Display Name', username: 'username', domain: 'example.com' },
       ].map(&method(:Fabricate).curry(2).call(:account))
 
-      results = Account.search_for("username")
+      results = Account.search_for('username')
       expect(results).to eq matches
     end
   end
@@ -581,23 +582,23 @@ RSpec.describe Account, type: :model do
     end
 
     it 'limits by 10 by default' do
-      11.times { Fabricate(:account, display_name: "Display Name") }
-      results = Account.advanced_search_for("display", account)
+      11.times { Fabricate(:account, display_name: 'Display Name') }
+      results = Account.advanced_search_for('display', account)
       expect(results.size).to eq 10
     end
 
     it 'accepts arbitrary limits' do
-      2.times { Fabricate(:account, display_name: "Display Name") }
-      results = Account.advanced_search_for("display", account, limit: 1)
+      2.times { Fabricate(:account, display_name: 'Display Name') }
+      results = Account.advanced_search_for('display', account, limit: 1)
       expect(results.size).to eq 1
     end
 
     it 'ranks followed accounts higher' do
-      match = Fabricate(:account, username: "Matching")
-      followed_match = Fabricate(:account, username: "Matcher")
+      match = Fabricate(:account, username: 'Matching')
+      followed_match = Fabricate(:account, username: 'Matcher')
       Fabricate(:follow, account: account, target_account: followed_match)
 
-      results = Account.advanced_search_for("match", account)
+      results = Account.advanced_search_for('match', account)
       expect(results).to eq [followed_match, match]
       expect(results.first.rank).to be > results.last.rank
     end
diff --git a/spec/models/account_statuses_cleanup_policy_spec.rb b/spec/models/account_statuses_cleanup_policy_spec.rb
index b01321a20..d3c011b3a 100644
--- a/spec/models/account_statuses_cleanup_policy_spec.rb
+++ b/spec/models/account_statuses_cleanup_policy_spec.rb
@@ -16,16 +16,15 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do
     context 'when widening a policy' do
       let!(:account_statuses_cleanup_policy) do
         Fabricate(:account_statuses_cleanup_policy,
-          account: account,
-          keep_direct: true,
-          keep_pinned: true,
-          keep_polls: true,
-          keep_media: true,
-          keep_self_fav: true,
-          keep_self_bookmark: true,
-          min_favs: 1,
-          min_reblogs: 1
-        )
+                  account: account,
+                  keep_direct: true,
+                  keep_pinned: true,
+                  keep_polls: true,
+                  keep_media: true,
+                  keep_self_fav: true,
+                  keep_self_bookmark: true,
+                  min_favs: 1,
+                  min_reblogs: 1)
       end
 
       before do
@@ -35,77 +34,76 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do
       it 'invalidates last_inspected when widened because of keep_direct' do
         account_statuses_cleanup_policy.keep_direct = false
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of keep_pinned' do
         account_statuses_cleanup_policy.keep_pinned = false
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of keep_polls' do
         account_statuses_cleanup_policy.keep_polls = false
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of keep_media' do
         account_statuses_cleanup_policy.keep_media = false
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of keep_self_fav' do
         account_statuses_cleanup_policy.keep_self_fav = false
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of keep_self_bookmark' do
         account_statuses_cleanup_policy.keep_self_bookmark = false
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of higher min_favs' do
         account_statuses_cleanup_policy.min_favs = 5
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of disabled min_favs' do
         account_statuses_cleanup_policy.min_favs = nil
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of higher min_reblogs' do
         account_statuses_cleanup_policy.min_reblogs = 5
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
 
       it 'invalidates last_inspected when widened because of disable min_reblogs' do
         account_statuses_cleanup_policy.min_reblogs = nil
         account_statuses_cleanup_policy.save
-        expect(account_statuses_cleanup_policy.last_inspected).to be nil
+        expect(account_statuses_cleanup_policy.last_inspected).to be_nil
       end
     end
 
     context 'when narrowing a policy' do
       let!(:account_statuses_cleanup_policy) do
         Fabricate(:account_statuses_cleanup_policy,
-          account: account,
-          keep_direct: false,
-          keep_pinned: false,
-          keep_polls: false,
-          keep_media: false,
-          keep_self_fav: false,
-          keep_self_bookmark: false,
-          min_favs: nil,
-          min_reblogs: nil
-        )
+                  account: account,
+                  keep_direct: false,
+                  keep_pinned: false,
+                  keep_polls: false,
+                  keep_media: false,
+                  keep_self_fav: false,
+                  keep_self_bookmark: false,
+                  min_favs: nil,
+                  min_reblogs: nil)
       end
 
       it 'does not unnecessarily invalidate last_inspected' do
@@ -136,6 +134,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do
   describe '#invalidate_last_inspected' do
     let(:account_statuses_cleanup_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) }
     let(:status) { Fabricate(:status, id: 10, account: account) }
+
     subject { account_statuses_cleanup_policy.invalidate_last_inspected(status, action) }
 
     before do
@@ -232,7 +231,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do
   end
 
   describe '#compute_cutoff_id' do
-    let!(:unrelated_status)  { Fabricate(:status, created_at: 3.years.ago) }
+    let!(:unrelated_status) { Fabricate(:status, created_at: 3.years.ago) }
     let(:account_statuses_cleanup_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) }
 
     subject { account_statuses_cleanup_policy.compute_cutoff_id }
diff --git a/spec/models/concerns/account_interactions_spec.rb b/spec/models/concerns/account_interactions_spec.rb
index b5aecf6be..1883ee8fc 100644
--- a/spec/models/concerns/account_interactions_spec.rb
+++ b/spec/models/concerns/account_interactions_spec.rb
@@ -101,7 +101,7 @@ describe AccountInteractions do
   describe '#follow!' do
     it 'creates and returns Follow' do
       expect do
-        expect(account.follow!(target_account)).to be_kind_of Follow
+        expect(account.follow!(target_account)).to be_a Follow
       end.to change { account.following.count }.by 1
     end
   end
@@ -109,7 +109,7 @@ describe AccountInteractions do
   describe '#block' do
     it 'creates and returns Block' do
       expect do
-        expect(account.block!(target_account)).to be_kind_of Block
+        expect(account.block!(target_account)).to be_a Block
       end.to change { account.block_relationships.count }.by 1
     end
   end
@@ -123,7 +123,7 @@ describe AccountInteractions do
 
         it 'creates Mute, and returns Mute' do
           expect do
-            expect(subject).to be_kind_of Mute
+            expect(subject).to be_a Mute
           end.to change { account.mute_relationships.count }.by 1
         end
       end
@@ -133,7 +133,7 @@ describe AccountInteractions do
 
         it 'creates Mute, and returns Mute' do
           expect do
-            expect(subject).to be_kind_of Mute
+            expect(subject).to be_a Mute
           end.to change { account.mute_relationships.count }.by 1
         end
       end
@@ -143,7 +143,7 @@ describe AccountInteractions do
 
         it 'creates Mute, and returns Mute' do
           expect do
-            expect(subject).to be_kind_of Mute
+            expect(subject).to be_a Mute
           end.to change { account.mute_relationships.count }.by 1
         end
       end
@@ -169,7 +169,7 @@ describe AccountInteractions do
 
           it 'returns Mute without updating mute.hide_notifications' do
             expect do
-              expect(subject).to be_kind_of Mute
+              expect(subject).to be_a Mute
             end.not_to change { mute.reload.hide_notifications? }.from(true)
           end
         end
@@ -179,7 +179,7 @@ describe AccountInteractions do
 
           it 'returns Mute, and updates mute.hide_notifications false' do
             expect do
-              expect(subject).to be_kind_of Mute
+              expect(subject).to be_a Mute
             end.to change { mute.reload.hide_notifications? }.from(true).to(false)
           end
         end
@@ -189,7 +189,7 @@ describe AccountInteractions do
 
           it 'returns Mute without updating mute.hide_notifications' do
             expect do
-              expect(subject).to be_kind_of Mute
+              expect(subject).to be_a Mute
             end.not_to change { mute.reload.hide_notifications? }.from(true)
           end
         end
@@ -203,7 +203,7 @@ describe AccountInteractions do
 
           it 'returns Mute, and updates mute.hide_notifications true' do
             expect do
-              expect(subject).to be_kind_of Mute
+              expect(subject).to be_a Mute
             end.to change { mute.reload.hide_notifications? }.from(false).to(true)
           end
         end
@@ -213,7 +213,7 @@ describe AccountInteractions do
 
           it 'returns Mute without updating mute.hide_notifications' do
             expect do
-              expect(subject).to be_kind_of Mute
+              expect(subject).to be_a Mute
             end.not_to change { mute.reload.hide_notifications? }.from(false)
           end
         end
@@ -223,7 +223,7 @@ describe AccountInteractions do
 
           it 'returns Mute, and updates mute.hide_notifications true' do
             expect do
-              expect(subject).to be_kind_of Mute
+              expect(subject).to be_a Mute
             end.to change { mute.reload.hide_notifications? }.from(false).to(true)
           end
         end
@@ -238,7 +238,7 @@ describe AccountInteractions do
 
     it 'creates and returns ConversationMute' do
       expect do
-        is_expected.to be_kind_of ConversationMute
+        is_expected.to be_a ConversationMute
       end.to change { account.conversation_mutes.count }.by 1
     end
   end
@@ -250,7 +250,7 @@ describe AccountInteractions do
 
     it 'creates and returns AccountDomainBlock' do
       expect do
-        is_expected.to be_kind_of AccountDomainBlock
+        is_expected.to be_a AccountDomainBlock
       end.to change { account.domain_blocks.count }.by 1
     end
   end
@@ -261,7 +261,7 @@ describe AccountInteractions do
     context 'following target_account' do
       it 'returns destroyed Follow' do
         account.active_relationships.create(target_account: target_account)
-        is_expected.to be_kind_of Follow
+        is_expected.to be_a Follow
         expect(subject).to be_destroyed
       end
     end
@@ -279,7 +279,7 @@ describe AccountInteractions do
     context 'blocking target_account' do
       it 'returns destroyed Block' do
         account.block_relationships.create(target_account: target_account)
-        is_expected.to be_kind_of Block
+        is_expected.to be_a Block
         expect(subject).to be_destroyed
       end
     end
@@ -297,7 +297,7 @@ describe AccountInteractions do
     context 'muting target_account' do
       it 'returns destroyed Mute' do
         account.mute_relationships.create(target_account: target_account)
-        is_expected.to be_kind_of Mute
+        is_expected.to be_a Mute
         expect(subject).to be_destroyed
       end
     end
@@ -317,14 +317,14 @@ describe AccountInteractions do
     context 'muting the conversation' do
       it 'returns destroyed ConversationMute' do
         account.conversation_mutes.create(conversation: conversation)
-        is_expected.to be_kind_of ConversationMute
+        is_expected.to be_a ConversationMute
         expect(subject).to be_destroyed
       end
     end
 
     context 'not muting the conversation' do
       it 'returns nil' do
-        is_expected.to be nil
+        is_expected.to be_nil
       end
     end
   end
@@ -338,7 +338,7 @@ describe AccountInteractions do
       it 'returns destroyed AccountDomainBlock' do
         account_domain_block = Fabricate(:account_domain_block, domain: domain)
         account.domain_blocks << account_domain_block
-        is_expected.to be_kind_of AccountDomainBlock
+        is_expected.to be_a AccountDomainBlock
         expect(subject).to be_destroyed
       end
     end
@@ -407,7 +407,7 @@ describe AccountInteractions do
     subject { account.domain_blocking?(domain) }
 
     context 'blocking the domain' do
-      it' returns true' do
+      it 'returns true' do
         account_domain_block = Fabricate(:account_domain_block, domain: domain)
         account.domain_blocks << account_domain_block
         is_expected.to be true
diff --git a/spec/models/custom_emoji_filter_spec.rb b/spec/models/custom_emoji_filter_spec.rb
index 2b1b5dc54..515c0a715 100644
--- a/spec/models/custom_emoji_filter_spec.rb
+++ b/spec/models/custom_emoji_filter_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe CustomEmojiFilter do
         let(:params) { { local: true } }
 
         it 'returns ActiveRecord::Relation' do
-          expect(subject).to be_kind_of(ActiveRecord::Relation)
+          expect(subject).to be_a(ActiveRecord::Relation)
           expect(subject).to match_array([custom_emoji_2])
         end
       end
@@ -24,7 +24,7 @@ RSpec.describe CustomEmojiFilter do
         let(:params) { { remote: true } }
 
         it 'returns ActiveRecord::Relation' do
-          expect(subject).to be_kind_of(ActiveRecord::Relation)
+          expect(subject).to be_a(ActiveRecord::Relation)
           expect(subject).to match_array([custom_emoji_0, custom_emoji_1])
         end
       end
@@ -33,7 +33,7 @@ RSpec.describe CustomEmojiFilter do
         let(:params) { { by_domain: 'a' } }
 
         it 'returns ActiveRecord::Relation' do
-          expect(subject).to be_kind_of(ActiveRecord::Relation)
+          expect(subject).to be_a(ActiveRecord::Relation)
           expect(subject).to match_array([custom_emoji_0])
         end
       end
@@ -42,7 +42,7 @@ RSpec.describe CustomEmojiFilter do
         let(:params) { { shortcode: 'hoge' } }
 
         it 'returns ActiveRecord::Relation' do
-          expect(subject).to be_kind_of(ActiveRecord::Relation)
+          expect(subject).to be_a(ActiveRecord::Relation)
           expect(subject).to match_array([custom_emoji_2])
         end
       end
@@ -62,7 +62,7 @@ RSpec.describe CustomEmojiFilter do
       let(:params) { { hoge: nil } }
 
       it 'returns ActiveRecord::Relation' do
-        expect(subject).to be_kind_of(ActiveRecord::Relation)
+        expect(subject).to be_a(ActiveRecord::Relation)
         expect(subject).to match_array([custom_emoji_0, custom_emoji_1, custom_emoji_2])
       end
     end
diff --git a/spec/models/custom_emoji_spec.rb b/spec/models/custom_emoji_spec.rb
index 9de218b4f..f9e1099c6 100644
--- a/spec/models/custom_emoji_spec.rb
+++ b/spec/models/custom_emoji_spec.rb
@@ -79,7 +79,7 @@ RSpec.describe CustomEmoji, type: :model do
   describe 'pre_validation' do
     let(:custom_emoji) { Fabricate(:custom_emoji, domain: 'wWw.MaStOdOn.CoM') }
 
-    it 'should downcase' do
+    it 'downcases' do
       custom_emoji.valid?
       expect(custom_emoji.domain).to eq('www.mastodon.com')
     end
diff --git a/spec/models/device_spec.rb b/spec/models/device_spec.rb
index f56fbf978..307552e91 100644
--- a/spec/models/device_spec.rb
+++ b/spec/models/device_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe Device, type: :model do
-
 end
diff --git a/spec/models/encrypted_message_spec.rb b/spec/models/encrypted_message_spec.rb
index 1238d57b6..64f9c6912 100644
--- a/spec/models/encrypted_message_spec.rb
+++ b/spec/models/encrypted_message_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe EncryptedMessage, type: :model do
-
 end
diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb
index 135d7a36b..5202ae9e1 100644
--- a/spec/models/export_spec.rb
+++ b/spec/models/export_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
 describe Export do
   let(:account) { Fabricate(:account) }
   let(:target_accounts) do
-    [ {}, { username: 'one', domain: 'local.host' } ].map(&method(:Fabricate).curry(2).call(:account))
+    [{}, { username: 'one', domain: 'local.host' }].map(&method(:Fabricate).curry(2).call(:account))
   end
 
   describe 'to_csv' do
diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb
index a5eec1722..4280b3237 100644
--- a/spec/models/import_spec.rb
+++ b/spec/models/import_spec.rb
@@ -1,9 +1,9 @@
 require 'rails_helper'
 
 RSpec.describe Import, type: :model do
-  let (:account) { Fabricate(:account) }
-  let (:type) { 'following' }
-  let (:data) { attachment_fixture('imports.txt') }
+  let(:account) { Fabricate(:account) }
+  let(:type) { 'following' }
+  let(:data) { attachment_fixture('imports.txt') }
 
   describe 'validations' do
     it 'has a valid parameters' do
diff --git a/spec/models/login_activity_spec.rb b/spec/models/login_activity_spec.rb
index ba2d207c9..12d8c4363 100644
--- a/spec/models/login_activity_spec.rb
+++ b/spec/models/login_activity_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe LoginActivity, type: :model do
-
 end
diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb
index 29fd313ae..d1a94d41a 100644
--- a/spec/models/media_attachment_spec.rb
+++ b/spec/models/media_attachment_spec.rb
@@ -94,8 +94,8 @@ RSpec.describe MediaAttachment, type: :model do
     end
 
     it 'sets meta' do
-      expect(media.file.meta["original"]["width"]).to eq 128
-      expect(media.file.meta["original"]["height"]).to eq 128
+      expect(media.file.meta['original']['width']).to eq 128
+      expect(media.file.meta['original']['height']).to eq 128
     end
   end
 
@@ -118,9 +118,9 @@ RSpec.describe MediaAttachment, type: :model do
         end
 
         it 'sets meta' do
-          expect(media.file.meta["original"]["width"]).to eq fixture[:width]
-          expect(media.file.meta["original"]["height"]).to eq fixture[:height]
-          expect(media.file.meta["original"]["aspect"]).to eq fixture[:aspect]
+          expect(media.file.meta['original']['width']).to eq fixture[:width]
+          expect(media.file.meta['original']['height']).to eq fixture[:height]
+          expect(media.file.meta['original']['aspect']).to eq fixture[:aspect]
         end
       end
     end
@@ -154,12 +154,12 @@ RSpec.describe MediaAttachment, type: :model do
     let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) }
 
     it 'sets meta for different style' do
-      expect(media.file.meta["original"]["width"]).to eq 600
-      expect(media.file.meta["original"]["height"]).to eq 400
-      expect(media.file.meta["original"]["aspect"]).to eq 1.5
-      expect(media.file.meta["small"]["width"]).to eq 588
-      expect(media.file.meta["small"]["height"]).to eq 392
-      expect(media.file.meta["small"]["aspect"]).to eq 1.5
+      expect(media.file.meta['original']['width']).to eq 600
+      expect(media.file.meta['original']['height']).to eq 400
+      expect(media.file.meta['original']['aspect']).to eq 1.5
+      expect(media.file.meta['small']['width']).to eq 588
+      expect(media.file.meta['small']['height']).to eq 392
+      expect(media.file.meta['small']['aspect']).to eq 1.5
     end
 
     it 'gives the file a random name' do
diff --git a/spec/models/one_time_key_spec.rb b/spec/models/one_time_key_spec.rb
index 34598334c..4b231c600 100644
--- a/spec/models/one_time_key_spec.rb
+++ b/spec/models/one_time_key_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe OneTimeKey, type: :model do
-
 end
diff --git a/spec/models/session_activation_spec.rb b/spec/models/session_activation_spec.rb
index 8db06c622..26f2b561a 100644
--- a/spec/models/session_activation_spec.rb
+++ b/spec/models/session_activation_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe SessionActivation, type: :model do
     let(:session_activation) { Fabricate(:session_activation, user_agent: 'Chrome/62.0.3202.89') }
 
     it 'sets a Browser instance as detection' do
-      expect(session_activation.detection).to be_kind_of Browser::Chrome
+      expect(session_activation.detection).to be_a Browser::Chrome
     end
   end
 
@@ -44,7 +44,7 @@ RSpec.describe SessionActivation, type: :model do
       let(:id) { nil }
 
       it 'returns nil' do
-        is_expected.to be nil
+        is_expected.to be_nil
       end
     end
 
@@ -80,7 +80,7 @@ RSpec.describe SessionActivation, type: :model do
     end
 
     it 'returns an instance of SessionActivation' do
-      expect(described_class.activate(**options)).to be_kind_of SessionActivation
+      expect(described_class.activate(**options)).to be_a SessionActivation
     end
   end
 
@@ -89,7 +89,7 @@ RSpec.describe SessionActivation, type: :model do
       let(:id) { nil }
 
       it 'returns nil' do
-        expect(described_class.deactivate(id)).to be nil
+        expect(described_class.deactivate(id)).to be_nil
       end
     end
 
diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb
index 3ccc21d6c..83ba415a8 100644
--- a/spec/models/setting_spec.rb
+++ b/spec/models/setting_spec.rb
@@ -127,7 +127,7 @@ RSpec.describe Setting, type: :model do
     let(:records)          { [original_setting] }
 
     it 'returns a Hash' do
-      expect(described_class.all_as_records).to be_kind_of Hash
+      expect(described_class.all_as_records).to be_a Hash
     end
 
     context 'records includes Setting with var as the key' do
@@ -146,7 +146,7 @@ RSpec.describe Setting, type: :model do
         it 'includes Setting with value of default_value' do
           setting = described_class.all_as_records[key]
 
-          expect(setting).to be_kind_of Setting
+          expect(setting).to be_a Setting
           expect(setting).to have_attributes(var: key)
           expect(setting).to have_attributes(value: 'default_value')
         end
@@ -181,7 +181,7 @@ RSpec.describe Setting, type: :model do
       let(:enabled) { true }
 
       it 'returns instance of RailsSettings::Default' do
-        is_expected.to be_kind_of RailsSettings::Default
+        is_expected.to be_a RailsSettings::Default
       end
     end
   end
diff --git a/spec/models/system_key_spec.rb b/spec/models/system_key_spec.rb
index a138bc131..86f07f964 100644
--- a/spec/models/system_key_spec.rb
+++ b/spec/models/system_key_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe SystemKey, type: :model do
-
 end
diff --git a/spec/models/trends/statuses_spec.rb b/spec/models/trends/statuses_spec.rb
index 5f338a65e..98a8c7264 100644
--- a/spec/models/trends/statuses_spec.rb
+++ b/spec/models/trends/statuses_spec.rb
@@ -76,7 +76,7 @@ RSpec.describe Trends::Statuses do
     before do
       13.times { reblog(status1, today) }
       13.times { reblog(status2, today) }
-       4.times { reblog(status3, today) }
+      4.times { reblog(status3, today) }
     end
 
     context do
diff --git a/spec/models/user_role_spec.rb b/spec/models/user_role_spec.rb
index 28019593e..52a8622f9 100644
--- a/spec/models/user_role_spec.rb
+++ b/spec/models/user_role_spec.rb
@@ -58,7 +58,7 @@ RSpec.describe UserRole, type: :model do
   end
 
   describe '#permissions_as_keys=' do
-    let(:input) { }
+    let(:input) {}
 
     before do
       subject.permissions_as_keys = input
@@ -127,7 +127,7 @@ RSpec.describe UserRole, type: :model do
     subject { described_class.everyone }
 
     it 'returns a role' do
-      expect(subject).to be_kind_of(described_class)
+      expect(subject).to be_a(described_class)
     end
 
     it 'is identified as the everyone role' do
@@ -139,7 +139,7 @@ RSpec.describe UserRole, type: :model do
     end
 
     it 'has negative position' do
-      expect(subject.position).to eq -1
+      expect(subject.position).to eq(-1)
     end
   end
 
@@ -147,7 +147,7 @@ RSpec.describe UserRole, type: :model do
     subject { described_class.nobody }
 
     it 'returns a role' do
-      expect(subject).to be_kind_of(described_class)
+      expect(subject).to be_a(described_class)
     end
 
     it 'is identified as the nobody role' do
@@ -159,7 +159,7 @@ RSpec.describe UserRole, type: :model do
     end
 
     it 'has negative position' do
-      expect(subject.position).to eq -1
+      expect(subject.position).to eq(-1)
     end
   end
 
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 4b3d6101f..dde1503c0 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -2,6 +2,9 @@ require 'rails_helper'
 require 'devise_two_factor/spec_helpers'
 
 RSpec.describe User, type: :model do
+  let(:password) { 'abcd1234' }
+  let(:account) { Fabricate(:account, username: 'alice') }
+
   it_behaves_like 'two_factor_backupable'
 
   describe 'otp_secret' do
@@ -96,9 +99,6 @@ RSpec.describe User, type: :model do
     end
   end
 
-  let(:account) { Fabricate(:account, username: 'alice') }
-  let(:password) { 'abcd1234' }
-
   describe 'blacklist' do
     around(:each) do |example|
       old_blacklist = Rails.configuration.x.email_blacklist
@@ -110,19 +110,19 @@ RSpec.describe User, type: :model do
       Rails.configuration.x.email_domains_blacklist = old_blacklist
     end
 
-    it 'should allow a non-blacklisted user to be created' do
+    it 'allows a non-blacklisted user to be created' do
       user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true)
 
       expect(user.valid?).to be_truthy
     end
 
-    it 'should not allow a blacklisted user to be created' do
+    it 'does not allow a blacklisted user to be created' do
       user = User.new(email: 'foo@mvrht.com', account: account, password: password, agreement: true)
 
       expect(user.valid?).to be_falsey
     end
 
-    it 'should not allow a subdomain blacklisted user to be created' do
+    it 'does not allow a subdomain blacklisted user to be created' do
       user = User.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password, agreement: true)
 
       expect(user.valid?).to be_falsey
@@ -285,7 +285,7 @@ RSpec.describe User, type: :model do
     it 'saves nil for otp_secret' do
       user = Fabricate.build(:user, otp_secret: 'oldotpcode')
       user.disable_two_factor!
-      expect(user.reload.otp_secret).to be nil
+      expect(user.reload.otp_secret).to be_nil
     end
 
     it 'saves cleared otp_backup_codes' do
@@ -313,7 +313,7 @@ RSpec.describe User, type: :model do
   describe 'settings' do
     it 'is instance of Settings::ScopedSettings' do
       user = Fabricate(:user)
-      expect(user.settings).to be_kind_of Settings::ScopedSettings
+      expect(user.settings).to be_a Settings::ScopedSettings
     end
   end
 
@@ -346,17 +346,17 @@ RSpec.describe User, type: :model do
       Rails.configuration.x.email_domains_whitelist = old_whitelist
     end
 
-    it 'should not allow a user to be created unless they are whitelisted' do
+    it 'does not allow a user to be created unless they are whitelisted' do
       user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true)
       expect(user.valid?).to be_falsey
     end
 
-    it 'should allow a user to be created if they are whitelisted' do
+    it 'allows a user to be created if they are whitelisted' do
       user = User.new(email: 'foo@mastodon.space', account: account, password: password, agreement: true)
       expect(user.valid?).to be_truthy
     end
 
-    it 'should not allow a user with a whitelisted top domain as subdomain in their email address to be created' do
+    it 'does not allow a user with a whitelisted top domain as subdomain in their email address to be created' do
       user = User.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password, agreement: true)
       expect(user.valid?).to be_falsey
     end
@@ -368,7 +368,7 @@ RSpec.describe User, type: :model do
         Rails.configuration.x.email_domains_blacklist = old_blacklist
       end
 
-      it 'should not allow a user to be created with a specific blacklisted subdomain even if the top domain is whitelisted' do
+      it 'does not allow a user to be created with a specific blacklisted subdomain even if the top domain is whitelisted' do
         Rails.configuration.x.email_domains_blacklist = 'blacklisted.mastodon.space'
 
         user = User.new(email: 'foo@blacklisted.mastodon.space', account: account, password: password)
diff --git a/spec/models/web/push_subscription_spec.rb b/spec/models/web/push_subscription_spec.rb
index bd5719593..eeadbb71c 100644
--- a/spec/models/web/push_subscription_spec.rb
+++ b/spec/models/web/push_subscription_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe Web::PushSubscription, type: :model do
       context "when notification is a #{type}" do
         let(:notification_type) { type }
 
-        it "returns boolean corresponding to alert setting" do
+        it 'returns boolean corresponding to alert setting' do
           expect(subject.pushable?(notification)).to eq data[:alerts][type]
         end
       end
diff --git a/spec/models/webauthn_credentials_spec.rb b/spec/models/webauthn_credentials_spec.rb
index a63ae6cd2..e070a6b60 100644
--- a/spec/models/webauthn_credentials_spec.rb
+++ b/spec/models/webauthn_credentials_spec.rb
@@ -35,8 +35,8 @@ RSpec.describe WebauthnCredential, type: :model do
     end
 
     it 'is invalid if already exist a webauthn credential with the same external id' do
-      existing_webauthn_credential = Fabricate(:webauthn_credential, external_id: "_Typ0ygudDnk9YUVWLQayw")
-      new_webauthn_credential = Fabricate.build(:webauthn_credential, external_id: "_Typ0ygudDnk9YUVWLQayw")
+      existing_webauthn_credential = Fabricate(:webauthn_credential, external_id: '_Typ0ygudDnk9YUVWLQayw')
+      new_webauthn_credential = Fabricate.build(:webauthn_credential, external_id: '_Typ0ygudDnk9YUVWLQayw')
 
       new_webauthn_credential.valid?
 
diff --git a/spec/presenters/instance_presenter_spec.rb b/spec/presenters/instance_presenter_spec.rb
index f4c415d2f..489eee40a 100644
--- a/spec/presenters/instance_presenter_spec.rb
+++ b/spec/presenters/instance_presenter_spec.rb
@@ -10,9 +10,9 @@ describe InstancePresenter do
       Setting.site_short_description = site_description
     end
 
-    it "delegates site_description to Setting" do
-      Setting.site_short_description = "Site desc"
-      expect(instance_presenter.description).to eq "Site desc"
+    it 'delegates site_description to Setting' do
+      Setting.site_short_description = 'Site desc'
+      expect(instance_presenter.description).to eq 'Site desc'
     end
   end
 
@@ -23,9 +23,9 @@ describe InstancePresenter do
       Setting.site_extended_description = site_extended_description
     end
 
-    it "delegates site_extended_description to Setting" do
-      Setting.site_extended_description = "Extended desc"
-      expect(instance_presenter.extended_description).to eq "Extended desc"
+    it 'delegates site_extended_description to Setting' do
+      Setting.site_extended_description = 'Extended desc'
+      expect(instance_presenter.extended_description).to eq 'Extended desc'
     end
   end
 
@@ -36,9 +36,9 @@ describe InstancePresenter do
       Setting.site_contact_email = site_contact_email
     end
 
-    it "delegates contact_email to Setting" do
-      Setting.site_contact_email = "admin@example.com"
-      expect(instance_presenter.contact.email).to eq "admin@example.com"
+    it 'delegates contact_email to Setting' do
+      Setting.site_contact_email = 'admin@example.com'
+      expect(instance_presenter.contact.email).to eq 'admin@example.com'
     end
   end
 
@@ -49,15 +49,15 @@ describe InstancePresenter do
       Setting.site_contact_username = site_contact_username
     end
 
-    it "returns the account for the site contact username" do
-      Setting.site_contact_username = "aaa"
-      account = Fabricate(:account, username: "aaa")
+    it 'returns the account for the site contact username' do
+      Setting.site_contact_username = 'aaa'
+      account = Fabricate(:account, username: 'aaa')
       expect(instance_presenter.contact.account).to eq(account)
     end
   end
 
   describe '#user_count' do
-    it "returns the number of site users" do
+    it 'returns the number of site users' do
       Rails.cache.write 'user_count', 123
 
       expect(instance_presenter.user_count).to eq(123)
@@ -65,7 +65,7 @@ describe InstancePresenter do
   end
 
   describe '#status_count' do
-    it "returns the number of local statuses" do
+    it 'returns the number of local statuses' do
       Rails.cache.write 'local_status_count', 234
 
       expect(instance_presenter.status_count).to eq(234)
@@ -73,7 +73,7 @@ describe InstancePresenter do
   end
 
   describe '#domain_count' do
-    it "returns the number of known domains" do
+    it 'returns the number of known domains' do
       Rails.cache.write 'distinct_domain_count', 345
 
       expect(instance_presenter.domain_count).to eq(345)
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index c197bc007..9a14fc3b1 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -1,7 +1,7 @@
 ENV['RAILS_ENV'] ||= 'test'
 require File.expand_path('../config/environment', __dir__)
 
-abort("The Rails environment is running in production mode!") if Rails.env.production?
+abort('The Rails environment is running in production mode!') if Rails.env.production?
 
 require 'spec_helper'
 require 'rspec/rails'
@@ -33,7 +33,7 @@ Devise::Test::ControllerHelpers.module_eval do
 end
 
 RSpec.configure do |config|
-  config.fixture_path = "#{::Rails.root}/spec/fixtures"
+  config.fixture_path = "#{Rails.root}/spec/fixtures"
   config.use_transactional_fixtures = true
   config.order = 'random'
   config.infer_spec_type_from_file_location!
diff --git a/spec/requests/catch_all_route_request_spec.rb b/spec/requests/catch_all_route_request_spec.rb
index f965f5522..fb18965d8 100644
--- a/spec/requests/catch_all_route_request_spec.rb
+++ b/spec/requests/catch_all_route_request_spec.rb
@@ -1,21 +1,21 @@
-require "rails_helper"
+require 'rails_helper'
 
-describe "The catch all route" do
-  describe "with a simple value" do
-    it "returns a 404 page as html" do
-      get "/test"
+describe 'The catch all route' do
+  describe 'with a simple value' do
+    it 'returns a 404 page as html' do
+      get '/test'
 
       expect(response.status).to eq 404
-      expect(response.media_type).to eq "text/html"
+      expect(response.media_type).to eq 'text/html'
     end
   end
 
-  describe "with an implied format" do
-    it "returns a 404 page as html" do
-      get "/test.test"
+  describe 'with an implied format' do
+    it 'returns a 404 page as html' do
+      get '/test.test'
 
       expect(response.status).to eq 404
-      expect(response.media_type).to eq "text/html"
+      expect(response.media_type).to eq 'text/html'
     end
   end
 end
diff --git a/spec/requests/host_meta_request_spec.rb b/spec/requests/host_meta_request_spec.rb
index 0ca641461..60153ba8c 100644
--- a/spec/requests/host_meta_request_spec.rb
+++ b/spec/requests/host_meta_request_spec.rb
@@ -1,12 +1,12 @@
-require "rails_helper"
+require 'rails_helper'
 
-describe "The host_meta route" do
-  describe "requested without accepts headers" do
-    it "returns an xml response" do
+describe 'The host_meta route' do
+  describe 'requested without accepts headers' do
+    it 'returns an xml response' do
       get host_meta_url
 
       expect(response).to have_http_status(200)
-      expect(response.media_type).to eq "application/xrd+xml"
+      expect(response.media_type).to eq 'application/xrd+xml'
     end
   end
 end
diff --git a/spec/requests/localization_spec.rb b/spec/requests/localization_spec.rb
index 0bc2786ac..39eeee5f0 100644
--- a/spec/requests/localization_spec.rb
+++ b/spec/requests/localization_spec.rb
@@ -10,7 +10,7 @@ describe 'Localization' do
   it 'uses a specific region when provided' do
     headers = { 'Accept-Language' => 'zh-HK' }
 
-    get "/auth/sign_in", headers: headers
+    get '/auth/sign_in', headers: headers
 
     expect(response.body).to include(
       I18n.t('auth.login', locale: 'zh-HK')
@@ -20,7 +20,7 @@ describe 'Localization' do
   it 'falls back to a locale when region missing' do
     headers = { 'Accept-Language' => 'es-FAKE' }
 
-    get "/auth/sign_in", headers: headers
+    get '/auth/sign_in', headers: headers
 
     expect(response.body).to include(
       I18n.t('auth.login', locale: 'es')
@@ -30,7 +30,7 @@ describe 'Localization' do
   it 'falls back to english when locale is missing' do
     headers = { 'Accept-Language' => '12-FAKE' }
 
-    get "/auth/sign_in", headers: headers
+    get '/auth/sign_in', headers: headers
 
     expect(response.body).to include(
       I18n.t('auth.login', locale: 'en')
diff --git a/spec/routing/api_routing_spec.rb b/spec/routing/api_routing_spec.rb
index 2683ccb8d..a822fba4c 100644
--- a/spec/routing/api_routing_spec.rb
+++ b/spec/routing/api_routing_spec.rb
@@ -5,99 +5,99 @@ require 'rails_helper'
 describe 'API routes' do
   describe 'Credentials routes' do
     it 'routes to verify credentials' do
-      expect(get('/api/v1/accounts/verify_credentials')).
-        to route_to('api/v1/accounts/credentials#show')
+      expect(get('/api/v1/accounts/verify_credentials'))
+        .to route_to('api/v1/accounts/credentials#show')
     end
 
     it 'routes to update credentials' do
-      expect(patch('/api/v1/accounts/update_credentials')).
-        to route_to('api/v1/accounts/credentials#update')
+      expect(patch('/api/v1/accounts/update_credentials'))
+        .to route_to('api/v1/accounts/credentials#update')
     end
   end
 
   describe 'Account routes' do
     it 'routes to statuses' do
-      expect(get('/api/v1/accounts/user/statuses')).
-        to route_to('api/v1/accounts/statuses#index', account_id: 'user')
+      expect(get('/api/v1/accounts/user/statuses'))
+        .to route_to('api/v1/accounts/statuses#index', account_id: 'user')
     end
 
     it 'routes to followers' do
-      expect(get('/api/v1/accounts/user/followers')).
-        to route_to('api/v1/accounts/follower_accounts#index', account_id: 'user')
+      expect(get('/api/v1/accounts/user/followers'))
+        .to route_to('api/v1/accounts/follower_accounts#index', account_id: 'user')
     end
 
     it 'routes to following' do
-      expect(get('/api/v1/accounts/user/following')).
-        to route_to('api/v1/accounts/following_accounts#index', account_id: 'user')
+      expect(get('/api/v1/accounts/user/following'))
+        .to route_to('api/v1/accounts/following_accounts#index', account_id: 'user')
     end
 
     it 'routes to search' do
-      expect(get('/api/v1/accounts/search')).
-        to route_to('api/v1/accounts/search#show')
+      expect(get('/api/v1/accounts/search'))
+        .to route_to('api/v1/accounts/search#show')
     end
 
     it 'routes to relationships' do
-      expect(get('/api/v1/accounts/relationships')).
-        to route_to('api/v1/accounts/relationships#index')
+      expect(get('/api/v1/accounts/relationships'))
+        .to route_to('api/v1/accounts/relationships#index')
     end
   end
 
   describe 'Statuses routes' do
     it 'routes reblogged_by' do
-      expect(get('/api/v1/statuses/123/reblogged_by')).
-        to route_to('api/v1/statuses/reblogged_by_accounts#index', status_id: '123')
+      expect(get('/api/v1/statuses/123/reblogged_by'))
+        .to route_to('api/v1/statuses/reblogged_by_accounts#index', status_id: '123')
     end
 
     it 'routes favourited_by' do
-      expect(get('/api/v1/statuses/123/favourited_by')).
-        to route_to('api/v1/statuses/favourited_by_accounts#index', status_id: '123')
+      expect(get('/api/v1/statuses/123/favourited_by'))
+        .to route_to('api/v1/statuses/favourited_by_accounts#index', status_id: '123')
     end
 
     it 'routes reblog' do
-      expect(post('/api/v1/statuses/123/reblog')).
-        to route_to('api/v1/statuses/reblogs#create', status_id: '123')
+      expect(post('/api/v1/statuses/123/reblog'))
+        .to route_to('api/v1/statuses/reblogs#create', status_id: '123')
     end
 
     it 'routes unreblog' do
-      expect(post('/api/v1/statuses/123/unreblog')).
-        to route_to('api/v1/statuses/reblogs#destroy', status_id: '123')
+      expect(post('/api/v1/statuses/123/unreblog'))
+        .to route_to('api/v1/statuses/reblogs#destroy', status_id: '123')
     end
 
     it 'routes favourite' do
-      expect(post('/api/v1/statuses/123/favourite')).
-        to route_to('api/v1/statuses/favourites#create', status_id: '123')
+      expect(post('/api/v1/statuses/123/favourite'))
+        .to route_to('api/v1/statuses/favourites#create', status_id: '123')
     end
 
     it 'routes unfavourite' do
-      expect(post('/api/v1/statuses/123/unfavourite')).
-        to route_to('api/v1/statuses/favourites#destroy', status_id: '123')
+      expect(post('/api/v1/statuses/123/unfavourite'))
+        .to route_to('api/v1/statuses/favourites#destroy', status_id: '123')
     end
 
     it 'routes mute' do
-      expect(post('/api/v1/statuses/123/mute')).
-        to route_to('api/v1/statuses/mutes#create', status_id: '123')
+      expect(post('/api/v1/statuses/123/mute'))
+        .to route_to('api/v1/statuses/mutes#create', status_id: '123')
     end
 
     it 'routes unmute' do
-      expect(post('/api/v1/statuses/123/unmute')).
-        to route_to('api/v1/statuses/mutes#destroy', status_id: '123')
+      expect(post('/api/v1/statuses/123/unmute'))
+        .to route_to('api/v1/statuses/mutes#destroy', status_id: '123')
     end
   end
 
   describe 'Timeline routes' do
     it 'routes to home timeline' do
-      expect(get('/api/v1/timelines/home')).
-        to route_to('api/v1/timelines/home#show')
+      expect(get('/api/v1/timelines/home'))
+        .to route_to('api/v1/timelines/home#show')
     end
 
     it 'routes to public timeline' do
-      expect(get('/api/v1/timelines/public')).
-        to route_to('api/v1/timelines/public#show')
+      expect(get('/api/v1/timelines/public'))
+        .to route_to('api/v1/timelines/public#show')
     end
 
     it 'routes to tag timeline' do
-      expect(get('/api/v1/timelines/tag/test')).
-        to route_to('api/v1/timelines/tag#show', id: 'test')
+      expect(get('/api/v1/timelines/tag/test'))
+        .to route_to('api/v1/timelines/tag#show', id: 'test')
     end
   end
 end
diff --git a/spec/routing/well_known_routes_spec.rb b/spec/routing/well_known_routes_spec.rb
index 2e25605c2..747463351 100644
--- a/spec/routing/well_known_routes_spec.rb
+++ b/spec/routing/well_known_routes_spec.rb
@@ -1,15 +1,17 @@
 require 'rails_helper'
 
-describe 'the host-meta route' do
-  it 'routes to correct place with xml format' do
-    expect(get('/.well-known/host-meta')).
-      to route_to('well_known/host_meta#show', format: 'xml')
+describe 'Well Known routes' do
+  describe 'the host-meta route' do
+    it 'routes to correct place with xml format' do
+      expect(get('/.well-known/host-meta'))
+        .to route_to('well_known/host_meta#show', format: 'xml')
+    end
   end
-end
 
-describe 'the webfinger route' do
-  it 'routes to correct place with json format' do
-    expect(get('/.well-known/webfinger')).
-      to route_to('well_known/webfinger#show')
+  describe 'the webfinger route' do
+    it 'routes to correct place with json format' do
+      expect(get('/.well-known/webfinger'))
+        .to route_to('well_known/webfinger#show')
+    end
   end
 end
diff --git a/spec/serializers/rest/account_serializer_spec.rb b/spec/serializers/rest/account_serializer_spec.rb
index ce29df3a7..3bca06b73 100644
--- a/spec/serializers/rest/account_serializer_spec.rb
+++ b/spec/serializers/rest/account_serializer_spec.rb
@@ -5,7 +5,7 @@ require 'rails_helper'
 describe REST::AccountSerializer do
   let(:role)    { Fabricate(:user_role, name: 'Role', highlighted: true) }
   let(:user)    { Fabricate(:user, role: role) }
-  let(:account) { user.account}
+  let(:account) { user.account }
 
   subject { JSON.parse(ActiveModelSerializers::SerializableResource.new(account, serializer: REST::AccountSerializer).to_json) }
 
@@ -34,4 +34,14 @@ describe REST::AccountSerializer do
       expect(subject['roles']).to eq []
     end
   end
+
+  context 'when the account is memorialized' do
+    before do
+      account.memorialize!
+    end
+
+    it 'marks it as such' do
+      expect(subject['memorial']).to be true
+    end
+  end
 end
diff --git a/spec/services/account_search_service_spec.rb b/spec/services/account_search_service_spec.rb
index 81cbc175e..d3b5baad6 100644
--- a/spec/services/account_search_service_spec.rb
+++ b/spec/services/account_search_service_spec.rb
@@ -76,7 +76,7 @@ describe AccountSearchService, type: :service do
       expect(results).to eq [partial]
     end
 
-    it "does not return suspended remote accounts" do
+    it 'does not return suspended remote accounts' do
       remote  = Fabricate(:account, username: 'a', domain: 'remote', display_name: 'e', suspended: true)
       results = subject.call('a@example.com', nil, limit: 2)
 
diff --git a/spec/services/account_statuses_cleanup_service_spec.rb b/spec/services/account_statuses_cleanup_service_spec.rb
index 257655c41..a30e14ab6 100644
--- a/spec/services/account_statuses_cleanup_service_spec.rb
+++ b/spec/services/account_statuses_cleanup_service_spec.rb
@@ -42,8 +42,8 @@ describe AccountStatusesCleanupService, type: :service do
 
       context 'when called repeatedly with a budget of 2' do
         it 'reports 2 then 1 deleted statuses' do
-         expect(subject.call(account_policy, 2)).to eq 2
-         expect(subject.call(account_policy, 2)).to eq 1
+          expect(subject.call(account_policy, 2)).to eq 2
+          expect(subject.call(account_policy, 2)).to eq 1
         end
 
         it 'actually deletes the statuses in the expected order' do
diff --git a/spec/services/activitypub/fetch_featured_collection_service_spec.rb b/spec/services/activitypub/fetch_featured_collection_service_spec.rb
index e6336dc1b..23d90a9a2 100644
--- a/spec/services/activitypub/fetch_featured_collection_service_spec.rb
+++ b/spec/services/activitypub/fetch_featured_collection_service_spec.rb
@@ -109,7 +109,7 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do
             type: 'CollectionPage',
             partOf: actor.featured_collection_url,
             items: items,
-          }
+          },
         }.with_indifferent_access
       end
 
diff --git a/spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb b/spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb
index 6ca22c9fc..692866bce 100644
--- a/spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb
+++ b/spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb
@@ -81,7 +81,7 @@ RSpec.describe ActivityPub::FetchFeaturedTagsCollectionService, type: :service d
             type: 'CollectionPage',
             partOf: collection_url,
             items: items,
-          }
+          },
         }.with_indifferent_access
       end
 
diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb
index a81dcad81..4f3503ac2 100644
--- a/spec/services/activitypub/fetch_remote_status_service_spec.rb
+++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
   let(:note) do
     {
       '@context': 'https://www.w3.org/ns/activitystreams',
-      id: "https://foo.bar/@foo/1234",
+      id: 'https://foo.bar/@foo/1234',
       type: 'Note',
       content: 'Lorem ipsum',
       attributedTo: ActivityPub::TagManager.instance.uri_for(sender),
@@ -46,7 +46,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
       let(:object) do
         {
           '@context': 'https://www.w3.org/ns/activitystreams',
-          id: "https://foo.bar/@foo/1234",
+          id: 'https://foo.bar/@foo/1234',
           type: 'Video',
           name: 'Nyan Cat 10 hours remix',
           attributedTo: ActivityPub::TagManager.instance.uri_for(sender),
@@ -54,13 +54,13 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
             {
               type: 'Link',
               mimeType: 'application/x-bittorrent',
-              href: "https://foo.bar/12345.torrent",
+              href: 'https://foo.bar/12345.torrent',
             },
 
             {
               type: 'Link',
               mimeType: 'text/html',
-              href: "https://foo.bar/watch?v=12345",
+              href: 'https://foo.bar/watch?v=12345',
             },
           ],
         }
@@ -70,8 +70,8 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.url).to eq "https://foo.bar/watch?v=12345"
-        expect(strip_tags(status.text)).to eq "Nyan Cat 10 hours remixhttps://foo.bar/watch?v=12345"
+        expect(status.url).to eq 'https://foo.bar/watch?v=12345'
+        expect(strip_tags(status.text)).to eq 'Nyan Cat 10 hours remixhttps://foo.bar/watch?v=12345'
       end
     end
 
@@ -79,7 +79,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
       let(:object) do
         {
           '@context': 'https://www.w3.org/ns/activitystreams',
-          id: "https://foo.bar/@foo/1234",
+          id: 'https://foo.bar/@foo/1234',
           type: 'Audio',
           name: 'Nyan Cat 10 hours remix',
           attributedTo: ActivityPub::TagManager.instance.uri_for(sender),
@@ -87,13 +87,13 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
             {
               type: 'Link',
               mimeType: 'application/x-bittorrent',
-              href: "https://foo.bar/12345.torrent",
+              href: 'https://foo.bar/12345.torrent',
             },
 
             {
               type: 'Link',
               mimeType: 'text/html',
-              href: "https://foo.bar/watch?v=12345",
+              href: 'https://foo.bar/watch?v=12345',
             },
           ],
         }
@@ -103,8 +103,8 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.url).to eq "https://foo.bar/watch?v=12345"
-        expect(strip_tags(status.text)).to eq "Nyan Cat 10 hours remixhttps://foo.bar/watch?v=12345"
+        expect(status.url).to eq 'https://foo.bar/watch?v=12345'
+        expect(strip_tags(status.text)).to eq 'Nyan Cat 10 hours remixhttps://foo.bar/watch?v=12345'
       end
     end
 
@@ -112,10 +112,10 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
       let(:object) do
         {
           '@context': 'https://www.w3.org/ns/activitystreams',
-          id: "https://foo.bar/@foo/1234",
+          id: 'https://foo.bar/@foo/1234',
           type: 'Event',
           name: "Let's change the world",
-          attributedTo: ActivityPub::TagManager.instance.uri_for(sender)
+          attributedTo: ActivityPub::TagManager.instance.uri_for(sender),
         }
       end
 
@@ -123,7 +123,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.url).to eq "https://foo.bar/@foo/1234"
+        expect(status.url).to eq 'https://foo.bar/@foo/1234'
         expect(strip_tags(status.text)).to eq "Let's change the worldhttps://foo.bar/@foo/1234"
       end
     end
@@ -132,7 +132,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
       let(:note) do
         {
           '@context': 'https://www.w3.org/ns/activitystreams',
-          id: "https://real.address/@foo/1234",
+          id: 'https://real.address/@foo/1234',
           type: 'Note',
           content: 'Lorem ipsum',
           attributedTo: ActivityPub::TagManager.instance.uri_for(sender),
@@ -154,7 +154,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
       let(:object) do
         {
           '@context': 'https://www.w3.org/ns/activitystreams',
-          id: "https://foo.bar/@foo/1234/create",
+          id: 'https://foo.bar/@foo/1234/create',
           type: 'Create',
           actor: ActivityPub::TagManager.instance.uri_for(sender),
           object: note,
@@ -174,11 +174,11 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
       let(:object) do
         {
           '@context': 'https://www.w3.org/ns/activitystreams',
-          id: "https://foo.bar/@foo/1234/create",
+          id: 'https://foo.bar/@foo/1234/create',
           type: 'Create',
           actor: ActivityPub::TagManager.instance.uri_for(sender),
           object: {
-            id: "https://real.address/@foo/1234",
+            id: 'https://real.address/@foo/1234',
             type: 'Note',
             content: 'Lorem ipsum',
             attributedTo: ActivityPub::TagManager.instance.uri_for(sender),
@@ -208,7 +208,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
         let(:object) do
           {
             '@context': 'https://www.w3.org/ns/activitystreams',
-            id: "https://foo.bar/@foo/1234/create",
+            id: 'https://foo.bar/@foo/1234/create',
             type: 'Create',
             actor: ActivityPub::TagManager.instance.uri_for(sender),
             object: note.merge(updated: '2021-09-08T22:39:25Z'),
@@ -233,7 +233,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
       let(:object) do
         {
           '@context': 'https://www.w3.org/ns/activitystreams',
-          id: "https://foo.bar/@foo/1",
+          id: 'https://foo.bar/@foo/1',
           type: 'Note',
           content: 'Lorem ipsum',
           inReplyTo: 'https://foo.bar/@foo/2',
@@ -269,7 +269,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
       let(:object) do
         {
           '@context': 'https://www.w3.org/ns/activitystreams',
-          id: "https://foo.bar/@foo/1",
+          id: 'https://foo.bar/@foo/1',
           type: 'Note',
           content: 'Lorem ipsum',
           replies: {
@@ -298,7 +298,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
               first: {
                 type: 'CollectionPage',
                 partOf: "https://foo.bar/@foo/#{i}/replies",
-                items: ["https://foo.bar/@foo/#{i+1}"],
+                items: ["https://foo.bar/@foo/#{i + 1}"],
               },
             },
             attributedTo: ActivityPub::TagManager.instance.uri_for(sender),
diff --git a/spec/services/activitypub/fetch_replies_service_spec.rb b/spec/services/activitypub/fetch_replies_service_spec.rb
index fe49b18c1..5741e0c3f 100644
--- a/spec/services/activitypub/fetch_replies_service_spec.rb
+++ b/spec/services/activitypub/fetch_replies_service_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe ActivityPub::FetchRepliesService, type: :service do
             type: 'CollectionPage',
             partOf: collection_uri,
             items: items,
-          }
+          },
         }.with_indifferent_access
       end
 
diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb
index 2b20d17b1..d0af7de76 100644
--- a/spec/services/activitypub/process_account_service_spec.rb
+++ b/spec/services/activitypub/process_account_service_spec.rb
@@ -172,10 +172,10 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
             {
               type: 'Mention',
               href: "https://foo.test/users/#{i + 1}",
-              name: "@user#{i + 1 }",
-            }
+              name: "@user#{i + 1}",
+            },
           ],
-          to: [ 'as:Public', "https://foo.test/users/#{i + 1}" ]
+          to: ['as:Public', "https://foo.test/users/#{i + 1}"],
         }.with_indifferent_access
         featured_json = {
           '@context': ['https://www.w3.org/ns/activitystreams'],
diff --git a/spec/services/activitypub/process_collection_service_spec.rb b/spec/services/activitypub/process_collection_service_spec.rb
index 093a188a2..fbfa6d6c6 100644
--- a/spec/services/activitypub/process_collection_service_spec.rb
+++ b/spec/services/activitypub/process_collection_service_spec.rb
@@ -95,11 +95,11 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
       context 'when receiving a fabricated status' do
         let!(:actor) do
           Fabricate(:account,
-            username: 'bob',
-            domain: 'example.com',
-            uri: 'https://example.com/users/bob',
-            public_key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuuYyoyfsRkYnXRotMsId\nW3euBDDfiv9oVqOxUVC7bhel8KednIMrMCRWFAkgJhbrlzbIkjVr68o1MP9qLcn7\nCmH/BXHp7yhuFTr4byjdJKpwB+/i2jNEsvDH5jR8WTAeTCe0x/QHg21V3F7dSI5m\nCCZ/1dSIyOXLRTWVlfDlm3rE4ntlCo+US3/7oSWbg/4/4qEnt1HC32kvklgScxua\n4LR5ATdoXa5bFoopPWhul7MJ6NyWCyQyScUuGdlj8EN4kmKQJvphKHrI9fvhgOuG\nTvhTR1S5InA4azSSchY0tXEEw/VNxraeX0KPjbgr6DPcwhPd/m0nhVDq0zVyVBBD\nMwIDAQAB\n-----END PUBLIC KEY-----\n",
-            private_key: nil)
+                    username: 'bob',
+                    domain: 'example.com',
+                    uri: 'https://example.com/users/bob',
+                    public_key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuuYyoyfsRkYnXRotMsId\nW3euBDDfiv9oVqOxUVC7bhel8KednIMrMCRWFAkgJhbrlzbIkjVr68o1MP9qLcn7\nCmH/BXHp7yhuFTr4byjdJKpwB+/i2jNEsvDH5jR8WTAeTCe0x/QHg21V3F7dSI5m\nCCZ/1dSIyOXLRTWVlfDlm3rE4ntlCo+US3/7oSWbg/4/4qEnt1HC32kvklgScxua\n4LR5ATdoXa5bFoopPWhul7MJ6NyWCyQyScUuGdlj8EN4kmKQJvphKHrI9fvhgOuG\nTvhTR1S5InA4azSSchY0tXEEw/VNxraeX0KPjbgr6DPcwhPd/m0nhVDq0zVyVBBD\nMwIDAQAB\n-----END PUBLIC KEY-----\n",
+                    private_key: nil)
         end
 
         let(:payload) do
@@ -107,48 +107,48 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
             '@context': [
               'https://www.w3.org/ns/activitystreams',
               nil,
-              {'object': 'https://www.w3.org/ns/activitystreams#object'}
+              { object: 'https://www.w3.org/ns/activitystreams#object' },
             ],
-            'id': 'https://example.com/users/bob/fake-status/activity',
-            'type': 'Create',
-            'actor': 'https://example.com/users/bob',
-            'published': '2022-01-22T15:00:00Z',
-            'to': [
-              'https://www.w3.org/ns/activitystreams#Public'
+            id: 'https://example.com/users/bob/fake-status/activity',
+            type: 'Create',
+            actor: 'https://example.com/users/bob',
+            published: '2022-01-22T15:00:00Z',
+            to: [
+              'https://www.w3.org/ns/activitystreams#Public',
             ],
-            'cc': [
-              'https://example.com/users/bob/followers'
+            cc: [
+              'https://example.com/users/bob/followers',
             ],
-            'signature': {
-              'type': 'RsaSignature2017',
-              'creator': 'https://example.com/users/bob#main-key',
-              'created': '2022-03-09T21:57:25Z',
-              'signatureValue': 'WculK0LelTQ0MvGwU9TPoq5pFzFfGYRDCJqjZ232/Udj4CHqDTGOSw5UTDLShqBOyycCkbZGrQwXG+dpyDpQLSe1UVPZ5TPQtc/9XtI57WlS2nMNpdvRuxGnnb2btPdesXZ7n3pCxo0zjaXrJMe0mqQh5QJO22mahb4bDwwmfTHgbD3nmkD+fBfGi+UV2qWwqr+jlV4L4JqNkh0gWljF5KTePLRRZCuWiQ/FAt7c67636cdIPf7fR+usjuZltTQyLZKEGuK8VUn2Gkfsx5qns7Vcjvlz1JqlAjyO8HPBbzTTHzUG2nUOIgC3PojCSWv6mNTmRGoLZzOscCAYQA6cKw=='
+            signature: {
+              type: 'RsaSignature2017',
+              creator: 'https://example.com/users/bob#main-key',
+              created: '2022-03-09T21:57:25Z',
+              signatureValue: 'WculK0LelTQ0MvGwU9TPoq5pFzFfGYRDCJqjZ232/Udj4CHqDTGOSw5UTDLShqBOyycCkbZGrQwXG+dpyDpQLSe1UVPZ5TPQtc/9XtI57WlS2nMNpdvRuxGnnb2btPdesXZ7n3pCxo0zjaXrJMe0mqQh5QJO22mahb4bDwwmfTHgbD3nmkD+fBfGi+UV2qWwqr+jlV4L4JqNkh0gWljF5KTePLRRZCuWiQ/FAt7c67636cdIPf7fR+usjuZltTQyLZKEGuK8VUn2Gkfsx5qns7Vcjvlz1JqlAjyO8HPBbzTTHzUG2nUOIgC3PojCSWv6mNTmRGoLZzOscCAYQA6cKw==',
             },
             '@id': 'https://example.com/users/bob/statuses/107928807471117876/activity',
             '@type': 'https://www.w3.org/ns/activitystreams#Create',
             'https://www.w3.org/ns/activitystreams#actor': {
-              '@id': 'https://example.com/users/bob'
+              '@id': 'https://example.com/users/bob',
             },
             'https://www.w3.org/ns/activitystreams#cc': {
-              '@id': 'https://example.com/users/bob/followers'
+              '@id': 'https://example.com/users/bob/followers',
             },
-            'object': {
-              'id': 'https://example.com/users/bob/fake-status',
-              'type': 'Note',
-              'published': '2022-01-22T15:00:00Z',
-              'url': 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=puck-was-here',
-              'attributedTo': 'https://example.com/users/bob',
-              'to': [
-                'https://www.w3.org/ns/activitystreams#Public'
+            object: {
+              id: 'https://example.com/users/bob/fake-status',
+              type: 'Note',
+              published: '2022-01-22T15:00:00Z',
+              url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=puck-was-here',
+              attributedTo: 'https://example.com/users/bob',
+              to: [
+                'https://www.w3.org/ns/activitystreams#Public',
               ],
-              'cc': [
-                'https://example.com/users/bob/followers'
+              cc: [
+                'https://example.com/users/bob/followers',
               ],
-              'sensitive': false,
-              'atomUri': 'https://example.com/users/bob/fake-status',
-              'conversation': 'tag:example.com,2022-03-09:objectId=15:objectType=Conversation',
-              'content': '<p>puck was here</p>',
+              sensitive: false,
+              atomUri: 'https://example.com/users/bob/fake-status',
+              conversation: 'tag:example.com,2022-03-09:objectId=15:objectType=Conversation',
+              content: '<p>puck was here</p>',
 
               '@id': 'https://example.com/users/bob/statuses/107928807471117876',
               '@type': 'https://www.w3.org/ns/activitystreams#Note',
@@ -156,21 +156,21 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
               'http://ostatus.org#conversation': 'tag:example.com,2022-03-09:objectId=15:objectType=Conversation',
               'https://www.w3.org/ns/activitystreams#attachment': [],
               'https://www.w3.org/ns/activitystreams#attributedTo': {
-                '@id': 'https://example.com/users/bob'
+                '@id': 'https://example.com/users/bob',
               },
               'https://www.w3.org/ns/activitystreams#cc': {
-                '@id': 'https://example.com/users/bob/followers'
+                '@id': 'https://example.com/users/bob/followers',
               },
               'https://www.w3.org/ns/activitystreams#content': [
                 '<p>hello world</p>',
                 {
                   '@value': '<p>hello world</p>',
-                  '@language': 'en'
-                }
+                  '@language': 'en',
+                },
               ],
               'https://www.w3.org/ns/activitystreams#published': {
                 '@type': 'http://www.w3.org/2001/XMLSchema#dateTime',
-                '@value': '2022-03-09T21:55:07Z'
+                '@value': '2022-03-09T21:55:07Z',
               },
               'https://www.w3.org/ns/activitystreams#replies': {
                 '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies',
@@ -179,29 +179,29 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
                   '@type': 'https://www.w3.org/ns/activitystreams#CollectionPage',
                   'https://www.w3.org/ns/activitystreams#items': [],
                   'https://www.w3.org/ns/activitystreams#next': {
-                    '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies?only_other_accounts=true&page=true'
+                    '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies?only_other_accounts=true&page=true',
                   },
                   'https://www.w3.org/ns/activitystreams#partOf': {
-                    '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies'
-                  }
-                }
+                    '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies',
+                  },
+                },
               },
               'https://www.w3.org/ns/activitystreams#sensitive': false,
               'https://www.w3.org/ns/activitystreams#tag': [],
               'https://www.w3.org/ns/activitystreams#to': {
-                '@id': 'https://www.w3.org/ns/activitystreams#Public'
+                '@id': 'https://www.w3.org/ns/activitystreams#Public',
               },
               'https://www.w3.org/ns/activitystreams#url': {
-                '@id': 'https://example.com/@bob/107928807471117876'
-              }
+                '@id': 'https://example.com/@bob/107928807471117876',
+              },
             },
             'https://www.w3.org/ns/activitystreams#published': {
               '@type': 'http://www.w3.org/2001/XMLSchema#dateTime',
-              '@value': '2022-03-09T21:55:07Z'
+              '@value': '2022-03-09T21:55:07Z',
             },
             'https://www.w3.org/ns/activitystreams#to': {
-              '@id': 'https://www.w3.org/ns/activitystreams#Public'
-            }
+              '@id': 'https://www.w3.org/ns/activitystreams#Public',
+            },
           }
         end
 
@@ -212,8 +212,8 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
                 'id' => 'https://example.com/users/bob/fake-status'
               )
             ),
-            anything(),
-            anything()
+            anything,
+            anything
           )
 
           expect(ActivityPub::Activity).not_to receive(:factory).with(
@@ -222,8 +222,8 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
                 'content' => '<p>puck was here</p>'
               )
             ),
-            anything(),
-            anything()
+            anything,
+            anything
           )
 
           subject.call(json, forwarder)
diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb
index 750369d57..5d15f6ffe 100644
--- a/spec/services/activitypub/process_status_update_service_spec.rb
+++ b/spec/services/activitypub/process_status_update_service_spec.rb
@@ -104,20 +104,19 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do
     end
 
     context 'when the status has not been explicitly edited and features a poll' do
-      let(:account)    { Fabricate(:account, domain: 'example.com') }
+      let(:account) { Fabricate(:account, domain: 'example.com') }
       let!(:expiration) { 10.days.from_now.utc }
       let!(:status) do
         Fabricate(:status,
-          text: 'Hello world',
-          account: account,
-          poll_attributes: {
-            options: %w(Foo Bar),
-            account: account,
-            multiple: false,
-            hide_totals: false,
-            expires_at: expiration
-          }
-        )
+                  text: 'Hello world',
+                  account: account,
+                  poll_attributes: {
+                    options: %w(Foo Bar),
+                    account: account,
+                    multiple: false,
+                    hide_totals: false,
+                    expires_at: expiration,
+                  })
       end
 
       let(:payload) do
@@ -156,20 +155,19 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do
     end
 
     context 'when the status changes a poll despite being not explicitly marked as updated' do
-      let(:account)    { Fabricate(:account, domain: 'example.com') }
+      let(:account) { Fabricate(:account, domain: 'example.com') }
       let!(:expiration) { 10.days.from_now.utc }
       let!(:status) do
         Fabricate(:status,
-          text: 'Hello world',
-          account: account,
-          poll_attributes: {
-            options: %w(Foo Bar),
-            account: account,
-            multiple: false,
-            hide_totals: false,
-            expires_at: expiration
-          }
-        )
+                  text: 'Hello world',
+                  account: account,
+                  poll_attributes: {
+                    options: %w(Foo Bar),
+                    account: account,
+                    multiple: false,
+                    hide_totals: false,
+                    expires_at: expiration,
+                  })
       end
 
       let(:payload) do
@@ -344,7 +342,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do
           updated: '2021-09-08T22:39:25Z',
           attachment: [
             { type: 'Image', mediaType: 'image/png', url: 'https://example.com/foo.png' },
-          ]
+          ],
         }
       end
 
@@ -376,7 +374,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do
           updated: '2021-09-08T22:39:25Z',
           attachment: [
             { type: 'Image', mediaType: 'image/png', url: 'https://example.com/foo.png', name: 'A picture' },
-          ]
+          ],
         }
       end
 
diff --git a/spec/services/activitypub/synchronize_followers_service_spec.rb b/spec/services/activitypub/synchronize_followers_service_spec.rb
index 75dcf204b..5a37f0733 100644
--- a/spec/services/activitypub/synchronize_followers_service_spec.rb
+++ b/spec/services/activitypub/synchronize_followers_service_spec.rb
@@ -91,7 +91,7 @@ RSpec.describe ActivityPub::SynchronizeFollowersService, type: :service do
             type: 'CollectionPage',
             partOf: collection_uri,
             items: items,
-          }
+          },
         }.with_indifferent_access
       end
 
diff --git a/spec/services/bootstrap_timeline_service_spec.rb b/spec/services/bootstrap_timeline_service_spec.rb
index 16f3e9962..149f6e6df 100644
--- a/spec/services/bootstrap_timeline_service_spec.rb
+++ b/spec/services/bootstrap_timeline_service_spec.rb
@@ -32,6 +32,5 @@ RSpec.describe BootstrapTimelineService, type: :service do
         expect(service).to_not have_received(:call)
       end
     end
-
   end
 end
diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb
index 1fbe4d07c..cc4b168fc 100644
--- a/spec/services/delete_account_service_spec.rb
+++ b/spec/services/delete_account_service_spec.rb
@@ -59,8 +59,8 @@ RSpec.describe DeleteAccountService, type: :service do
 
   describe '#call on local account' do
     before do
-      stub_request(:post, "https://alice.com/inbox").to_return(status: 201)
-      stub_request(:post, "https://bob.com/inbox").to_return(status: 201)
+      stub_request(:post, 'https://alice.com/inbox').to_return(status: 201)
+      stub_request(:post, 'https://bob.com/inbox').to_return(status: 201)
     end
 
     let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) }
@@ -72,16 +72,16 @@ RSpec.describe DeleteAccountService, type: :service do
 
       it 'sends a delete actor activity to all known inboxes' do
         subject
-        expect(a_request(:post, "https://alice.com/inbox")).to have_been_made.once
-        expect(a_request(:post, "https://bob.com/inbox")).to have_been_made.once
+        expect(a_request(:post, 'https://alice.com/inbox')).to have_been_made.once
+        expect(a_request(:post, 'https://bob.com/inbox')).to have_been_made.once
       end
     end
   end
 
   describe '#call on remote account' do
     before do
-      stub_request(:post, "https://alice.com/inbox").to_return(status: 201)
-      stub_request(:post, "https://bob.com/inbox").to_return(status: 201)
+      stub_request(:post, 'https://alice.com/inbox').to_return(status: 201)
+      stub_request(:post, 'https://bob.com/inbox').to_return(status: 201)
     end
 
     include_examples 'common behavior' do
diff --git a/spec/services/favourite_service_spec.rb b/spec/services/favourite_service_spec.rb
index 9781f0d78..8703c2af8 100644
--- a/spec/services/favourite_service_spec.rb
+++ b/spec/services/favourite_service_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe FavouriteService, type: :service do
     let(:status) { Fabricate(:status, account: bob) }
 
     before do
-      stub_request(:post, "http://example.com/inbox").to_return(status: 200, body: "", headers: {})
+      stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {})
       subject.call(sender, status)
     end
 
@@ -32,7 +32,7 @@ RSpec.describe FavouriteService, type: :service do
     end
 
     it 'sends a like activity' do
-      expect(a_request(:post, "http://example.com/inbox")).to have_been_made.once
+      expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
     end
   end
 end
diff --git a/spec/services/fetch_link_card_service_spec.rb b/spec/services/fetch_link_card_service_spec.rb
index 4914c2753..458473c39 100644
--- a/spec/services/fetch_link_card_service_spec.rb
+++ b/spec/services/fetch_link_card_service_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe FetchLinkCardService, type: :service do
 
       it 'works with SJIS' do
         expect(a_request(:get, 'http://example.com/sjis')).to have_been_made.at_least_once
-        expect(status.preview_cards.first.title).to eq("SJISのページ")
+        expect(status.preview_cards.first.title).to eq('SJISのページ')
       end
     end
 
@@ -39,7 +39,7 @@ RSpec.describe FetchLinkCardService, type: :service do
 
       it 'works with SJIS even with wrong charset header' do
         expect(a_request(:get, 'http://example.com/sjis_with_wrong_charset')).to have_been_made.at_least_once
-        expect(status.preview_cards.first.title).to eq("SJISのページ")
+        expect(status.preview_cards.first.title).to eq('SJISのページ')
       end
     end
 
@@ -48,7 +48,7 @@ RSpec.describe FetchLinkCardService, type: :service do
 
       it 'works with koi8-r' do
         expect(a_request(:get, 'http://example.com/koi8-r')).to have_been_made.at_least_once
-        expect(status.preview_cards.first.title).to eq("Московя начинаетъ только въ XVI ст. привлекать внимане иностранцевъ.")
+        expect(status.preview_cards.first.title).to eq('Московя начинаетъ только въ XVI ст. привлекать внимане иностранцевъ.')
       end
     end
 
@@ -66,7 +66,7 @@ RSpec.describe FetchLinkCardService, type: :service do
 
       it 'works with Japanese path string' do
         expect(a_request(:get, 'http://example.com/日本語')).to have_been_made.at_least_once
-        expect(status.preview_cards.first.title).to eq("SJISのページ")
+        expect(status.preview_cards.first.title).to eq('SJISのページ')
       end
     end
 
diff --git a/spec/services/fetch_oembed_service_spec.rb b/spec/services/fetch_oembed_service_spec.rb
index 88f0113ed..cf46f2d39 100644
--- a/spec/services/fetch_oembed_service_spec.rb
+++ b/spec/services/fetch_oembed_service_spec.rb
@@ -6,9 +6,9 @@ describe FetchOEmbedService, type: :service do
   subject { described_class.new }
 
   before do
-    stub_request(:get, "https://host.test/provider.json").to_return(status: 404)
-    stub_request(:get, "https://host.test/provider.xml").to_return(status: 404)
-    stub_request(:get, "https://host.test/empty_provider.json").to_return(status: 200)
+    stub_request(:get, 'https://host.test/provider.json').to_return(status: 404)
+    stub_request(:get, 'https://host.test/provider.xml').to_return(status: 404)
+    stub_request(:get, 'https://host.test/empty_provider.json').to_return(status: 200)
   end
 
   describe 'discover_provider' do
@@ -18,7 +18,7 @@ describe FetchOEmbedService, type: :service do
           stub_request(:get, 'https://www.youtube.com/watch?v=IPSbNdBmWKE').to_return(
             status: 200,
             headers: { 'Content-Type': 'text/html' },
-            body: request_fixture('oembed_youtube.html'),
+            body: request_fixture('oembed_youtube.html')
           )
           stub_request(:get, 'https://www.youtube.com/oembed?format=json&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DIPSbNdBmWKE').to_return(
             status: 200,
@@ -151,7 +151,6 @@ describe FetchOEmbedService, type: :service do
           expect(subject.format).to eq :json
         end
       end
-
     end
 
     context 'when endpoint is cached' do
diff --git a/spec/services/fetch_remote_status_service_spec.rb b/spec/services/fetch_remote_status_service_spec.rb
index 4f6ad6496..02c62f8d6 100644
--- a/spec/services/fetch_remote_status_service_spec.rb
+++ b/spec/services/fetch_remote_status_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe FetchRemoteStatusService, type: :service do
   let(:note) do
     {
       '@context': 'https://www.w3.org/ns/activitystreams',
-      id: "https://example.org/@foo/1234",
+      id: 'https://example.org/@foo/1234',
       type: 'Note',
       content: 'Lorem ipsum',
       attributedTo: ActivityPub::TagManager.instance.uri_for(account),
diff --git a/spec/services/fetch_resource_service_spec.rb b/spec/services/fetch_resource_service_spec.rb
index c0c96ab69..c39f52632 100644
--- a/spec/services/fetch_resource_service_spec.rb
+++ b/spec/services/fetch_resource_service_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe FetchResourceService, type: :service do
 
     context 'with blank url' do
       let(:url) { '' }
+
       it { is_expected.to be_nil }
     end
 
@@ -21,7 +22,7 @@ RSpec.describe FetchResourceService, type: :service do
 
     context 'when OpenSSL::SSL::SSLError is raised' do
       before do
-        request = double()
+        request = double
         allow(Request).to receive(:new).and_return(request)
         allow(request).to receive(:add_headers)
         allow(request).to receive(:on_behalf_of)
@@ -33,7 +34,7 @@ RSpec.describe FetchResourceService, type: :service do
 
     context 'when HTTP::ConnectionError is raised' do
       before do
-        request = double()
+        request = double
         allow(Request).to receive(:new).and_return(request)
         allow(request).to receive(:add_headers)
         allow(request).to receive(:on_behalf_of)
@@ -62,6 +63,7 @@ RSpec.describe FetchResourceService, type: :service do
 
       before do
         stub_request(:get, url).to_return(status: 200, body: body, headers: headers)
+        stub_request(:get, 'http://example.com/foo').to_return(status: 200, body: json, headers: { 'Content-Type' => 'application/activity+json' })
       end
 
       it 'signs request' do
@@ -89,13 +91,8 @@ RSpec.describe FetchResourceService, type: :service do
         it { is_expected.to eq [1, { prefetched_body: body, id: true }] }
       end
 
-      before do
-        stub_request(:get, url).to_return(status: 200, body: body, headers: headers)
-        stub_request(:get, 'http://example.com/foo').to_return(status: 200, body: json, headers: { 'Content-Type' => 'application/activity+json' })
-      end
-
       context 'when link header is present' do
-        let(:headers) { { 'Link' => '<http://example.com/foo>; rel="alternate"; type="application/activity+json"', } }
+        let(:headers) { { 'Link' => '<http://example.com/foo>; rel="alternate"; type="application/activity+json"' } }
 
         it { is_expected.to eq [1, { prefetched_body: json, id: true }] }
       end
diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb
index 412c04d76..59073c27f 100644
--- a/spec/services/follow_service_spec.rb
+++ b/spec/services/follow_service_spec.rb
@@ -140,7 +140,7 @@ RSpec.describe FollowService, type: :service do
     let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
 
     before do
-      stub_request(:post, "http://example.com/inbox").to_return(status: 200, body: "", headers: {})
+      stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {})
       subject.call(sender, bob)
     end
 
diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb
index e2d182920..a12148833 100644
--- a/spec/services/import_service_spec.rb
+++ b/spec/services/import_service_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe ImportService, type: :service do
   let!(:eve)     { Fabricate(:account, username: 'eve', domain: 'example.com', locked: false, protocol: :activitypub, inbox_url: 'https://example.com/inbox') }
 
   before do
-    stub_request(:post, "https://example.com/inbox").to_return(status: 200)
+    stub_request(:post, 'https://example.com/inbox').to_return(status: 200)
   end
 
   context 'import old-style list of muted users' do
@@ -18,6 +18,7 @@ RSpec.describe ImportService, type: :service do
 
     describe 'when no accounts are muted' do
       let(:import) { Import.create(account: account, type: 'muting', data: csv) }
+
       it 'mutes the listed accounts, including notifications' do
         subject.call(import)
         expect(account.muting.count).to eq 2
@@ -55,6 +56,7 @@ RSpec.describe ImportService, type: :service do
 
     describe 'when no accounts are muted' do
       let(:import) { Import.create(account: account, type: 'muting', data: csv) }
+
       it 'mutes the listed accounts, respecting notifications' do
         subject.call(import)
         expect(account.muting.count).to eq 2
@@ -95,6 +97,7 @@ RSpec.describe ImportService, type: :service do
 
     describe 'when no accounts are followed' do
       let(:import) { Import.create(account: account, type: 'following', data: csv) }
+
       it 'follows the listed accounts, including boosts' do
         subject.call(import)
 
@@ -136,6 +139,7 @@ RSpec.describe ImportService, type: :service do
 
     describe 'when no accounts are followed' do
       let(:import) { Import.create(account: account, type: 'following', data: csv) }
+
       it 'follows the listed accounts, respecting boosts' do
         subject.call(import)
         expect(account.following.count).to eq 1
@@ -178,18 +182,18 @@ RSpec.describe ImportService, type: :service do
   context 'utf-8 encoded domains' do
     subject { ImportService.new }
 
-    let!(:nare)     { Fabricate(:account, username: 'nare', domain: 'թութ.հայ', locked: false, protocol: :activitypub, inbox_url: 'https://թութ.հայ/inbox') }
+    let!(:nare) { Fabricate(:account, username: 'nare', domain: 'թութ.հայ', locked: false, protocol: :activitypub, inbox_url: 'https://թութ.հայ/inbox') }
 
     # Make sure to not actually go to the remote server
     before do
-      stub_request(:post, "https://թութ.հայ/inbox").to_return(status: 200)
+      stub_request(:post, 'https://թութ.հայ/inbox').to_return(status: 200)
     end
 
     let(:csv) { attachment_fixture('utf8-followers.txt') }
     let(:import) { Import.create(account: account, type: 'following', data: csv) }
 
     it 'follows the listed account' do
-    expect(account.follow_requests.count).to eq 0
+      expect(account.follow_requests.count).to eq 0
       subject.call(import)
       expect(account.follow_requests.count).to eq 1
     end
@@ -224,6 +228,7 @@ RSpec.describe ImportService, type: :service do
 
     describe 'when no bookmarks are set' do
       let(:import) { Import.create(account: account, type: 'bookmarks', data: csv) }
+
       it 'adds the toots the user has access to to bookmarks' do
         local_status = Fabricate(:status, account: local_account, uri: 'https://local.com/users/foo/statuses/42', id: 42, local: true)
         subject.call(import)
diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb
index 28f20e9c7..0b72253a5 100644
--- a/spec/services/post_status_service_spec.rb
+++ b/spec/services/post_status_service_spec.rb
@@ -5,7 +5,7 @@ RSpec.describe PostStatusService, type: :service do
 
   it 'creates a new status' do
     account = Fabricate(:account)
-    text = "test status update"
+    text = 'test status update'
 
     status = subject.call(account, text: text)
 
@@ -16,7 +16,7 @@ RSpec.describe PostStatusService, type: :service do
   it 'creates a new response status' do
     in_reply_to_status = Fabricate(:status)
     account = Fabricate(:account)
-    text = "test status update"
+    text = 'test status update'
 
     status = subject.call(account, text: text, thread: in_reply_to_status)
 
@@ -58,7 +58,7 @@ RSpec.describe PostStatusService, type: :service do
     boosted_status = Fabricate(:status)
     in_reply_to_status = Fabricate(:status, reblog: boosted_status)
     account = Fabricate(:account)
-    text = "test status update"
+    text = 'test status update'
 
     status = subject.call(account, text: text, thread: in_reply_to_status)
 
@@ -75,7 +75,7 @@ RSpec.describe PostStatusService, type: :service do
   end
 
   it 'creates a status with spoiler text' do
-    spoiler_text = "spoiler text"
+    spoiler_text = 'spoiler text'
 
     status = create_status_with_options(spoiler_text: spoiler_text)
 
@@ -101,14 +101,14 @@ RSpec.describe PostStatusService, type: :service do
     status = create_status_with_options(visibility: :private)
 
     expect(status).to be_persisted
-    expect(status.visibility).to eq "private"
+    expect(status.visibility).to eq 'private'
   end
 
   it 'creates a status with limited visibility for silenced users' do
     status = subject.call(Fabricate(:account, silenced: true), text: 'test', visibility: :public)
 
     expect(status).to be_persisted
-    expect(status.visibility).to eq "unlisted"
+    expect(status.visibility).to eq 'unlisted'
   end
 
   it 'creates a status for the given application' do
@@ -135,7 +135,7 @@ RSpec.describe PostStatusService, type: :service do
     allow(ProcessMentionsService).to receive(:new).and_return(mention_service)
     account = Fabricate(:account)
 
-    status = subject.call(account, text: "test status update")
+    status = subject.call(account, text: 'test status update')
 
     expect(ProcessMentionsService).to have_received(:new)
     expect(mention_service).to have_received(:call).with(status, save_records: false)
@@ -148,7 +148,7 @@ RSpec.describe PostStatusService, type: :service do
 
     expect do
       subject.call(account, text: '@alice hm, @bob is really annoying lately', allowed_mentions: [mentioned_account.id])
-    end.to raise_error(an_instance_of(PostStatusService::UnexpectedMentionsError).and having_attributes(accounts: [unexpected_mentioned_account]))
+    end.to raise_error(an_instance_of(PostStatusService::UnexpectedMentionsError).and(having_attributes(accounts: [unexpected_mentioned_account])))
   end
 
   it 'processes duplicate mentions correctly' do
@@ -166,7 +166,7 @@ RSpec.describe PostStatusService, type: :service do
     allow(ProcessHashtagsService).to receive(:new).and_return(hashtags_service)
     account = Fabricate(:account)
 
-    status = subject.call(account, text: "test status update")
+    status = subject.call(account, text: 'test status update')
 
     expect(ProcessHashtagsService).to have_received(:new)
     expect(hashtags_service).to have_received(:call).with(status)
@@ -178,7 +178,7 @@ RSpec.describe PostStatusService, type: :service do
 
     account = Fabricate(:account)
 
-    status = subject.call(account, text: "test status update")
+    status = subject.call(account, text: 'test status update')
 
     expect(DistributionWorker).to have_received(:perform_async).with(status.id)
     expect(ActivityPub::DistributionWorker).to have_received(:perform_async).with(status.id)
@@ -188,7 +188,7 @@ RSpec.describe PostStatusService, type: :service do
     allow(LinkCrawlWorker).to receive(:perform_async)
     account = Fabricate(:account)
 
-    status = subject.call(account, text: "test status update")
+    status = subject.call(account, text: 'test status update')
 
     expect(LinkCrawlWorker).to have_received(:perform_async).with(status.id)
   end
@@ -199,8 +199,8 @@ RSpec.describe PostStatusService, type: :service do
 
     status = subject.call(
       account,
-      text: "test status update",
-      media_ids: [media.id],
+      text: 'test status update',
+      media_ids: [media.id]
     )
 
     expect(media.reload.status).to eq status
@@ -212,8 +212,8 @@ RSpec.describe PostStatusService, type: :service do
 
     status = subject.call(
       account,
-      text: "test status update",
-      media_ids: [media.id],
+      text: 'test status update',
+      media_ids: [media.id]
     )
 
     expect(media.reload.status).to eq nil
@@ -225,18 +225,18 @@ RSpec.describe PostStatusService, type: :service do
     expect do
       subject.call(
         account,
-        text: "test status update",
+        text: 'test status update',
         media_ids: [
           Fabricate(:media_attachment, account: account),
           Fabricate(:media_attachment, account: account),
           Fabricate(:media_attachment, account: account),
           Fabricate(:media_attachment, account: account),
           Fabricate(:media_attachment, account: account),
-        ].map(&:id),
+        ].map(&:id)
       )
     end.to raise_error(
       Mastodon::ValidationError,
-      I18n.t('media_attachments.validations.too_many'),
+      I18n.t('media_attachments.validations.too_many')
     )
   end
 
@@ -250,15 +250,15 @@ RSpec.describe PostStatusService, type: :service do
     expect do
       subject.call(
         account,
-        text: "test status update",
+        text: 'test status update',
         media_ids: [
           video,
           image,
-        ].map(&:id),
+        ].map(&:id)
       )
     end.to raise_error(
       Mastodon::ValidationError,
-      I18n.t('media_attachments.validations.images_and_video'),
+      I18n.t('media_attachments.validations.images_and_video')
     )
   end
 
diff --git a/spec/services/precompute_feed_service_spec.rb b/spec/services/precompute_feed_service_spec.rb
index 86b93b5d2..b28824f9a 100644
--- a/spec/services/precompute_feed_service_spec.rb
+++ b/spec/services/precompute_feed_service_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe PrecomputeFeedService, type: :service do
 
   describe 'call' do
     let(:account) { Fabricate(:account) }
+
     it 'fills a user timeline with statuses' do
       account = Fabricate(:account)
       status = Fabricate(:status, account: account)
diff --git a/spec/services/process_mentions_service_spec.rb b/spec/services/process_mentions_service_spec.rb
index 0dd62c807..6a16928e0 100644
--- a/spec/services/process_mentions_service_spec.rb
+++ b/spec/services/process_mentions_service_spec.rb
@@ -62,7 +62,7 @@ RSpec.describe ProcessMentionsService, type: :service do
 
       context 'with an IDN domain' do
         let!(:remote_user) { Fabricate(:account, username: 'sneak', protocol: :activitypub, domain: 'xn--hresiar-mxa.ch', inbox_url: 'http://example.com/inbox') }
-        let!(:status) { Fabricate(:status, account: account, text: "Hello @sneak@hæresiar.ch") }
+        let!(:status) { Fabricate(:status, account: account, text: 'Hello @sneak@hæresiar.ch') }
 
         before do
           subject.call(status)
@@ -75,7 +75,7 @@ RSpec.describe ProcessMentionsService, type: :service do
 
       context 'with an IDN TLD' do
         let!(:remote_user) { Fabricate(:account, username: 'foo', protocol: :activitypub, domain: 'xn--y9a3aq.xn--y9a3aq', inbox_url: 'http://example.com/inbox') }
-        let!(:status) { Fabricate(:status, account: account, text: "Hello @foo@հայ.հայ") }
+        let!(:status) { Fabricate(:status, account: account, text: 'Hello @foo@հայ.հայ') }
 
         before do
           subject.call(status)
@@ -91,8 +91,8 @@ RSpec.describe ProcessMentionsService, type: :service do
       let!(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox', last_webfingered_at: nil) }
 
       before do
-        stub_request(:get, "https://example.com/.well-known/host-meta").to_return(status: 404)
-        stub_request(:get, "https://example.com/.well-known/webfinger?resource=acct:remote_user@example.com").to_return(status: 500)
+        stub_request(:get, 'https://example.com/.well-known/host-meta').to_return(status: 404)
+        stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:remote_user@example.com').to_return(status: 500)
         subject.call(status)
       end
 
diff --git a/spec/services/remove_from_follwers_service_spec.rb b/spec/services/remove_from_follwers_service_spec.rb
index a83f6f49a..9b9c846cf 100644
--- a/spec/services/remove_from_follwers_service_spec.rb
+++ b/spec/services/remove_from_follwers_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe RemoveFromFollowersService, type: :service do
 
   describe 'local' do
     let(:sender) { Fabricate(:account, username: 'alice') }
- 
+
     before do
       Follow.create(account: sender, target_account: bob)
       subject.call(bob, sender)
diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb
index 482068d58..e253052f3 100644
--- a/spec/services/remove_status_service_spec.rb
+++ b/spec/services/remove_status_service_spec.rb
@@ -37,29 +37,29 @@ RSpec.describe RemoveStatusService, type: :service do
     it 'sends Delete activity to followers' do
       subject.call(@status)
       expect(a_request(:post, 'http://example.com/inbox').with(
-        body: hash_including({
-          'type' => 'Delete',
-          'object' => {
-            'type' => 'Tombstone',
-            'id' => ActivityPub::TagManager.instance.uri_for(@status),
-            'atomUri' => OStatus::TagManager.instance.uri_for(@status),
-          },
-        })
-      )).to have_been_made.once
+               body: hash_including({
+                 'type' => 'Delete',
+                 'object' => {
+                   'type' => 'Tombstone',
+                   'id' => ActivityPub::TagManager.instance.uri_for(@status),
+                   'atomUri' => OStatus::TagManager.instance.uri_for(@status),
+                 },
+               })
+             )).to have_been_made.once
     end
 
     it 'sends Delete activity to rebloggers' do
       subject.call(@status)
       expect(a_request(:post, 'http://example2.com/inbox').with(
-        body: hash_including({
-          'type' => 'Delete',
-          'object' => {
-            'type' => 'Tombstone',
-            'id' => ActivityPub::TagManager.instance.uri_for(@status),
-            'atomUri' => OStatus::TagManager.instance.uri_for(@status),
-          },
-        })
-      )).to have_been_made.once
+               body: hash_including({
+                 'type' => 'Delete',
+                 'object' => {
+                   'type' => 'Tombstone',
+                   'id' => ActivityPub::TagManager.instance.uri_for(@status),
+                   'atomUri' => OStatus::TagManager.instance.uri_for(@status),
+                 },
+               })
+             )).to have_been_made.once
     end
 
     it 'remove status from notifications' do
@@ -78,14 +78,14 @@ RSpec.describe RemoveStatusService, type: :service do
     it 'sends Undo activity to followers' do
       subject.call(@status)
       expect(a_request(:post, 'http://example.com/inbox').with(
-        body: hash_including({
-          'type' => 'Undo',
-          'object' => hash_including({
-            'type' => 'Announce',
-            'object' => ActivityPub::TagManager.instance.uri_for(@original_status),
-          }),
-        })
-      )).to have_been_made.once
+               body: hash_including({
+                 'type' => 'Undo',
+                 'object' => hash_including({
+                   'type' => 'Announce',
+                   'object' => ActivityPub::TagManager.instance.uri_for(@original_status),
+                 }),
+               })
+             )).to have_been_made.once
     end
   end
 
@@ -98,14 +98,14 @@ RSpec.describe RemoveStatusService, type: :service do
     it 'sends Undo activity to followers' do
       subject.call(@status)
       expect(a_request(:post, 'http://example.com/inbox').with(
-        body: hash_including({
-          'type' => 'Undo',
-          'object' => hash_including({
-            'type' => 'Announce',
-            'object' => ActivityPub::TagManager.instance.uri_for(@original_status),
-          }),
-        })
-      )).to have_been_made.once
+               body: hash_including({
+                 'type' => 'Undo',
+                 'object' => hash_including({
+                   'type' => 'Announce',
+                   'object' => ActivityPub::TagManager.instance.uri_for(@original_status),
+                 }),
+               })
+             )).to have_been_made.once
     end
   end
 end
diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb
index 654606bea..192225229 100644
--- a/spec/services/resolve_account_service_spec.rb
+++ b/spec/services/resolve_account_service_spec.rb
@@ -4,11 +4,11 @@ RSpec.describe ResolveAccountService, type: :service do
   subject { described_class.new }
 
   before do
-    stub_request(:get, "https://example.com/.well-known/host-meta").to_return(status: 404)
-    stub_request(:get, "https://quitter.no/avatar/7477-300-20160211190340.png").to_return(request_fixture('avatar.txt'))
-    stub_request(:get, "https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com").to_return(request_fixture('activitypub-webfinger.txt'))
-    stub_request(:get, "https://ap.example.com/users/foo").to_return(request_fixture('activitypub-actor.txt'))
-    stub_request(:get, "https://ap.example.com/users/foo.atom").to_return(request_fixture('activitypub-feed.txt'))
+    stub_request(:get, 'https://example.com/.well-known/host-meta').to_return(status: 404)
+    stub_request(:get, 'https://quitter.no/avatar/7477-300-20160211190340.png').to_return(request_fixture('avatar.txt'))
+    stub_request(:get, 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com').to_return(request_fixture('activitypub-webfinger.txt'))
+    stub_request(:get, 'https://ap.example.com/users/foo').to_return(request_fixture('activitypub-actor.txt'))
+    stub_request(:get, 'https://ap.example.com/users/foo.atom').to_return(request_fixture('activitypub-feed.txt'))
     stub_request(:get, %r{https://ap.example.com/users/foo/\w+}).to_return(status: 404)
     stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:hoge@example.com').to_return(status: 410)
   end
@@ -56,8 +56,8 @@ RSpec.describe ResolveAccountService, type: :service do
 
   context 'when there is an LRDD endpoint but no resolvable account' do
     before do
-      stub_request(:get, "https://quitter.no/.well-known/host-meta").to_return(request_fixture('.host-meta.txt'))
-      stub_request(:get, "https://quitter.no/.well-known/webfinger?resource=acct:catsrgr8@quitter.no").to_return(status: 404)
+      stub_request(:get, 'https://quitter.no/.well-known/host-meta').to_return(request_fixture('.host-meta.txt'))
+      stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:catsrgr8@quitter.no').to_return(status: 404)
     end
 
     it 'returns nil' do
@@ -67,7 +67,7 @@ RSpec.describe ResolveAccountService, type: :service do
 
   context 'when there is no LRDD endpoint nor resolvable account' do
     before do
-      stub_request(:get, "https://example.com/.well-known/webfinger?resource=acct:catsrgr8@example.com").to_return(status: 404)
+      stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:catsrgr8@example.com').to_return(status: 404)
     end
 
     it 'returns nil' do
@@ -153,7 +153,7 @@ RSpec.describe ResolveAccountService, type: :service do
 
     context 'with multiple types' do
       before do
-        stub_request(:get, "https://ap.example.com/users/foo").to_return(request_fixture('activitypub-actor-individual.txt'))
+        stub_request(:get, 'https://ap.example.com/users/foo').to_return(request_fixture('activitypub-actor-individual.txt'))
       end
 
       it 'returns new remote account' do
@@ -190,7 +190,7 @@ RSpec.describe ResolveAccountService, type: :service do
 
   context 'with an already-known acct: URI changing ActivityPub id' do
     let!(:old_account) { Fabricate(:account, username: 'foo', domain: 'ap.example.com', uri: 'https://old.example.com/users/foo', last_webfingered_at: nil) }
-    let!(:status)    { Fabricate(:status, account: old_account, text: 'foo') }
+    let!(:status) { Fabricate(:status, account: old_account, text: 'foo') }
 
     it 'returns new remote account' do
       account = subject.call('foo@ap.example.com')
diff --git a/spec/services/resolve_url_service_spec.rb b/spec/services/resolve_url_service_spec.rb
index b3e3defbf..3598311ee 100644
--- a/spec/services/resolve_url_service_spec.rb
+++ b/spec/services/resolve_url_service_spec.rb
@@ -133,7 +133,7 @@ describe ResolveURLService, type: :service do
       let!(:status) { Fabricate(:status, account: poster, visibility: :public) }
       let(:url)     { 'https://link.to/foobar' }
       let(:status_url) { ActivityPub::TagManager.instance.url_for(status) }
-      let(:uri)     { ActivityPub::TagManager.instance.uri_for(status) }
+      let(:uri) { ActivityPub::TagManager.instance.uri_for(status) }
 
       before do
         stub_request(:get, url).to_return(status: 302, headers: { 'Location' => status_url })
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
index 5b52662ba..6f32007e8 100644
--- a/spec/services/search_service_spec.rb
+++ b/spec/services/search_service_spec.rb
@@ -83,6 +83,7 @@ describe SearchService, type: :service do
           expect(Tag).to have_received(:search_for).with('tag', 10, 0, exclude_unreviewed: nil)
           expect(results).to eq empty_results.merge(hashtags: [tag])
         end
+
         it 'does not include tag when starts with @ character' do
           query = '@username'
           allow(Tag).to receive(:search_for)
@@ -91,6 +92,7 @@ describe SearchService, type: :service do
           expect(Tag).not_to have_received(:search_for)
           expect(results).to eq empty_results
         end
+
         it 'does not include account when starts with # character' do
           query = '#tag'
           allow(AccountSearchService).to receive(:new)
diff --git a/spec/services/update_status_service_spec.rb b/spec/services/update_status_service_spec.rb
index 16e981d2b..a7364ca8b 100644
--- a/spec/services/update_status_service_spec.rb
+++ b/spec/services/update_status_service_spec.rb
@@ -111,7 +111,7 @@ RSpec.describe UpdateStatusService, type: :service do
 
   context 'when poll changes' do
     let(:account) { Fabricate(:account) }
-    let!(:status) { Fabricate(:status, text: 'Foo', account: account, poll_attributes: {options: %w(Foo Bar), account: account, multiple: false, hide_totals: false, expires_at: 7.days.from_now }) }
+    let!(:status) { Fabricate(:status, text: 'Foo', account: account, poll_attributes: { options: %w(Foo Bar), account: account, multiple: false, hide_totals: false, expires_at: 7.days.from_now }) }
     let!(:poll)   { status.poll }
     let!(:voter) { Fabricate(:account) }
 
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 0414ba9ed..97b8d83c5 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -12,7 +12,7 @@ end
 gc_counter = -1
 
 RSpec.configure do |config|
-  config.example_status_persistence_file_path = "tmp/rspec/examples.txt"
+  config.example_status_persistence_file_path = 'tmp/rspec/examples.txt'
   config.expect_with :rspec do |expectations|
     expectations.include_chain_clauses_in_custom_matcher_descriptions = true
   end
@@ -60,7 +60,7 @@ end
 
 def expect_push_bulk_to_match(klass, matcher)
   expect(Sidekiq::Client).to receive(:push_bulk).with(hash_including({
-    "class" => klass,
-    "args" => matcher
+    'class' => klass,
+    'args' => matcher,
   }))
 end
diff --git a/spec/support/matchers/model/model_have_error_on_field.rb b/spec/support/matchers/model/model_have_error_on_field.rb
index 85bdd8215..d85db2fca 100644
--- a/spec/support/matchers/model/model_have_error_on_field.rb
+++ b/spec/support/matchers/model/model_have_error_on_field.rb
@@ -1,8 +1,6 @@
 RSpec::Matchers.define :model_have_error_on_field do |expected|
   match do |record|
-    if record.errors.empty?
-      record.valid?
-    end
+    record.valid? if record.errors.empty?
 
     record.errors.has_key?(expected)
   end
diff --git a/spec/support/stories/profile_stories.rb b/spec/support/stories/profile_stories.rb
index 0c4a14d1c..de7ae17e6 100644
--- a/spec/support/stories/profile_stories.rb
+++ b/spec/support/stories/profile_stories.rb
@@ -20,8 +20,8 @@ module ProfileStories
   end
 
   def with_alice_as_local_user
-    @alice_bio = '@alice and @bob are fictional characters commonly used as'\
-                 'placeholder names in #cryptology, as well as #science and'\
+    @alice_bio = '@alice and @bob are fictional characters commonly used as' \
+                 'placeholder names in #cryptology, as well as #science and' \
                  'engineering 📖 literature. Not affiliated with @pepe.'
 
     @alice = Fabricate(
diff --git a/spec/validators/note_length_validator_spec.rb b/spec/validators/note_length_validator_spec.rb
index 6e9b4e132..390ac8d90 100644
--- a/spec/validators/note_length_validator_spec.rb
+++ b/spec/validators/note_length_validator_spec.rb
@@ -15,7 +15,7 @@ describe NoteLengthValidator do
     end
 
     it 'counts URLs as 23 characters flat' do
-      text   = ('a' * 476) + " http://#{'b' * 30}.com/example"
+      text = ('a' * 476) + " http://#{'b' * 30}.com/example"
       account = double(note: text, errors: double(add: nil))
 
       subject.validate_each(account, 'note', text)
@@ -23,7 +23,7 @@ describe NoteLengthValidator do
     end
 
     it 'does not count non-autolinkable URLs as 23 characters flat' do
-      text   = ('a' * 476) + "http://#{'b' * 30}.com/example"
+      text = ('a' * 476) + "http://#{'b' * 30}.com/example"
       account = double(note: text, errors: double(add: nil))
 
       subject.validate_each(account, 'note', text)
diff --git a/spec/validators/poll_validator_spec.rb b/spec/validators/poll_validator_spec.rb
index 941b83401..a76c63ccc 100644
--- a/spec/validators/poll_validator_spec.rb
+++ b/spec/validators/poll_validator_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe PollValidator, type: :validator do
 
     context 'expires just 5 min ago' do
       let(:expires_at) { 5.minutes.from_now }
+
       it 'not calls errors add' do
         expect(errors).not_to have_received(:add)
       end
diff --git a/spec/validators/unreserved_username_validator_spec.rb b/spec/validators/unreserved_username_validator_spec.rb
index 746b3866c..e2f051b08 100644
--- a/spec/validators/unreserved_username_validator_spec.rb
+++ b/spec/validators/unreserved_username_validator_spec.rb
@@ -11,10 +11,10 @@ RSpec.describe UnreservedUsernameValidator, type: :validator do
 
     let(:validator) { described_class.new }
     let(:account)   { double(username: username, errors: errors) }
-    let(:errors )   { double(add: nil) }
+    let(:errors) { double(add: nil) }
 
     context '@username.blank?' do
-      let(:username)  { nil }
+      let(:username) { nil }
 
       it 'not calls errors.add' do
         expect(errors).not_to have_received(:add).with(:username, any_args)
@@ -22,7 +22,7 @@ RSpec.describe UnreservedUsernameValidator, type: :validator do
     end
 
     context '!@username.blank?' do
-      let(:username)  { 'f' }
+      let(:username) { 'f' }
 
       context 'reserved_username?' do
         let(:reserved_username) { true }
diff --git a/spec/workers/activitypub/distribution_worker_spec.rb b/spec/workers/activitypub/distribution_worker_spec.rb
index 3a5900d9b..7f63e197b 100644
--- a/spec/workers/activitypub/distribution_worker_spec.rb
+++ b/spec/workers/activitypub/distribution_worker_spec.rb
@@ -34,7 +34,7 @@ describe ActivityPub::DistributionWorker do
     end
 
     context 'with direct status' do
-      let(:mentioned_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/inbox')}
+      let(:mentioned_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/inbox') }
 
       before do
         status.update(visibility: :direct)
diff --git a/spec/workers/activitypub/move_distribution_worker_spec.rb b/spec/workers/activitypub/move_distribution_worker_spec.rb
index af8c44cc0..482fa9db4 100644
--- a/spec/workers/activitypub/move_distribution_worker_spec.rb
+++ b/spec/workers/activitypub/move_distribution_worker_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
 describe ActivityPub::MoveDistributionWorker do
   subject { described_class.new }
 
-  let(:migration)   { Fabricate(:account_migration) }
+  let(:migration) { Fabricate(:account_migration) }
   let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') }
   let(:blocker) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example2.com') }
 
@@ -15,9 +15,9 @@ describe ActivityPub::MoveDistributionWorker do
 
     it 'delivers to followers and known blockers' do
       expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [
-        [kind_of(String), migration.account.id, 'http://example.com'],
-        [kind_of(String), migration.account.id, 'http://example2.com']
-      ])
+                                  [kind_of(String), migration.account.id, 'http://example.com'],
+                                  [kind_of(String), migration.account.id, 'http://example2.com'],
+                                ])
       subject.perform(migration.id)
     end
   end
diff --git a/spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb b/spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb
index 8f20725c8..8faf04836 100644
--- a/spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb
+++ b/spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb
@@ -82,7 +82,7 @@ describe Scheduler::AccountsStatusesCleanupScheduler do
 
   describe '#get_budget' do
     context 'on a single thread' do
-      let(:process_set_stub) { [ { 'concurrency' => 1, 'queues' => ['push', 'default'] } ] }
+      let(:process_set_stub) { [{ 'concurrency' => 1, 'queues' => ['push', 'default'] }] }
 
       it 'returns a low value' do
         expect(subject.compute_budget).to be < 10
diff --git a/yarn.lock b/yarn.lock
index 033e43ebe..d0c4a1926 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1096,6 +1096,11 @@
   resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz#c9c61d9fe5ca5ac664e1153bb0aa0eba1c6d6308"
   integrity sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==
 
+"@discoveryjs/json-ext@0.5.7":
+  version "0.5.7"
+  resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
+  integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
+
 "@emotion/babel-plugin@^11.7.1":
   version "11.9.2"
   resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.9.2.tgz#723b6d394c89fb2ef782229d92ba95a740576e95"
@@ -1263,109 +1268,109 @@
   resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
   integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==
 
-"@jest/console@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.4.1.tgz#cbc31d73f6329f693b3d34b365124de797704fff"
-  integrity sha512-m+XpwKSi3PPM9znm5NGS8bBReeAJJpSkL1OuFCqaMaJL2YX9YXLkkI+MBchMPwu+ZuM2rynL51sgfkQteQ1CKQ==
+"@jest/console@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.4.3.tgz#1f25a99f7f860e4c46423b5b1038262466fadde1"
+  integrity sha512-W/o/34+wQuXlgqlPYTansOSiBnuxrTv61dEVkA6HNmpcgHLUjfaUbdqt6oVvOzaawwo9IdW9QOtMgQ1ScSZC4A==
   dependencies:
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
     chalk "^4.0.0"
-    jest-message-util "^29.4.1"
-    jest-util "^29.4.1"
+    jest-message-util "^29.4.3"
+    jest-util "^29.4.3"
     slash "^3.0.0"
 
-"@jest/core@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.4.1.tgz#91371179b5959951e211dfaeea4277a01dcca14f"
-  integrity sha512-RXFTohpBqpaTebNdg5l3I5yadnKo9zLBajMT0I38D0tDhreVBYv3fA8kywthI00sWxPztWLD3yjiUkewwu/wKA==
+"@jest/core@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.4.3.tgz#829dd65bffdb490de5b0f69e97de8e3b5eadd94b"
+  integrity sha512-56QvBq60fS4SPZCuM7T+7scNrkGIe7Mr6PVIXUpu48ouvRaWOFqRPV91eifvFM0ay2HmfswXiGf97NGUN5KofQ==
   dependencies:
-    "@jest/console" "^29.4.1"
-    "@jest/reporters" "^29.4.1"
-    "@jest/test-result" "^29.4.1"
-    "@jest/transform" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/console" "^29.4.3"
+    "@jest/reporters" "^29.4.3"
+    "@jest/test-result" "^29.4.3"
+    "@jest/transform" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
     ansi-escapes "^4.2.1"
     chalk "^4.0.0"
     ci-info "^3.2.0"
     exit "^0.1.2"
     graceful-fs "^4.2.9"
-    jest-changed-files "^29.4.0"
-    jest-config "^29.4.1"
-    jest-haste-map "^29.4.1"
-    jest-message-util "^29.4.1"
-    jest-regex-util "^29.2.0"
-    jest-resolve "^29.4.1"
-    jest-resolve-dependencies "^29.4.1"
-    jest-runner "^29.4.1"
-    jest-runtime "^29.4.1"
-    jest-snapshot "^29.4.1"
-    jest-util "^29.4.1"
-    jest-validate "^29.4.1"
-    jest-watcher "^29.4.1"
+    jest-changed-files "^29.4.3"
+    jest-config "^29.4.3"
+    jest-haste-map "^29.4.3"
+    jest-message-util "^29.4.3"
+    jest-regex-util "^29.4.3"
+    jest-resolve "^29.4.3"
+    jest-resolve-dependencies "^29.4.3"
+    jest-runner "^29.4.3"
+    jest-runtime "^29.4.3"
+    jest-snapshot "^29.4.3"
+    jest-util "^29.4.3"
+    jest-validate "^29.4.3"
+    jest-watcher "^29.4.3"
     micromatch "^4.0.4"
-    pretty-format "^29.4.1"
+    pretty-format "^29.4.3"
     slash "^3.0.0"
     strip-ansi "^6.0.0"
 
-"@jest/environment@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.4.1.tgz#52d232a85cdc995b407a940c89c86568f5a88ffe"
-  integrity sha512-pJ14dHGSQke7Q3mkL/UZR9ZtTOxqskZaC91NzamEH4dlKRt42W+maRBXiw/LWkdJe+P0f/zDR37+SPMplMRlPg==
+"@jest/environment@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.4.3.tgz#9fe2f3169c3b33815dc4bd3960a064a83eba6548"
+  integrity sha512-dq5S6408IxIa+lr54zeqce+QgI+CJT4nmmA+1yzFgtcsGK8c/EyiUb9XQOgz3BMKrRDfKseeOaxj2eO8LlD3lA==
   dependencies:
-    "@jest/fake-timers" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/fake-timers" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
-    jest-mock "^29.4.1"
+    jest-mock "^29.4.3"
 
-"@jest/expect-utils@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.1.tgz#105b9f3e2c48101f09cae2f0a4d79a1b3a419cbb"
-  integrity sha512-w6YJMn5DlzmxjO00i9wu2YSozUYRBhIoJ6nQwpMYcBMtiqMGJm1QBzOf6DDgRao8dbtpDoaqLg6iiQTvv0UHhQ==
+"@jest/expect-utils@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.3.tgz#95ce4df62952f071bcd618225ac7c47eaa81431e"
+  integrity sha512-/6JWbkxHOP8EoS8jeeTd9dTfc9Uawi+43oLKHfp6zzux3U2hqOOVnV3ai4RpDYHOccL6g+5nrxpoc8DmJxtXVQ==
   dependencies:
-    jest-get-type "^29.2.0"
+    jest-get-type "^29.4.3"
 
-"@jest/expect@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.1.tgz#3338fa20f547bb6e550c4be37d6f82711cc13c38"
-  integrity sha512-ZxKJP5DTUNF2XkpJeZIzvnzF1KkfrhEF6Rz0HGG69fHl6Bgx5/GoU3XyaeFYEjuuKSOOsbqD/k72wFvFxc3iTw==
+"@jest/expect@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.3.tgz#d31a28492e45a6bcd0f204a81f783fe717045c6e"
+  integrity sha512-iktRU/YsxEtumI9zsPctYUk7ptpC+AVLLk1Ax3AsA4g1C+8OOnKDkIQBDHtD5hA/+VtgMd5AWI5gNlcAlt2vxQ==
   dependencies:
-    expect "^29.4.1"
-    jest-snapshot "^29.4.1"
+    expect "^29.4.3"
+    jest-snapshot "^29.4.3"
 
-"@jest/fake-timers@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.4.1.tgz#7b673131e8ea2a2045858f08241cace5d518b42b"
-  integrity sha512-/1joI6rfHFmmm39JxNfmNAO3Nwm6Y0VoL5fJDy7H1AtWrD1CgRtqJbN9Ld6rhAkGO76qqp4cwhhxJ9o9kYjQMw==
+"@jest/fake-timers@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.4.3.tgz#31e982638c60fa657d310d4b9d24e023064027b0"
+  integrity sha512-4Hote2MGcCTWSD2gwl0dwbCpBRHhE6olYEuTj8FMowdg3oQWNKr2YuxenPQYZ7+PfqPY1k98wKDU4Z+Hvd4Tiw==
   dependencies:
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     "@sinonjs/fake-timers" "^10.0.2"
     "@types/node" "*"
-    jest-message-util "^29.4.1"
-    jest-mock "^29.4.1"
-    jest-util "^29.4.1"
+    jest-message-util "^29.4.3"
+    jest-mock "^29.4.3"
+    jest-util "^29.4.3"
 
-"@jest/globals@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.4.1.tgz#3cd78c5567ab0249f09fbd81bf9f37a7328f4713"
-  integrity sha512-znoK2EuFytbHH0ZSf2mQK2K1xtIgmaw4Da21R2C/NE/+NnItm5mPEFQmn8gmF3f0rfOlmZ3Y3bIf7bFj7DHxAA==
+"@jest/globals@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.4.3.tgz#63a2c4200d11bc6d46f12bbe25b07f771fce9279"
+  integrity sha512-8BQ/5EzfOLG7AaMcDh7yFCbfRLtsc+09E1RQmRBI4D6QQk4m6NSK/MXo+3bJrBN0yU8A2/VIcqhvsOLFmziioA==
   dependencies:
-    "@jest/environment" "^29.4.1"
-    "@jest/expect" "^29.4.1"
-    "@jest/types" "^29.4.1"
-    jest-mock "^29.4.1"
+    "@jest/environment" "^29.4.3"
+    "@jest/expect" "^29.4.3"
+    "@jest/types" "^29.4.3"
+    jest-mock "^29.4.3"
 
-"@jest/reporters@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.4.1.tgz#50d509c08575c75e3cd2176d72ec3786419d5e04"
-  integrity sha512-AISY5xpt2Xpxj9R6y0RF1+O6GRy9JsGa8+vK23Lmzdy1AYcpQn5ItX79wJSsTmfzPKSAcsY1LNt/8Y5Xe5LOSg==
+"@jest/reporters@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.4.3.tgz#0a68a0c0f20554760cc2e5443177a0018969e353"
+  integrity sha512-sr2I7BmOjJhyqj9ANC6CTLsL4emMoka7HkQpcoMRlhCbQJjz2zsRzw0BDPiPyEFDXAbxKgGFYuQZiSJ1Y6YoTg==
   dependencies:
     "@bcoe/v8-coverage" "^0.2.3"
-    "@jest/console" "^29.4.1"
-    "@jest/test-result" "^29.4.1"
-    "@jest/transform" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/console" "^29.4.3"
+    "@jest/test-result" "^29.4.3"
+    "@jest/transform" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@jridgewell/trace-mapping" "^0.3.15"
     "@types/node" "*"
     chalk "^4.0.0"
@@ -1378,70 +1383,70 @@
     istanbul-lib-report "^3.0.0"
     istanbul-lib-source-maps "^4.0.0"
     istanbul-reports "^3.1.3"
-    jest-message-util "^29.4.1"
-    jest-util "^29.4.1"
-    jest-worker "^29.4.1"
+    jest-message-util "^29.4.3"
+    jest-util "^29.4.3"
+    jest-worker "^29.4.3"
     slash "^3.0.0"
     string-length "^4.0.1"
     strip-ansi "^6.0.0"
     v8-to-istanbul "^9.0.1"
 
-"@jest/schemas@^29.4.0":
-  version "29.4.0"
-  resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.0.tgz#0d6ad358f295cc1deca0b643e6b4c86ebd539f17"
-  integrity sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ==
+"@jest/schemas@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788"
+  integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==
   dependencies:
     "@sinclair/typebox" "^0.25.16"
 
-"@jest/source-map@^29.2.0":
-  version "29.2.0"
-  resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744"
-  integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==
+"@jest/source-map@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20"
+  integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==
   dependencies:
     "@jridgewell/trace-mapping" "^0.3.15"
     callsites "^3.0.0"
     graceful-fs "^4.2.9"
 
-"@jest/test-result@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.4.1.tgz#997f19695e13b34779ceb3c288a416bd26c3238d"
-  integrity sha512-WRt29Lwt+hEgfN8QDrXqXGgCTidq1rLyFqmZ4lmJOpVArC8daXrZWkWjiaijQvgd3aOUj2fM8INclKHsQW9YyQ==
+"@jest/test-result@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.4.3.tgz#e13d973d16c8c7cc0c597082d5f3b9e7f796ccb8"
+  integrity sha512-Oi4u9NfBolMq9MASPwuWTlC5WvmNRwI4S8YrQg5R5Gi47DYlBe3sh7ILTqi/LGrK1XUE4XY9KZcQJTH1WJCLLA==
   dependencies:
-    "@jest/console" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/console" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/istanbul-lib-coverage" "^2.0.0"
     collect-v8-coverage "^1.0.0"
 
-"@jest/test-sequencer@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.4.1.tgz#f7a006ec7058b194a10cf833c88282ef86d578fd"
-  integrity sha512-v5qLBNSsM0eHzWLXsQ5fiB65xi49A3ILPSFQKPXzGL4Vyux0DPZAIN7NAFJa9b4BiTDP9MBF/Zqc/QA1vuiJ0w==
+"@jest/test-sequencer@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.4.3.tgz#0862e876a22993385a0f3e7ea1cc126f208a2898"
+  integrity sha512-yi/t2nES4GB4G0mjLc0RInCq/cNr9dNwJxcGg8sslajua5Kb4kmozAc+qPLzplhBgfw1vLItbjyHzUN92UXicw==
   dependencies:
-    "@jest/test-result" "^29.4.1"
+    "@jest/test-result" "^29.4.3"
     graceful-fs "^4.2.9"
-    jest-haste-map "^29.4.1"
+    jest-haste-map "^29.4.3"
     slash "^3.0.0"
 
-"@jest/transform@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.4.1.tgz#e4f517841bb795c7dcdee1ba896275e2c2d26d4a"
-  integrity sha512-5w6YJrVAtiAgr0phzKjYd83UPbCXsBRTeYI4BXokv9Er9CcrH9hfXL/crCvP2d2nGOcovPUnlYiLPFLZrkG5Hg==
+"@jest/transform@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.4.3.tgz#f7d17eac9cb5bb2e1222ea199c7c7e0835e0c037"
+  integrity sha512-8u0+fBGWolDshsFgPQJESkDa72da/EVwvL+II0trN2DR66wMwiQ9/CihaGfHdlLGFzbBZwMykFtxuwFdZqlKwg==
   dependencies:
     "@babel/core" "^7.11.6"
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     "@jridgewell/trace-mapping" "^0.3.15"
     babel-plugin-istanbul "^6.1.1"
     chalk "^4.0.0"
     convert-source-map "^2.0.0"
     fast-json-stable-stringify "^2.1.0"
     graceful-fs "^4.2.9"
-    jest-haste-map "^29.4.1"
-    jest-regex-util "^29.2.0"
-    jest-util "^29.4.1"
+    jest-haste-map "^29.4.3"
+    jest-regex-util "^29.4.3"
+    jest-util "^29.4.3"
     micromatch "^4.0.4"
     pirates "^4.0.4"
     slash "^3.0.0"
-    write-file-atomic "^5.0.0"
+    write-file-atomic "^4.0.2"
 
 "@jest/types@^25.5.0":
   version "25.5.0"
@@ -1464,12 +1469,12 @@
     "@types/yargs" "^16.0.0"
     chalk "^4.0.0"
 
-"@jest/types@^29.4.1":
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.1.tgz#f9f83d0916f50696661da72766132729dcb82ecb"
-  integrity sha512-zbrAXDUOnpJ+FMST2rV7QZOgec8rskg2zv8g2ajeqitp4tvZiyqTCYXANrKsM+ryj5o+LI+ZN2EgU9drrkiwSA==
+"@jest/types@^29.4.2", "@jest/types@^29.4.3":
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.3.tgz#9069145f4ef09adf10cec1b2901b2d390031431f"
+  integrity sha512-bPYfw8V65v17m2Od1cv44FH+SiKW7w2Xu7trhcdTLUmSv85rfKsP+qXSjO4KGJr4dtPSzl/gvslZBXctf1qGEA==
   dependencies:
-    "@jest/schemas" "^29.4.0"
+    "@jest/schemas" "^29.4.3"
     "@types/istanbul-lib-coverage" "^2.0.0"
     "@types/istanbul-reports" "^3.0.0"
     "@types/node" "*"
@@ -2195,12 +2200,7 @@ acorn@^6.4.1:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474"
   integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==
 
-acorn@^8.0.4, acorn@^8.1.0, acorn@^8.5.0, acorn@^8.8.1:
-  version "8.8.1"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
-  integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
-
-acorn@^8.8.0:
+acorn@^8.0.4, acorn@^8.1.0, acorn@^8.5.0, acorn@^8.8.0, acorn@^8.8.1:
   version "8.8.2"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
   integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
@@ -2560,10 +2560,10 @@ axe-core@^4.6.2:
   resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.3.tgz#fc0db6fdb65cc7a80ccf85286d91d64ababa3ece"
   integrity sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==
 
-axios@^1.3.2:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.2.tgz#7ac517f0fa3ec46e0e636223fd973713a09c72b3"
-  integrity sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==
+axios@^1.3.3:
+  version "1.3.3"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.3.tgz#e7011384ba839b885007c9c9fae1ff23dceb295b"
+  integrity sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==
   dependencies:
     follow-redirects "^1.15.0"
     form-data "^4.0.0"
@@ -2576,15 +2576,15 @@ axobject-query@^3.1.1:
   dependencies:
     deep-equal "^2.0.5"
 
-babel-jest@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.1.tgz#01fa167e27470b35c2d4a1b841d9586b1764da19"
-  integrity sha512-xBZa/pLSsF/1sNpkgsiT3CmY7zV1kAsZ9OxxtrFqYucnOuRftXAfcJqcDVyOPeN4lttWTwhLdu0T9f8uvoPEUg==
+babel-jest@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.3.tgz#478b84d430972b277ad67dd631be94abea676792"
+  integrity sha512-o45Wyn32svZE+LnMVWv/Z4x0SwtLbh4FyGcYtR20kIWd+rdrDZ9Fzq8Ml3MYLD+mZvEdzCjZsCnYZ2jpJyQ+Nw==
   dependencies:
-    "@jest/transform" "^29.4.1"
+    "@jest/transform" "^29.4.3"
     "@types/babel__core" "^7.1.14"
     babel-plugin-istanbul "^6.1.1"
-    babel-preset-jest "^29.4.0"
+    babel-preset-jest "^29.4.3"
     chalk "^4.0.0"
     graceful-fs "^4.2.9"
     slash "^3.0.0"
@@ -2610,10 +2610,10 @@ babel-plugin-istanbul@^6.1.1:
     istanbul-lib-instrument "^5.0.4"
     test-exclude "^6.0.0"
 
-babel-plugin-jest-hoist@^29.4.0:
-  version "29.4.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz#3fd3dfcedf645932df6d0c9fc3d9a704dd860248"
-  integrity sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg==
+babel-plugin-jest-hoist@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.3.tgz#ad1dfb5d31940957e00410ef7d9b2aa94b216101"
+  integrity sha512-mB6q2q3oahKphy5V7CpnNqZOCkxxZ9aokf1eh82Dy3jQmg4xvM1tGrh5y6BQUJh4a3Pj9+eLfwvAZ7VNKg7H8Q==
   dependencies:
     "@babel/template" "^7.3.3"
     "@babel/types" "^7.3.3"
@@ -2719,12 +2719,12 @@ babel-preset-current-node-syntax@^1.0.0:
     "@babel/plugin-syntax-optional-chaining" "^7.8.3"
     "@babel/plugin-syntax-top-level-await" "^7.8.3"
 
-babel-preset-jest@^29.4.0:
-  version "29.4.0"
-  resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz#c2b03c548b02dea0a18ae21d5759c136f9251ee4"
-  integrity sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA==
+babel-preset-jest@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.4.3.tgz#bb926b66ae253b69c6e3ef87511b8bb5c53c5b52"
+  integrity sha512-gWx6COtSuma6n9bw+8/F+2PCXrIgxV/D1TJFnp6OyBK2cxPWg0K9p/sriNYeifKjpUkMViWQ09DSWtzJQRETsw==
   dependencies:
-    babel-plugin-jest-hoist "^29.4.0"
+    babel-plugin-jest-hoist "^29.4.3"
     babel-preset-current-node-syntax "^1.0.0"
 
 balanced-match@^1.0.0:
@@ -4115,10 +4115,10 @@ diff-sequences@^25.2.6:
   resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd"
   integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==
 
-diff-sequences@^29.3.1:
-  version "29.3.1"
-  resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e"
-  integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==
+diff-sequences@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2"
+  integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==
 
 diffie-hellman@^5.0.0:
   version "5.0.3"
@@ -4815,16 +4815,16 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2:
   dependencies:
     homedir-polyfill "^1.0.1"
 
-expect@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.1.tgz#58cfeea9cbf479b64ed081fd1e074ac8beb5a1fe"
-  integrity sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A==
+expect@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.3.tgz#5e47757316df744fe3b8926c3ae8a3ebdafff7fe"
+  integrity sha512-uC05+Q7eXECFpgDrHdXA4k2rpMyStAYPItEDLyQDo5Ta7fVkJnNA/4zh/OIVkVVNZ1oOK1PipQoyNjuZ6sz6Dg==
   dependencies:
-    "@jest/expect-utils" "^29.4.1"
-    jest-get-type "^29.2.0"
-    jest-matcher-utils "^29.4.1"
-    jest-message-util "^29.4.1"
-    jest-util "^29.4.1"
+    "@jest/expect-utils" "^29.4.3"
+    jest-get-type "^29.4.3"
+    jest-matcher-utils "^29.4.3"
+    jest-message-util "^29.4.3"
+    jest-util "^29.4.3"
 
 express@^4.17.1, express@^4.18.2:
   version "4.18.2"
@@ -6481,82 +6481,82 @@ jake@^10.8.5:
     filelist "^1.0.1"
     minimatch "^3.0.4"
 
-jest-changed-files@^29.4.0:
-  version "29.4.0"
-  resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.4.0.tgz#ac2498bcd394228f7eddcadcf928b3583bf2779d"
-  integrity sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w==
+jest-changed-files@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.4.3.tgz#7961fe32536b9b6d5c28dfa0abcfab31abcf50a7"
+  integrity sha512-Vn5cLuWuwmi2GNNbokPOEcvrXGSGrqVnPEZV7rC6P7ck07Dyw9RFnvWglnupSh+hGys0ajGtw/bc2ZgweljQoQ==
   dependencies:
     execa "^5.0.0"
     p-limit "^3.1.0"
 
-jest-circus@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.4.1.tgz#ff1b63eb04c3b111cefea9489e8dbadd23ce49bd"
-  integrity sha512-v02NuL5crMNY4CGPHBEflLzl4v91NFb85a+dH9a1pUNx6Xjggrd8l9pPy4LZ1VYNRXlb+f65+7O/MSIbLir6pA==
+jest-circus@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.4.3.tgz#fff7be1cf5f06224dd36a857d52a9efeb005ba04"
+  integrity sha512-Vw/bVvcexmdJ7MLmgdT3ZjkJ3LKu8IlpefYokxiqoZy6OCQ2VAm6Vk3t/qHiAGUXbdbJKJWnc8gH3ypTbB/OBw==
   dependencies:
-    "@jest/environment" "^29.4.1"
-    "@jest/expect" "^29.4.1"
-    "@jest/test-result" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/environment" "^29.4.3"
+    "@jest/expect" "^29.4.3"
+    "@jest/test-result" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
     chalk "^4.0.0"
     co "^4.6.0"
     dedent "^0.7.0"
     is-generator-fn "^2.0.0"
-    jest-each "^29.4.1"
-    jest-matcher-utils "^29.4.1"
-    jest-message-util "^29.4.1"
-    jest-runtime "^29.4.1"
-    jest-snapshot "^29.4.1"
-    jest-util "^29.4.1"
+    jest-each "^29.4.3"
+    jest-matcher-utils "^29.4.3"
+    jest-message-util "^29.4.3"
+    jest-runtime "^29.4.3"
+    jest-snapshot "^29.4.3"
+    jest-util "^29.4.3"
     p-limit "^3.1.0"
-    pretty-format "^29.4.1"
+    pretty-format "^29.4.3"
     slash "^3.0.0"
     stack-utils "^2.0.3"
 
-jest-cli@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.4.1.tgz#7abef96944f300feb9b76f68b1eb2d68774fe553"
-  integrity sha512-jz7GDIhtxQ37M+9dlbv5K+/FVcIo1O/b1sX3cJgzlQUf/3VG25nvuWzlDC4F1FLLzUThJeWLu8I7JF9eWpuURQ==
+jest-cli@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.4.3.tgz#fe31fdd0c90c765f392b8b7c97e4845071cd2163"
+  integrity sha512-PiiAPuFNfWWolCE6t3ZrDXQc6OsAuM3/tVW0u27UWc1KE+n/HSn5dSE6B2juqN7WP+PP0jAcnKtGmI4u8GMYCg==
   dependencies:
-    "@jest/core" "^29.4.1"
-    "@jest/test-result" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/core" "^29.4.3"
+    "@jest/test-result" "^29.4.3"
+    "@jest/types" "^29.4.3"
     chalk "^4.0.0"
     exit "^0.1.2"
     graceful-fs "^4.2.9"
     import-local "^3.0.2"
-    jest-config "^29.4.1"
-    jest-util "^29.4.1"
-    jest-validate "^29.4.1"
+    jest-config "^29.4.3"
+    jest-util "^29.4.3"
+    jest-validate "^29.4.3"
     prompts "^2.0.1"
     yargs "^17.3.1"
 
-jest-config@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.4.1.tgz#e62670c6c980ec21d75941806ec4d0c0c6402728"
-  integrity sha512-g7p3q4NuXiM4hrS4XFATTkd+2z0Ml2RhFmFPM8c3WyKwVDNszbl4E7cV7WIx1YZeqqCtqbtTtZhGZWJlJqngzg==
+jest-config@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.4.3.tgz#fca9cdfe6298ae6d04beef1624064d455347c978"
+  integrity sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ==
   dependencies:
     "@babel/core" "^7.11.6"
-    "@jest/test-sequencer" "^29.4.1"
-    "@jest/types" "^29.4.1"
-    babel-jest "^29.4.1"
+    "@jest/test-sequencer" "^29.4.3"
+    "@jest/types" "^29.4.3"
+    babel-jest "^29.4.3"
     chalk "^4.0.0"
     ci-info "^3.2.0"
     deepmerge "^4.2.2"
     glob "^7.1.3"
     graceful-fs "^4.2.9"
-    jest-circus "^29.4.1"
-    jest-environment-node "^29.4.1"
-    jest-get-type "^29.2.0"
-    jest-regex-util "^29.2.0"
-    jest-resolve "^29.4.1"
-    jest-runner "^29.4.1"
-    jest-util "^29.4.1"
-    jest-validate "^29.4.1"
+    jest-circus "^29.4.3"
+    jest-environment-node "^29.4.3"
+    jest-get-type "^29.4.3"
+    jest-regex-util "^29.4.3"
+    jest-resolve "^29.4.3"
+    jest-runner "^29.4.3"
+    jest-util "^29.4.3"
+    jest-validate "^29.4.3"
     micromatch "^4.0.4"
     parse-json "^5.2.0"
-    pretty-format "^29.4.1"
+    pretty-format "^29.4.3"
     slash "^3.0.0"
     strip-json-comments "^3.1.1"
 
@@ -6570,224 +6570,223 @@ jest-diff@^25.2.1:
     jest-get-type "^25.2.6"
     pretty-format "^25.5.0"
 
-jest-diff@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.1.tgz#9a6dc715037e1fa7a8a44554e7d272088c4029bd"
-  integrity sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw==
+jest-diff@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.3.tgz#42f4eb34d0bf8c0fb08b0501069b87e8e84df347"
+  integrity sha512-YB+ocenx7FZ3T5O9lMVMeLYV4265socJKtkwgk/6YUz/VsEzYDkiMuMhWzZmxm3wDRQvayJu/PjkjjSkjoHsCA==
   dependencies:
     chalk "^4.0.0"
-    diff-sequences "^29.3.1"
-    jest-get-type "^29.2.0"
-    pretty-format "^29.4.1"
+    diff-sequences "^29.4.3"
+    jest-get-type "^29.4.3"
+    pretty-format "^29.4.3"
 
-jest-docblock@^29.2.0:
-  version "29.2.0"
-  resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82"
-  integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==
+jest-docblock@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8"
+  integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==
   dependencies:
     detect-newline "^3.0.0"
 
-jest-each@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.4.1.tgz#05ce9979e7486dbd0f5d41895f49ccfdd0afce01"
-  integrity sha512-QlYFiX3llJMWUV0BtWht/esGEz9w+0i7BHwODKCze7YzZzizgExB9MOfiivF/vVT0GSQ8wXLhvHXh3x2fVD4QQ==
+jest-each@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.4.3.tgz#a434c199a2f6151c5e3dc80b2d54586bdaa72819"
+  integrity sha512-1ElHNAnKcbJb/b+L+7j0/w7bDvljw4gTv1wL9fYOczeJrbTbkMGQ5iQPFJ3eFQH19VPTx1IyfePdqSpePKss7Q==
   dependencies:
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     chalk "^4.0.0"
-    jest-get-type "^29.2.0"
-    jest-util "^29.4.1"
-    pretty-format "^29.4.1"
-
-jest-environment-jsdom@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.4.1.tgz#34d491244ddd6fe3d666da603b576bd0ae6aef78"
-  integrity sha512-+KfYmRTl5CBHQst9hIz77TiiriHYvuWoLjMT855gx2AMxhHxpk1vtKvag1DQfyWCPVTWV/AG7SIqVh5WI1O/uw==
-  dependencies:
-    "@jest/environment" "^29.4.1"
-    "@jest/fake-timers" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    jest-get-type "^29.4.3"
+    jest-util "^29.4.3"
+    pretty-format "^29.4.3"
+
+jest-environment-jsdom@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.4.3.tgz#bd8ed3808e6d3f616403fbaf8354f77019613d90"
+  integrity sha512-rFjf8JXrw3OjUzzmSE5l0XjMj0/MSVEUMCSXBGPDkfwb1T03HZI7iJSL0cGctZApPSyJxbjyKDVxkZuyhHkuTw==
+  dependencies:
+    "@jest/environment" "^29.4.3"
+    "@jest/fake-timers" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/jsdom" "^20.0.0"
     "@types/node" "*"
-    jest-mock "^29.4.1"
-    jest-util "^29.4.1"
+    jest-mock "^29.4.3"
+    jest-util "^29.4.3"
     jsdom "^20.0.0"
 
-jest-environment-node@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.4.1.tgz#22550b7d0f8f0b16228639c9f88ca04bbf3c1974"
-  integrity sha512-x/H2kdVgxSkxWAIlIh9MfMuBa0hZySmfsC5lCsWmWr6tZySP44ediRKDUiNggX/eHLH7Cd5ZN10Rw+XF5tXsqg==
+jest-environment-node@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.4.3.tgz#579c4132af478befc1889ddc43c2413a9cdbe014"
+  integrity sha512-gAiEnSKF104fsGDXNkwk49jD/0N0Bqu2K9+aMQXA6avzsA9H3Fiv1PW2D+gzbOSR705bWd2wJZRFEFpV0tXISg==
   dependencies:
-    "@jest/environment" "^29.4.1"
-    "@jest/fake-timers" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/environment" "^29.4.3"
+    "@jest/fake-timers" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
-    jest-mock "^29.4.1"
-    jest-util "^29.4.1"
+    jest-mock "^29.4.3"
+    jest-util "^29.4.3"
 
 jest-get-type@^25.2.6:
   version "25.2.6"
   resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877"
   integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==
 
-jest-get-type@^29.2.0:
-  version "29.2.0"
-  resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408"
-  integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==
+jest-get-type@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5"
+  integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==
 
-jest-haste-map@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.4.1.tgz#b0579dc82d94b40ed9041af56ad25c2f80bedaeb"
-  integrity sha512-imTjcgfVVTvg02khXL11NNLTx9ZaofbAWhilrMg/G8dIkp+HYCswhxf0xxJwBkfhWb3e8dwbjuWburvxmcr58w==
+jest-haste-map@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.4.3.tgz#085a44283269e7ace0645c63a57af0d2af6942e2"
+  integrity sha512-eZIgAS8tvm5IZMtKlR8Y+feEOMfo2pSQkmNbufdbMzMSn9nitgGxF1waM/+LbryO3OkMcKS98SUb+j/cQxp/vQ==
   dependencies:
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     "@types/graceful-fs" "^4.1.3"
     "@types/node" "*"
     anymatch "^3.0.3"
     fb-watchman "^2.0.0"
     graceful-fs "^4.2.9"
-    jest-regex-util "^29.2.0"
-    jest-util "^29.4.1"
-    jest-worker "^29.4.1"
+    jest-regex-util "^29.4.3"
+    jest-util "^29.4.3"
+    jest-worker "^29.4.3"
     micromatch "^4.0.4"
     walker "^1.0.8"
   optionalDependencies:
     fsevents "^2.3.2"
 
-jest-leak-detector@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.1.tgz#632186c546e084da2b490b7496fee1a1c9929637"
-  integrity sha512-akpZv7TPyGMnH2RimOCgy+hPmWZf55EyFUvymQ4LMsQP8xSPlZumCPtXGoDhFNhUE2039RApZkTQDKU79p/FiQ==
+jest-leak-detector@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.3.tgz#2b35191d6b35aa0256e63a9b79b0f949249cf23a"
+  integrity sha512-9yw4VC1v2NspMMeV3daQ1yXPNxMgCzwq9BocCwYrRgXe4uaEJPAN0ZK37nFBhcy3cUwEVstFecFLaTHpF7NiGA==
   dependencies:
-    jest-get-type "^29.2.0"
-    pretty-format "^29.4.1"
+    jest-get-type "^29.4.3"
+    pretty-format "^29.4.3"
 
-jest-matcher-utils@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.1.tgz#73d834e305909c3b43285fbc76f78bf0ad7e1954"
-  integrity sha512-k5h0u8V4nAEy6lSACepxL/rw78FLDkBnXhZVgFneVpnJONhb2DhZj/Gv4eNe+1XqQ5IhgUcqj745UwH0HJmMnA==
+jest-matcher-utils@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.3.tgz#ea68ebc0568aebea4c4213b99f169ff786df96a0"
+  integrity sha512-TTciiXEONycZ03h6R6pYiZlSkvYgT0l8aa49z/DLSGYjex4orMUcafuLXYyyEDWB1RKglq00jzwY00Ei7yFNVg==
   dependencies:
     chalk "^4.0.0"
-    jest-diff "^29.4.1"
-    jest-get-type "^29.2.0"
-    pretty-format "^29.4.1"
+    jest-diff "^29.4.3"
+    jest-get-type "^29.4.3"
+    pretty-format "^29.4.3"
 
-jest-message-util@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.1.tgz#522623aa1df9a36ebfdffb06495c7d9d19e8a845"
-  integrity sha512-H4/I0cXUaLeCw6FM+i4AwCnOwHRgitdaUFOdm49022YD5nfyr8C/DrbXOBEyJaj+w/y0gGJ57klssOaUiLLQGQ==
+jest-message-util@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.3.tgz#65b5280c0fdc9419503b49d4f48d4999d481cb5b"
+  integrity sha512-1Y8Zd4ZCN7o/QnWdMmT76If8LuDv23Z1DRovBj/vcSFNlGCJGoO8D1nJDw1AdyAGUk0myDLFGN5RbNeJyCRGCw==
   dependencies:
     "@babel/code-frame" "^7.12.13"
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     "@types/stack-utils" "^2.0.0"
     chalk "^4.0.0"
     graceful-fs "^4.2.9"
     micromatch "^4.0.4"
-    pretty-format "^29.4.1"
+    pretty-format "^29.4.3"
     slash "^3.0.0"
     stack-utils "^2.0.3"
 
-jest-mock@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.1.tgz#a218a2abf45c99c501d4665207748a6b9e29afbd"
-  integrity sha512-MwA4hQ7zBOcgVCVnsM8TzaFLVUD/pFWTfbkY953Y81L5ret3GFRZtmPmRFAjKQSdCKoJvvqOu6Bvfpqlwwb0dQ==
+jest-mock@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.3.tgz#23d84a20a74cdfff0510fdbeefb841ed57b0fe7e"
+  integrity sha512-LjFgMg+xed9BdkPMyIJh+r3KeHt1klXPJYBULXVVAkbTaaKjPX1o1uVCAZADMEp/kOxGTwy/Ot8XbvgItOrHEg==
   dependencies:
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
-    jest-util "^29.4.1"
+    jest-util "^29.4.3"
 
 jest-pnp-resolver@^1.2.2:
   version "1.2.2"
   resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c"
   integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==
 
-jest-regex-util@^29.2.0:
-  version "29.2.0"
-  resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b"
-  integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==
+jest-regex-util@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8"
+  integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==
 
-jest-resolve-dependencies@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.1.tgz#02420a2e055da105e5fca8218c471d8b9553c904"
-  integrity sha512-Y3QG3M1ncAMxfjbYgtqNXC5B595zmB6e//p/qpA/58JkQXu/IpLDoLeOa8YoYfsSglBKQQzNUqtfGJJT/qLmJg==
+jest-resolve-dependencies@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.3.tgz#9ad7f23839a6d88cef91416bda9393a6e9fd1da5"
+  integrity sha512-uvKMZAQ3nmXLH7O8WAOhS5l0iWyT3WmnJBdmIHiV5tBbdaDZ1wqtNX04FONGoaFvSOSHBJxnwAVnSn1WHdGVaw==
   dependencies:
-    jest-regex-util "^29.2.0"
-    jest-snapshot "^29.4.1"
+    jest-regex-util "^29.4.3"
+    jest-snapshot "^29.4.3"
 
-jest-resolve@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.4.1.tgz#4c6bf71a07b8f0b79c5fdf4f2a2cf47317694c5e"
-  integrity sha512-j/ZFNV2lm9IJ2wmlq1uYK0Y/1PiyDq9g4HEGsNTNr3viRbJdV+8Lf1SXIiLZXFvyiisu0qUyIXGBnw+OKWkJwQ==
+jest-resolve@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.4.3.tgz#3c5b5c984fa8a763edf9b3639700e1c7900538e2"
+  integrity sha512-GPokE1tzguRyT7dkxBim4wSx6E45S3bOQ7ZdKEG+Qj0Oac9+6AwJPCk0TZh5Vu0xzeX4afpb+eDmgbmZFFwpOw==
   dependencies:
     chalk "^4.0.0"
     graceful-fs "^4.2.9"
-    jest-haste-map "^29.4.1"
+    jest-haste-map "^29.4.3"
     jest-pnp-resolver "^1.2.2"
-    jest-util "^29.4.1"
-    jest-validate "^29.4.1"
+    jest-util "^29.4.3"
+    jest-validate "^29.4.3"
     resolve "^1.20.0"
     resolve.exports "^2.0.0"
     slash "^3.0.0"
 
-jest-runner@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.4.1.tgz#57460d9ebb0eea2e27eeddca1816cf8537469661"
-  integrity sha512-8d6XXXi7GtHmsHrnaqBKWxjKb166Eyj/ksSaUYdcBK09VbjPwIgWov1VwSmtupCIz8q1Xv4Qkzt/BTo3ZqiCeg==
+jest-runner@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.4.3.tgz#68dc82c68645eda12bea42b5beece6527d7c1e5e"
+  integrity sha512-GWPTEiGmtHZv1KKeWlTX9SIFuK19uLXlRQU43ceOQ2hIfA5yPEJC7AMkvFKpdCHx6pNEdOD+2+8zbniEi3v3gA==
   dependencies:
-    "@jest/console" "^29.4.1"
-    "@jest/environment" "^29.4.1"
-    "@jest/test-result" "^29.4.1"
-    "@jest/transform" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/console" "^29.4.3"
+    "@jest/environment" "^29.4.3"
+    "@jest/test-result" "^29.4.3"
+    "@jest/transform" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
     chalk "^4.0.0"
     emittery "^0.13.1"
     graceful-fs "^4.2.9"
-    jest-docblock "^29.2.0"
-    jest-environment-node "^29.4.1"
-    jest-haste-map "^29.4.1"
-    jest-leak-detector "^29.4.1"
-    jest-message-util "^29.4.1"
-    jest-resolve "^29.4.1"
-    jest-runtime "^29.4.1"
-    jest-util "^29.4.1"
-    jest-watcher "^29.4.1"
-    jest-worker "^29.4.1"
+    jest-docblock "^29.4.3"
+    jest-environment-node "^29.4.3"
+    jest-haste-map "^29.4.3"
+    jest-leak-detector "^29.4.3"
+    jest-message-util "^29.4.3"
+    jest-resolve "^29.4.3"
+    jest-runtime "^29.4.3"
+    jest-util "^29.4.3"
+    jest-watcher "^29.4.3"
+    jest-worker "^29.4.3"
     p-limit "^3.1.0"
     source-map-support "0.5.13"
 
-jest-runtime@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.4.1.tgz#9a50f9c69d3a391690897c01b0bfa8dc5dd45808"
-  integrity sha512-UXTMU9uKu2GjYwTtoAw5rn4STxWw/nadOfW7v1sx6LaJYa3V/iymdCLQM6xy3+7C6mY8GfX22vKpgxY171UIoA==
-  dependencies:
-    "@jest/environment" "^29.4.1"
-    "@jest/fake-timers" "^29.4.1"
-    "@jest/globals" "^29.4.1"
-    "@jest/source-map" "^29.2.0"
-    "@jest/test-result" "^29.4.1"
-    "@jest/transform" "^29.4.1"
-    "@jest/types" "^29.4.1"
+jest-runtime@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.4.3.tgz#f25db9874dcf35a3ab27fdaabca426666cc745bf"
+  integrity sha512-F5bHvxSH+LvLV24vVB3L8K467dt3y3dio6V3W89dUz9nzvTpqd/HcT9zfYKL2aZPvD63vQFgLvaUX/UpUhrP6Q==
+  dependencies:
+    "@jest/environment" "^29.4.3"
+    "@jest/fake-timers" "^29.4.3"
+    "@jest/globals" "^29.4.3"
+    "@jest/source-map" "^29.4.3"
+    "@jest/test-result" "^29.4.3"
+    "@jest/transform" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
     chalk "^4.0.0"
     cjs-module-lexer "^1.0.0"
     collect-v8-coverage "^1.0.0"
     glob "^7.1.3"
     graceful-fs "^4.2.9"
-    jest-haste-map "^29.4.1"
-    jest-message-util "^29.4.1"
-    jest-mock "^29.4.1"
-    jest-regex-util "^29.2.0"
-    jest-resolve "^29.4.1"
-    jest-snapshot "^29.4.1"
-    jest-util "^29.4.1"
-    semver "^7.3.5"
+    jest-haste-map "^29.4.3"
+    jest-message-util "^29.4.3"
+    jest-mock "^29.4.3"
+    jest-regex-util "^29.4.3"
+    jest-resolve "^29.4.3"
+    jest-snapshot "^29.4.3"
+    jest-util "^29.4.3"
     slash "^3.0.0"
     strip-bom "^4.0.0"
 
-jest-snapshot@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.4.1.tgz#5692210b3690c94f19317913d4082b123bd83dd9"
-  integrity sha512-l4iV8EjGgQWVz3ee/LR9sULDk2pCkqb71bjvlqn+qp90lFwpnulHj4ZBT8nm1hA1C5wowXLc7MGnw321u0tsYA==
+jest-snapshot@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.4.3.tgz#183d309371450d9c4a3de7567ed2151eb0e91145"
+  integrity sha512-NGlsqL0jLPDW91dz304QTM/SNO99lpcSYYAjNiX0Ou+sSGgkanKBcSjCfp/pqmiiO1nQaOyLp6XQddAzRcx3Xw==
   dependencies:
     "@babel/core" "^7.11.6"
     "@babel/generator" "^7.7.2"
@@ -6795,61 +6794,61 @@ jest-snapshot@^29.4.1:
     "@babel/plugin-syntax-typescript" "^7.7.2"
     "@babel/traverse" "^7.7.2"
     "@babel/types" "^7.3.3"
-    "@jest/expect-utils" "^29.4.1"
-    "@jest/transform" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/expect-utils" "^29.4.3"
+    "@jest/transform" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/babel__traverse" "^7.0.6"
     "@types/prettier" "^2.1.5"
     babel-preset-current-node-syntax "^1.0.0"
     chalk "^4.0.0"
-    expect "^29.4.1"
+    expect "^29.4.3"
     graceful-fs "^4.2.9"
-    jest-diff "^29.4.1"
-    jest-get-type "^29.2.0"
-    jest-haste-map "^29.4.1"
-    jest-matcher-utils "^29.4.1"
-    jest-message-util "^29.4.1"
-    jest-util "^29.4.1"
+    jest-diff "^29.4.3"
+    jest-get-type "^29.4.3"
+    jest-haste-map "^29.4.3"
+    jest-matcher-utils "^29.4.3"
+    jest-message-util "^29.4.3"
+    jest-util "^29.4.3"
     natural-compare "^1.4.0"
-    pretty-format "^29.4.1"
+    pretty-format "^29.4.3"
     semver "^7.3.5"
 
-jest-util@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.1.tgz#2eeed98ff4563b441b5a656ed1a786e3abc3e4c4"
-  integrity sha512-bQy9FPGxVutgpN4VRc0hk6w7Hx/m6L53QxpDreTZgJd9gfx/AV2MjyPde9tGyZRINAUrSv57p2inGBu2dRLmkQ==
+jest-util@^29.4.2, jest-util@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.3.tgz#851a148e23fc2b633c55f6dad2e45d7f4579f496"
+  integrity sha512-ToSGORAz4SSSoqxDSylWX8JzkOQR7zoBtNRsA7e+1WUX5F8jrOwaNpuh1YfJHJKDHXLHmObv5eOjejUd+/Ws+Q==
   dependencies:
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
     chalk "^4.0.0"
     ci-info "^3.2.0"
     graceful-fs "^4.2.9"
     picomatch "^2.2.3"
 
-jest-validate@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.4.1.tgz#0d5174510415083ec329d4f981bf6779211f17e9"
-  integrity sha512-qNZXcZQdIQx4SfUB/atWnI4/I2HUvhz8ajOSYUu40CSmf9U5emil8EDHgE7M+3j9/pavtk3knlZBDsgFvv/SWw==
+jest-validate@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.4.3.tgz#a13849dec4f9e95446a7080ad5758f58fa88642f"
+  integrity sha512-J3u5v7aPQoXPzaar6GndAVhdQcZr/3osWSgTeKg5v574I9ybX/dTyH0AJFb5XgXIB7faVhf+rS7t4p3lL9qFaw==
   dependencies:
-    "@jest/types" "^29.4.1"
+    "@jest/types" "^29.4.3"
     camelcase "^6.2.0"
     chalk "^4.0.0"
-    jest-get-type "^29.2.0"
+    jest-get-type "^29.4.3"
     leven "^3.1.0"
-    pretty-format "^29.4.1"
+    pretty-format "^29.4.3"
 
-jest-watcher@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.4.1.tgz#6e3e2486918bd778849d4d6e67fd77b814f3e6ed"
-  integrity sha512-vFOzflGFs27nU6h8dpnVRER3O2rFtL+VMEwnG0H3KLHcllLsU8y9DchSh0AL/Rg5nN1/wSiQ+P4ByMGpuybaVw==
+jest-watcher@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.4.3.tgz#e503baa774f0c2f8f3c8db98a22ebf885f19c384"
+  integrity sha512-zwlXH3DN3iksoIZNk73etl1HzKyi5FuQdYLnkQKm5BW4n8HpoG59xSwpVdFrnh60iRRaRBGw0gcymIxjJENPcA==
   dependencies:
-    "@jest/test-result" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/test-result" "^29.4.3"
+    "@jest/types" "^29.4.3"
     "@types/node" "*"
     ansi-escapes "^4.2.1"
     chalk "^4.0.0"
     emittery "^0.13.1"
-    jest-util "^29.4.1"
+    jest-util "^29.4.3"
     string-length "^4.0.1"
 
 jest-worker@^26.2.1, jest-worker@^26.5.0:
@@ -6861,25 +6860,25 @@ jest-worker@^26.2.1, jest-worker@^26.5.0:
     merge-stream "^2.0.0"
     supports-color "^7.0.0"
 
-jest-worker@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.4.1.tgz#7cb4a99a38975679600305650f86f4807460aab1"
-  integrity sha512-O9doU/S1EBe+yp/mstQ0VpPwpv0Clgn68TkNwGxL6/usX/KUW9Arnn4ag8C3jc6qHcXznhsT5Na1liYzAsuAbQ==
+jest-worker@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.4.3.tgz#9a4023e1ea1d306034237c7133d7da4240e8934e"
+  integrity sha512-GLHN/GTAAMEy5BFdvpUfzr9Dr80zQqBrh0fz1mtRMe05hqP45+HfQltu7oTBfduD0UeZs09d+maFtFYAXFWvAA==
   dependencies:
     "@types/node" "*"
-    jest-util "^29.4.1"
+    jest-util "^29.4.3"
     merge-stream "^2.0.0"
     supports-color "^8.0.0"
 
-jest@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/jest/-/jest-29.4.1.tgz#bb34baca8e05901b49c02c62f1183a6182ea1785"
-  integrity sha512-cknimw7gAXPDOmj0QqztlxVtBVCw2lYY9CeIE5N6kD+kET1H4H79HSNISJmijb1HF+qk+G+ploJgiDi5k/fRlg==
+jest@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/jest/-/jest-29.4.3.tgz#1b8be541666c6feb99990fd98adac4737e6e6386"
+  integrity sha512-XvK65feuEFGZT8OO0fB/QAQS+LGHvQpaadkH5p47/j3Ocqq3xf2pK9R+G0GzgfuhXVxEv76qCOOcMb5efLk6PA==
   dependencies:
-    "@jest/core" "^29.4.1"
-    "@jest/types" "^29.4.1"
+    "@jest/core" "^29.4.3"
+    "@jest/types" "^29.4.3"
     import-local "^3.0.2"
-    jest-cli "^29.4.1"
+    jest-cli "^29.4.3"
 
 js-sdsl@^4.1.4:
   version "4.3.0"
@@ -8795,10 +8794,10 @@ prelude-ls@~1.1.2:
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
   integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
 
-prettier@^2.8.3:
-  version "2.8.3"
-  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.3.tgz#ab697b1d3dd46fb4626fbe2f543afe0cc98d8632"
-  integrity sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==
+prettier@^2.8.4:
+  version "2.8.4"
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3"
+  integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==
 
 pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
   version "5.6.0"
@@ -8825,12 +8824,12 @@ pretty-format@^27.0.2:
     ansi-styles "^5.0.0"
     react-is "^17.0.1"
 
-pretty-format@^29.4.1:
-  version "29.4.1"
-  resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.1.tgz#0da99b532559097b8254298da7c75a0785b1751c"
-  integrity sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg==
+pretty-format@^29.4.3:
+  version "29.4.3"
+  resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.3.tgz#25500ada21a53c9e8423205cf0337056b201244c"
+  integrity sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA==
   dependencies:
-    "@jest/schemas" "^29.4.0"
+    "@jest/schemas" "^29.4.3"
     ansi-styles "^5.0.0"
     react-is "^18.0.0"
 
@@ -9744,10 +9743,10 @@ sass-loader@^10.2.0:
     schema-utils "^3.0.0"
     semver "^7.3.2"
 
-sass@^1.58.0:
-  version "1.58.0"
-  resolved "https://registry.yarnpkg.com/sass/-/sass-1.58.0.tgz#ee8aea3ad5ea5c485c26b3096e2df6087d0bb1cc"
-  integrity sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg==
+sass@^1.58.2:
+  version "1.58.2"
+  resolved "https://registry.yarnpkg.com/sass/-/sass-1.58.2.tgz#ef3c5098a02dd006f09a2350b114f1ac445e38ce"
+  integrity sha512-2mbyOWOv/lhEXD6nVrQZQ4KT2DlwcODbTskM42EyqBAFUWOhiiYtAXZqjZz1ygzapYf+N+2GwfIH9M5FM4GUMg==
   dependencies:
     chokidar ">=3.0.0 <4.0.0"
     immutable "^4.0.0"
@@ -10488,10 +10487,10 @@ stylelint-config-recommended@^10.0.1:
   resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-10.0.1.tgz#25a8828acf6cde87dac6db2950c8c4ed82a69ae1"
   integrity sha512-TQ4xQ48tW4QSlODcti7pgSRqBZcUaBzuh0jPpfiMhwJKBPkqzTIAU+IrSWL/7BgXlOM90DjB7YaNgFpx8QWhuA==
 
-stylelint-config-standard-scss@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/stylelint-config-standard-scss/-/stylelint-config-standard-scss-7.0.0.tgz#c7076bf5afa705d9e5ddc3ede39da7a684fa0f60"
-  integrity sha512-rHgydRJxN4Q9lDcwrLFoiFA3S8CRqsUcyBBCLwEMjIwzJViluFfsOKFPSomx6hScVQgQ4//Fx0hRKiSHyO0ihw==
+stylelint-config-standard-scss@^7.0.1:
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/stylelint-config-standard-scss/-/stylelint-config-standard-scss-7.0.1.tgz#4ba83fa19e1508937f7e02674e085cf94fc1a145"
+  integrity sha512-m5sRdtsB1F5fnC1Ozla7ryftU47wVpO+HWd+JQTqeoG0g/oPh5EfbWfcVHbNCEtuoHfALIySiUWS20pz2hX6jA==
   dependencies:
     stylelint-config-recommended-scss "^9.0.0"
     stylelint-config-standard "^30.0.1"
@@ -11371,11 +11370,12 @@ webpack-assets-manifest@^4.0.6:
     tapable "^1.0"
     webpack-sources "^1.0"
 
-webpack-bundle-analyzer@^4.7.0:
-  version "4.7.0"
-  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz#33c1c485a7fcae8627c547b5c3328b46de733c66"
-  integrity sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg==
+webpack-bundle-analyzer@^4.8.0:
+  version "4.8.0"
+  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.8.0.tgz#951b8aaf491f665d2ae325d8b84da229157b1d04"
+  integrity sha512-ZzoSBePshOKhr+hd8u6oCkZVwpVaXgpw23ScGLFpR6SjYI7+7iIWYarjN6OEYOfRt8o7ZyZZQk0DuMizJ+LEIg==
   dependencies:
+    "@discoveryjs/json-ext" "0.5.7"
     acorn "^8.0.4"
     acorn-walk "^8.0.0"
     chalk "^4.1.0"
@@ -11830,6 +11830,14 @@ wrappy@1:
   resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
   integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
 
+write-file-atomic@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd"
+  integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==
+  dependencies:
+    imurmurhash "^0.1.4"
+    signal-exit "^3.0.7"
+
 write-file-atomic@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.0.tgz#54303f117e109bf3d540261125c8ea5a7320fab0"
@@ -11850,10 +11858,10 @@ ws@^7.3.1:
   resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
   integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
 
-ws@^8.11.0, ws@^8.12.0:
-  version "8.12.0"
-  resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.0.tgz#485074cc392689da78e1828a9ff23585e06cddd8"
-  integrity sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==
+ws@^8.11.0, ws@^8.12.1:
+  version "8.12.1"
+  resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.1.tgz#c51e583d79140b5e42e39be48c934131942d4a8f"
+  integrity sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==
 
 xml-name-validator@^4.0.0:
   version "4.0.0"
@@ -11929,10 +11937,10 @@ yargs@^13.3.2:
     y18n "^4.0.0"
     yargs-parser "^13.1.2"
 
-yargs@^17.3.1, yargs@^17.6.2:
-  version "17.6.2"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541"
-  integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==
+yargs@^17.3.1, yargs@^17.7.0:
+  version "17.7.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.0.tgz#b21e9af1e0a619a2a9c67b1133219b2975a07985"
+  integrity sha512-dwqOPg5trmrre9+v8SUo2q/hAwyKoVfu8OC1xPHKJGNdxAvPl4sKxL4vBnh3bQz/ZvvGAFeA5H3ou2kcOY8sQQ==
   dependencies:
     cliui "^8.0.1"
     escalade "^3.1.1"