about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.env.production.sample2
-rw-r--r--.eslintrc.js7
-rw-r--r--.rubocop.yml4
-rw-r--r--AUTHORS.md205
-rw-r--r--CHANGELOG.md150
-rw-r--r--app/chewy/statuses_index.rb2
-rw-r--r--app/controllers/api/v1/statuses/reblogs_controller.rb10
-rw-r--r--app/controllers/auth/sessions_controller.rb1
-rw-r--r--app/controllers/tags_controller.rb2
-rw-r--r--app/javascript/flavours/glitch/features/account_gallery/components/media_item.js86
-rw-r--r--app/javascript/flavours/glitch/features/account_gallery/index.js4
-rw-r--r--app/javascript/flavours/glitch/features/audio/index.js16
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/audio_modal.js18
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/boost_modal.js17
-rw-r--r--app/javascript/flavours/glitch/features/video/index.js2
-rw-r--r--app/javascript/flavours/glitch/selectors/index.js5
-rw-r--r--app/javascript/flavours/glitch/styles/components/modal.scss8
-rw-r--r--app/javascript/mastodon/features/account_gallery/components/media_item.js92
-rw-r--r--app/javascript/mastodon/features/account_gallery/index.js4
-rw-r--r--app/javascript/mastodon/features/audio/index.js16
-rw-r--r--app/javascript/mastodon/features/ui/components/audio_modal.js18
-rw-r--r--app/javascript/mastodon/features/ui/components/boost_modal.js17
-rw-r--r--app/javascript/mastodon/features/video/index.js2
-rw-r--r--app/javascript/mastodon/locales/ar.json26
-rw-r--r--app/javascript/mastodon/locales/ast.json20
-rw-r--r--app/javascript/mastodon/locales/bg.json20
-rw-r--r--app/javascript/mastodon/locales/bn.json20
-rw-r--r--app/javascript/mastodon/locales/br.json102
-rw-r--r--app/javascript/mastodon/locales/ca.json20
-rw-r--r--app/javascript/mastodon/locales/co.json20
-rw-r--r--app/javascript/mastodon/locales/cs.json20
-rw-r--r--app/javascript/mastodon/locales/cy.json20
-rw-r--r--app/javascript/mastodon/locales/da.json20
-rw-r--r--app/javascript/mastodon/locales/de.json26
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json8
-rw-r--r--app/javascript/mastodon/locales/el.json20
-rw-r--r--app/javascript/mastodon/locales/en.json2
-rw-r--r--app/javascript/mastodon/locales/eo.json26
-rw-r--r--app/javascript/mastodon/locales/es-AR.json20
-rw-r--r--app/javascript/mastodon/locales/es.json20
-rw-r--r--app/javascript/mastodon/locales/et.json20
-rw-r--r--app/javascript/mastodon/locales/eu.json20
-rw-r--r--app/javascript/mastodon/locales/fa.json24
-rw-r--r--app/javascript/mastodon/locales/fi.json20
-rw-r--r--app/javascript/mastodon/locales/fr.json22
-rw-r--r--app/javascript/mastodon/locales/ga.json16
-rw-r--r--app/javascript/mastodon/locales/gl.json20
-rw-r--r--app/javascript/mastodon/locales/he.json54
-rw-r--r--app/javascript/mastodon/locales/hi.json20
-rw-r--r--app/javascript/mastodon/locales/hr.json20
-rw-r--r--app/javascript/mastodon/locales/hu.json20
-rw-r--r--app/javascript/mastodon/locales/hy.json26
-rw-r--r--app/javascript/mastodon/locales/id.json20
-rw-r--r--app/javascript/mastodon/locales/io.json20
-rw-r--r--app/javascript/mastodon/locales/is.json20
-rw-r--r--app/javascript/mastodon/locales/it.json20
-rw-r--r--app/javascript/mastodon/locales/ja.json20
-rw-r--r--app/javascript/mastodon/locales/ka.json20
-rw-r--r--app/javascript/mastodon/locales/kab.json54
-rw-r--r--app/javascript/mastodon/locales/kk.json20
-rw-r--r--app/javascript/mastodon/locales/kn.json20
-rw-r--r--app/javascript/mastodon/locales/ko.json20
-rw-r--r--app/javascript/mastodon/locales/ku.json461
-rw-r--r--app/javascript/mastodon/locales/lt.json20
-rw-r--r--app/javascript/mastodon/locales/lv.json38
-rw-r--r--app/javascript/mastodon/locales/mk.json20
-rw-r--r--app/javascript/mastodon/locales/ml.json54
-rw-r--r--app/javascript/mastodon/locales/mr.json20
-rw-r--r--app/javascript/mastodon/locales/ms.json20
-rw-r--r--app/javascript/mastodon/locales/nl.json54
-rw-r--r--app/javascript/mastodon/locales/nn.json20
-rw-r--r--app/javascript/mastodon/locales/no.json20
-rw-r--r--app/javascript/mastodon/locales/oc.json32
-rw-r--r--app/javascript/mastodon/locales/pl.json20
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json20
-rw-r--r--app/javascript/mastodon/locales/pt-PT.json26
-rw-r--r--app/javascript/mastodon/locales/ro.json20
-rw-r--r--app/javascript/mastodon/locales/ru.json22
-rw-r--r--app/javascript/mastodon/locales/sc.json20
-rw-r--r--app/javascript/mastodon/locales/sk.json20
-rw-r--r--app/javascript/mastodon/locales/sl.json20
-rw-r--r--app/javascript/mastodon/locales/sq.json20
-rw-r--r--app/javascript/mastodon/locales/sr-Latn.json20
-rw-r--r--app/javascript/mastodon/locales/sr.json20
-rw-r--r--app/javascript/mastodon/locales/sv.json20
-rw-r--r--app/javascript/mastodon/locales/szl.json20
-rw-r--r--app/javascript/mastodon/locales/ta.json20
-rw-r--r--app/javascript/mastodon/locales/tai.json20
-rw-r--r--app/javascript/mastodon/locales/te.json20
-rw-r--r--app/javascript/mastodon/locales/th.json20
-rw-r--r--app/javascript/mastodon/locales/tr.json32
-rw-r--r--app/javascript/mastodon/locales/ug.json461
-rw-r--r--app/javascript/mastodon/locales/uk.json32
-rw-r--r--app/javascript/mastodon/locales/ur.json20
-rw-r--r--app/javascript/mastodon/locales/vi.json132
-rw-r--r--app/javascript/mastodon/locales/whitelist_ku.json2
-rw-r--r--app/javascript/mastodon/locales/whitelist_ug.json2
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json20
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json22
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json20
-rw-r--r--app/javascript/mastodon/selectors/index.js5
-rw-r--r--app/lib/activitypub/activity.rb2
-rw-r--r--app/lib/activitypub/activity/create.rb2
-rw-r--r--app/lib/activitypub/tag_manager.rb12
-rw-r--r--app/lib/proof_provider/keybase/config_serializer.rb2
-rw-r--r--app/lib/request.rb1
-rw-r--r--app/lib/settings/scoped_settings.rb5
-rw-r--r--app/models/concerns/omniauthable.rb2
-rw-r--r--app/models/media_attachment.rb6
-rw-r--r--app/services/after_block_domain_from_account_service.rb2
-rw-r--r--app/services/after_unallow_domain_service.rb9
-rw-r--r--app/services/unallow_domain_service.rb13
-rw-r--r--app/workers/after_unallow_domain_worker.rb9
-rw-r--r--config/environments/production.rb1
-rw-r--r--config/locales/activerecord.ku.yml1
-rw-r--r--config/locales/activerecord.ml.yml5
-rw-r--r--config/locales/activerecord.ug.yml1
-rw-r--r--config/locales/ar.yml22
-rw-r--r--config/locales/bn.yml4
-rw-r--r--config/locales/co.yml3
-rw-r--r--config/locales/de.yml7
-rw-r--r--config/locales/devise.br.yml7
-rw-r--r--config/locales/devise.kab.yml35
-rw-r--r--config/locales/devise.ku.yml1
-rw-r--r--config/locales/devise.ug.yml1
-rw-r--r--config/locales/devise.zh-HK.yml2
-rw-r--r--config/locales/doorkeeper.ku.yml1
-rw-r--r--config/locales/doorkeeper.ml.yml9
-rw-r--r--config/locales/doorkeeper.ug.yml1
-rw-r--r--config/locales/doorkeeper.vi.yml2
-rw-r--r--config/locales/el.yml4
-rw-r--r--config/locales/en.yml4
-rw-r--r--config/locales/eo.yml5
-rw-r--r--config/locales/eu.yml4
-rw-r--r--config/locales/fa.yml6
-rw-r--r--config/locales/fr.yml32
-rw-r--r--config/locales/gl.yml4
-rw-r--r--config/locales/hu.yml4
-rw-r--r--config/locales/id.yml4
-rw-r--r--config/locales/ja.yml6
-rw-r--r--config/locales/kab.yml49
-rw-r--r--config/locales/ko.yml2
-rw-r--r--config/locales/ku.yml1
-rw-r--r--config/locales/nl.yml104
-rw-r--r--config/locales/no.yml4
-rw-r--r--config/locales/oc.yml2
-rw-r--r--config/locales/pt-BR.yml4
-rw-r--r--config/locales/simple_form.ar.yml5
-rw-r--r--config/locales/simple_form.hy.yml28
-rw-r--r--config/locales/simple_form.kab.yml4
-rw-r--r--config/locales/simple_form.ku.yml1
-rw-r--r--config/locales/simple_form.nl.yml8
-rw-r--r--config/locales/simple_form.tr.yml4
-rw-r--r--config/locales/simple_form.ug.yml1
-rw-r--r--config/locales/simple_form.uk.yml5
-rw-r--r--config/locales/simple_form.vi.yml26
-rw-r--r--config/locales/simple_form.zh-CN.yml4
-rw-r--r--config/locales/sv.yml4
-rw-r--r--config/locales/th.yml7
-rw-r--r--config/locales/tr.yml13
-rw-r--r--config/locales/ug.yml20
-rw-r--r--config/locales/uk.yml27
-rw-r--r--config/locales/vi.yml161
-rw-r--r--config/locales/zh-CN.yml52
-rw-r--r--config/routes.rb32
-rw-r--r--lib/mastodon/cli_helper.rb1
-rw-r--r--lib/mastodon/search_cli.rb142
-rw-r--r--lib/mastodon/version.rb6
-rw-r--r--spec/controllers/api/v1/statuses/reblogs_controller_spec.rb30
-rw-r--r--spec/services/unallow_domain_service_spec.rb64
170 files changed, 3311 insertions, 1210 deletions
diff --git a/.env.production.sample b/.env.production.sample
index 6d9929f70..d51144d96 100644
--- a/.env.production.sample
+++ b/.env.production.sample
@@ -2,7 +2,7 @@
 # with the `rake mastodon:setup` interactive setup wizard, but to customize
 # your setup even further, you'll need to edit it manually. This sample does
 # not demonstrate all available configuration options. Please look at
-# https://docs.joinmastodon/admin/config/ for the full documentation.
+# https://docs.joinmastodon.org/admin/config/ for the full documentation.
 
 # Federation
 # ----------
diff --git a/.eslintrc.js b/.eslintrc.js
index 177496d3a..7dda01108 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -199,6 +199,11 @@ module.exports = {
     'import/no-unresolved': 'error',
     'import/no-webpack-loader-syntax': 'error',
 
-    'promise/catch-or-return': 'error',
+    'promise/catch-or-return': [
+      'error',
+      {
+        allowFinally: true,
+      },
+    ],
   },
 };
diff --git a/.rubocop.yml b/.rubocop.yml
index 3a11f7000..25e0fa940 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -28,6 +28,10 @@ Layout/EmptyLineAfterMagicComment:
 Layout/SpaceInsideHashLiteralBraces:
   EnforcedStyle: space
 
+Lint/UselessAccessModifier:
+  ContextCreatingMethods:
+    - class_methods
+
 Metrics/AbcSize:
   Max: 100
 
diff --git a/AUTHORS.md b/AUTHORS.md
index 5f5985fba..5ff241afd 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -5,62 +5,66 @@ Mastodon is available on [GitHub](https://github.com/tootsuite/mastodon)
 and provided thanks to the work of the following contributors:
 
 * [Gargron](https://github.com/Gargron)
+* [dependabot-preview[bot]](https://github.com/apps/dependabot-preview)
 * [ThibG](https://github.com/ThibG)
 * [ykzts](https://github.com/ykzts)
 * [dependabot[bot]](https://github.com/apps/dependabot)
 * [akihikodaki](https://github.com/akihikodaki)
-* [dependabot-preview[bot]](https://github.com/apps/dependabot-preview)
 * [mjankowski](https://github.com/mjankowski)
 * [unarist](https://github.com/unarist)
 * [yiskah](https://github.com/yiskah)
 * [nolanlawson](https://github.com/nolanlawson)
-* [ysksn](https://github.com/ysksn)
 * [abcang](https://github.com/abcang)
+* [ysksn](https://github.com/ysksn)
+* [mayaeh](https://github.com/mayaeh)
 * [sorin-davidoi](https://github.com/sorin-davidoi)
 * [lynlynlynx](https://github.com/lynlynlynx)
-* [mayaeh](https://github.com/mayaeh)
 * [m4sk1n](mailto:me@m4sk.in)
 * [Marcin Mikołajczak](mailto:me@m4sk.in)
 * [Kjwon15](https://github.com/Kjwon15)
+* [noellabo](https://github.com/noellabo)
 * [renatolond](https://github.com/renatolond)
 * [alpaca-tc](https://github.com/alpaca-tc)
 * [jeroenpraat](https://github.com/jeroenpraat)
 * [nclm](https://github.com/nclm)
 * [ineffyble](https://github.com/ineffyble)
-* [mabkenar](https://github.com/mabkenar)
+* [shleeable](https://github.com/shleeable)
+* [zunda](https://github.com/zunda)
+* [Masoud Abkenar](mailto:ampbox@gmail.com)
 * [blackle](https://github.com/blackle)
 * [Quent-in](https://github.com/Quent-in)
 * [JantsoP](https://github.com/JantsoP)
-* [zunda](https://github.com/zunda)
 * [nullkal](https://github.com/nullkal)
 * [yookoala](https://github.com/yookoala)
+* [Sasha-Sorokin](https://github.com/Sasha-Sorokin)
 * [Aditoo17](https://github.com/Aditoo17)
 * [Quenty31](https://github.com/Quenty31)
 * [marek-lach](https://github.com/marek-lach)
 * [shuheiktgw](https://github.com/shuheiktgw)
 * [ashfurrow](https://github.com/ashfurrow)
+* [danhunsaker](https://github.com/danhunsaker)
 * [eramdam](https://github.com/eramdam)
-* [noellabo](https://github.com/noellabo)
 * [takayamaki](https://github.com/takayamaki)
-* [danhunsaker](https://github.com/danhunsaker)
+* [ariasuni](https://github.com/ariasuni)
 * [masarakki](https://github.com/masarakki)
 * [ticky](https://github.com/ticky)
 * [ThisIsMissEm](https://github.com/ThisIsMissEm)
+* [hinaloe](https://github.com/hinaloe)
 * [hcmiya](https://github.com/hcmiya)
 * [stephenburgess8](https://github.com/stephenburgess8)
-* [Wonderfall](https://github.com/Wonderfall)
+* [Wonderfall](mailto:wonderfall@targaryen.house)
 * [matteoaquila](https://github.com/matteoaquila)
 * [yukimochi](https://github.com/yukimochi)
 * [palindromordnilap](https://github.com/palindromordnilap)
 * [rkarabut](https://github.com/rkarabut)
-* [Artoria2e5](https://github.com/Artoria2e5)
+* [trwnh](https://github.com/trwnh)
 * [nightpool](https://github.com/nightpool)
+* [Artoria2e5](https://github.com/Artoria2e5)
 * [marrus-sh](https://github.com/marrus-sh)
-* [hinaloe](https://github.com/hinaloe)
 * [krainboltgreene](https://github.com/krainboltgreene)
 * [pfigel](https://github.com/pfigel)
-* [Aldarone](https://github.com/Aldarone)
 * [BoFFire](https://github.com/BoFFire)
+* [Aldarone](https://github.com/Aldarone)
 * [clworld](https://github.com/clworld)
 * [MasterGroosha](https://github.com/MasterGroosha)
 * [dracos](https://github.com/dracos)
@@ -68,52 +72,50 @@ and provided thanks to the work of the following contributors:
 * [SerCom_KC](mailto:sercom-kc@users.noreply.github.com)
 * [Sylvhem](https://github.com/Sylvhem)
 * [MitarashiDango](https://github.com/MitarashiDango)
+* [angristan](https://github.com/angristan)
 * [JeanGauthier](https://github.com/JeanGauthier)
 * [kschaper](https://github.com/kschaper)
 * [beatrix-bitrot](https://github.com/beatrix-bitrot)
-* [angristan](https://github.com/angristan)
+* [koyuawsmbrtn](https://github.com/koyuawsmbrtn)
+* [BenLubar](https://github.com/BenLubar)
 * [adbelle](https://github.com/adbelle)
 * [evanminto](https://github.com/evanminto)
 * [MightyPork](https://github.com/MightyPork)
-* [ashleyhull-versent](mailto:ashley.hull@versent.com.au)
+* [ashleyhull-versent](https://github.com/ashleyhull-versent)
 * [yhirano55](https://github.com/yhirano55)
 * [rinsuki](https://github.com/rinsuki)
+* [dunn](https://github.com/dunn)
+* [devkral](https://github.com/devkral)
 * [camponez](https://github.com/camponez)
+* [hugogameiro](https://github.com/hugogameiro)
 * [SerCom_KC](mailto:szescxz@gmail.com)
 * [aschmitz](https://github.com/aschmitz)
-* [trwnh](https://github.com/trwnh)
-* [devkral](https://github.com/devkral)
 * [fpiesche](https://github.com/fpiesche)
-* [hugogameiro](https://github.com/hugogameiro)
 * [gandaro](https://github.com/gandaro)
 * [johnsudaar](https://github.com/johnsudaar)
-* [ariasuni](https://github.com/ariasuni)
 * [trebmuh](https://github.com/trebmuh)
 * [rmhasan](https://github.com/rmhasan)
 * [kedamaDQ](https://github.com/kedamaDQ)
 * [lindwurm](https://github.com/lindwurm)
 * [victorhck](mailto:victorhck@geeko.site)
 * [voidsatisfaction](https://github.com/voidsatisfaction)
-* [BenLubar](https://github.com/BenLubar)
 * [hikari-no-yume](https://github.com/hikari-no-yume)
 * [seefood](https://github.com/seefood)
 * [jackjennings](https://github.com/jackjennings)
-* [koyuawsmbrtn](https://github.com/koyuawsmbrtn)
+* [mfmfuyu](https://github.com/mfmfuyu)
+* [puckipedia](https://github.com/puckipedia)
 * [spla](mailto:spla@mastodont.cat)
-* [expenses](https://github.com/expenses)
 * [walf443](https://github.com/walf443)
 * [JoelQ](https://github.com/JoelQ)
 * [mistydemeo](https://github.com/mistydemeo)
-* [dunn](https://github.com/dunn)
+* [Ashley](mailto:expenses@airmail.cc)
 * [xqus](https://github.com/xqus)
 * [pfm-eyesightjp](https://github.com/pfm-eyesightjp)
-* [fakenine](https://github.com/fakenine)
-* [Shleeble](https://github.com/Shleeble)
+* [Samy KACIMI](mailto:samy.kacimi@gmail.com)
 * [tsuwatch](https://github.com/tsuwatch)
 * [victorhck](https://github.com/victorhck)
 * [mkljczk](https://github.com/mkljczk)
 * [manuelviens](https://github.com/manuelviens)
-* [puckipedia](https://github.com/puckipedia)
 * [fvh-P](https://github.com/fvh-P)
 * [rtucker](https://github.com/rtucker)
 * [Anna e só](mailto:contraexemplos@gmail.com)
@@ -123,6 +125,7 @@ and provided thanks to the work of the following contributors:
 * [diomed](https://github.com/diomed)
 * [Neetshin](mailto:neetshin@neetsh.in)
 * [rainyday](https://github.com/rainyday)
+* [tcitworld](https://github.com/tcitworld)
 * [ProgVal](https://github.com/ProgVal)
 * [valentin2105](https://github.com/valentin2105)
 * [yuntan](https://github.com/yuntan)
@@ -136,44 +139,53 @@ and provided thanks to the work of the following contributors:
 * [TheKinrar](https://github.com/TheKinrar)
 * [AA4ch1](https://github.com/AA4ch1)
 * [alexgleason](https://github.com/alexgleason)
+* [Bèr Kessels](mailto:ber@berk.es)
 * [cpytel](https://github.com/cpytel)
 * [northerner](https://github.com/northerner)
 * [fhemberger](https://github.com/fhemberger)
+* [Gomasy](https://github.com/Gomasy)
 * [greysteil](https://github.com/greysteil)
 * [hencatsmith](https://github.com/hencatsmith)
 * [d6rkaiz](https://github.com/d6rkaiz)
 * [Reverite](https://github.com/Reverite)
 * [JohnD28](https://github.com/JohnD28)
 * [znz](https://github.com/znz)
+* [saper](https://github.com/saper)
 * [Naouak](https://github.com/Naouak)
 * [pawelngei](https://github.com/pawelngei)
 * [reneklacan](https://github.com/reneklacan)
 * [ekiru](https://github.com/ekiru)
-* [tcitworld](https://github.com/tcitworld)
 * [geta6](https://github.com/geta6)
 * [happycoloredbanana](https://github.com/happycoloredbanana)
 * [leopku](https://github.com/leopku)
 * [SansPseudoFix](https://github.com/SansPseudoFix)
-* [salvadorpla](https://github.com/salvadorpla)
+* [spla](mailto:sp@mastodont.cat)
+* [tateisu](https://github.com/tateisu)
 * [tomfhowe](https://github.com/tomfhowe)
 * [noraworld](https://github.com/noraworld)
+* [lfuelling](https://github.com/lfuelling)
 * [theboss](https://github.com/theboss)
 * [nzws](https://github.com/nzws)
+* [duxovni](https://github.com/duxovni)
+* [smorimoto](https://github.com/smorimoto)
 * [178inaba](https://github.com/178inaba)
+* [acid-chicken](https://github.com/acid-chicken)
 * [xgess](https://github.com/xgess)
 * [alyssais](https://github.com/alyssais)
 * [aablinov](https://github.com/aablinov)
 * [stalker314314](https://github.com/stalker314314)
 * [cutls](https://github.com/cutls)
+* [dariusk](https://github.com/dariusk)
 * [huertanix](https://github.com/huertanix)
-* [genesixx](https://github.com/genesixx)
+* [eleboucher](https://github.com/eleboucher)
 * [halkeye](https://github.com/halkeye)
+* [Hanage999](https://github.com/Hanage999)
 * [treby](https://github.com/treby)
 * [jpdevries](https://github.com/jpdevries)
 * [gdpelican](https://github.com/gdpelican)
 * [kmichl](https://github.com/kmichl)
 * [Kurtis Rainbolt-Greene](mailto:me@kurtisrainboltgreene.name)
-* [saper](https://github.com/saper)
+* [panarom](https://github.com/panarom)
 * [Dar13](https://github.com/Dar13)
 * [nevillepark](https://github.com/nevillepark)
 * [ornithocoder](https://github.com/ornithocoder)
@@ -181,7 +193,7 @@ and provided thanks to the work of the following contributors:
 * [pierreozoux](https://github.com/pierreozoux)
 * [qguv](https://github.com/qguv)
 * [Ram Lmn](mailto:ramlmn@users.noreply.github.com)
-* [aurelia-sl](https://github.com/aurelia-sl)
+* [Sascha](mailto:sascha@serenitylabs.cloud)
 * [harukasan](https://github.com/harukasan)
 * [stamak](https://github.com/stamak)
 * [Technowix](https://github.com/Technowix)
@@ -196,9 +208,9 @@ and provided thanks to the work of the following contributors:
 * [chr-1x](https://github.com/chr-1x)
 * [esetomo](https://github.com/esetomo)
 * [foxiehkins](https://github.com/foxiehkins)
+* [highemerly](https://github.com/highemerly)
 * [hoodie](mailto:hoodiekitten@outlook.com)
 * [luzi82](https://github.com/luzi82)
-* [duxovni](https://github.com/duxovni)
 * [slice](https://github.com/slice)
 * [tmm576](https://github.com/tmm576)
 * [unsmell](mailto:unsmell@users.noreply.github.com)
@@ -209,13 +221,12 @@ and provided thanks to the work of the following contributors:
 * [AndreLewin](https://github.com/AndreLewin)
 * [0xflotus](https://github.com/0xflotus)
 * [redtachyons](https://github.com/redtachyons)
-* [acid-chicken](https://github.com/acid-chicken)
 * [thurloat](https://github.com/thurloat)
 * [aaribaud](https://github.com/aaribaud)
 * [pointlessone](https://github.com/pointlessone)
 * [Andrew](mailto:andrewlchronister@gmail.com)
 * [aurelien-reeves](https://github.com/aurelien-reeves)
-* [AnaGelez](https://github.com/AnaGelez)
+* [elegaanz](https://github.com/elegaanz)
 * [estuans](https://github.com/estuans)
 * [dissolve](https://github.com/dissolve)
 * [PurpleBooth](https://github.com/PurpleBooth)
@@ -227,16 +238,14 @@ and provided thanks to the work of the following contributors:
 * [muffinista](https://github.com/muffinista)
 * [cdutson](https://github.com/cdutson)
 * [farlistener](https://github.com/farlistener)
-* [dariusk](https://github.com/dariusk)
 * [DavidLibeau](https://github.com/DavidLibeau)
+* [dmerejkowsky](https://github.com/dmerejkowsky)
 * [ddevault](https://github.com/ddevault)
 * [Fjoerfoks](https://github.com/Fjoerfoks)
 * [fmauNeko](https://github.com/fmauNeko)
 * [gloaec](https://github.com/gloaec)
-* [Gomasy](https://github.com/Gomasy)
 * [unstabler](https://github.com/unstabler)
 * [potato4d](https://github.com/potato4d)
-* [Hanage999](https://github.com/Hanage999)
 * [h-izumi](https://github.com/h-izumi)
 * [ErikXXon](https://github.com/ErikXXon)
 * [ian-kelling](https://github.com/ian-kelling)
@@ -251,13 +260,17 @@ and provided thanks to the work of the following contributors:
 * [tkbky](https://github.com/tkbky)
 * [Kaylee](mailto:kaylee@codethat.sucks)
 * [Kazhnuz](https://github.com/Kazhnuz)
+* [mkody](https://github.com/mkody)
 * [connyduck](https://github.com/connyduck)
 * [LindseyB](https://github.com/LindseyB)
 * [Lorenz Diener](mailto:halcyon@icosahedron.website)
-* [alimony](https://github.com/alimony)
+* [Markus Amalthea Magnuson](mailto:markus.magnuson@gmail.com)
+* [madmath03](https://github.com/madmath03)
 * [mig5](https://github.com/mig5)
 * [moritzheiber](https://github.com/moritzheiber)
+* [Nathaniel Suchy](mailto:me@lunorian.is)
 * [ndarville](https://github.com/ndarville)
+* [NimaBoscarino](https://github.com/NimaBoscarino)
 * [Abzol](https://github.com/Abzol)
 * [PatOnTheBack](https://github.com/PatOnTheBack)
 * [xPaw](https://github.com/xPaw)
@@ -287,16 +300,15 @@ and provided thanks to the work of the following contributors:
 * [amazedkoumei](https://github.com/amazedkoumei)
 * [anon5r](https://github.com/anon5r)
 * [aus-social](https://github.com/aus-social)
-* [imbsky](https://github.com/imbsky)
 * [bsky](mailto:me@imbsky.net)
 * [codl](https://github.com/codl)
 * [cpsdqs](https://github.com/cpsdqs)
 * [barzamin](https://github.com/barzamin)
 * [fhalna](https://github.com/fhalna)
-* [highemerly](https://github.com/highemerly)
 * [haoyayoi](https://github.com/haoyayoi)
 * [ik11235](https://github.com/ik11235)
 * [kawax](https://github.com/kawax)
+* [shrft](https://github.com/shrft)
 * [007lva](https://github.com/007lva)
 * [mbajur](https://github.com/mbajur)
 * [matsurai25](https://github.com/matsurai25)
@@ -307,15 +319,18 @@ and provided thanks to the work of the following contributors:
 * [pinfort](https://github.com/pinfort)
 * [rbaumert](https://github.com/rbaumert)
 * [rhoio](https://github.com/rhoio)
+* [sclaire-1](https://github.com/sclaire-1)
+* [umonaca](https://github.com/umonaca)
 * [usagi-f](https://github.com/usagi-f)
 * [vidarlee](https://github.com/vidarlee)
 * [vjackson725](https://github.com/vjackson725)
 * [wxcafe](https://github.com/wxcafe)
+* [Grawl](https://github.com/Grawl)
 * [新都心(Neet Shin)](mailto:nucx@dio-vox.com)
 * [clarfon](https://github.com/clarfon)
 * [cygnan](https://github.com/cygnan)
 * [Awea](https://github.com/Awea)
-* [halcy](https://github.com/halcy)
+* [eai04191](https://github.com/eai04191)
 * [8398a7](https://github.com/8398a7)
 * [857b](https://github.com/857b)
 * [insom](https://github.com/insom)
@@ -332,6 +347,7 @@ and provided thanks to the work of the following contributors:
 * [a2](https://github.com/a2)
 * [alfiedotwtf](https://github.com/alfiedotwtf)
 * [0xa](https://github.com/0xa)
+* [ArisuOngaku](https://github.com/ArisuOngaku)
 * [virtualpain](https://github.com/virtualpain)
 * [sapphirus](https://github.com/sapphirus)
 * [amandavisconti](https://github.com/amandavisconti)
@@ -342,15 +358,22 @@ and provided thanks to the work of the following contributors:
 * [schas002](https://github.com/schas002)
 * [contraexemplo](https://github.com/contraexemplo)
 * [abackstrom](https://github.com/abackstrom)
+* [arielrodrigues](https://github.com/arielrodrigues)
+* [orlea](https://github.com/orlea)
 * [armandfardeau](https://github.com/armandfardeau)
 * [raboof](https://github.com/raboof)
 * [jumbosushi](https://github.com/jumbosushi)
 * [ayumin](https://github.com/ayumin)
 * [bzg](https://github.com/bzg)
-* [benediktg](https://github.com/benediktg)
+* [BastienDurel](https://github.com/BastienDurel)
+* [li-bei](https://github.com/li-bei)
+* [Benedikt Geißler](mailto:benedikt@g5r.eu)
+* [BenisonSebastian](https://github.com/BenisonSebastian)
 * [blakebarnett](https://github.com/blakebarnett)
-* [bradj](https://github.com/bradj)
+* [Brad Janke](mailto:brad.janke@gmail.com)
+* [bclindner](https://github.com/bclindner)
 * [brycied00d](https://github.com/brycied00d)
+* [berkes](https://github.com/berkes)
 * [carlosjs23](https://github.com/carlosjs23)
 * [cgxxx](https://github.com/cgxxx)
 * [kibitan](https://github.com/kibitan)
@@ -358,41 +381,48 @@ and provided thanks to the work of the following contributors:
 * [chris-martin](https://github.com/chris-martin)
 * [DoubleMalt](https://github.com/DoubleMalt)
 * [Moosh-be](https://github.com/Moosh-be)
+* [cchoi12](https://github.com/cchoi12)
 * [Motoma](https://github.com/Motoma)
 * [Christopher Kolstad](mailto:christopher.kolstad@finn.no)
 * [csu](https://github.com/csu)
 * [kklleemm](https://github.com/kklleemm)
 * [colindean](https://github.com/colindean)
+* [DeeUnderscore](https://github.com/DeeUnderscore)
 * [dachinat](https://github.com/dachinat)
-* [multiple-creatures](https://github.com/multiple-creatures)
+* [shapeshifter-system](https://github.com/shapeshifter-system)
 * [watilde](https://github.com/watilde)
 * [daprice](https://github.com/daprice)
 * [da2x](https://github.com/da2x)
+* [codesections](https://github.com/codesections)
 * [dar5hak](https://github.com/dar5hak)
 * [kant](https://github.com/kant)
 * [maxolasersquad](https://github.com/maxolasersquad)
 * [singingwolfboy](https://github.com/singingwolfboy)
+* [caldwell](https://github.com/caldwell)
 * [davidcelis](https://github.com/davidcelis)
+* [divergentdave](https://github.com/divergentdave)
 * [davefp](https://github.com/davefp)
 * [yipdw](https://github.com/yipdw)
 * [debanshuk](https://github.com/debanshuk)
+* [mascali33](https://github.com/mascali33)
 * [DerekNonGeneric](https://github.com/DerekNonGeneric)
 * [dblandin](https://github.com/dblandin)
 * [Drew Gates](mailto:aranaur@users.noreply.github.com)
 * [dtschust](https://github.com/dtschust)
 * [Dryusdan](https://github.com/Dryusdan)
-* [eai04191](https://github.com/eai04191)
 * [d3vgru](https://github.com/d3vgru)
 * [Elizafox](https://github.com/Elizafox)
 * [enewhuis](https://github.com/enewhuis)
 * [ericblade](https://github.com/ericblade)
 * [mikoim](https://github.com/mikoim)
 * [espenronnevik](https://github.com/espenronnevik)
+* [Expenses](mailto:expenses@airmail.cc)
 * [fabianonline](https://github.com/fabianonline)
 * [Finariel](https://github.com/Finariel)
 * [siuying](https://github.com/siuying)
 * [zoc](https://github.com/zoc)
 * [fwenzel](https://github.com/fwenzel)
+* [gabrielrumiranda](https://github.com/gabrielrumiranda)
 * [GenbuHase](https://github.com/GenbuHase)
 * [nilsding](https://github.com/nilsding)
 * [hattori6789](https://github.com/hattori6789)
@@ -401,6 +431,7 @@ and provided thanks to the work of the following contributors:
 * [myfreeweb](https://github.com/myfreeweb)
 * [gfaivre](https://github.com/gfaivre)
 * [Fiaxhs](https://github.com/Fiaxhs)
+* [rasjonell](https://github.com/rasjonell)
 * [reedcourty](https://github.com/reedcourty)
 * [anneau](https://github.com/anneau)
 * [lanodan](https://github.com/lanodan)
@@ -421,46 +452,49 @@ and provided thanks to the work of the following contributors:
 * [jack-michaud](https://github.com/jack-michaud)
 * [Floppy](https://github.com/Floppy)
 * [loomchild](https://github.com/loomchild)
+* [jglauche](https://github.com/jglauche)
 * [jenkr55](https://github.com/jenkr55)
 * [hyenagirl64](https://github.com/hyenagirl64)
 * [press5](https://github.com/press5)
 * [TrollDecker](https://github.com/TrollDecker)
 * [jmontane](https://github.com/jmontane)
-* [jonathanklee](https://github.com/jonathanklee)
-* [jguerder](https://github.com/jguerder)
-* [Jehops](https://github.com/Jehops)
-* [joshuap](https://github.com/joshuap)
-* [Tiwy57](https://github.com/Tiwy57)
-* [xuv](https://github.com/xuv)
-* [Jnsll](https://github.com/Jnsll)
-* [j0k3r](https://github.com/j0k3r)
-* [KEINOS](https://github.com/KEINOS)
-* [futoase](https://github.com/futoase)
-* [pot8to](https://github.com/pot8to)
+* [Jonathan Klee](mailto:klee.jonathan@gmail.com)
+* [Jordan Guerder](mailto:jguerder@fr.pulseheberg.net)
+* [Joseph Mingrone](mailto:jehops@users.noreply.github.com)
+* [Joshua Wood](mailto:josh@joshuawood.net)
+* [Julien](mailto:tiwy57@users.noreply.github.com)
+* [Julien Deswaef](mailto:juego@requiem4tv.com)
+* [June Sallou](mailto:jnsll@users.noreply.github.com)
+* [Jérémy Benoist](mailto:j0k3r@users.noreply.github.com)
+* [KEINOS](mailto:github@keinos.com)
+* [Keiji Matsuzaki](mailto:futoase@gmail.com)
+* [Kevin Liu](mailto:kevin@potatofrom.space)
 * [Kit Redgrave](mailto:qwertyitis@gmail.com)
 * [Knut Erik](mailto:abjectio@users.noreply.github.com)
-* [mkody](https://github.com/mkody)
-* [k0ta0uchi](https://github.com/k0ta0uchi)
-* [KrzysiekJ](https://github.com/KrzysiekJ)
+* [Kota Ouchi](mailto:k0ta0uchi@gmail.com)
+* [Krzysztof Jurewicz](mailto:krzysztof.jurewicz@gmail.com)
 * [Leo Wzukw](mailto:leowzukw@users.noreply.github.com)
-* [Tak](https://github.com/Tak)
-* [cacheflow](https://github.com/cacheflow)
-* [ldidry](https://github.com/ldidry)
-* [jemus42](https://github.com/jemus42)
-* [lfuelling](https://github.com/lfuelling)
-* [Grabacr07](https://github.com/Grabacr07)
-* [mistermantas](https://github.com/mistermantas)
-* [MareenaKunjachan](https://github.com/MareenaKunjachan)
-* [mareklach](https://github.com/mareklach)
-* [wirehack7](https://github.com/wirehack7)
-* [martymcguire](https://github.com/martymcguire)
-* [marvinkopf](https://github.com/marvinkopf)
-* [otsune](https://github.com/otsune)
-* [mbugowski](https://github.com/mbugowski)
+* [Leonie](mailto:62470640+bubblineyuri@users.noreply.github.com)
+* [Levi Bard](mailto:taktaktaktaktaktaktaktaktaktak@gmail.com)
+* [Lex Alexander](mailto:l.alexander10@gmail.com)
+* [Lorenz Diener](mailto:lorenzd@gmail.com)
+* [Luc Didry](mailto:ldidry@users.noreply.github.com)
+* [Lukas Burk](mailto:jemus42@users.noreply.github.com)
+* [Manato Kameya](mailto:grabacr07+github@gmail.com)
+* [Mantas](mailto:mistermantas@users.noreply.github.com)
+* [Marcin Mikołajczak](mailto:me@mkljczk.pl)
+* [Mareena Kunjachan](mailto:mareenakunjachan@gmail.com)
+* [Marek Lach](mailto:marek.brohatwack.lach@gmail.com)
+* [Markus R](mailto:wirehack7@users.noreply.github.com)
+* [Marty McGuire](mailto:schmartissimo@gmail.com)
+* [Marvin Kopf](mailto:marvinkopf@posteo.de)
+* [Masafumi Otsune](mailto:info@otsune.com)
+* [Matej Ľach](mailto:matejlach@users.noreply.github.com)
+* [Mateusz Bugowski](mailto:23140767+mbugowski@users.noreply.github.com)
 * [Mathias B](mailto:10813340+mathias-b@users.noreply.github.com)
-* [madmath03](https://github.com/madmath03)
-* [matt-auckland](https://github.com/matt-auckland)
-* [webroo](https://github.com/webroo)
+* [Mathieu Brunot](mailto:mb.mathieu.brunot@gmail.com)
+* [Matt](mailto:matt-auckland@users.noreply.github.com)
+* [Matt Sweetman](mailto:webroo@gmail.com)
 * [Matthias Beyer](mailto:mail@beyermatthias.de)
 * [Matthias Jouan](mailto:matthias.jouan@gmail.com)
 * [Matthieu Paret](mailto:matthieuparet69@gmail.com)
@@ -512,10 +546,11 @@ and provided thanks to the work of the following contributors:
 * [S.H](mailto:gamelinks007@gmail.com)
 * [Sadiq Saif](mailto:staticsafe@users.noreply.github.com)
 * [Sam Hewitt](mailto:hewittsamuel@gmail.com)
-* [Sasha Sorokin](mailto:dafri.nochiterov8@gmail.com)
+* [Sara Aimée Smiseth](mailto:51710585+sarasmiseth@users.noreply.github.com)
 * [Satoshi KOJIMA](mailto:skoji@mac.com)
 * [ScienJus](mailto:i@scienjus.com)
 * [Scott Larkin](mailto:scott@codeclimate.com)
+* [Scott Sweeny](mailto:scott@ssweeny.net)
 * [Sebastian Hübner](mailto:imolein@users.noreply.github.com)
 * [Sebastian Morr](mailto:sebastian@morr.cc)
 * [Sergei Č](mailto:noiwex1911@gmail.com)
@@ -525,10 +560,12 @@ and provided thanks to the work of the following contributors:
 * [Shin Kojima](mailto:shin@kojima.org)
 * [Shouko Yu](mailto:imshouko@gmail.com)
 * [Sina Mashek](mailto:sina@mashek.xyz)
+* [Soft. Dev](mailto:24978+nileshkumar@users.noreply.github.com)
 * [Soshi Kato](mailto:mail@sossii.com)
 * [Spanky](mailto:2788886+spankyworks@users.noreply.github.com)
 * [StefOfficiel](mailto:pichard.stephane@free.fr)
 * [Steven Tappert](mailto:admin@dark-it.net)
+* [Stéphane Guillou](mailto:stephane.guillou@member.fsf.org)
 * [Svetlozar Todorov](mailto:svetlik@users.noreply.github.com)
 * [Sébastien Santoro](mailto:dereckson@espace-win.org)
 * [Tad Thorley](mailto:phaedryx@users.noreply.github.com)
@@ -536,7 +573,10 @@ and provided thanks to the work of the following contributors:
 * [Takayuki KUSANO](mailto:github@tkusano.jp)
 * [TakesxiSximada](mailto:takesxi.sximada@gmail.com)
 * [Tao Bror Bojlén](mailto:brortao@users.noreply.github.com)
+* [Taras Gogol](mailto:taras2358@gmail.com)
+* [Tdxdxoz](mailto:tdxdxoz@gmail.com)
 * [TheInventrix](mailto:theinventrix@users.noreply.github.com)
+* [TheMainOne](mailto:50847364+theevilskeleton@users.noreply.github.com)
 * [Thomas Alberola](mailto:thomas@needacoffee.fr)
 * [Toby Deshane](mailto:fortyseven@users.noreply.github.com)
 * [Toby Pinder](mailto:gigitrix@gmail.com)
@@ -563,6 +603,7 @@ and provided thanks to the work of the following contributors:
 * [Yann Klis](mailto:yann.klis@gmail.com)
 * [Yağızhan](mailto:35808275+yagizhan49@users.noreply.github.com)
 * [Yeechan Lu](mailto:wz.bluesnow@gmail.com)
+* [Your Name](mailto:lorenzd@gmail.com)
 * [Yusuke Abe](mailto:moonset20@gmail.com)
 * [Zachary Spector](mailto:logicaldash@gmail.com)
 * [ZiiX](mailto:ziix@users.noreply.github.com)
@@ -572,6 +613,7 @@ and provided thanks to the work of the following contributors:
 * [bsky](mailto:git@imbsky.net)
 * [caesarologia](mailto:lopesgemelli.1@gmail.com)
 * [cbayerlein](mailto:c.bayerlein@gmail.com)
+* [chr v1.x](mailto:chr@cybre.space)
 * [chrolis](mailto:chrolis@users.noreply.github.com)
 * [cormo](mailto:cormorant2+github@gmail.com)
 * [d0p1](mailto:dopi-sama@hush.com)
@@ -582,6 +624,7 @@ and provided thanks to the work of the following contributors:
 * [fusshi-](mailto:dikky1218@users.noreply.github.com)
 * [gentaro](mailto:gentaroooo@gmail.com)
 * [gol-cha](mailto:info@mevo.xyz)
+* [guigeekz](mailto:pattusg@gmail.com)
 * [hakoai](mailto:hk--76@qa2.so-net.ne.jp)
 * [haosbvnker](mailto:github@chaosbunker.com)
 * [ichi_i](mailto:51489410+ichi-i@users.noreply.github.com)
@@ -593,10 +636,11 @@ and provided thanks to the work of the following contributors:
 * [jooops](mailto:joops@autistici.org)
 * [jukper](mailto:jukkaperanto@gmail.com)
 * [jumoru](mailto:jumoru@mailbox.org)
+* [kaiyou](mailto:pierre@jaury.eu)
 * [karlyeurl](mailto:karl.yeurl@gmail.com)
 * [kedama](mailto:32974885+kedamadq@users.noreply.github.com)
-* [kodai](mailto:shirafuta.kodai@gmail.com)
 * [kuro5hin](mailto:rusty@kuro5hin.org)
+* [leo60228](mailto:leo@60228.dev)
 * [luzpaz](mailto:luzpaz@users.noreply.github.com)
 * [maxypy](mailto:maxime@mpigou.fr)
 * [mhe](mailto:mail@marcus-herrmann.com)
@@ -607,21 +651,25 @@ and provided thanks to the work of the following contributors:
 * [muan](mailto:muan@github.com)
 * [namelessGonbai](mailto:43787036+namelessgonbai@users.noreply.github.com)
 * [neetshin](mailto:neetshin@neetsh.in)
+* [noiob](mailto:8197071+noiob@users.noreply.github.com)
+* [notozeki](mailto:notozeki@users.noreply.github.com)
+* [ntl-purism](mailto:57806346+ntl-purism@users.noreply.github.com)
 * [nzws](mailto:git-yuzu@svk.jp)
 * [rch850](mailto:rich850@gmail.com)
 * [roikale](mailto:roikale@users.noreply.github.com)
 * [rysiekpl](mailto:rysiek@hackerspace.pl)
 * [saturday06](mailto:dyob@lunaport.net)
+* [scd31](mailto:57571338+scd31@users.noreply.github.com)
 * [scriptjunkie](mailto:scriptjunkie@scriptjunkie.us)
 * [seekr](mailto:mario.drs@gmail.com)
+* [sternenseemann](mailto:git@lukasepple.de)
 * [sundevour](mailto:31990469+sundevour@users.noreply.github.com)
 * [syui](mailto:syui@users.noreply.github.com)
 * [tackeyy](mailto:mailto.takita.yusuke@gmail.com)
-* [tateisu](mailto:tateisu@gmail.com)
+* [taicv](mailto:chuvantai@gmail.com)
 * [tmyt](mailto:shigure@refy.net)
 * [trevDev()](mailto:trev@trevdev.ca)
 * [tsia](mailto:github@tsia.de)
-* [umonaca](mailto:53662960+umonaca@users.noreply.github.com)
 * [utam0k](mailto:k0ma@utam0k.jp)
 * [vpzomtrrfrt](mailto:vpzomtrrfrt@gmail.com)
 * [walfie](mailto:walfington@gmail.com)
@@ -634,6 +682,7 @@ and provided thanks to the work of the following contributors:
 * [りんすき](mailto:6533808+rinsuki@users.noreply.github.com)
 * [ヨイツの賢狼ホロ | 3rd style](mailto:horo@yoitsu.moe)
 * [唐宗勛](mailto:tangzongxun@hotmail.com)
+* [夕日](mailto:xirikm@gmail.com)
 * [猫吸血鬼ディフリス / 猫ロキP](mailto:deflis@gmail.com)
 * [艮 鮟鱇](mailto:ushitora_anqou@yahoo.co.jp)
 * [西小倉宏信](mailto:nishiko@mindia.jp)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7d0110936..348d1cefc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,156 @@ Changelog
 
 All notable changes to this project will be documented in this file.
 
+## Unreleased
+### Added
+
+- Add `SMTP_SSL` environment variable ([OmmyZhang](https://github.com/tootsuite/mastodon/pull/14309))
+- Add hotkey for toggling content warning input in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13987))
+- **Add e-mail-based sign in challenge for users with disabled 2FA** ([Gargron](https://github.com/tootsuite/mastodon/pull/14013))
+  - If user tries signing in after:
+    - Being inactive for a while
+    - With a previously unknown IP
+    - Without 2FA being enabled
+  - Require to enter a token sent via e-mail before sigining in
+- Add `limit` param to RSS feeds ([noellabo](https://github.com/tootsuite/mastodon/pull/13743))
+- Add `visibility` param to share page ([noellabo](https://github.com/tootsuite/mastodon/pull/13023))
+- Add blurhash to link previews ([ThibG](https://github.com/tootsuite/mastodon/pull/13984), [ThibG](https://github.com/tootsuite/mastodon/pull/14143), [ThibG](https://github.com/tootsuite/mastodon/pull/13985), [Sasha-Sorokin](https://github.com/tootsuite/mastodon/pull/14267), [Sasha-Sorokin](https://github.com/tootsuite/mastodon/pull/14278), [ThibG](https://github.com/tootsuite/mastodon/pull/14126), [ThibG](https://github.com/tootsuite/mastodon/pull/14261), [ThibG](https://github.com/tootsuite/mastodon/pull/14260))
+  - In web UI, toots cannot be marked as sensitive unless there is media attached
+  - However, it's possible to do via API or ActivityPub
+  - Thumnails of link previews of such posts now use blurhash in web UI
+  - The Card entity in REST API has a new `blurhash` attribute
+- Add support for `summary` field for media description in ActivityPub ([ThibG](https://github.com/tootsuite/mastodon/pull/13763))
+- Add hints about incomplete remote content to web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/14031), [noellabo](https://github.com/tootsuite/mastodon/pull/14195))
+- **Add personal notes for accounts** ([ThibG](https://github.com/tootsuite/mastodon/pull/14148), [Gargron](https://github.com/tootsuite/mastodon/pull/14208), [Sasha-Sorokin](https://github.com/tootsuite/mastodon/pull/14251))
+  - To clarify, these are notes only you can see, to help you remember details
+  - Notes can be viewed and edited from profiles in web UI
+  - New REST API: `POST /api/v1/accounts/:id/note` with `comment` param
+  - The Relationship entity in REST API has a new `note` attribute
+- Add Helm chart ([dunn](https://github.com/tootsuite/mastodon/pull/14090), [dunn](https://github.com/tootsuite/mastodon/pull/14256), [dunn](https://github.com/tootsuite/mastodon/pull/14245))
+- **Add customizable thumbnails for audio and video attachments** ([Gargron](https://github.com/tootsuite/mastodon/pull/14145), [Gargron](https://github.com/tootsuite/mastodon/pull/14244), [Gargron](https://github.com/tootsuite/mastodon/pull/14273), [Gargron](https://github.com/tootsuite/mastodon/pull/14203), [ThibG](https://github.com/tootsuite/mastodon/pull/14255), [ThibG](https://github.com/tootsuite/mastodon/pull/14306))
+  - Metadata (album, artist, etc) is no longer stripped from audio files
+  - Album art is automatically extracted from audio files
+  - Thumbnail can be manually uploaded for both audio and video attachments
+  - Media upload APIs now support `thumbnail` param
+    - On `POST /api/v1/media` and `POST /api/v2/media`
+    - And on `PUT /api/v1/media/:id`
+  - ActivityPub representation of media attachments represents custom thumbnails with an `icon` attribute
+- **Add color extraction for thumbnails** ([Gargron](https://github.com/tootsuite/mastodon/pull/14209), [ThibG](https://github.com/tootsuite/mastodon/pull/14264))
+  - The `meta` attribute on the Media Attachment entity in REST API can now have a `colors` attribute which in turn contains three hex colors: `background`, `foreground`, and `accent`
+  - The background color is chosen from the most dominant color around the edges of the thumbnail
+  - The foreground and accent colors are chosen from the colors that are the most different from the background color using the CIEDE2000 algorithm
+  - The most satured color of the two is designated as the accent color
+  - The one with the highest W3C contrast is designated as the foreground color
+  - If there are not enough colors in the thumbnail, new ones are generated using a monochrome pattern
+- Add a visibility indicator to toots in web UI ([noellabo](https://github.com/tootsuite/mastodon/pull/14123), [highemerly](https://github.com/tootsuite/mastodon/pull/14292))
+- Add `tootctl email_domain_blocks` ([tateisu](https://github.com/tootsuite/mastodon/pull/13589), [Gargron](https://github.com/tootsuite/mastodon/pull/14147))
+- Add "Add new domain block" to header of federation page in admin UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13934))
+- Add ability to keep emoji picker open with ctrl+click in web UI ([bclindner](https://github.com/tootsuite/mastodon/pull/13896), [noellabo](https://github.com/tootsuite/mastodon/pull/14096))
+
+### Changed
+
+- Change `.env.production.sample` to be leaner and cleaner ([Gargron](https://github.com/tootsuite/mastodon/pull/14206))
+  - It was overloaded as de-facto documentation and getting quite crowded
+  - Defer to the actual documentation while still giving a minimal example
+- Change `tootctl search deploy` to work faster and display progress ([Gargron](https://github.com/tootsuite/mastodon/pull/14300))
+- Change User-Agent of link preview fetching service to include "Bot" ([Gargron](https://github.com/tootsuite/mastodon/pull/14248))
+  - Some websites may not render OpenGraph tags into HTML if that's not the case
+- Change behaviour to carry blocks over when someone migrates their followers ([ThibG](https://github.com/tootsuite/mastodon/pull/14144))
+- Change volume control and download buttons in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/14122))
+- **Change design of audio players in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/14095), [ThibG](https://github.com/tootsuite/mastodon/pull/14281), [Gargron](https://github.com/tootsuite/mastodon/pull/14282), [ThibG](https://github.com/tootsuite/mastodon/pull/14118), [Gargron](https://github.com/tootsuite/mastodon/pull/14199))
+- Change reply filter to never filter own toots in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14128))
+- Change boost button to no longer serve as visibility indicator in web UI ([noellabo](https://github.com/tootsuite/mastodon/pull/14132))
+- Change contrast of flash messages ([cchoi12](https://github.com/tootsuite/mastodon/pull/13892))
+- Change wording from "Hide media" to "Hide image/images" in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13834))
+- Change appearence of settings pages to be more consistent ([ariasuni](https://github.com/tootsuite/mastodon/pull/13938))
+- Change "Add media" tooltip to not include long list of formats in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13954))
+- Change how badly contrasting emoji are rendered in web UI ([leo60228](https://github.com/tootsuite/mastodon/pull/13773), [ThibG](https://github.com/tootsuite/mastodon/pull/13772), [mfmfuyu](https://github.com/tootsuite/mastodon/pull/14020), [ThibG](https://github.com/tootsuite/mastodon/pull/14015))
+- Change structure of unavailable content section on about page ([ariasuni](https://github.com/tootsuite/mastodon/pull/13930))
+- Change behaviour to accept ActivityPub activities relayed through group actor ([noellabo](https://github.com/tootsuite/mastodon/pull/14279))
+
+### Removed
+
+- Remove the terms "blacklist" and "whitelist" from UX ([Gargron](https://github.com/tootsuite/mastodon/pull/14149), [mayaeh](https://github.com/tootsuite/mastodon/pull/14192))
+  - Environment variables changed (old versions continue to work):
+    - `WHITELIST_MODE` → `LIMITED_FEDERATION_MODE`
+    - `EMAIL_DOMAIN_BLACKLIST` → `EMAIL_DOMAIN_DENYLIST`
+    - `EMAIL_DOMAIN_WHITELIST` → `EMAIL_DOMAIN_ALLOWLIST`
+  - CLI option changed:
+    - `tootctl domains purge --whitelist-mode` → `tootctl domains purge --limited-federation-mode`
+- Remove some unnecessary database indices ([lfuelling](https://github.com/tootsuite/mastodon/pull/13695), [noellabo](https://github.com/tootsuite/mastodon/pull/14259))
+- Remove unnecessary Node.js version upper bound ([ykzts](https://github.com/tootsuite/mastodon/pull/14139))
+
+### Fixed
+
+- Fix large shortened numbers (like 1.2K) using incorrect pluralization ([Sasha-Sorokin](https://github.com/tootsuite/mastodon/pull/14061))
+- Fix streaming server trying to use empty password to connect to Redis when `REDIS_PASSWORD` is given but blank ([ThibG](https://github.com/tootsuite/mastodon/pull/14135))
+- Fix being unable to unboost posts when blocked by their author ([ThibG](https://github.com/tootsuite/mastodon/pull/14308))
+- Fix account domain block not properly unfollowing accounts from domain ([Gargron](https://github.com/tootsuite/mastodon/pull/14304))
+- Fix removing a domain allow wiping known accounts in open federation mode ([ThibG](https://github.com/tootsuite/mastodon/pull/14298))
+- Fix blocks and mutes pagination in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14275))
+- Fix new posts pushing down origin of opened dropdown in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14271))
+- Fix timeline markers not being saved sometimes ([ThibG](https://github.com/tootsuite/mastodon/pull/13887), [ThibG](https://github.com/tootsuite/mastodon/pull/13889), [ThibG](https://github.com/tootsuite/mastodon/pull/14155))
+- Fix CSV uploads being rejected ([noellabo](https://github.com/tootsuite/mastodon/pull/13835))
+- Fix incompatibility with ElasticSearch 7.x ([noellabo](https://github.com/tootsuite/mastodon/pull/13828))
+- Fix being able to search posts where you're in the target audience but not actively mentioned ([noellabo](https://github.com/tootsuite/mastodon/pull/13829))
+- Fix non-local posts appearing on local-only hashtag timelines in web UI ([noellabo](https://github.com/tootsuite/mastodon/pull/13827))
+- Fix `tootctl media remove-orphans` choking on unknown files in storage ([Gargron](https://github.com/tootsuite/mastodon/pull/13765))
+- Fix `tootctl upgrade storage-schema` misbehaving ([Gargron](https://github.com/tootsuite/mastodon/pull/13761), [angristan](https://github.com/tootsuite/mastodon/pull/13768))
+  - Fix it marking records as upgraded even though no files were moved
+  - Fix it not working with S3 storage
+  - Fix it not working with custom emojis
+- Fix GIF reader raising incorrect exceptions ([ThibG](https://github.com/tootsuite/mastodon/pull/13760))
+- Fix hashtag search performing account search as well ([ThibG](https://github.com/tootsuite/mastodon/pull/13758))
+- Fix Webfinger returning wrong status code on malformed or missing param ([ThibG](https://github.com/tootsuite/mastodon/pull/13759))
+- Fix `rake mastodon:setup` error when some environment variables are set ([ThibG](https://github.com/tootsuite/mastodon/pull/13928))
+- Fix admin page crashing when trying to block an invalid domain name in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13884))
+- Fix unsent toot confirmation dialog not popping up in single column mode in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13888))
+- Fix performance of follow import ([noellabo](https://github.com/tootsuite/mastodon/pull/13836))
+  - Reduce timeout of Webfinger requests to that of other requests
+  - Use circuit breakers to stop hitting unresponsive servers
+  - Avoid hitting servers that are already known to be generally unavailable
+- Fix filters ignoring media descriptions ([BenLubar](https://github.com/tootsuite/mastodon/pull/13837))
+- Fix soem actions on custom emojis leading to cryptic errors in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13951))
+- Fix ActivityPub serialization of replies when some of them are URIs ([ThibG](https://github.com/tootsuite/mastodon/pull/13957))
+- Fix `rake mastodon:setup` choking on environment variables containing `%` ([ThibG](https://github.com/tootsuite/mastodon/pull/13940))
+- Fix account redirect confirmation message talking about moved followers ([ThibG](https://github.com/tootsuite/mastodon/pull/13950))
+- Fix avatars having the wrong size on public detailed status pages ([ThibG](https://github.com/tootsuite/mastodon/pull/14140))
+- Fix various issues around OpenGraph representation of media ([Gargron](https://github.com/tootsuite/mastodon/pull/14133))
+  - Pages containing audio no longer say "Attached: 1 image" in description
+  - Audio attachments now represented as OpenGraph `og:audio`
+  - The `twitter:player` page now uses Mastodon's proper audio/video player
+  - Audio/video buffered bars now display correctly in audio/video player
+  - Volume and progress bars now respond to movement/move smoother
+- Fix audio/video/images/cards not reacting to window resizes in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/14130))
+- Fix very wide media attachments resulting in too thin a thumbnail in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14127))
+- Fix crash when merging posts into home feed after following someone ([ThibG](https://github.com/tootsuite/mastodon/pull/14129))
+- Fix unique username constraint for local users not being enforced in database ([ThibG](https://github.com/tootsuite/mastodon/pull/14099))
+- Fix unnecessary gap under video modal in web UI ([mfmfuyu](https://github.com/tootsuite/mastodon/pull/14098))
+- Fix 2FA and sign in token pages not respecting user locale ([mfmfuyu](https://github.com/tootsuite/mastodon/pull/14087))
+- Fix unapproved users being able to view profiles when in limited-federation mode *and* requiring approval for sign-ups ([ThibG](https://github.com/tootsuite/mastodon/pull/14093))
+- Fix initial audio volume not corresponding to what's displayed in audio player in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14057))
+- Fix timelines sometimes jumping when closing modals in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14019))
+- Fix memory usage of downloading remote files ([Gargron](https://github.com/tootsuite/mastodon/pull/14184), [Gargron](https://github.com/tootsuite/mastodon/pull/14181))
+  - Don't read entire file (up to 40 MB) into memory
+  - Read and write it to temp file in small chunks
+- Fix inconsistent account header padding in web UI ([trwnh](https://github.com/tootsuite/mastodon/pull/14179))
+- Fix Thai being skipped from language detection ([Sasha-Sorokin](https://github.com/tootsuite/mastodon/pull/13989))
+  - Since Thai has its own alphabet, it can be detected more reliably
+- Fix broken hashtag column options styling in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14247))
+- Fix pointer cursor being shown on toots that are not clickable in web UI ([arielrodrigues](https://github.com/tootsuite/mastodon/pull/14185))
+- Fix lock icon not being shown when locking account in profile settings ([ThibG](https://github.com/tootsuite/mastodon/pull/14190))
+- Fix domain blocks doing work the wrong way around ([ThibG](https://github.com/tootsuite/mastodon/pull/13424))
+  - Instead of suspending accounts one by one, mark all as suspended first (quick)
+  - Only then proceed to start removing their data (slow)
+  - Clear out media attachments in a separate worker (slow)
+
+## [v3.1.5] - 2020-07-07
+### Security
+
+- Fix media attachment enumeration ([ThibG](https://github.com/tootsuite/mastodon/pull/14254))
+- Change rate limits for various paths ([Gargron](https://github.com/tootsuite/mastodon/pull/14253))
+- Fix other sessions not being logged out on password change ([Gargron](https://github.com/tootsuite/mastodon/pull/14252))
+
 ## [v3.1.4] - 2020-05-14
 ### Added
 
diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb
index d4b05fca9..47cb856ea 100644
--- a/app/chewy/statuses_index.rb
+++ b/app/chewy/statuses_index.rb
@@ -31,7 +31,7 @@ class StatusesIndex < Chewy::Index
     },
   }
 
-  define_type ::Status.unscoped.kept.without_reblogs.includes(:media_attachments), delete_if: ->(status) { status.searchable_by.empty? } do
+  define_type ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preloadable_poll) do
     crutch :mentions do |collection|
       data = ::Mention.where(status_id: collection.map(&:id)).where(account: Account.local, silent: false).pluck(:status_id, :account_id)
       data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
diff --git a/app/controllers/api/v1/statuses/reblogs_controller.rb b/app/controllers/api/v1/statuses/reblogs_controller.rb
index 7fa774a4d..1be15a5a4 100644
--- a/app/controllers/api/v1/statuses/reblogs_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogs_controller.rb
@@ -5,7 +5,7 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
 
   before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
   before_action :require_user!
-  before_action :set_reblog
+  before_action :set_reblog, only: [:create]
 
   override_rate_limit_headers :create, family: :statuses
 
@@ -16,15 +16,21 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
   end
 
   def destroy
-    @status = current_account.statuses.find_by(reblog_of_id: @reblog.id)
+    @status = current_account.statuses.find_by(reblog_of_id: params[:status_id])
 
     if @status
       authorize @status, :unreblog?
       @status.discard
       RemovalWorker.perform_async(@status.id)
+      @reblog = @status.reblog
+    else
+      @reblog = Status.find(params[:status_id])
+      authorize @reblog, :show?
     end
 
     render json: @reblog, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, reblogs_map: { @reblog.id => false })
+  rescue Mastodon::NotPermittedError
+    not_found
   end
 
   private
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index c54f6643a..441833e85 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -48,6 +48,7 @@ class Auth::SessionsController < Devise::SessionsController
       user   = User.authenticate_with_ldap(user_params) if Devise.ldap_authentication
       user ||= User.authenticate_with_pam(user_params) if Devise.pam_authentication
       user ||= User.find_for_authentication(email: user_params[:email])
+      user
     end
   end
 
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index e46c0532c..69db89eb3 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -28,7 +28,7 @@ class TagsController < ApplicationController
         expires_in 0, public: true
 
         limit     = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE
-        @statuses = HashtagQueryService.new.call(@tag, filter_params, nil, @local).limit(PAGE_SIZE)
+        @statuses = HashtagQueryService.new.call(@tag, filter_params, nil, @local).limit(limit)
         @statuses = cache_collection(@statuses, Status)
 
         render xml: RSS::TagSerializer.render(@tag, @statuses)
diff --git a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
index b88f23aa4..781bd4e03 100644
--- a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
+++ b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
@@ -61,73 +61,81 @@ export default class MediaItem extends ImmutablePureComponent {
     const width  = `${Math.floor((displayWidth - 4) / 3) - 4}px`;
     const height = width;
     const status = attachment.get('status');
-    const title = status.get('spoiler_text') || attachment.get('description');
+    const title  = status.get('spoiler_text') || attachment.get('description');
 
-    let thumbnail = '';
+    let thumbnail, label, icon, content;
 
-    if (attachment.get('type') === 'unknown') {
-      // Skip
-    } else if (attachment.get('type') === 'audio') {
-      thumbnail = (
+    if (!visible) {
+      icon = (
         <span className='account-gallery__item__icons'>
-          <Icon id='music' />
+          <Icon id='eye-slash' />
         </span>
       );
-    } else if (attachment.get('type') === 'image') {
-      const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
-      const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
-      const x      = ((focusX /  2) + .5) * 100;
-      const y      = ((focusY / -2) + .5) * 100;
-
-      thumbnail = (
-        <img
-          src={attachment.get('preview_url')}
-          alt={attachment.get('description')}
-          title={attachment.get('description')}
-          style={{ objectPosition: `${x}% ${y}%` }}
-          onLoad={this.handleImageLoad}
-        />
-      );
-    } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) {
-      const autoPlay = !isIOS() && autoPlayGif;
-      const label    = attachment.get('type') === 'video' ? <Icon id='play' /> : 'GIF';
-
-      thumbnail = (
-        <div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}>
+    } else {
+      if (['audio', 'video'].includes(attachment.get('type'))) {
+        content = (
+          <img
+            src={attachment.get('preview_url') || attachment.getIn(['account', 'avatar_static'])}
+            alt={attachment.get('description')}
+            onLoad={this.handleImageLoad}
+          />
+        );
+
+        if (attachment.get('type') === 'audio') {
+          label = <Icon id='music' />;
+        } else {
+          label = <Icon id='play' />;
+        }
+      } else if (attachment.get('type') === 'image') {
+        const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
+        const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
+        const x      = ((focusX /  2) + .5) * 100;
+        const y      = ((focusY / -2) + .5) * 100;
+
+        content = (
+          <img
+            src={attachment.get('preview_url')}
+            alt={attachment.get('description')}
+            style={{ objectPosition: `${x}% ${y}%` }}
+            onLoad={this.handleImageLoad}
+          />
+        );
+      } else if (attachment.get('type') === 'gifv') {
+        content = (
           <video
             className='media-gallery__item-gifv-thumbnail'
             aria-label={attachment.get('description')}
-            title={attachment.get('description')}
             role='application'
             src={attachment.get('url')}
             onMouseEnter={this.handleMouseEnter}
             onMouseLeave={this.handleMouseLeave}
-            autoPlay={autoPlay}
+            autoPlay={!isIOS() && autoPlayGif}
             loop
             muted
           />
+        );
+
+        label = 'GIF';
+      }
+
+      thumbnail = (
+        <div className='media-gallery__gifv'>
+          {content}
 
           <span className='media-gallery__gifv__label'>{label}</span>
         </div>
       );
     }
 
-    const icon = (
-      <span className='account-gallery__item__icons'>
-        <Icon id='eye-slash' />
-      </span>
-    );
-
     return (
       <div className='account-gallery__item' style={{ width, height }}>
         <a className='media-gallery__item-thumbnail' href={status.get('url')} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'>
           <Blurhash
             hash={attachment.get('blurhash')}
-            className={classNames('media-gallery__preview', {
-              'media-gallery__preview--hidden': visible && loaded,
-            })}
+            className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })}
             dummy={!useBlurhash}
           />
+
           {visible ? thumbnail : icon}
         </a>
       </div>
diff --git a/app/javascript/flavours/glitch/features/account_gallery/index.js b/app/javascript/flavours/glitch/features/account_gallery/index.js
index f5fe6c930..040741c2a 100644
--- a/app/javascript/flavours/glitch/features/account_gallery/index.js
+++ b/app/javascript/flavours/glitch/features/account_gallery/index.js
@@ -113,9 +113,9 @@ class AccountGallery extends ImmutablePureComponent {
 
   handleOpenMedia = attachment => {
     if (attachment.get('type') === 'video') {
-      this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') }));
+      this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status'), options: { autoPlay: true } }));
     } else if (attachment.get('type') === 'audio') {
-      this.props.dispatch(openModal('AUDIO', { media: attachment, status: attachment.get('status') }));
+      this.props.dispatch(openModal('AUDIO', { media: attachment, status: attachment.get('status'), options: { autoPlay: true } }));
     } else {
       const media = attachment.getIn(['status', 'media_attachments']);
       const index = media.findIndex(x => x.get('id') === attachment.get('id'));
diff --git a/app/javascript/flavours/glitch/features/audio/index.js b/app/javascript/flavours/glitch/features/audio/index.js
index 120a5ce1a..4e85e3c58 100644
--- a/app/javascript/flavours/glitch/features/audio/index.js
+++ b/app/javascript/flavours/glitch/features/audio/index.js
@@ -37,6 +37,7 @@ class Audio extends React.PureComponent {
     backgroundColor: PropTypes.string,
     foregroundColor: PropTypes.string,
     accentColor: PropTypes.string,
+    autoPlay: PropTypes.bool,
   };
 
   state = {
@@ -244,6 +245,14 @@ class Audio extends React.PureComponent {
     this.setState({ hovered: false });
   }
 
+  handleLoadedData = () => {
+    const { autoPlay } = this.props;
+
+    if (autoPlay) {
+      this.audio.play();
+    }
+  }
+
   _initAudioContext () {
     const context  = new AudioContext();
     const source   = context.createMediaElementSource(this.audio);
@@ -274,6 +283,8 @@ class Audio extends React.PureComponent {
 
   _renderCanvas () {
     requestAnimationFrame(() => {
+      if (!this.audio) return;
+
       this.handleTimeUpdate();
       this._clear();
       this._draw();
@@ -321,7 +332,7 @@ class Audio extends React.PureComponent {
   }
 
   render () {
-    const { src, intl, alt, editable } = this.props;
+    const { src, intl, alt, editable, autoPlay } = this.props;
     const { paused, muted, volume, currentTime, duration, buffer, dragging } = this.state;
     const progress = (currentTime / duration) * 100;
 
@@ -330,10 +341,11 @@ class Audio extends React.PureComponent {
         <audio
           src={src}
           ref={this.setAudioRef}
-          preload='none'
+          preload={autoPlay ? 'auto' : 'none'}
           onPlay={this.handlePlay}
           onPause={this.handlePause}
           onProgress={this.handleProgress}
+          onLoadedData={this.handleLoadedData}
           crossOrigin='anonymous'
         />
 
diff --git a/app/javascript/flavours/glitch/features/ui/components/audio_modal.js b/app/javascript/flavours/glitch/features/ui/components/audio_modal.js
index f0c3b3bcc..f9d4bb2f3 100644
--- a/app/javascript/flavours/glitch/features/ui/components/audio_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/audio_modal.js
@@ -2,16 +2,26 @@ import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import Audio from 'flavours/glitch/features/audio';
+import { connect } from 'react-redux';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { FormattedMessage } from 'react-intl';
 import classNames from 'classnames';
 import Icon from 'flavours/glitch/components/icon';
 
-export default class AudioModal extends ImmutablePureComponent {
+const mapStateToProps = (state, { status }) => ({
+  account: state.getIn(['accounts', status.get('account')]),
+});
+
+export default @connect(mapStateToProps)
+class AudioModal extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
     status: ImmutablePropTypes.map,
+    options: PropTypes.shape({
+      autoPlay: PropTypes.bool,
+    }),
+    account: ImmutablePropTypes.map,
     onClose: PropTypes.func.isRequired,
   };
 
@@ -27,7 +37,8 @@ export default class AudioModal extends ImmutablePureComponent {
   }
 
   render () {
-    const { media, status } = this.props;
+    const { media, status, account } = this.props;
+    const options = this.props.options || {};
 
     return (
       <div className='modal-root__modal audio-modal'>
@@ -37,10 +48,11 @@ export default class AudioModal extends ImmutablePureComponent {
             alt={media.get('description')}
             duration={media.getIn(['meta', 'original', 'duration'], 0)}
             height={150}
-            poster={media.get('preview_url') || status.getIn(['account', 'avatar_static'])}
+            poster={media.get('preview_url') || account.get('avatar_static')}
             backgroundColor={media.getIn(['meta', 'colors', 'background'])}
             foregroundColor={media.getIn(['meta', 'colors', 'foreground'])}
             accentColor={media.getIn(['meta', 'colors', 'accent'])}
+            autoPlay={options.autoPlay}
           />
         </div>
 
diff --git a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
index cd2929fdb..8092e862f 100644
--- a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
@@ -10,10 +10,15 @@ import DisplayName from 'flavours/glitch/components/display_name';
 import AttachmentList from 'flavours/glitch/components/attachment_list';
 import Icon from 'flavours/glitch/components/icon';
 import ImmutablePureComponent from 'react-immutable-pure-component';
+import classNames from 'classnames';
 
 const messages = defineMessages({
   cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
   reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
+  public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
+  unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
+  private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
+  direct_short: { id: 'privacy.direct.short', defaultMessage: 'Direct' },
 });
 
 export default @injectIntl
@@ -58,14 +63,24 @@ class BoostModal extends ImmutablePureComponent {
     const { status, missingMediaDescription, intl } = this.props;
     const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog;
 
+    const visibilityIconInfo = {
+      'public': { icon: 'globe', text: intl.formatMessage(messages.public_short) },
+      'unlisted': { icon: 'unlock', text: intl.formatMessage(messages.unlisted_short) },
+      'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
+      'direct': { icon: 'envelope', text: intl.formatMessage(messages.direct_short) },
+    };
+
+    const visibilityIcon = visibilityIconInfo[status.get('visibility')];
+
     return (
       <div className='modal-root__modal boost-modal'>
         <div className='boost-modal__container'>
-          <div className='status light'>
+          <div className={classNames('status', `status-${status.get('visibility')}`, 'light')}>
             <div className='boost-modal__status-header'>
               <div className='boost-modal__status-time'>
                 <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
               </div>
+              <span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span>
 
               <a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
                 <div className='status__avatar'>
diff --git a/app/javascript/flavours/glitch/features/video/index.js b/app/javascript/flavours/glitch/features/video/index.js
index 976cdefc0..cc60a0d2e 100644
--- a/app/javascript/flavours/glitch/features/video/index.js
+++ b/app/javascript/flavours/glitch/features/video/index.js
@@ -195,6 +195,8 @@ class Video extends React.PureComponent {
 
   _updateTime () {
     requestAnimationFrame(() => {
+      if (!this.video) return;
+
       this.handleTimeUpdate();
 
       if (!this.state.paused) {
diff --git a/app/javascript/flavours/glitch/selectors/index.js b/app/javascript/flavours/glitch/selectors/index.js
index 4a3303c36..bb9180d12 100644
--- a/app/javascript/flavours/glitch/selectors/index.js
+++ b/app/javascript/flavours/glitch/selectors/index.js
@@ -183,12 +183,13 @@ export const makeGetNotification = () => {
 export const getAccountGallery = createSelector([
   (state, id) => state.getIn(['timelines', `account:${id}:media`, 'items'], ImmutableList()),
   state       => state.get('statuses'),
-], (statusIds, statuses) => {
+  (state, id) => state.getIn(['accounts', id]),
+], (statusIds, statuses, account) => {
   let medias = ImmutableList();
 
   statusIds.forEach(statusId => {
     const status = statuses.get(statusId);
-    medias = medias.concat(status.get('media_attachments').map(media => media.set('status', status)));
+    medias = medias.concat(status.get('media_attachments').map(media => media.set('status', status).set('account', account)));
   });
 
   return medias;
diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss
index 4310f620a..d0be730ac 100644
--- a/app/javascript/flavours/glitch/styles/components/modal.scss
+++ b/app/javascript/flavours/glitch/styles/components/modal.scss
@@ -425,6 +425,14 @@
     padding: initial;
   }
 
+  .status__visibility-icon {
+    color: $dark-text-color;
+    float: right;
+    font-size: 14px;
+    margin-left: 4px;
+    margin-right: 4px;
+  }
+
   .status__display-name {
     display: flex;
   }
diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js
index 9eb4ed0d3..c9a7af7f7 100644
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.js
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js
@@ -61,78 +61,82 @@ export default class MediaItem extends ImmutablePureComponent {
     const width  = `${Math.floor((displayWidth - 4) / 3) - 4}px`;
     const height = width;
     const status = attachment.get('status');
-    const title = status.get('spoiler_text') || attachment.get('description');
+    const title  = status.get('spoiler_text') || attachment.get('description');
 
-    let thumbnail = '';
-    let icon;
+    let thumbnail, label, icon, content;
 
-    if (attachment.get('type') === 'unknown') {
-      // Skip
-    } else if (attachment.get('type') === 'audio') {
-      thumbnail = (
+    if (!visible) {
+      icon = (
         <span className='account-gallery__item__icons'>
-          <Icon id='music' />
+          <Icon id='eye-slash' />
         </span>
       );
-    } else if (attachment.get('type') === 'image') {
-      const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
-      const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
-      const x      = ((focusX /  2) + .5) * 100;
-      const y      = ((focusY / -2) + .5) * 100;
-
-      thumbnail = (
-        <img
-          src={attachment.get('preview_url')}
-          alt={attachment.get('description')}
-          title={attachment.get('description')}
-          style={{ objectPosition: `${x}% ${y}%` }}
-          onLoad={this.handleImageLoad}
-        />
-      );
-    } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) {
-      const autoPlay = !isIOS() && autoPlayGif;
-      const label    = attachment.get('type') === 'video' ? <Icon id='play' /> : 'GIF';
-
-      thumbnail = (
-        <div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}>
+    } else {
+      if (['audio', 'video'].includes(attachment.get('type'))) {
+        content = (
+          <img
+            src={attachment.get('preview_url') || attachment.getIn(['account', 'avatar_static'])}
+            alt={attachment.get('description')}
+            onLoad={this.handleImageLoad}
+          />
+        );
+
+        if (attachment.get('type') === 'audio') {
+          label = <Icon id='music' />;
+        } else {
+          label = <Icon id='play' />;
+        }
+      } else if (attachment.get('type') === 'image') {
+        const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
+        const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
+        const x      = ((focusX /  2) + .5) * 100;
+        const y      = ((focusY / -2) + .5) * 100;
+
+        content = (
+          <img
+            src={attachment.get('preview_url')}
+            alt={attachment.get('description')}
+            style={{ objectPosition: `${x}% ${y}%` }}
+            onLoad={this.handleImageLoad}
+          />
+        );
+      } else if (attachment.get('type') === 'gifv') {
+        content = (
           <video
             className='media-gallery__item-gifv-thumbnail'
             aria-label={attachment.get('description')}
-            title={attachment.get('description')}
             role='application'
             src={attachment.get('url')}
             onMouseEnter={this.handleMouseEnter}
             onMouseLeave={this.handleMouseLeave}
-            autoPlay={autoPlay}
+            autoPlay={!isIOS() && autoPlayGif}
             loop
             muted
           />
+        );
+
+        label = 'GIF';
+      }
+
+      thumbnail = (
+        <div className='media-gallery__gifv'>
+          {content}
 
           <span className='media-gallery__gifv__label'>{label}</span>
         </div>
       );
     }
 
-    if (!visible) {
-      icon = (
-        <span className='account-gallery__item__icons'>
-          <Icon id='eye-slash' />
-        </span>
-      );
-    }
-
     return (
       <div className='account-gallery__item' style={{ width, height }}>
         <a className='media-gallery__item-thumbnail' href={status.get('url')} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'>
           <Blurhash
             hash={attachment.get('blurhash')}
-            className={classNames('media-gallery__preview', {
-              'media-gallery__preview--hidden': visible && loaded,
-            })}
+            className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })}
             dummy={!useBlurhash}
           />
-          {visible && thumbnail}
-          {!visible && icon}
+
+          {visible ? thumbnail : icon}
         </a>
       </div>
     );
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index de481075c..fc5aead48 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -101,9 +101,9 @@ class AccountGallery extends ImmutablePureComponent {
 
   handleOpenMedia = attachment => {
     if (attachment.get('type') === 'video') {
-      this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') }));
+      this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status'), options: { autoPlay: true } }));
     } else if (attachment.get('type') === 'audio') {
-      this.props.dispatch(openModal('AUDIO', { media: attachment, status: attachment.get('status') }));
+      this.props.dispatch(openModal('AUDIO', { media: attachment, status: attachment.get('status'), options: { autoPlay: true } }));
     } else {
       const media = attachment.getIn(['status', 'media_attachments']);
       const index = media.findIndex(x => x.get('id') === attachment.get('id'));
diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js
index a49489257..1ab1c3117 100644
--- a/app/javascript/mastodon/features/audio/index.js
+++ b/app/javascript/mastodon/features/audio/index.js
@@ -37,6 +37,7 @@ class Audio extends React.PureComponent {
     backgroundColor: PropTypes.string,
     foregroundColor: PropTypes.string,
     accentColor: PropTypes.string,
+    autoPlay: PropTypes.bool,
   };
 
   state = {
@@ -259,6 +260,14 @@ class Audio extends React.PureComponent {
     this.setState({ hovered: false });
   }
 
+  handleLoadedData = () => {
+    const { autoPlay } = this.props;
+
+    if (autoPlay) {
+      this.audio.play();
+    }
+  }
+
   _initAudioContext () {
     const context  = new AudioContext();
     const source   = context.createMediaElementSource(this.audio);
@@ -289,6 +298,8 @@ class Audio extends React.PureComponent {
 
   _renderCanvas () {
     requestAnimationFrame(() => {
+      if (!this.audio) return;
+
       this.handleTimeUpdate();
       this._clear();
       this._draw();
@@ -336,7 +347,7 @@ class Audio extends React.PureComponent {
   }
 
   render () {
-    const { src, intl, alt, editable } = this.props;
+    const { src, intl, alt, editable, autoPlay } = this.props;
     const { paused, muted, volume, currentTime, duration, buffer, dragging } = this.state;
     const progress = (currentTime / duration) * 100;
 
@@ -345,10 +356,11 @@ class Audio extends React.PureComponent {
         <audio
           src={src}
           ref={this.setAudioRef}
-          preload='none'
+          preload={autoPlay ? 'auto' : 'none'}
           onPlay={this.handlePlay}
           onPause={this.handlePause}
           onProgress={this.handleProgress}
+          onLoadedData={this.handleLoadedData}
           crossOrigin='anonymous'
         />
 
diff --git a/app/javascript/mastodon/features/ui/components/audio_modal.js b/app/javascript/mastodon/features/ui/components/audio_modal.js
index dc033434e..a80776b22 100644
--- a/app/javascript/mastodon/features/ui/components/audio_modal.js
+++ b/app/javascript/mastodon/features/ui/components/audio_modal.js
@@ -2,17 +2,27 @@ import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import Audio from 'mastodon/features/audio';
+import { connect } from 'react-redux';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { FormattedMessage } from 'react-intl';
 import { previewState } from './video_modal';
 import classNames from 'classnames';
 import Icon from 'mastodon/components/icon';
 
-export default class AudioModal extends ImmutablePureComponent {
+const mapStateToProps = (state, { status }) => ({
+  account: state.getIn(['accounts', status.get('account')]),
+});
+
+export default @connect(mapStateToProps)
+class AudioModal extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
     status: ImmutablePropTypes.map,
+    options: PropTypes.shape({
+      autoPlay: PropTypes.bool,
+    }),
+    account: ImmutablePropTypes.map,
     onClose: PropTypes.func.isRequired,
   };
 
@@ -50,7 +60,8 @@ export default class AudioModal extends ImmutablePureComponent {
   }
 
   render () {
-    const { media, status } = this.props;
+    const { media, status, account } = this.props;
+    const options = this.props.options || {};
 
     return (
       <div className='modal-root__modal audio-modal'>
@@ -60,10 +71,11 @@ export default class AudioModal extends ImmutablePureComponent {
             alt={media.get('description')}
             duration={media.getIn(['meta', 'original', 'duration'], 0)}
             height={150}
-            poster={media.get('preview_url') || status.getIn(['account', 'avatar_static'])}
+            poster={media.get('preview_url') || account.get('avatar_static')}
             backgroundColor={media.getIn(['meta', 'colors', 'background'])}
             foregroundColor={media.getIn(['meta', 'colors', 'foreground'])}
             accentColor={media.getIn(['meta', 'colors', 'accent'])}
+            autoPlay={options.autoPlay}
           />
         </div>
 
diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js
index 0e79005f0..00c0481f3 100644
--- a/app/javascript/mastodon/features/ui/components/boost_modal.js
+++ b/app/javascript/mastodon/features/ui/components/boost_modal.js
@@ -10,10 +10,15 @@ import DisplayName from '../../../components/display_name';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import Icon from 'mastodon/components/icon';
 import AttachmentList from 'mastodon/components/attachment_list';
+import classNames from 'classnames';
 
 const messages = defineMessages({
   cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
   reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
+  public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
+  unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
+  private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
+  direct_short: { id: 'privacy.direct.short', defaultMessage: 'Direct' },
 });
 
 export default @injectIntl
@@ -55,14 +60,24 @@ class BoostModal extends ImmutablePureComponent {
     const { status, intl } = this.props;
     const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog;
 
+    const visibilityIconInfo = {
+      'public': { icon: 'globe', text: intl.formatMessage(messages.public_short) },
+      'unlisted': { icon: 'unlock', text: intl.formatMessage(messages.unlisted_short) },
+      'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
+      'direct': { icon: 'envelope', text: intl.formatMessage(messages.direct_short) },
+    };
+
+    const visibilityIcon = visibilityIconInfo[status.get('visibility')];
+
     return (
       <div className='modal-root__modal boost-modal'>
         <div className='boost-modal__container'>
-          <div className='status light'>
+          <div className={classNames('status', `status-${status.get('visibility')}`, 'light')}>
             <div className='boost-modal__status-header'>
               <div className='boost-modal__status-time'>
                 <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
               </div>
+              <span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span>
 
               <a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
                 <div className='status__avatar'>
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index fb12567f0..99dcdca22 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -182,6 +182,8 @@ class Video extends React.PureComponent {
 
   _updateTime () {
     requestAnimationFrame(() => {
+      if (!this.video) return;
+
       this.handleTimeUpdate();
 
       if (!this.state.paused) {
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 4decd3f74..a0b540432 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -1,13 +1,12 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "ملاحظة",
   "account.add_or_remove_from_list": "أضفه أو أزله من القائمة",
   "account.badges.bot": "روبوت",
   "account.badges.group": "فريق",
   "account.block": "حظر @{name}",
   "account.block_domain": "إخفاء كل شيء قادم من اسم النطاق {domain}",
   "account.blocked": "محظور",
-  "account.browse_more_on_origin_server": "Browse more on the original profile",
+  "account.browse_more_on_origin_server": "تصفح المزيد على الملف التعريفي الأصلي",
   "account.cancel_follow_request": "إلغاء طلب المتابَعة",
   "account.direct": "رسالة خاصة إلى @{name}",
   "account.domain_blocked": "النطاق مخفي",
@@ -16,7 +15,8 @@
   "account.follow": "تابِع",
   "account.followers": "مُتابِعون",
   "account.followers.empty": "لا أحد يتبع هذا الحساب بعد.",
-  "account.follows": "يتابع",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "هذا الحساب لا يتبع أحدًا بعد.",
   "account.follows_you": "يتابعك",
   "account.hide_reblogs": "إخفاء ترقيات @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "في انتظار الموافقة. اضْغَطْ/ي لإلغاء طلب المتابعة",
   "account.share": "شارك ملف تعريف @{name}",
   "account.show_reblogs": "اعرض ترقيات @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "إلغاء الحظر عن @{name}",
   "account.unblock_domain": "فك الخْفى عن {domain}",
   "account.unendorse": "أزل ترويجه مِن الملف التعريفي",
   "account.unfollow": "إلغاء المتابعة",
   "account.unmute": "إلغاء الكتم عن @{name}",
   "account.unmute_notifications": "إلغاء كتم إخطارات @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "انقر لإضافة ملاحظة",
   "alert.rate_limited.message": "يرجى إعادة المحاولة بعد {retry_time, time, medium}.",
   "alert.rate_limited.title": "المعدل محدود",
   "alert.unexpected.message": "لقد طرأ هناك خطأ غير متوقّع.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "ترخيص",
   "follow_request.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.",
+  "generic.saved": "تم الحفظ",
   "getting_started.developers": "المُطوِّرون",
   "getting_started.directory": "دليل الصفحات التعريفية",
   "getting_started.documentation": "الدليل",
@@ -420,13 +419,16 @@
   "time_remaining.minutes": "{number, plural, one {# دقيقة} other {# دقائق}} متبقية",
   "time_remaining.moments": "لحظات متبقية",
   "time_remaining.seconds": "{number, plural, one {# ثانية} other {# ثوانٍ}} متبقية",
-  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
+  "timeline_hint.remote_resource_not_displayed": "{resource} من الخوادم الأخرى لا يتم عرضها.",
   "timeline_hint.resources.followers": "المتابِعون",
-  "timeline_hint.resources.follows": "Follows",
+  "timeline_hint.resources.follows": "المتابَعون",
   "timeline_hint.resources.statuses": "التبويقات القديمة",
-  "trends.count_by_accounts": "{count} {rawCount, plural, zero {} one {شخص واحد} two {شخصين} few {أشخاص} many {أشخاص} other {أشخاص}} تتحدّث",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "المتداولة الآن",
   "ui.beforeunload": "سوف تفقد مسودتك إن تركت ماستدون.",
+  "units.short.billion": "{count} مليار",
+  "units.short.million": "{count}  مليون",
+  "units.short.thousand": "{count}  ألف",
   "upload_area.title": "اسحب ثم أفلت للرفع",
   "upload_button.label": "إضافة وسائط ({formats})",
   "upload_error.limit": "لقد تم بلوغ الحد الأقصى المسموح به لإرسال الملفات.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "وصف للأشخاص ذي قِصر السمع",
   "upload_form.description": "وصف للمعاقين بصريا",
   "upload_form.edit": "تعديل",
+  "upload_form.thumbnail": "غيّر الصورة المصغرة",
   "upload_form.undo": "حذف",
   "upload_form.video_description": "وصف للمعاقين بصريا أو لِذي قِصر السمع",
   "upload_modal.analyzing_picture": "جارٍ فحص الصورة…",
   "upload_modal.apply": "طبّق",
+  "upload_modal.choose_image": "اختر صورة",
   "upload_modal.description_placeholder": "نصٌّ حكيمٌ لهُ سِرٌّ قاطِعٌ وَذُو شَأنٍ عَظيمٍ مكتوبٌ على ثوبٍ أخضرَ ومُغلفٌ بجلدٍ أزرق",
   "upload_modal.detect_text": "اكتشف النص مِن الصورة",
   "upload_modal.edit_media": "تعديل الوسائط",
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index 80d1d4aac..491faa057 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Amestar o desaniciar de les llistes",
   "account.badges.bot": "Robó",
   "account.badges.group": "Grupu",
@@ -16,7 +15,8 @@
   "account.follow": "Siguir",
   "account.followers": "Siguidores",
   "account.followers.empty": "Naide sigue a esti usuariu entá.",
-  "account.follows": "Sigue",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Esti usuariu entá nun sigue a naide.",
   "account.follows_you": "Síguete",
   "account.hide_reblogs": "Anubrir les comparticiones de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Esperando pola aprobación. Calca pa encaboxar la solicitú de siguimientu",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Amosar les comparticiones de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquiar a @{name}",
   "account.unblock_domain": "Amosar {domain}",
   "account.unendorse": "Nun destacar nel perfil",
   "account.unfollow": "Dexar de siguir",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "Asocedió un fallu inesperáu.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Refugar",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Desendolcadores",
   "getting_started.directory": "Direutoriu de perfiles",
   "getting_started.documentation": "Documentación",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persona} other {persones}} falando",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "El borrador va perdese si coles de Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Arrastra y suelta pa xubir",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Descripción pa persones con perda auditiva",
   "upload_form.description": "Descripción pa discapacitaos visuales",
   "upload_form.edit": "Editar",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Desaniciar",
   "upload_form.video_description": "Descripción pa persones con perda auditiva o discapacidá visual",
   "upload_modal.analyzing_picture": "Analizando la semeya…",
   "upload_modal.apply": "Aplicar",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Deteutar el testu de la semeya",
   "upload_modal.edit_media": "Edición",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index 7fa980202..472c88afc 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Добави или премахни от списъците",
   "account.badges.bot": "бот",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Последвай",
   "account.followers": "Последователи",
   "account.followers.empty": "Все още никой не следва този потребител.",
-  "account.follows": "Следвам",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Този потребител все още не следва никого.",
   "account.follows_you": "Твой последовател",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "В очакване на одобрение",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Не блокирай",
   "account.unblock_domain": "Unhide {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Не следвай",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Добави медия",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Отмяна",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json
index c5f08a40e..b41cdf16d 100644
--- a/app/javascript/mastodon/locales/bn.json
+++ b/app/javascript/mastodon/locales/bn.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "তালিকাতে যুক্ত বা অপসারণ করুন",
   "account.badges.bot": "বট",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "অনুসরণ করুন",
   "account.followers": "অনুসরণকারী",
   "account.followers.empty": "এই সদস্যকে এখনো কেউ অনুসরণ করে না।.",
-  "account.follows": "যাদেরকে অনুসরণ করেন",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "এই সদস্য কাওকে এখনো অনুসরণ করেন না.",
   "account.follows_you": "আপনাকে অনুসরণ করে",
   "account.hide_reblogs": "@{name}'র সমর্থনগুলি লুকিয়ে ফেলুন",
@@ -36,16 +36,14 @@
   "account.requested": "অনুমতির অপেক্ষা। অনুসরণ করার অনুরোধ বাতিল করতে এখানে ক্লিক করুন",
   "account.share": "@{name} র প্রোফাইল অন্যদের দেখান",
   "account.show_reblogs": "@{name} র সমর্থনগুলো দেখান",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} র কার্যকলাপ দেখুন",
   "account.unblock_domain": "{domain} কে আবার দেখুন",
   "account.unendorse": "আপনার নিজের পাতায় এটা দেখবেন না",
   "account.unfollow": "অনুসরণ না করতে",
   "account.unmute": "@{name} র কার্যকলাপ আবার দেখুন",
   "account.unmute_notifications": "@{name} র প্রজ্ঞাপন দেখুন",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "{retry_time, time, medium} -এর পরে আবার প্রচেষ্টা করুন।",
   "alert.rate_limited.title": "হার সীমিত",
   "alert.unexpected.message": "সমস্যা অপ্রত্যাশিত.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "অনুমতি দিন",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "তৈরিকারকদের জন্য",
   "getting_started.directory": "নিজস্ব-পাতাগুলির তালিকা",
   "getting_started.documentation": "নথিপত্র",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} কথা বলছে",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "বর্তমানে জনপ্রিয়",
   "ui.beforeunload": "যে পর্যন্ত এটা লেখা হয়েছে, মাস্টাডন থেকে চলে গেলে এটা মুছে যাবে।",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "টেনে এখানে ছেড়ে দিলে এখানে যুক্ত করা যাবে",
   "upload_button.label": "ছবি বা ভিডিও যুক্ত করতে (এসব ধরণের: JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "যা যুক্ত করতে চাচ্ছেন সেটি বেশি বড়, এখানকার সর্বাধিকের মেমোরির উপরে চলে গেছে।",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "যারা দেখতে পায়না তাদের জন্য এটা বর্ণনা করতে",
   "upload_form.edit": "সম্পাদন",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "মুছে ফেলতে",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "চিত্র বিশ্লেষণ করা হচ্ছে…",
   "upload_modal.apply": "প্রয়োগ করুন",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "ছবি থেকে পাঠ্য সনাক্ত করুন",
   "upload_modal.edit_media": "মিডিয়া সম্পাদনা করুন",
diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json
index e6ad55fb9..e0be9d1a2 100644
--- a/app/javascript/mastodon/locales/br.json
+++ b/app/javascript/mastodon/locales/br.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Notenn",
   "account.add_or_remove_from_list": "Ouzhpenn pe dilemel eus al listennadoù",
   "account.badges.bot": "Robot",
   "account.badges.group": "Strollad",
@@ -16,7 +15,8 @@
   "account.follow": "Heuliañ",
   "account.followers": "Heulier·ezed·ien",
   "account.followers.empty": "Den na heul an implijer-mañ c'hoazh.",
-  "account.follows": "Koumanantoù",
+  "account.followers_counter": "{count, plural, other{{counter} Heulier}}",
+  "account.following_counter": "{count, plural, other {{counter} Heuliañ}}",
   "account.follows.empty": "An implijer·ez-mañ na heul den ebet.",
   "account.follows_you": "Ho heul",
   "account.hide_reblogs": "Kuzh toudoù rannet gant @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "O c'hortoz an asant. Klikit evit nullañ ar goulenn heuliañ",
   "account.share": "Skignañ profil @{name}",
   "account.show_reblogs": "Diskouez skignadennoù @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Diverzañ @{name}",
   "account.unblock_domain": "Diverzañ an domani {domain}",
   "account.unendorse": "Paouez da lakaat war-wel war ar profil",
   "account.unfollow": "Diheuliañ",
   "account.unmute": "Diguzhat @{name}",
   "account.unmute_notifications": "Diguzhat kemennoù a @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Klikit evit ouzhpenniñ un notenn",
   "alert.rate_limited.message": "Klaskit en-dro a-benn {retry_time, time, medium}.",
   "alert.rate_limited.title": "Feur bevennet",
   "alert.unexpected.message": "Ur fazi dic'hortozet zo degouezhet.",
@@ -81,9 +79,9 @@
   "column_header.show_settings": "Diskouez an arventennoù",
   "column_header.unpin": "Dispilhennañ",
   "column_subheading.settings": "Arventennoù",
-  "community.column_settings.local_only": "Local only",
+  "community.column_settings.local_only": "Nemet lec'hel",
   "community.column_settings.media_only": "Nemet Mediaoù",
-  "community.column_settings.remote_only": "Remote only",
+  "community.column_settings.remote_only": "Nemet a-bell",
   "compose_form.direct_message_warning": "An toud-mañ a vo kaset nemet d'an implijer·ezed·ien meneget.",
   "compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h",
   "compose_form.hashtag_warning": "Ne vo ket lakaet an toud-mañ er rolloù gerioù-klik dre mard eo anlistennet. N'eus nemet an toudoù foran a c'hall bezañ klasket dre c'her-klik.",
@@ -174,12 +172,13 @@
   "follow_request.authorize": "Aotren",
   "follow_request.reject": "Nac'hañ",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Enrollet",
   "getting_started.developers": "Diorroerien",
   "getting_started.directory": "Roll ar profiloù",
   "getting_started.documentation": "Teuliadur",
   "getting_started.heading": "Loc'hañ",
   "getting_started.invite": "Pediñ tud",
-  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
+  "getting_started.open_source_notice": "Mastodoñ zo ur meziant digor e darzh. Gallout a rit kenoberzhiañ dezhañ pe danevellañ kudennoù war GitHub e {github}.",
   "getting_started.security": "Arventennoù ar gont",
   "getting_started.terms": "Divizoù gwerzhañ hollek",
   "hashtag.column_header.tag_mode.all": "ha {additional}",
@@ -194,14 +193,14 @@
   "home.column_settings.basic": "Diazez",
   "home.column_settings.show_reblogs": "Diskouez ar skignadennoù",
   "home.column_settings.show_replies": "Diskouez ar respontoù",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
+  "home.hide_announcements": "Kuzhat ar c'hemennoù",
+  "home.show_announcements": "Diskouez ar c'hemennoù",
   "intervals.full.days": "{number, plural, one {# devezh} other{# a zevezhioù}}",
   "intervals.full.hours": "{number, plural, one {# eurvezh} other{# eurvezh}}",
   "intervals.full.minutes": "{number, plural, one {# munut} other{# a vunutoù}}",
   "introduction.federation.action": "Da-heul",
   "introduction.federation.federated.headline": "Kevreet",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.federated.text": "Embannadennoù publik eus dafariaded all ar c'hevrebed a yo war-wel er red-amzer kevredet.",
   "introduction.federation.home.headline": "Degemer",
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Lec'hel",
@@ -224,13 +223,13 @@
   "keyboard_shortcuts.description": "Deskrivadur",
   "keyboard_shortcuts.direct": "to open direct messages column",
   "keyboard_shortcuts.down": "to move down in the list",
-  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.enter": "evit digeriñ un toud",
   "keyboard_shortcuts.favourite": "to favourite",
   "keyboard_shortcuts.favourites": "to open favourites list",
   "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": "Berradur",
   "keyboard_shortcuts.legend": "to display this legend",
   "keyboard_shortcuts.local": "to open local timeline",
   "keyboard_shortcuts.mention": "to mention author",
@@ -247,13 +246,13 @@
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
   "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
-  "keyboard_shortcuts.toot": "to start a brand new toot",
+  "keyboard_shortcuts.toot": "da gregiñ gant un toud nevez-flamm",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Serriñ",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "lightbox.view_context": "View context",
+  "lightbox.next": "Da-heul",
+  "lightbox.previous": "A-raok",
+  "lightbox.view_context": "Diskouez ar c'hemperzh",
   "lists.account.add": "Ouzhpennañ d'al listenn",
   "lists.account.remove": "Lemel kuit eus al listenn",
   "lists.delete": "Dilemel al listenn",
@@ -299,14 +298,14 @@
   "notification.own_poll": "Your poll has ended",
   "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} boosted your status",
-  "notifications.clear": "Clear notifications",
+  "notifications.clear": "Skarzhañ ar c'hemennoù",
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
-  "notifications.column_settings.alert": "Desktop notifications",
+  "notifications.column_settings.alert": "Kemennoù war ar burev",
   "notifications.column_settings.favourite": "Ar re vuiañ-karet:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
+  "notifications.column_settings.filter_bar.advanced": "Skrammañ an-holl rummadoù",
   "notifications.column_settings.filter_bar.category": "Barrenn siloù prim",
   "notifications.column_settings.filter_bar.show": "Diskouez",
-  "notifications.column_settings.follow": "New followers:",
+  "notifications.column_settings.follow": "Heulierien nevez:",
   "notifications.column_settings.follow_request": "New follow requests:",
   "notifications.column_settings.mention": "Menegoù:",
   "notifications.column_settings.poll": "Disoc'hoù ar sontadeg:",
@@ -317,7 +316,7 @@
   "notifications.filter.all": "Pep tra",
   "notifications.filter.boosts": "Skignadennoù",
   "notifications.filter.favourites": "Muiañ-karet",
-  "notifications.filter.follows": "Follows",
+  "notifications.filter.follows": "Heuliañ",
   "notifications.filter.mentions": "Menegoù",
   "notifications.filter.polls": "Disoc'hoù ar sontadegoù",
   "notifications.group": "{count} a gemennoù",
@@ -351,8 +350,8 @@
   "report.forward": "Treuzkas da: {target}",
   "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
   "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
-  "report.placeholder": "Additional comments",
-  "report.submit": "Submit",
+  "report.placeholder": "Askelennoù ouzhpenn",
+  "report.submit": "Kinnig",
   "report.target": "Report {target}",
   "search.placeholder": "Klask",
   "search_popout.search_format": "Advanced search format",
@@ -368,24 +367,24 @@
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
-  "status.block": "Block @{name}",
+  "status.block": "Berzañ @{name}",
   "status.bookmark": "Ouzhpennañ d'ar sinedoù",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
-  "status.copy": "Copy link to status",
+  "status.copy": "Eilañ liamm an toud",
   "status.delete": "Dilemel",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Kas ur c'hemennad da @{name}",
   "status.embed": "Enframmañ",
   "status.favourite": "Muiañ-karet",
-  "status.filtered": "Filtered",
+  "status.filtered": "Silet",
   "status.load_more": "Kargañ muioc'h",
   "status.media_hidden": "Media kuzhet",
   "status.mention": "Menegiñ @{name}",
   "status.more": "Muioc'h",
   "status.mute": "Kuzhat @{name}",
   "status.mute_conversation": "Kuzhat ar gaozeadenn",
-  "status.open": "Expand this status",
+  "status.open": "Kreskaat an toud-mañ",
   "status.pin": "Spilhennañ d'ar profil",
   "status.pinned": "Toud spilhennet",
   "status.read_more": "Lenn muioc'h",
@@ -394,23 +393,23 @@
   "status.reblogged_by": "{name} boosted",
   "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
   "status.redraft": "Delete & re-draft",
-  "status.remove_bookmark": "Remove bookmark",
+  "status.remove_bookmark": "Dilemel ar sined",
   "status.reply": "Respont",
-  "status.replyAll": "Reply to thread",
+  "status.replyAll": "Respont d'ar gaozeadenn",
   "status.report": "Disklêriañ @{name}",
   "status.sensitive_warning": "Sensitive content",
   "status.share": "Rannañ",
-  "status.show_less": "Show less",
+  "status.show_less": "Diskouez nebeutoc'h",
   "status.show_less_all": "Show less for all",
-  "status.show_more": "Show more",
+  "status.show_more": "Diskouez muioc'h",
   "status.show_more_all": "Show more for all",
-  "status.show_thread": "Show thread",
-  "status.uncached_media_warning": "Not available",
+  "status.show_thread": "Diskouez ar gaozeadenn",
+  "status.uncached_media_warning": "Dihegerz",
   "status.unmute_conversation": "Diguzhat ar gaozeadenn",
   "status.unpin": "Dispilhennañ eus ar profil",
   "suggestions.dismiss": "Dismiss suggestion",
   "suggestions.header": "You might be interested in…",
-  "tabs_bar.federated_timeline": "Federated",
+  "tabs_bar.federated_timeline": "Kevredet",
   "tabs_bar.home": "Degemer",
   "tabs_bar.local_timeline": "Lec'hel",
   "tabs_bar.notifications": "Kemennoù",
@@ -421,12 +420,15 @@
   "time_remaining.moments": "Moments remaining",
   "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
-  "timeline_hint.resources.followers": "Followers",
-  "timeline_hint.resources.follows": "Follows",
-  "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "timeline_hint.resources.followers": "Heulier·ezed·ien",
+  "timeline_hint.resources.follows": "Heuliañ",
+  "timeline_hint.resources.statuses": "Toudoù koshoc'h",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Luskad ar mare",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Ouzhpennañ ur media ({formats})",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,22 +436,24 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Aozañ",
+  "upload_form.thumbnail": "Kemmañ ar velvenn",
   "upload_form.undo": "Dilemel",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
-  "upload_modal.apply": "Apply",
+  "upload_modal.apply": "Arloañ",
+  "upload_modal.choose_image": "Dibab ur skeudenn",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
-  "upload_modal.detect_text": "Detect text from picture",
-  "upload_modal.edit_media": "Edit media",
+  "upload_modal.detect_text": "Dinoiñ testenn diouzh ar skeudenn",
+  "upload_modal.edit_media": "Embann ar media",
   "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
-  "upload_modal.preview_label": "Preview ({ratio})",
+  "upload_modal.preview_label": "Rakwel ({ratio})",
   "upload_progress.label": "O pellgargañ...",
-  "video.close": "Close video",
+  "video.close": "Serriñ ar video",
   "video.download": "Pellgargañ ar restr",
-  "video.exit_fullscreen": "Exit full screen",
+  "video.exit_fullscreen": "Kuitaat ar mod skramm leun",
   "video.expand": "Expand video",
-  "video.fullscreen": "Full screen",
-  "video.hide": "Hide video",
+  "video.fullscreen": "Skramm a-bezh",
+  "video.hide": "Kuzhat ar video",
   "video.mute": "Mute sound",
   "video.pause": "Pause",
   "video.play": "Play",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 3ad7158fc..04a37fc03 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "La teva nota per a @{name}",
   "account.add_or_remove_from_list": "Afegir o Treure de les llistes",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grup",
@@ -16,7 +15,8 @@
   "account.follow": "Segueix",
   "account.followers": "Seguidors",
   "account.followers.empty": "Encara ningú no segueix aquest usuari.",
-  "account.follows": "Seguiments",
+  "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidors}}",
+  "account.following_counter": "{count, plural, one {} other {{counter} Seguint}}",
   "account.follows.empty": "Aquest usuari encara no segueix a ningú.",
   "account.follows_you": "Et segueix",
   "account.hide_reblogs": "Amaga els impulsos de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Esperant aprovació. Clic per a cancel·lar la petició de seguiment",
   "account.share": "Comparteix el perfil de @{name}",
   "account.show_reblogs": "Mostra els impulsos de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Tut} other {{counter} Tuts}}",
   "account.unblock": "Desbloqueja @{name}",
   "account.unblock_domain": "Mostra {domain}",
   "account.unendorse": "No recomanar en el perfil",
   "account.unfollow": "Deixa de seguir",
   "account.unmute": "Treure silenci de @{name}",
   "account.unmute_notifications": "Activar notificacions de @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Sense comentaris",
   "alert.rate_limited.message": "Si us plau torna-ho a provar després de {retry_time, time, medium}.",
   "alert.rate_limited.title": "Límit de freqüència",
   "alert.unexpected.message": "S'ha produït un error inesperat.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autoritzar",
   "follow_request.reject": "Rebutjar",
   "follow_requests.unlocked_explanation": "Tot i que el teu compte no està bloquejat, el personal de {domain} ha pensat que és possible que vulguis revisar les sol·licituds de seguiment d’aquests comptes de forma manual.",
+  "generic.saved": "Guardat",
   "getting_started.developers": "Desenvolupadors",
   "getting_started.directory": "Directori de perfils",
   "getting_started.documentation": "Documentació",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Seguidors",
   "timeline_hint.resources.follows": "Seguiments",
   "timeline_hint.resources.statuses": "Tuts més antics",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persona} other {persones}} parlant-hi",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} persones}} parlant-hi",
   "trends.trending_now": "Ara en tendència",
   "ui.beforeunload": "El teu esborrany es perdrà si surts de Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Arrossega i deixa anar per a carregar",
   "upload_button.label": "Afegir multimèdia (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "S'ha superat el límit de càrrega d'arxius.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Descriviu per a les persones amb pèrdua auditiva",
   "upload_form.description": "Descriure els problemes visuals",
   "upload_form.edit": "Edita",
+  "upload_form.thumbnail": "Canvia la miniatura",
   "upload_form.undo": "Esborra",
   "upload_form.video_description": "Descriu per a les persones amb pèrdua auditiva o deficiència visual",
   "upload_modal.analyzing_picture": "Analitzant imatge…",
   "upload_modal.apply": "Aplica",
+  "upload_modal.choose_image": "Tria imatge",
   "upload_modal.description_placeholder": "Uns salts ràpids de guineu marró sobre el gos gandul",
   "upload_modal.detect_text": "Detecta el text de l'imatge",
   "upload_modal.edit_media": "Editar multimèdia",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index 93c26a19c..1bd9cda0b 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "A vostra nota per @{name}",
   "account.add_or_remove_from_list": "Aghjunghje o toglie da e liste",
   "account.badges.bot": "Bot",
   "account.badges.group": "Gruppu",
@@ -16,7 +15,8 @@
   "account.follow": "Siguità",
   "account.followers": "Abbunati",
   "account.followers.empty": "Nisunu hè abbunatu à st'utilizatore.",
-  "account.follows": "Abbunamenti",
+  "account.followers_counter": "{count, plural, one {{counter} Abbunatu} other {{counter} Abbunati}}",
+  "account.following_counter": "{count, plural, one {{counter} Abbunamentu} other {{counter} Abbunamenti}}",
   "account.follows.empty": "St'utilizatore ùn seguita nisunu.",
   "account.follows_you": "Vi seguita",
   "account.hide_reblogs": "Piattà spartere da @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "In attesa d'apprubazione. Cliccate per annullà a dumanda",
   "account.share": "Sparte u prufile di @{name}",
   "account.show_reblogs": "Vede spartere da @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Statutu} other {{counter} Statuti}}",
   "account.unblock": "Sbluccà @{name}",
   "account.unblock_domain": "Ùn piattà più {domain}",
   "account.unendorse": "Ùn fà figurà nant'à u prufilu",
   "account.unfollow": "Ùn siguità più",
   "account.unmute": "Ùn piattà più @{name}",
   "account.unmute_notifications": "Ùn piattà più nutificazione da @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Senza cummentariu",
   "alert.rate_limited.message": "Pruvate ancu dop'à {retry_time, time, medium}.",
   "alert.rate_limited.title": "Ghjettu limitatu",
   "alert.unexpected.message": "Un prublemu inaspettatu hè accadutu.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Auturizà",
   "follow_request.reject": "Righjittà",
   "follow_requests.unlocked_explanation": "U vostru contu ùn hè micca privatu, ma a squadra d'amministrazione di {domain} pensa chì e dumande d'abbunamentu di questi conti anu bisognu d'esse verificate manualmente.",
+  "generic.saved": "Salvatu",
   "getting_started.developers": "Sviluppatori",
   "getting_started.directory": "Annuariu di i prufili",
   "getting_started.documentation": "Ducumentazione",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Abbunati",
   "timeline_hint.resources.follows": "Abbunamenti",
   "timeline_hint.resources.statuses": "Statuti più anziani",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} parlanu",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} persona chì parla} other {{counter} persone chì parlanu}}",
   "trends.trending_now": "Tindenze d'avà",
   "ui.beforeunload": "A bruttacopia sarà persa s'ellu hè chjosu Mastodon.",
+  "units.short.billion": "{count}G",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop per caricà un fugliale",
   "upload_button.label": "Aghjunghje un media ({formats})",
   "upload_error.limit": "Limita di caricamentu di fugliali trapassata.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Discrizzione per i ciochi",
   "upload_form.description": "Discrive per i malvistosi",
   "upload_form.edit": "Mudificà",
+  "upload_form.thumbnail": "Cambià vignetta",
   "upload_form.undo": "Sguassà",
   "upload_form.video_description": "Discrizzione per i ciochi o cechi",
   "upload_modal.analyzing_picture": "Analisi di u ritrattu…",
   "upload_modal.apply": "Affettà",
+  "upload_modal.choose_image": "Cambià ritrattu",
   "upload_modal.description_placeholder": "Chì tempi brevi ziu, quandu solfeghji",
   "upload_modal.detect_text": "Ditettà testu da u ritrattu",
   "upload_modal.edit_media": "Cambià media",
diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json
index 593311167..f991b7a25 100644
--- a/app/javascript/mastodon/locales/cs.json
+++ b/app/javascript/mastodon/locales/cs.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Přidat nebo odstranit ze seznamů",
   "account.badges.bot": "Robot",
   "account.badges.group": "Skupina",
@@ -16,7 +15,8 @@
   "account.follow": "Sledovat",
   "account.followers": "Sledující",
   "account.followers.empty": "Tohoto uživatele ještě nikdo nesleduje.",
-  "account.follows": "Sledovaní",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Tento uživatel ještě nikoho nesleduje.",
   "account.follows_you": "Sleduje vás",
   "account.hide_reblogs": "Skrýt boosty od uživatele @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Čeká na schválení. Kliknutím žádost o sledování zrušíte",
   "account.share": "Sdílet profil uživatele @{name}",
   "account.show_reblogs": "Zobrazit boosty od uživatele @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Odblokovat uživatele @{name}",
   "account.unblock_domain": "Odkrýt doménu {domain}",
   "account.unendorse": "Nezvýrazňovat na profilu",
   "account.unfollow": "Přestat sledovat",
   "account.unmute": "Odkrýt uživatele @{name}",
   "account.unmute_notifications": "Odkrýt oznámení od uživatele @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Zkuste to prosím znovu za {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rychlost omezena",
   "alert.unexpected.message": "Objevila se neočekávaná chyba.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizovat",
   "follow_request.reject": "Odmítnout",
   "follow_requests.unlocked_explanation": "Přestože váš účet není uzamčen, {domain} si myslí, že budete chtít následující požadavky na sledování zkontrolovat ručně.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Vývojáři",
   "getting_started.directory": "Adresář profilů",
   "getting_started.documentation": "Dokumentace",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Sledující",
   "timeline_hint.resources.follows": "Sleduje",
   "timeline_hint.resources.statuses": "Starší tooty",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {člověk} few {lidé} many {lidí} other {lidí}} hovoří",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Aktuální trendy",
   "ui.beforeunload": "Pokud Mastodon opustíte, váš koncept se ztratí.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Nahrajte přetažením",
   "upload_button.label": "Přidat média ({formats})",
   "upload_error.limit": "Byl překročen limit nahraných souborů.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Popis pro sluchově postižené",
   "upload_form.description": "Popis pro zrakově postižené",
   "upload_form.edit": "Upravit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Smazat",
   "upload_form.video_description": "Popis pro sluchově či zrakově postižené",
   "upload_modal.analyzing_picture": "Analyzuji obrázek…",
   "upload_modal.apply": "Použít",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Příliš žluťoučký kůň úpěl ďábelské ódy",
   "upload_modal.detect_text": "Detekovat text z obrázku",
   "upload_modal.edit_media": "Upravit média",
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index 5a1085389..984237a32 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Ychwanegu neu Dileu o'r rhestrau",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grŵp",
@@ -16,7 +15,8 @@
   "account.follow": "Dilyn",
   "account.followers": "Dilynwyr",
   "account.followers.empty": "Nid oes neb yn dilyn y defnyddiwr hwn eto.",
-  "account.follows": "Yn dilyn",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.",
   "account.follows_you": "Yn eich dilyn chi",
   "account.hide_reblogs": "Cuddio bwstiau o @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Aros am gymeradwyaeth. Cliciwch er mwyn canslo cais dilyn",
   "account.share": "Rhannwch broffil @{name}",
   "account.show_reblogs": "Dangos bwstiau o @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Dadflocio @{name}",
   "account.unblock_domain": "Dadguddio {domain}",
   "account.unendorse": "Peidio a'i arddangos ar fy mhroffil",
   "account.unfollow": "Dad-ddilyn",
   "account.unmute": "Dad-dawelu @{name}",
   "account.unmute_notifications": "Dad-dawelu hysbysiadau o @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Ceisiwch eto ar ôl {retry_time, time, medium}.",
   "alert.rate_limited.title": "Cyfradd gyfyngedig",
   "alert.unexpected.message": "Digwyddodd gwall annisgwyl.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Caniatau",
   "follow_request.reject": "Gwrthod",
   "follow_requests.unlocked_explanation": "Er nid yw eich cyfrif wedi'i gloi, oedd y staff {domain} yn meddwl efallai hoffech adolygu ceisiadau dilyn o'r cyfrifau rhain wrth law.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Datblygwyr",
   "getting_started.directory": "Cyfeiriadur proffil",
   "getting_started.documentation": "Dogfennaeth",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} yn siarad",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Yn tueddu nawr",
   "ui.beforeunload": "Mi fyddwch yn colli eich drafft os gadewch Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Llusgwch & gollwing i uwchlwytho",
   "upload_button.label": "Ychwanegwch gyfryngau (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Wedi mynd heibio'r uchafswm terfyn uwchlwytho.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Disgrifio ar gyfer pobl sydd â cholled clyw",
   "upload_form.description": "Disgrifio i'r rheini a nam ar ei golwg",
   "upload_form.edit": "Golygu",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Dileu",
   "upload_form.video_description": "Disgrifio ar gyfer pobl sydd â cholled clyw neu amhariad golwg",
   "upload_modal.analyzing_picture": "Dadansoddi llun…",
   "upload_modal.apply": "Gweithredu",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Mae ei phen bach llawn jocs, 'run peth a fy nghot golff, rhai dyddiau",
   "upload_modal.detect_text": "Canfod testun o'r llun",
   "upload_modal.edit_media": "Golygu cyfryngau",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 9354308cc..e59f5283c 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Tilføj eller fjern fra lister",
   "account.badges.bot": "Robot",
   "account.badges.group": "Gruppe",
@@ -16,7 +15,8 @@
   "account.follow": "Følg",
   "account.followers": "Følgere",
   "account.followers.empty": "Der er endnu ingen der følger denne bruger.",
-  "account.follows": "Følger",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Denne bruger følger endnu ikke nogen.",
   "account.follows_you": "Følger dig",
   "account.hide_reblogs": "Skjul fremhævelserne fra @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning",
   "account.share": "Del @{name}s profil",
   "account.show_reblogs": "Vis fremhævelserne fra @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Fjern blokeringen af @{name}",
   "account.unblock_domain": "Skjul ikke længere {domain}",
   "account.unendorse": "Fremhæv ikke på profil",
   "account.unfollow": "Følg ikke længere",
   "account.unmute": "Fjern dæmpningen af @{name}",
   "account.unmute_notifications": "Fjern dæmpningen af notifikationer fra @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Prøv venligst igen efter {retry_time, time, medium}.",
   "alert.rate_limited.title": "Gradsbegrænset",
   "alert.unexpected.message": "Der opstod en uventet fejl.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Godkend",
   "follow_request.reject": "Afvis",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Udviklere",
   "getting_started.directory": "Profilliste",
   "getting_started.documentation": "Dokumentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {personer}} snakker",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Hot lige nu",
   "ui.beforeunload": "Din kladde vil gå tabt hvis du forlader Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Træk og slip for at uploade",
   "upload_button.label": "Tilføj medie (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Uploadgrænse overskredet.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Beskriv for svagtseende",
   "upload_form.edit": "Redigér",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Slet",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyserer billede…",
   "upload_modal.apply": "Anvend",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "En hurtig brun ræv hopper over den dovne hund",
   "upload_modal.detect_text": "Find tekst i billede på automatisk vis",
   "upload_modal.edit_media": "Redigér medie",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 81209dbb7..61d7bd58a 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Deine Notiz für @{name}",
   "account.add_or_remove_from_list": "Hinzufügen oder Entfernen von Listen",
   "account.badges.bot": "Bot",
   "account.badges.group": "Gruppe",
@@ -16,7 +15,8 @@
   "account.follow": "Folgen",
   "account.followers": "Folgende",
   "account.followers.empty": "Diesem Profil folgt noch niemand.",
-  "account.follows": "Folgt",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Follower}}",
+  "account.following_counter": "{count, plural, one {{counter} Folgender} other {{counter} Folgende}}",
   "account.follows.empty": "Dieses Profil folgt noch niemandem.",
   "account.follows_you": "Folgt dir",
   "account.hide_reblogs": "Geteilte Beiträge von @{name} verbergen",
@@ -36,16 +36,14 @@
   "account.requested": "Warte auf Erlaubnis. Klicke zum Abbrechen",
   "account.share": "Profil von @{name} teilen",
   "account.show_reblogs": "Von @{name} geteilte Beiträge anzeigen",
+  "account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
   "account.unblock": "@{name} entblocken",
   "account.unblock_domain": "Blockieren von {domain} beenden",
   "account.unendorse": "Nicht auf Profil hervorheben",
   "account.unfollow": "Entfolgen",
   "account.unmute": "@{name} nicht mehr stummschalten",
   "account.unmute_notifications": "Benachrichtigungen von @{name} einschalten",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Kein Kommentar angegeben",
   "alert.rate_limited.message": "Bitte versuche es nach {retry_time, time, medium}.",
   "alert.rate_limited.title": "Anfragelimit überschritten",
   "alert.unexpected.message": "Ein unerwarteter Fehler ist aufgetreten.",
@@ -96,7 +94,7 @@
   "compose_form.poll.remove_option": "Wahl entfernen",
   "compose_form.poll.switch_to_multiple": "Umfrage ändern, um mehrere Optionen zu erlauben",
   "compose_form.poll.switch_to_single": "Umfrage ändern, um eine einzige Wahl zu erlauben",
-  "compose_form.publish": "Tröt",
+  "compose_form.publish": "Beitrag",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.hide": "Medien als heikel markieren",
   "compose_form.sensitive.marked": "Medien sind als heikel markiert",
@@ -120,7 +118,7 @@
   "confirmations.mute.explanation": "Dies wird Beiträge von dieser Person und Beiträge, die diese Person erwähnen, ausblenden, aber es wird der Person trotzdem erlauben, deine Beiträge zu sehen und dir zu folgen.",
   "confirmations.mute.message": "Bist du dir sicher, dass du {name} stummschalten möchtest?",
   "confirmations.redraft.confirm": "Löschen und neu erstellen",
-  "confirmations.redraft.message": "Bist du dir sicher, dass du diesen Tröt löschen und neu erstellen möchtest? Favs, geteilte Beiträge und Antworten werden verloren gehen.",
+  "confirmations.redraft.message": "Bist du dir sicher, dass du diesen Beitrag löschen und neu machen möchtest? Favoriten und Boosts werden verloren gehen und Antworten zu diesem Beitrag werden verwaist sein.",
   "confirmations.reply.confirm": "Antworten",
   "confirmations.reply.message": "Wenn du jetzt antwortest wird es die gesamte Nachricht verwerfen, die du gerade schreibst. Möchtest du wirklich fortfahren?",
   "confirmations.unfollow.confirm": "Entfolgen",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Erlauben",
   "follow_request.reject": "Ablehnen",
   "follow_requests.unlocked_explanation": "Auch wenn dein Konto nicht gesperrt ist, haben die Mitarbeiter von {domain} gedacht, dass es besser wäre den Follow manuell zu bestätigen.",
+  "generic.saved": "Gespeichert",
   "getting_started.developers": "Entwickler",
   "getting_started.directory": "Profilverzeichnis",
   "getting_started.documentation": "Dokumentation",
@@ -356,7 +355,7 @@
   "report.target": "{target} melden",
   "search.placeholder": "Suche",
   "search_popout.search_format": "Fortgeschrittenes Suchformat",
-  "search_popout.tips.full_text": "Einfache Texteingabe gibt Tröts, die du geschrieben, gefavt und geteilt hast zurück. Außerdem auch Tröts, 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 Nutzernamen, Anzeigenamen oder Hashtags.",
   "search_popout.tips.hashtag": "Hashtag",
   "search_popout.tips.status": "Beitrag",
   "search_popout.tips.text": "Einfache Texteingabe gibt Anzeigenamen, Benutzernamen und Hashtags zurück",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Follower",
   "timeline_hint.resources.follows": "Folgt",
   "timeline_hint.resources.statuses": "Ältere Toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, eine {Person} other {Personen}} reden darüber",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} Person redet darüber} other {{counter} Personen reden darüber}}",
   "trends.trending_now": "In den Trends",
   "ui.beforeunload": "Dein Entwurf geht verloren, wenn du Mastodon verlässt.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Zum Hochladen hereinziehen",
   "upload_button.label": "Mediendatei hinzufügen ({formats})",
   "upload_error.limit": "Dateiupload-Limit erreicht.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Beschreibe die Audiodatei für Menschen mit Hörschädigungen",
   "upload_form.description": "Für Menschen mit Sehbehinderung beschreiben",
   "upload_form.edit": "Beschreiben",
+  "upload_form.thumbnail": "Miniaturansicht ändern",
   "upload_form.undo": "Löschen",
   "upload_form.video_description": "Beschreibe das Video für Menschen mit einer Hör- oder Sehbehinderung",
   "upload_modal.analyzing_picture": "Analysiere Bild…",
   "upload_modal.apply": "Übernehmen",
+  "upload_modal.choose_image": "Bild auswählen",
   "upload_modal.description_placeholder": "Die heiße Zypernsonne quälte Max und Victoria ja böse auf dem Weg bis zur Küste",
   "upload_modal.detect_text": "Text aus Bild erkennen",
   "upload_modal.edit_media": "Medien bearbeiten",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 813d40789..24b4634c7 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -2767,6 +2767,10 @@
         "id": "upload_modal.description_placeholder"
       },
       {
+        "defaultMessage": "Choose image",
+        "id": "upload_modal.choose_image"
+      },
+      {
         "defaultMessage": "Describe for people with hearing loss",
         "id": "upload_form.audio_description"
       },
@@ -2787,6 +2791,10 @@
         "id": "upload_modal.hint"
       },
       {
+        "defaultMessage": "Change thumbnail",
+        "id": "upload_form.thumbnail"
+      },
+      {
         "defaultMessage": "Analyzing picture…",
         "id": "upload_modal.analyzing_picture"
       },
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index f6e3c07c4..74b3e1c9a 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Σημείωση",
   "account.add_or_remove_from_list": "Προσθήκη ή Αφαίρεση από λίστες",
   "account.badges.bot": "Μποτ",
   "account.badges.group": "Ομάδα",
@@ -16,7 +15,8 @@
   "account.follow": "Ακολούθησε",
   "account.followers": "Ακόλουθοι",
   "account.followers.empty": "Κανείς δεν ακολουθεί αυτό τον χρήστη ακόμα.",
-  "account.follows": "Ακολουθεί",
+  "account.followers_counter": "{count, plural, one {{counter} Ακόλουθος} other {{counter} Ακόλουθοι}}",
+  "account.following_counter": "{count, plural, one {} other {{counter} Ακολουθεί}}",
   "account.follows.empty": "Αυτός ο χρήστης δεν ακολουθεί κανέναν ακόμα.",
   "account.follows_you": "Σε ακολουθεί",
   "account.hide_reblogs": "Απόκρυψη προωθήσεων από @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα παρακολούθησης",
   "account.share": "Μοίρασμα του προφίλ @{name}",
   "account.show_reblogs": "Εμφάνιση προωθήσεων από @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Τουτ} other {{counter} Τουτ}}",
   "account.unblock": "Ξεμπλόκαρε @{name}",
   "account.unblock_domain": "Αποκάλυψε το {domain}",
   "account.unendorse": "Άνευ προβολής στο προφίλ",
   "account.unfollow": "Διακοπή παρακολούθησης",
   "account.unmute": "Διακοπή αποσιώπησης @{name}",
   "account.unmute_notifications": "Διακοπή αποσιώπησης ειδοποιήσεων του/της @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Κλικ για να βάλεις σημείωση",
   "alert.rate_limited.message": "Παρακαλούμε δοκίμασε ξανά αφού περάσει η {retry_time, time, medium}.",
   "alert.rate_limited.title": "Περιορισμός συχνότητας",
   "alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Ενέκρινε",
   "follow_request.reject": "Απέρριψε",
   "follow_requests.unlocked_explanation": "Παρόλο που ο λογαριασμός σου δεν είναι κλειδωμένος, οι διαχειριστές του {domain} θεώρησαν πως ίσως να θέλεις να ελέγξεις χειροκίνητα αυτά τα αιτήματα ακολούθησης.",
+  "generic.saved": "Αποθηκεύτηκε",
   "getting_started.developers": "Ανάπτυξη",
   "getting_started.directory": "Κατάλογος λογαριασμών",
   "getting_started.documentation": "Τεκμηρίωση",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Ακόλουθοι",
   "timeline_hint.resources.follows": "Ακολουθεί",
   "timeline_hint.resources.statuses": "Παλαιότερα τουτ",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {άτομο μιλάει} other {άτομα μιλάνε}}",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} άτομο μιλάει} other {{counter} άτομα μιλάνε}}",
   "trends.trending_now": "Δημοφιλή τώρα",
   "ui.beforeunload": "Το προσχέδιό σου θα χαθεί αν φύγεις από το Mastodon.",
+  "units.short.billion": "{count}Δ",
+  "units.short.million": "{count}Ε",
+  "units.short.thousand": "{count}Χ",
   "upload_area.title": "Drag & drop για να ανεβάσεις",
   "upload_button.label": "Πρόσθεσε πολυμέσα ({formats})",
   "upload_error.limit": "Υπέρβαση ορίου μεγέθους ανεβασμένων αρχείων.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Περιγραφή για άτομα με προβλήματα ακοής",
   "upload_form.description": "Περιέγραψε για όσους & όσες έχουν προβλήματα όρασης",
   "upload_form.edit": "Ενημέρωση",
+  "upload_form.thumbnail": "Αλλαγή μικρογραφίας",
   "upload_form.undo": "Διαγραφή",
   "upload_form.video_description": "Περιγραφή για άτομα με προβλήματα ακοής ή όρασης",
   "upload_modal.analyzing_picture": "Ανάλυση εικόνας…",
   "upload_modal.apply": "Εφαρμογή",
+  "upload_modal.choose_image": "Επιλογή εικόνας",
   "upload_modal.description_placeholder": "Λύκος μαύρος και ισχνός του πατέρα του καημός",
   "upload_modal.detect_text": "Αναγνώριση κειμένου από την εικόνα",
   "upload_modal.edit_media": "Επεξεργασία Πολυμέσων",
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index ba2e6da9e..cec1dacdd 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -441,10 +441,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Describe",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 9f902c522..886083392 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Noto",
   "account.add_or_remove_from_list": "Aldoni al aŭ forigi el listoj",
   "account.badges.bot": "Roboto",
   "account.badges.group": "Grupo",
@@ -16,7 +15,8 @@
   "account.follow": "Sekvi",
   "account.followers": "Sekvantoj",
   "account.followers.empty": "Ankoraŭ neniu sekvas tiun uzanton.",
-  "account.follows": "Sekvatoj",
+  "account.followers_counter": "{count, plural, one{{counter} Sekvanto} other {{counter} Sekvantoj}}",
+  "account.following_counter": "{count, plural, other{{counter} Sekvi}}",
   "account.follows.empty": "Tiu uzanto ankoraŭ ne sekvas iun.",
   "account.follows_you": "Sekvas vin",
   "account.hide_reblogs": "Kaŝi diskonigojn de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Atendo de aprobo. Alklaku por nuligi peton de sekvado",
   "account.share": "Diskonigi la profilon de @{name}",
   "account.show_reblogs": "Montri diskonigojn de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Tooto} other {{counter} Tootoj}}",
   "account.unblock": "Malbloki @{name}",
   "account.unblock_domain": "Malkaŝi {domain}",
   "account.unendorse": "Ne montri en profilo",
   "account.unfollow": "Ne plu sekvi",
   "account.unmute": "Malsilentigi @{name}",
   "account.unmute_notifications": "Malsilentigi sciigojn de @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Bonvolu reprovi post {retry_time, time, medium}.",
   "alert.rate_limited.title": "Mesaĝkvante limigita",
   "alert.unexpected.message": "Neatendita eraro okazis.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Rajtigi",
   "follow_request.reject": "Rifuzi",
   "follow_requests.unlocked_explanation": "137/5000\nKvankam via konto ne estas ŝlosita, la dungitaro de {domain} opiniis, ke vi eble volus revizii petojn de sekvadon el ĉi tiuj kontoj permane.",
+  "generic.saved": "Konservita",
   "getting_started.developers": "Programistoj",
   "getting_started.directory": "Profilujo",
   "getting_started.documentation": "Dokumentado",
@@ -421,12 +420,15 @@
   "time_remaining.moments": "Momenteto restas",
   "time_remaining.seconds": "{number, plural, one {# sekundo} other {# sekundoj}} restas",
   "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
-  "timeline_hint.resources.followers": "Followers",
-  "timeline_hint.resources.follows": "Follows",
-  "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persono} other {personoj}} parolas",
+  "timeline_hint.resources.followers": "Sekvantoj",
+  "timeline_hint.resources.follows": "Sekvatoj",
+  "timeline_hint.resources.statuses": "Pli malnovaj tootoj",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} persono} other {{counter} personoj}} parolante",
   "trends.trending_now": "Nunaj furoraĵoj",
   "ui.beforeunload": "Via malneto perdiĝos se vi eliras de Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Altreni kaj lasi por alŝuti",
   "upload_button.label": "Aldoni aŭdovidaĵon (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Limo de dosiera alŝutado transpasita.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Priskribi por homoj kiuj malfacile aŭdi",
   "upload_form.description": "Priskribi por misvidantaj homoj",
   "upload_form.edit": "Redakti",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Forigi",
   "upload_form.video_description": "Priskribi por homoj kiuj malfacile aŭdi aŭ vidi",
   "upload_modal.analyzing_picture": "Bilda analizado…",
   "upload_modal.apply": "Apliki",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Laŭ Ludoviko Zamenhof bongustas freŝa ĉeĥa manĝaĵo kun spicoj",
   "upload_modal.detect_text": "Detekti tekston de la bildo",
   "upload_modal.edit_media": "Redakti aŭdovidaĵon",
diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json
index c94e15878..fda386455 100644
--- a/app/javascript/mastodon/locales/es-AR.json
+++ b/app/javascript/mastodon/locales/es-AR.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Tu nota para @{name}",
   "account.add_or_remove_from_list": "Agregar o quitar de las listas",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grupo",
@@ -16,7 +15,8 @@
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
   "account.followers.empty": "Todavía nadie sigue a este usuario.",
-  "account.follows": "Sigue",
+  "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidores}}",
+  "account.following_counter": "{count, plural, other {{counter} Siguiendo}}",
   "account.follows.empty": "Todavía este usuario no sigue a nadie.",
   "account.follows_you": "Te sigue",
   "account.hide_reblogs": "Ocultar retoots de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Esperando aprobación. Hacé clic para cancelar la solicitud de seguimiento.",
   "account.share": "Compartir el perfil de @{name}",
   "account.show_reblogs": "Mostrar retoots de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear a @{name}",
   "account.unblock_domain": "Mostrar {domain}",
   "account.unendorse": "No destacar en el perfil",
   "account.unfollow": "Dejar de seguir",
   "account.unmute": "Dejar de silenciar a @{name}",
   "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "No se ofreció ningún comentario",
   "alert.rate_limited.message": "Por favor, reintentá después de las {retry_time, time, medium}.",
   "alert.rate_limited.title": "Tarifa limitada",
   "alert.unexpected.message": "Ocurrió un error.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rechazar",
   "follow_requests.unlocked_explanation": "A pesar de que tu cuenta no está bloqueada, el equipo de {domain} pensó que podrías querer revisar manualmente las solicitudes de seguimiento de estas cuentas.",
+  "generic.saved": "Guardado",
   "getting_started.developers": "Desarrolladores",
   "getting_started.directory": "Directorio de perfiles",
   "getting_started.documentation": "Documentación",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Seguidores",
   "timeline_hint.resources.follows": "Siguiendo",
   "timeline_hint.resources.statuses": "Toots antiguos",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persona} other {personas}} hablando",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} personas}} hablando",
   "trends.trending_now": "Tendencia ahora",
   "ui.beforeunload": "Tu borrador se perderá si abandonás Mastodon.",
+  "units.short.billion": "{count}MM",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}mil",
   "upload_area.title": "Para subir, arrastrá y soltá",
   "upload_button.label": "Agregar medios ({formats})",
   "upload_error.limit": "Se excedió el límite de subida de archivos.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describir para personas con problemas auditivos",
   "upload_form.description": "Agregar descripción para los usuarios con dificultades visuales",
   "upload_form.edit": "Editar",
+  "upload_form.thumbnail": "Cambiar miniatura",
   "upload_form.undo": "Eliminar",
   "upload_form.video_description": "Describir para personas con problemas auditivos o visuales",
   "upload_modal.analyzing_picture": "Analizando imagen…",
   "upload_modal.apply": "Aplicar",
+  "upload_modal.choose_image": "Elegir imagen",
   "upload_modal.description_placeholder": "El veloz murciélago hindú comía feliz cardillo y kiwi. La cigüeña tocaba el saxofón detrás del palenque de paja.",
   "upload_modal.detect_text": "Detectar texto de la imagen",
   "upload_modal.edit_media": "Editar medio",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index aee23fb11..d9cca021a 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Nota",
   "account.add_or_remove_from_list": "Agregar o eliminar de listas",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grupo",
@@ -16,7 +15,8 @@
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
   "account.followers.empty": "Todavía nadie sigue a este usuario.",
-  "account.follows": "Sigue",
+  "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidores}}",
+  "account.following_counter": "{count, plural, other {{counter} Siguiendo}}",
   "account.follows.empty": "Este usuario todavía no sigue a nadie.",
   "account.follows_you": "Te sigue",
   "account.hide_reblogs": "Ocultar retoots de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Esperando aprobación",
   "account.share": "Compartir el perfil de @{name}",
   "account.show_reblogs": "Mostrar retoots de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear a @{name}",
   "account.unblock_domain": "Mostrar a {domain}",
   "account.unendorse": "No mostrar en el perfil",
   "account.unfollow": "Dejar de seguir",
   "account.unmute": "Dejar de silenciar a @{name}",
   "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Clic para añadir nota",
   "alert.rate_limited.message": "Por favor reintente después de {retry_time, time, medium}.",
   "alert.rate_limited.title": "Tarifa limitada",
   "alert.unexpected.message": "Hubo un error inesperado.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rechazar",
   "follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizás deberías revisar manualmente las solicitudes de seguimiento de estas cuentas.",
+  "generic.saved": "Guardado",
   "getting_started.developers": "Desarrolladores",
   "getting_started.directory": "Directorio de perfil",
   "getting_started.documentation": "Documentación",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Seguidores",
   "timeline_hint.resources.follows": "Seguidos",
   "timeline_hint.resources.statuses": "Toots más antiguos",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persona} other {personas}} hablando",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} personas}} hablando",
   "trends.trending_now": "Tendencia ahora",
   "ui.beforeunload": "Tu borrador se perderá si sales de Mastodon.",
+  "units.short.billion": "{count}MM",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}mil",
   "upload_area.title": "Arrastra y suelta para subir",
   "upload_button.label": "Subir multimedia (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Límite de subida de archivos excedido.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describir para personas con problemas auditivos",
   "upload_form.description": "Describir para los usuarios con dificultad visual",
   "upload_form.edit": "Describir",
+  "upload_form.thumbnail": "Cambiar miniatura",
   "upload_form.undo": "Borrar",
   "upload_form.video_description": "Describir para personas con problemas auditivos o visuales",
   "upload_modal.analyzing_picture": "Analizando imagen…",
   "upload_modal.apply": "Aplicar",
+  "upload_modal.choose_image": "Elegir imagen",
   "upload_modal.description_placeholder": "Un rápido zorro marrón salta sobre el perro perezoso",
   "upload_modal.detect_text": "Detectar texto de la imagen",
   "upload_modal.edit_media": "Editar multimedia",
diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json
index 7328b2474..fc00a6270 100644
--- a/app/javascript/mastodon/locales/et.json
+++ b/app/javascript/mastodon/locales/et.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Lisa või Eemalda nimekirjadest",
   "account.badges.bot": "Robot",
   "account.badges.group": "Grupp",
@@ -16,7 +15,8 @@
   "account.follow": "Jälgi",
   "account.followers": "Jälgijad",
   "account.followers.empty": "Keegi ei jälgi seda kasutajat veel.",
-  "account.follows": "Jälgib",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "See kasutaja ei jälgi veel kedagi.",
   "account.follows_you": "Jälgib Teid",
   "account.hide_reblogs": "Peida upitused kasutajalt @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Ootab kinnitust. Klõpsa jälgimise soovi tühistamiseks",
   "account.share": "Jaga @{name} profiili",
   "account.show_reblogs": "Näita kasutaja @{name} upitusi",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Eemalda blokeering @{name}",
   "account.unblock_domain": "Tee {domain} nähtavaks",
   "account.unendorse": "Ära kuva profiilil",
   "account.unfollow": "Ära jälgi",
   "account.unmute": "Ära vaigista @{name}",
   "account.unmute_notifications": "Ära vaigista teateid kasutajalt @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Palun proovi uuesti pärast {retry_time, time, medium}.",
   "alert.rate_limited.title": "Piiratud",
   "alert.unexpected.message": "Tekkis ootamatu viga.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autoriseeri",
   "follow_request.reject": "Hülga",
   "follow_requests.unlocked_explanation": "Kuigi Teie konto pole lukustatud, soovitab {domain} personal siiski manuaalselt üle vaadata jälgimistaotlused nendelt kontodelt.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Arendajad",
   "getting_started.directory": "Profiili kataloog",
   "getting_started.documentation": "Dokumentatsioon",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {inimene} other {inimesed}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Praegu populaarne",
   "ui.beforeunload": "Teie mustand läheb kaotsi, kui lahkute Mastodonist.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Lohista & aseta üleslaadimiseks",
   "upload_button.label": "Lisa meedia (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Faili üleslaadimise limiit ületatud.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Kirjelda kuulmispuudega inimeste jaoks",
   "upload_form.description": "Kirjelda vaegnägijatele",
   "upload_form.edit": "Redigeeri",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Kustuta",
   "upload_form.video_description": "Kirjelda kuulmis- või nägemispuudega inimeste jaoks",
   "upload_modal.analyzing_picture": "Analüüsime pilti…",
   "upload_modal.apply": "Rakenda",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Kiire pruun rebane hüppab üle laisa koera",
   "upload_modal.detect_text": "Tuvasta teksti pildilt",
   "upload_modal.edit_media": "Muuda meediat",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index f122cb2a6..0a8043d4d 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Gehitu edo kendu zerrendetatik",
   "account.badges.bot": "Bot-a",
   "account.badges.group": "Taldea",
@@ -16,7 +15,8 @@
   "account.follow": "Jarraitu",
   "account.followers": "Jarraitzaileak",
   "account.followers.empty": "Ez du inork erabiltzaile hau jarraitzen oraindik.",
-  "account.follows": "Jarraitzen",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Erabiltzaile honek ez du inor jarraitzen oraindik.",
   "account.follows_you": "Jarraitzen dizu",
   "account.hide_reblogs": "Ezkutatu @{name}(r)en bultzadak",
@@ -36,16 +36,14 @@
   "account.requested": "Onarpenaren zain. Klikatu jarraitzeko eskaera ezeztatzeko",
   "account.share": "@{name}(e)ren profila elkarbanatu",
   "account.show_reblogs": "Erakutsi @{name}(r)en bultzadak",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desblokeatu @{name}",
   "account.unblock_domain": "Berriz erakutsi {domain}",
   "account.unendorse": "Ez nabarmendu profilean",
   "account.unfollow": "Utzi jarraitzeari",
   "account.unmute": "Desmututu @{name}",
   "account.unmute_notifications": "Desmututu @{name}(r)en jakinarazpenak",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Saiatu {retry_time, time, medium} barru.",
   "alert.rate_limited.title": "Abiadura mugatua",
   "alert.unexpected.message": "Ustekabeko errore bat gertatu da.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Baimendu",
   "follow_request.reject": "Ukatu",
   "follow_requests.unlocked_explanation": "Zure kontua blokeatuta ez badago ere, {domain} domeinuko arduradunek uste dute kontu hauetako jarraipen eskariak agian eskuz begiratu nahiko dituzula.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Garatzaileak",
   "getting_started.directory": "Profil-direktorioa",
   "getting_started.documentation": "Dokumentazioa",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {pertsona} other {pertsona}} hitz egiten",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Joera orain",
   "ui.beforeunload": "Zure zirriborroa galduko da Mastodon uzten baduzu.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Arrastatu eta jaregin igotzeko",
   "upload_button.label": "Gehitu multimedia  (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Fitxategi igoera muga gaindituta.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Deskribatu entzumen galera duten pertsonentzat",
   "upload_form.description": "Deskribatu ikusmen arazoak dituztenentzat",
   "upload_form.edit": "Editatu",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Ezabatu",
   "upload_form.video_description": "Deskribatu entzumen galera edo ikusmen urritasuna duten pertsonentzat",
   "upload_modal.analyzing_picture": "Irudia aztertzen…",
   "upload_modal.apply": "Aplikatu",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Vaudeville itxurako filmean yogi ñaño bat jipoitzen dute Quebec-en whiski truk",
   "upload_modal.detect_text": "Antzeman testua iruditik",
   "upload_modal.edit_media": "Editatu media",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 91236538e..6685b2ccb 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "یادداشت",
   "account.add_or_remove_from_list": "افزودن یا برداشتن از فهرست‌ها",
   "account.badges.bot": "ربات",
   "account.badges.group": "گروه",
@@ -16,7 +15,8 @@
   "account.follow": "پی بگیرید",
   "account.followers": "پی‌گیران",
   "account.followers.empty": "هنوز کسی پیگیر این کاربر نیست.",
-  "account.follows": "پی می‌گیرد",
+  "account.followers_counter": "{count, plural, one {{counter} پی‌گیر} other {{counter} پی‌گیر}}",
+  "account.following_counter": "{count, plural, other {{counter} پی می‌گیرد}}",
   "account.follows.empty": "این کاربر هنوز پیگیر کسی نیست.",
   "account.follows_you": "پیگیر شماست",
   "account.hide_reblogs": "نهفتن بازبوق‌های @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "منتظر پذیرش. برای لغو درخواست پی‌گیری کلیک کنید",
   "account.share": "هم‌رسانی نمایهٔ @{name}",
   "account.show_reblogs": "نمایش بازبوق‌های @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} بوق} other {{counter} بوق}}",
   "account.unblock": "رفع انسداد @{name}",
   "account.unblock_domain": "رفع نهفتن {domain}",
   "account.unendorse": "معرّفی نکردن در نمایه",
   "account.unfollow": "پایان پیگیری",
   "account.unmute": "رفع خموشی @{name}",
   "account.unmute_notifications": "رفع خموشی اعلان‌ها از @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "نظری فراهم نشده",
   "alert.rate_limited.message": "لطفاً پس از {retry_time, time, medium} دوباره بیازمایید.",
   "alert.rate_limited.title": "محدودیت تعداد",
   "alert.unexpected.message": "خطایی غیرمنتظره رخ داد.",
@@ -81,7 +79,7 @@
   "column_header.show_settings": "نمایش تنظیمات",
   "column_header.unpin": "رهاکردن",
   "column_subheading.settings": "تنظیمات",
-  "community.column_settings.local_only": "تنها محلّی",
+  "community.column_settings.local_only": "تنها بومی",
   "community.column_settings.media_only": "فقط رسانه",
   "community.column_settings.remote_only": "تنها دوردست",
   "compose_form.direct_message_warning": "این بوق تنها به کاربرانی که از آن‌ها نام برده شده فرستاده خواهد شد.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "اجازه دهید",
   "follow_request.reject": "رد کنید",
   "follow_requests.unlocked_explanation": "با این که حسابتان قفل نیست، کارکنان {domain} فکر کردند که ممکن است بخواهید درخواست‌ها از این حساب‌ها را به صورت دستی بازبینی کنید.",
+  "generic.saved": "ذخیره شده",
   "getting_started.developers": "توسعه‌دهندگان",
   "getting_started.directory": "فهرست نمایه",
   "getting_started.documentation": "مستندات",
@@ -335,7 +334,7 @@
   "privacy.private.long": "ارسال فقط به پی‌گیران",
   "privacy.private.short": "خصوصی",
   "privacy.public.long": "ارسال به خط‌زمانی عمومی",
-  "privacy.public.short": "عمومی",
+  "privacy.public.short": "همگانی",
   "privacy.unlisted.long": "ارسال نکردن به خط‌زمانی عمومی",
   "privacy.unlisted.short": "فهرست‌نشده",
   "refresh": "به‌روزرسانی",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "پی‌گیر",
   "timeline_hint.resources.follows": "پی می‌گیرد",
   "timeline_hint.resources.statuses": "بوق‌های قدیمی‌تر",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {نفر نوشته است} other {نفر نوشته‌اند}}",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} نفر} other {{counter} نفر}} صحبت می‌کنند",
   "trends.trending_now": "پرطرفدار",
   "ui.beforeunload": "اگر از ماستودون خارج شوید پیش‌نویس شما از دست خواهد رفت.",
+  "units.short.billion": "{count}میلیارد",
+  "units.short.million": "{count}میلیون",
+  "units.short.thousand": "{count}هزار",
   "upload_area.title": "برای بارگذاری به این‌جا بکشید",
   "upload_button.label": "افزودن رسانه ({formats})",
   "upload_error.limit": "از حد مجاز باگذاری پرونده فراتر رفتید.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "برای ناشنوایان توصیفش کنید",
   "upload_form.description": "برای کم‌بینایان توصیفش کنید",
   "upload_form.edit": "ویرایش",
+  "upload_form.thumbnail": "تغییر بندانگشتی",
   "upload_form.undo": "حذف",
   "upload_form.video_description": "برای کم‌بینایان یا ناشنوایان توصیفش کنید",
   "upload_modal.analyzing_picture": "در حال پردازش تصویر…",
   "upload_modal.apply": "اعمال",
+  "upload_modal.choose_image": "گزینش تصویر",
   "upload_modal.description_placeholder": "الا یا ایّها الساقی، ادر کأساً و ناولها",
   "upload_modal.detect_text": "تشخیص متن درون عکس",
   "upload_modal.edit_media": "ویرایش رسانه",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index d00fbd6fb..b808be172 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Lisää tai poista listoilta",
   "account.badges.bot": "Botti",
   "account.badges.group": "Ryhmä",
@@ -16,7 +15,8 @@
   "account.follow": "Seuraa",
   "account.followers": "Seuraajaa",
   "account.followers.empty": "Tällä käyttäjällä ei ole vielä seuraajia.",
-  "account.follows": "Seuraa",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Tämä käyttäjä ei vielä seuraa ketään.",
   "account.follows_you": "Seuraa sinua",
   "account.hide_reblogs": "Piilota buustaukset käyttäjältä @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Odottaa hyväksyntää. Peruuta seuraamispyyntö klikkaamalla",
   "account.share": "Jaa käyttäjän @{name} profiili",
   "account.show_reblogs": "Näytä buustaukset käyttäjältä @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Salli @{name}",
   "account.unblock_domain": "Salli {domain}",
   "account.unendorse": "Poista suosittelu profiilistasi",
   "account.unfollow": "Lakkaa seuraamasta",
   "account.unmute": "Poista käyttäjän @{name} mykistys",
   "account.unmute_notifications": "Poista mykistys käyttäjän @{name} ilmoituksilta",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Yritä uudestaan {retry_time, time, medium} jälkeen.",
   "alert.rate_limited.title": "Määrää rajoitettu",
   "alert.unexpected.message": "Tapahtui odottamaton virhe.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Valtuuta",
   "follow_request.reject": "Hylkää",
   "follow_requests.unlocked_explanation": "Vaikka tilisi ei ole lukittu, {domain} ylläpitäjien mielestä haluat tarkistaa näiden tilien seurauspyynnöt manuaalisesti.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Kehittäjille",
   "getting_started.directory": "Profiilihakemisto",
   "getting_started.documentation": "Documentaatio",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {henkilö} other {henkilöä}} keskustelee",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Suosittua nyt",
   "ui.beforeunload": "Luonnos häviää, jos poistut Mastodonista.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Lataa raahaamalla ja pudottamalla tähän",
   "upload_button.label": "Lisää mediaa",
   "upload_error.limit": "Tiedostolatauksien raja ylitetty.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Kuvaile kuulovammaisille",
   "upload_form.description": "Anna kuvaus näkörajoitteisia varten",
   "upload_form.edit": "Kuvaile",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Peru",
   "upload_form.video_description": "Kuvaile kuulo- tai näkövammaisille",
   "upload_modal.analyzing_picture": "Analysoidaan kuvaa…",
   "upload_modal.apply": "Käytä",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Eräänä jäätävänä ja pimeänä yönä gorilla ratkaisi sudokun kahdessa minuutissa",
   "upload_modal.detect_text": "Tunnista teksti kuvasta",
   "upload_modal.edit_media": "Muokkaa mediaa",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 1cbb35da3..a13bc2da9 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Ajouter ou retirer des listes",
   "account.badges.bot": "Robot",
   "account.badges.group": "Groupe",
@@ -16,7 +15,8 @@
   "account.follow": "Suivre",
   "account.followers": "Abonné·e·s",
   "account.followers.empty": "Personne ne suit cet·te utilisateur·rice pour l’instant.",
-  "account.follows": "Abonnements",
+  "account.followers_counter": "{count, plural, one {{counter} Abonné·e} other {{counter} Abonné·e·s}}",
+  "account.following_counter": "{count, plural, other {{counter} Abonnements}}",
   "account.follows.empty": "Cet·te utilisateur·rice ne suit personne pour l’instant.",
   "account.follows_you": "Vous suit",
   "account.hide_reblogs": "Masquer les partages de @{name}",
@@ -36,18 +36,16 @@
   "account.requested": "En attente d’approbation. Cliquez pour annuler la requête",
   "account.share": "Partager le profil de @{name}",
   "account.show_reblogs": "Afficher les partages de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Pouet} other {{counter} Pouets}}",
   "account.unblock": "Débloquer @{name}",
   "account.unblock_domain": "Débloquer le domaine {domain}",
   "account.unendorse": "Ne plus recommander sur le profil",
   "account.unfollow": "Ne plus suivre",
   "account.unmute": "Ne plus masquer @{name}",
   "account.unmute_notifications": "Ne plus masquer les notifications de @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Cliquez pour ajouter une note",
   "alert.rate_limited.message": "Veuillez réessayer après {retry_time, time, medium}.",
-  "alert.rate_limited.title": "Taux limité",
+  "alert.rate_limited.title": "Débit limité",
   "alert.unexpected.message": "Une erreur inattendue s’est produite.",
   "alert.unexpected.title": "Oups !",
   "announcement.announcement": "Annonce",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Accepter",
   "follow_request.reject": "Rejeter",
   "follow_requests.unlocked_explanation": "Même si votre compte n’est pas verrouillé, l’équipe de {domain} a pensé que vous pourriez vouloir consulter manuellement les demandes de suivi de ces comptes.",
+  "generic.saved": "Sauvegardé",
   "getting_started.developers": "Développeur·euse·s",
   "getting_started.directory": "Annuaire des profils",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Les abonnés",
   "timeline_hint.resources.follows": "Les abonnements",
   "timeline_hint.resources.statuses": "Les anciens pouets",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {personne discute} other {personnes discutent}}",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} personne} other {{counter} personnes}} en parle·nt",
   "trends.trending_now": "Tendance en ce moment",
   "ui.beforeunload": "Votre brouillon sera perdu si vous quittez Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Glissez et déposez pour envoyer",
   "upload_button.label": "Joindre un média ({formats})",
   "upload_error.limit": "Taille maximale d'envoi de fichier dépassée.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Décrire pour les personnes ayant des difficultés d’audition",
   "upload_form.description": "Décrire pour les malvoyant·e·s",
   "upload_form.edit": "Décrire",
+  "upload_form.thumbnail": "Changer la vignette",
   "upload_form.undo": "Supprimer",
   "upload_form.video_description": "Décrire pour les personnes ayant des problèmes d’audition ou de vision",
   "upload_modal.analyzing_picture": "Analyse de l’image en cours…",
   "upload_modal.apply": "Appliquer",
+  "upload_modal.choose_image": "Choisir une image",
   "upload_modal.description_placeholder": "Buvez de ce whisky que le patron juge fameux",
   "upload_modal.detect_text": "Détecter le texte de l’image",
   "upload_modal.edit_media": "Modifier le média",
diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json
index e893095b4..5a27ed96c 100644
--- a/app/javascript/mastodon/locales/ga.json
+++ b/app/javascript/mastodon/locales/ga.json
@@ -1,6 +1,5 @@
 {
   "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Follow",
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Awaiting approval",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unhide {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
   "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add media ({formats})",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index c29488b89..e0180a083 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "A túa nota para @{name}",
   "account.add_or_remove_from_list": "Engadir ou eliminar das listaxes",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grupo",
@@ -16,7 +15,8 @@
   "account.follow": "Seguir",
   "account.followers": "Seguidoras",
   "account.followers.empty": "Aínda ninguén segue esta usuaria.",
-  "account.follows": "Seguindo",
+  "account.followers_counter": "{count, plural, one {{counter} Seguidora} other {{counter} Seguidoras}}",
+  "account.following_counter": "{count, plural, one {} other {{counter} Seguindo}}",
   "account.follows.empty": "Esta usuaria aínda non segue a ninguén.",
   "account.follows_you": "Séguete",
   "account.hide_reblogs": "Agochar repeticións de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Agardando aprovación. Preme para desbotar a solicitude de seguimento",
   "account.share": "Compartir o perfil de @{name}",
   "account.show_reblogs": "Amosar compartidos de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Amosar {domain}",
   "account.unendorse": "Non amosar no perfil",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Deixar de silenciar a @{name}",
   "account.unmute_notifications": "Deixar de silenciar as notificacións de @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Sen comentarios",
   "alert.rate_limited.message": "Téntao novamente após {retry_time, time, medium}.",
   "alert.rate_limited.title": "Límite de intentos",
   "alert.unexpected.message": "Ocorreu un erro non agardado.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rexeitar",
   "follow_requests.unlocked_explanation": "Malia que a túa conta non é privada, a administración de {domain} pensou que quizabes terías que revisar de xeito manual as solicitudes de seguiminto.",
+  "generic.saved": "Gardado",
   "getting_started.developers": "Desenvolvedoras",
   "getting_started.directory": "Directorio local",
   "getting_started.documentation": "Documentación",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Seguidoras",
   "timeline_hint.resources.follows": "Seguindo",
   "timeline_hint.resources.statuses": "Toots antigos",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persoa} other {persoas}} falando",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} persoa} other {{counter} persoas}} comentando",
   "trends.trending_now": "Tendencias actuais",
   "ui.beforeunload": "O borrador perderase se saes de Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Arrastra e solta para subir",
   "upload_button.label": "Engadir multimedia ({formats})",
   "upload_error.limit": "Límite máximo do ficheiro a subir excedido.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describir para persoas con problemas auditivos",
   "upload_form.description": "Describir para persoas con problemas visuais",
   "upload_form.edit": "Editar",
+  "upload_form.thumbnail": "Cambiar a miniatura",
   "upload_form.undo": "Eliminar",
   "upload_form.video_description": "Describir para persoas con problemas visuais ou auditivos",
   "upload_modal.analyzing_picture": "Estase a analizar a imaxe…",
   "upload_modal.apply": "Aplicar",
+  "upload_modal.choose_image": "Elixir imaxe",
   "upload_modal.description_placeholder": "Un raposo veloz brinca sobre o can preguiceiro",
   "upload_modal.detect_text": "Detectar texto na imaxe",
   "upload_modal.edit_media": "Editar multimedia",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 4a2754e64..81e713dc3 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -1,13 +1,12 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "ההודעה שלך ל@{name}",
   "account.add_or_remove_from_list": "הוסף או הסר מהרשימות",
   "account.badges.bot": "בוט",
-  "account.badges.group": "Group",
+  "account.badges.group": "קבוצה",
   "account.block": "חסימת @{name}",
   "account.block_domain": "להסתיר הכל מהקהילה {domain}",
   "account.blocked": "חסום",
-  "account.browse_more_on_origin_server": "Browse more on the original profile",
+  "account.browse_more_on_origin_server": "המשך לגלוש בפרופיל המקורי",
   "account.cancel_follow_request": "בטל בקשת מעקב",
   "account.direct": "Direct Message @{name}",
   "account.domain_blocked": "הדומיין חסוי",
@@ -16,59 +15,58 @@
   "account.follow": "מעקב",
   "account.followers": "עוקבים",
   "account.followers.empty": "אף אחד לא עוקב אחר המשתמש הזה עדיין.",
-  "account.follows": "נעקבים",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "משתמש זה לא עוקב אחר אף אחד עדיין.",
   "account.follows_you": "במעקב אחריך",
   "account.hide_reblogs": "להסתיר הידהודים מאת @{name}",
   "account.last_status": "פעילות אחרונה",
   "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": "אזכור של @{name}",
   "account.moved_to": "החשבון {name} הועבר אל:",
   "account.mute": "להשתיק את @{name}",
   "account.mute_notifications": "להסתיר התראות מאת @{name}",
-  "account.muted": "Muted",
-  "account.never_active": "Never",
+  "account.muted": "מושתק",
+  "account.never_active": "אף פעם",
   "account.posts": "הודעות",
   "account.posts_with_replies": "Toots with replies",
   "account.report": "לדווח על @{name}",
   "account.requested": "בהמתנה לאישור",
   "account.share": "לשתף את הפרופיל של @{name}",
   "account.show_reblogs": "להראות הדהודים מאת @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "הסרת חסימה מעל @{name}",
   "account.unblock_domain": "הסר חסימה מקהילת {domain}",
   "account.unendorse": "לא להציג בפרופיל",
   "account.unfollow": "הפסקת מעקב",
   "account.unmute": "הפסקת השתקת @{name}",
   "account.unmute_notifications": "להפסיק הסתרת הודעות מעם @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
-  "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
-  "alert.rate_limited.title": "Rate limited",
+  "account_note.placeholder": "ללא הערה",
+  "alert.rate_limited.message": "נא לנסות אחרי {retry_time, time, medium}.",
+  "alert.rate_limited.title": "מגבלות מיכסה",
   "alert.unexpected.message": "אירעה שגיאה בלתי צפויה.",
   "alert.unexpected.title": "אופס!",
-  "announcement.announcement": "Announcement",
-  "autosuggest_hashtag.per_week": "{count} per week",
+  "announcement.announcement": "הודעה",
+  "autosuggest_hashtag.per_week": "{count} לשבוע",
   "boost_modal.combo": "ניתן להקיש {combo} כדי לדלג בפעם הבאה",
   "bundle_column_error.body": "משהו השתבש בעת הצגת הרכיב הזה.",
   "bundle_column_error.retry": "לנסות שוב",
-  "bundle_column_error.title": "Network error",
+  "bundle_column_error.title": "שגיאת רשת",
   "bundle_modal_error.close": "לסגור",
   "bundle_modal_error.message": "משהו השתבש בעת טעינת הרכיב הזה.",
   "bundle_modal_error.retry": "לנסות שוב",
   "column.blocks": "חסימות",
-  "column.bookmarks": "Bookmarks",
+  "column.bookmarks": "סימניות",
   "column.community": "ציר זמן מקומי",
-  "column.direct": "Direct messages",
-  "column.directory": "Browse profiles",
+  "column.direct": "הודעות ישירות",
+  "column.directory": "גלוש פרופילים",
   "column.domain_blocks": "Hidden domains",
   "column.favourites": "חיבובים",
   "column.follow_requests": "בקשות מעקב",
   "column.home": "בבית",
-  "column.lists": "Lists",
+  "column.lists": "רשימות",
   "column.mutes": "השתקות",
   "column.notifications": "התראות",
   "column.pins": "Pinned toot",
@@ -81,11 +79,11 @@
   "column_header.show_settings": "הצגת העדפות",
   "column_header.unpin": "שחרור קיבוע",
   "column_subheading.settings": "אפשרויות",
-  "community.column_settings.local_only": "Local only",
+  "community.column_settings.local_only": "מקומי בלבד",
   "community.column_settings.media_only": "Media only",
-  "community.column_settings.remote_only": "Remote only",
+  "community.column_settings.remote_only": "מרחוק בלבד",
   "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "compose_form.direct_message_warning_learn_more": "מידע נוסף",
   "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
   "compose_form.lock_disclaimer": "חשבונך אינו {locked}. כל אחד יוכל לעקוב אחריך כדי לקרוא את הודעותיך המיועדות לעוקבים בלבד.",
   "compose_form.lock_disclaimer.lock": "נעול",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "קבלה",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "הטיוטא תאבד אם תעזבו את מסטודון.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "ניתן להעלות על ידי Drag & drop",
   "upload_button.label": "הוספת מדיה",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "תיאור לכבדי ראיה",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "ביטול",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json
index 0ca745020..4cc12830f 100644
--- a/app/javascript/mastodon/locales/hi.json
+++ b/app/javascript/mastodon/locales/hi.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "सूची में जोड़ें या हटाए",
   "account.badges.bot": "बॉट",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "फॉलो करें",
   "account.followers": "फॉलोवर",
   "account.followers.empty": "कोई भी इस यूज़र् को फ़ॉलो नहीं करता है",
-  "account.follows": "फॉलो करें",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "यह यूज़र् अभी तक किसी को फॉलो नहीं करता है।",
   "account.follows_you": "आपको फॉलो करता है",
   "account.hide_reblogs": "@{name} के बूस्ट छुपाएं",
@@ -36,16 +36,14 @@
   "account.requested": "मंजूरी का इंतजार। फॉलो रिक्वेस्ट को रद्द करने के लिए क्लिक करें",
   "account.share": "@{name} की प्रोफाइल शेयर करे",
   "account.show_reblogs": "@{name} के बूस्ट दिखाए",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} को अनब्लॉक करें",
   "account.unblock_domain": "{domain} दिखाए",
   "account.unendorse": "प्रोफ़ाइल पर न दिखाए",
   "account.unfollow": "अनफॉलो करें",
   "account.unmute": "अनम्यूट @{name}",
   "account.unmute_notifications": "@{name} के नोटिफिकेशन अनम्यूट करे",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "कृप्या {retry_time, time, medium} के बाद दुबारा कोशिश करें",
   "alert.rate_limited.title": "सीमित दर",
   "alert.unexpected.message": "एक अप्रत्याशित त्रुटि हुई है!",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "अधिकार दें",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "डेवॅलपर्स",
   "getting_started.directory": "प्रोफ़ाइल निर्देशिका",
   "getting_started.documentation": "प्रलेखन",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "संशोधन करें",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "मिटाए",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "लागू करें",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "मीडिया में संशोधन करें",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index 48f776982..a7e13b2eb 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Slijedi",
   "account.followers": "Sljedbenici",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Slijedi",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "te slijedi",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Čeka pristanak",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Deblokiraj @{name}",
   "account.unblock_domain": "Poništi sakrivanje {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Prestani slijediti",
   "account.unmute": "Poništi utišavanje @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autoriziraj",
   "follow_request.reject": "Odbij",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Povuci i spusti kako bi uploadao",
   "upload_button.label": "Dodaj media",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Poništi",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 2ea401870..713abba5f 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Megjegyzés @{name} fiókhoz",
   "account.add_or_remove_from_list": "Hozzáadás vagy eltávolítás a listáról",
   "account.badges.bot": "Bot",
   "account.badges.group": "Csoport",
@@ -16,7 +15,8 @@
   "account.follow": "Követés",
   "account.followers": "Követő",
   "account.followers.empty": "Ezt a felhasználót még senki sem követi.",
-  "account.follows": "Követések",
+  "account.followers_counter": "{count, plural, one {{counter} Követő} other {{counter} Követő}}",
+  "account.following_counter": "{count, plural, one {} other {{counter} Követett}}",
   "account.follows.empty": "Ez a felhasználó még senkit sem követ.",
   "account.follows_you": "Követ téged",
   "account.hide_reblogs": "@{name} megtolásainak némítása",
@@ -36,16 +36,14 @@
   "account.requested": "Engedélyre vár. Kattints a követési kérés visszavonásához",
   "account.share": "@{name} profiljának megosztása",
   "account.show_reblogs": "@{name} megtolásainak mutatása",
+  "account.statuses_counter": "{count, plural, one {{counter} Tülk} other {{counter} Tülk}}",
   "account.unblock": "@{name} letiltásának feloldása",
   "account.unblock_domain": "{domain} elrejtésének feloldása",
   "account.unendorse": "Kiemelés törlése a profilodról",
   "account.unfollow": "Követés vége",
   "account.unmute": "@{name} némítás feloldása",
   "account.unmute_notifications": "@{name} némított értesítéseinek feloldása",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Nincs megjegyzés",
   "alert.rate_limited.message": "Próbáld újra {retry_time, time, medium} után.",
   "alert.rate_limited.title": "Forgalomkorlátozás",
   "alert.unexpected.message": "Váratlan hiba történt.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Engedélyezés",
   "follow_request.reject": "Elutasítás",
   "follow_requests.unlocked_explanation": "Bár a fiókod nincs zárolva, a(z) {domain} csapata úgy gondolta, hogy talán kézzel szeretnéd ellenőrizni a fiók követési kéréseit.",
+  "generic.saved": "Elmentve",
   "getting_started.developers": "Fejlesztőknek",
   "getting_started.directory": "Profilok",
   "getting_started.documentation": "Dokumentáció",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Követő",
   "timeline_hint.resources.follows": "Követett",
   "timeline_hint.resources.statuses": "Régi tülkök",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {résztvevő} other {résztvevő}} beszélget",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} személy} other {{counter} személy}} beszélget",
   "trends.trending_now": "Most felkapott",
   "ui.beforeunload": "A piszkozatod el fog veszni, ha elhagyod a Mastodont.",
+  "units.short.billion": "{count}Mrd",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Húzd ide a feltöltéshez",
   "upload_button.label": "Média hozzáadása ({formats})",
   "upload_error.limit": "Túllépted a fájlfeltöltési korlátot.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Írja le a hallássérültek számára",
   "upload_form.description": "Leírás látáskorlátozottak számára",
   "upload_form.edit": "Szerkesztés",
+  "upload_form.thumbnail": "Előnézet megváltoztatása",
   "upload_form.undo": "Törlés",
   "upload_form.video_description": "Írja le a hallás- vagy látássérültek számára",
   "upload_modal.analyzing_picture": "Kép elemzése…",
   "upload_modal.apply": "Alkalmaz",
+  "upload_modal.choose_image": "Kép kiválasztása",
   "upload_modal.description_placeholder": "A gyors, barna róka átugrik a lusta kutya fölött",
   "upload_modal.detect_text": "Szöveg felismerése a képről",
   "upload_modal.edit_media": "Média szerkesztése",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index 4c1547a69..29810cd9f 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Աւելացնել կամ հեռացնել ցանկերից",
   "account.badges.bot": "Բոտ",
   "account.badges.group": "Խումբ",
@@ -16,7 +15,8 @@
   "account.follow": "Հետեւել",
   "account.followers": "Հետեւողներ",
   "account.followers.empty": "Այս օգտատիրոջը դեռ ոչ մէկ չի հետեւում։",
-  "account.follows": "Հետեւում է",
+  "account.followers_counter": "{count, plural, one {{counter} Հետևորդ} other {{counter} Հետևորդներ}}",
+  "account.following_counter": "{count, plural, one {} other {{counter} Հետևում են}}",
   "account.follows.empty": "Այս օգտատէրը դեռ ոչ մէկի չի հետեւում։",
   "account.follows_you": "Հետեւում է քեզ",
   "account.hide_reblogs": "Թաքցնել @{name}֊ի տարածածները",
@@ -36,16 +36,14 @@
   "account.requested": "Հաստատման կարիք ունի։ Սեղմիր՝ հետեւելու հայցը չեղարկելու համար։",
   "account.share": "Կիսուել @{name}֊ի էջով",
   "account.show_reblogs": "Ցուցադրել @{name}֊ի տարածածները",
+  "account.statuses_counter": "{count, plural, one {{counter} Թութ} other {{counter} Թութեր}}",
   "account.unblock": "Ապաարգելափակել @{name}֊ին",
   "account.unblock_domain": "Ցուցադրել {domain} թաքցուած տիրոյթի գրառումները",
   "account.unendorse": "Չցուցադրել անձնական էջում",
   "account.unfollow": "Ապահետեւել",
   "account.unmute": "Ապալռեցնել @{name}֊ին",
   "account.unmute_notifications": "Միացնել ծանուցումները @{name}֊ից",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Փորձէք  որոշ ժամանակ անց՝ {retry_time, time, medium}։",
   "alert.rate_limited.title": "Գործողութիւնների յաճախութիւնը գերազանցում է թոյլատրելին",
   "alert.unexpected.message": "Անսպասելի սխալ տեղի ունեցաւ։",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Վավերացնել",
   "follow_request.reject": "Մերժել",
   "follow_requests.unlocked_explanation": "Այս հարցումը ուղարկված է հաշվից, որի համար {domain}-ի անձնակազմը միացրել է ձեռքով ստուգում։",
+  "generic.saved": "Պահպանված է",
   "getting_started.developers": "Մշակողներ",
   "getting_started.directory": "Օգտատէրերի շտեմարան",
   "getting_started.documentation": "Փաստաթղթեր",
@@ -421,12 +420,15 @@
   "time_remaining.moments": "Մնացել է մի քանի վարկեան",
   "time_remaining.seconds": "{number, plural, one {# վարկեան} other {# վարկեան}} անց",
   "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
-  "timeline_hint.resources.followers": "Followers",
-  "timeline_hint.resources.follows": "Follows",
-  "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {հոգի} other {հոգի}} խոսում է սրա մասին",
+  "timeline_hint.resources.followers": "Հետևորդներ",
+  "timeline_hint.resources.follows": "Հետևել",
+  "timeline_hint.resources.statuses": "Հին թութեր",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} մարդ} other {{counter} մարդիկ}} խոսում են",
   "trends.trending_now": "Այժմ արդիական",
   "ui.beforeunload": "Քո սեւագիրը կկորի, եթե լքես Մաստոդոնը։",
+  "units.short.billion": "{count}մլրդ",
+  "units.short.million": "{count}մլն",
+  "units.short.thousand": "{count}Հազ.",
   "upload_area.title": "Քաշիր ու նետիր՝ վերբեռնելու համար",
   "upload_button.label": "Ավելացնել մեդիա",
   "upload_error.limit": "Ֆայլի վերբեռնման սահմանաչափը գերազանցված է։",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Նկարագրիր ձայնագրութեան բովանդակութիւնը լսողական խնդիրներով անձանց համար",
   "upload_form.description": "Նկարագիր՝ տեսողական խնդիրներ ունեցողների համար",
   "upload_form.edit": "Խմբագրել",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Հետարկել",
   "upload_form.video_description": "Նկարագրիր տեսանիւթը լսողական կամ տեսողական խնդիրներով անձանց համար",
   "upload_modal.analyzing_picture": "Լուսանկարի վերլուծում…",
   "upload_modal.apply": "Կիրառել",
+  "upload_modal.choose_image": "Ընտրել նկար",
   "upload_modal.description_placeholder": "Բել դղյակի ձախ ժամն օֆ ազգությանը ցպահանջ չճշտած վնաս էր եւ փառք։",
   "upload_modal.detect_text": "Հայտնբերել տեքստը նկարից",
   "upload_modal.edit_media": "Խմբագրել մեդիան",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index f3080d4fc..5b0f345af 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Tambah atau Hapus dari daftar",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grup",
@@ -16,7 +15,8 @@
   "account.follow": "Ikuti",
   "account.followers": "Pengikut",
   "account.followers.empty": "Tidak ada satupun yang mengkuti pengguna ini saat ini.",
-  "account.follows": "Mengikuti",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Pengguna ini belum mengikuti siapapun.",
   "account.follows_you": "Mengikuti anda",
   "account.hide_reblogs": "Sembunyikan boosts dari @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Menunggu persetujuan. Klik untuk membatalkan permintaan",
   "account.share": "Bagikan profil @{name}",
   "account.show_reblogs": "Tampilkan boost dari @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Hapus blokir @{name}",
   "account.unblock_domain": "Tampilkan {domain}",
   "account.unendorse": "Jangan tampilkan di profil",
   "account.unfollow": "Berhenti mengikuti",
   "account.unmute": "Berhenti membisukan @{name}",
   "account.unmute_notifications": "Munculkan notifikasi dari @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Tolong ulangi setelah {retry_time, time, medium}.",
   "alert.rate_limited.title": "Batasan tingkat",
   "alert.unexpected.message": "Terjadi kesalahan yang tidak terduga.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Izinkan",
   "follow_request.reject": "Tolak",
   "follow_requests.unlocked_explanation": "Meskipun akun Anda tidak dikunci, staf {domain} menyarankan Anda untuk meninjau permintaan mengikuti dari akun-akun ini secara manual.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Pengembang",
   "getting_started.directory": "Direktori profil",
   "getting_started.documentation": "Dokumentasi",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, other {orang}} berbicara",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Sedang tren sekarang",
   "ui.beforeunload": "Naskah anda akan hilang jika anda keluar dari Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Seret & lepaskan untuk mengunggah",
   "upload_button.label": "Tambahkan media",
   "upload_error.limit": "Batas unggah berkas terlampaui.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Penjelasan untuk orang dengan gangguan pendengaran",
   "upload_form.description": "Deskripsikan untuk mereka yang tidak bisa melihat dengan jelas",
   "upload_form.edit": "Sunting",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Undo",
   "upload_form.video_description": "Penjelasan untuk orang dengan gangguan pendengaran atau penglihatan",
   "upload_modal.analyzing_picture": "Analisis gambar…",
   "upload_modal.apply": "Terapkan",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Muharjo seorang xenofobia universal yang takut pada warga jazirah, contohnya Qatar",
   "upload_modal.detect_text": "Deteksi teks pada gambar",
   "upload_modal.edit_media": "Sunting media",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index 05c8ffd02..45e74b675 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Sequar",
   "account.followers": "Sequanti",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Sequas",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Sequas tu",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Vartante aprobo",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desblokusar @{name}",
   "account.unblock_domain": "Unhide {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Ne plus sequar",
   "account.unmute": "Ne plus celar @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Yurizar",
   "follow_request.reject": "Refuzar",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Tranar faligar por kargar",
   "upload_button.label": "Adjuntar kontenajo",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Desfacar",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json
index 547b6c061..4a281cf80 100644
--- a/app/javascript/mastodon/locales/is.json
+++ b/app/javascript/mastodon/locales/is.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Minnispunkturinn þinn fyrir @{name}",
   "account.add_or_remove_from_list": "Bæta á eða fjarlægja af listum",
   "account.badges.bot": "Róbót",
   "account.badges.group": "Hópur",
@@ -16,7 +15,8 @@
   "account.follow": "Fylgjast með",
   "account.followers": "Fylgjendur",
   "account.followers.empty": "Ennþá fylgist enginn með þessum notanda.",
-  "account.follows": "Fylgist með",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Þessi notandi fylgist ennþá ekki með neinum.",
   "account.follows_you": "Fylgir þér",
   "account.hide_reblogs": "Fela endurbirtingar fyrir @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Bíður eftir samþykki. Smelltu til að hætta við beiðni um að fylgjast með",
   "account.share": "Deila notandasniði fyrir @{name}",
   "account.show_reblogs": "Sýna endurbirtingar frá @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Aflétta útilokun af @{name}",
   "account.unblock_domain": "Hætta að fela {domain}",
   "account.unendorse": "Ekki birta á notandasniði",
   "account.unfollow": "Hætta að fylgja",
   "account.unmute": "Hætta að þagga niður í @{name}",
   "account.unmute_notifications": "Hætta að þagga tilkynningar frá @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Engin athugasemd gefin",
   "alert.rate_limited.message": "Prófaðu aftur eftir {retry_time, time, medium}.",
   "alert.rate_limited.title": "Með takmörkum",
   "alert.unexpected.message": "Upp kom óvænt villa.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Heimila",
   "follow_request.reject": "Hafna",
   "follow_requests.unlocked_explanation": "Jafnvel þótt aðgangurinn þinn sé ekki læstur, hafa umsjónarmenn {domain} ímyndað sér að þú gætir viljað yfirfara handvirkt fylgjendabeiðnir frá þessum notendum.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Forritarar",
   "getting_started.directory": "Notandasniðamappa",
   "getting_started.documentation": "Hjálparskjöl",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Fylgjendur",
   "timeline_hint.resources.follows": "Fylgist með",
   "timeline_hint.resources.statuses": "Eldri tíst",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {aðili} other {aðilar}} að tala",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Í umræðunni núna",
   "ui.beforeunload": "Drögin tapast ef þú ferð út úr Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Dragðu-og-slepptu hér til að senda inn",
   "upload_button.label": "Bæta við ({formats}) myndskrá",
   "upload_error.limit": "Fór yfir takmörk á innsendingum skráa.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Lýstu þessu fyrir heyrnarskerta",
   "upload_form.description": "Lýstu þessu fyrir sjónskerta",
   "upload_form.edit": "Breyta",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Eyða",
   "upload_form.video_description": "Lýstu þessu fyrir fólk sem heyrir illa eða er með skerta sjón",
   "upload_modal.analyzing_picture": "Greini mynd…",
   "upload_modal.apply": "Virkja",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Öllum dýrunum í skóginum þætti bezt að vera vinir",
   "upload_modal.detect_text": "Skynja texta úr mynd",
   "upload_modal.edit_media": "Breyta myndskrá",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 03597e06f..077f61e48 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "La tua nota per @{name}",
   "account.add_or_remove_from_list": "Aggiungi o Rimuovi dagli elenchi",
   "account.badges.bot": "Bot",
   "account.badges.group": "Gruppo",
@@ -16,7 +15,8 @@
   "account.follow": "Segui",
   "account.followers": "Seguaci",
   "account.followers.empty": "Ancora nessuno segue questo utente.",
-  "account.follows": "Segue",
+  "account.followers_counter": "{count, plural, one {{counter} Seguace} other {{counter} Seguaci}}",
+  "account.following_counter": "{count, plural, other {{counter} Seguiti}}",
   "account.follows.empty": "Questo utente non segue ancora nessuno.",
   "account.follows_you": "Ti segue",
   "account.hide_reblogs": "Nascondi incrementi da @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "In attesa di approvazione. Clicca per annullare la richiesta di seguire",
   "account.share": "Condividi il profilo di @{name}",
   "account.show_reblogs": "Mostra incrementi da @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toot}}",
   "account.unblock": "Sblocca @{name}",
   "account.unblock_domain": "Sblocca il dominio {domain}",
   "account.unendorse": "Non mostrare sul profilo",
   "account.unfollow": "Smetti di seguire",
   "account.unmute": "Non silenziare @{name}",
   "account.unmute_notifications": "Non silenziare le notifiche da @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Nessun commento fornito",
   "alert.rate_limited.message": "Sei pregato di riprovare tra {retry_time, time, medium}.",
   "alert.rate_limited.title": "Intervallo limitato",
   "alert.unexpected.message": "Si è verificato un errore inatteso.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizza",
   "follow_request.reject": "Rifiuta",
   "follow_requests.unlocked_explanation": "Anche se il tuo account non è bloccato, lo staff di {domain} ha pensato che potresti voler esaminare manualmente le richieste di seguirti di questi account.",
+  "generic.saved": "Salvato",
   "getting_started.developers": "Sviluppatori",
   "getting_started.directory": "Directory dei profili",
   "getting_started.documentation": "Documentazione",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Seguaci",
   "timeline_hint.resources.follows": "Segue",
   "timeline_hint.resources.statuses": "Toot meno recenti",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persona ne sta} other {persone ne stanno}} parlando",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} persone}} ne parla·no",
   "trends.trending_now": "Di tendenza ora",
   "ui.beforeunload": "La bozza andrà persa se esci da Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Trascina per caricare",
   "upload_button.label": "Aggiungi file multimediale",
   "upload_error.limit": "Limite al caricamento di file superato.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Descrizione per persone con difetti uditivi",
   "upload_form.description": "Descrizione per utenti con disabilità visive",
   "upload_form.edit": "Modifica",
+  "upload_form.thumbnail": "Cambia miniatura",
   "upload_form.undo": "Cancella",
   "upload_form.video_description": "Descrizione per persone con difetti uditivi o visivi",
   "upload_modal.analyzing_picture": "Analisi immagine…",
   "upload_modal.apply": "Applica",
+  "upload_modal.choose_image": "Scegli immagine",
   "upload_modal.description_placeholder": "Ma la volpe col suo balzo ha raggiunto il quieto Fido",
   "upload_modal.detect_text": "Rileva testo dall'immagine",
   "upload_modal.edit_media": "Modifica media",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 9b3337666..8bf63287c 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "メモ",
   "account.add_or_remove_from_list": "リストから追加または外す",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "フォロー",
   "account.followers": "フォロワー",
   "account.followers.empty": "まだ誰もフォローしていません。",
-  "account.follows": "フォロー",
+  "account.followers_counter": "{counter} フォロワー",
+  "account.following_counter": "{counter} フォロー",
   "account.follows.empty": "まだ誰もフォローしていません。",
   "account.follows_you": "フォローされています",
   "account.hide_reblogs": "@{name}さんからのブーストを非表示",
@@ -36,16 +36,14 @@
   "account.requested": "フォロー承認待ちです。クリックしてキャンセル",
   "account.share": "@{name}さんのプロフィールを共有する",
   "account.show_reblogs": "@{name}さんからのブーストを表示",
+  "account.statuses_counter": "{counter} トゥート",
   "account.unblock": "@{name}さんのブロックを解除",
   "account.unblock_domain": "{domain}のブロックを解除",
   "account.unendorse": "プロフィールから外す",
   "account.unfollow": "フォロー解除",
   "account.unmute": "@{name}さんのミュートを解除",
   "account.unmute_notifications": "@{name}さんからの通知を受け取るようにする",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "クリックしてメモを追加",
   "alert.rate_limited.message": "{retry_time, time, medium} 以降に再度実行してください。",
   "alert.rate_limited.title": "制限に達しました",
   "alert.unexpected.message": "不明なエラーが発生しました。",
@@ -178,6 +176,7 @@
   "follow_request.authorize": "許可",
   "follow_request.reject": "拒否",
   "follow_requests.unlocked_explanation": "あなたのアカウントは承認制ではありませんが、{domain} のスタッフはこれらのアカウントからのフォローリクエストの確認が必要であると判断しました。",
+  "generic.saved": "保存しました",
   "getting_started.developers": "開発",
   "getting_started.directory": "ディレクトリ",
   "getting_started.documentation": "ドキュメント",
@@ -429,9 +428,12 @@
   "timeline_hint.resources.followers": "フォロワー",
   "timeline_hint.resources.follows": "フォロー",
   "timeline_hint.resources.statuses": "以前のトゥート",
-  "trends.count_by_accounts": "{count}人がトゥート",
+  "trends.counter_by_accounts": "{counter} 人がトゥート",
   "trends.trending_now": "トレンドタグ",
   "ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "ドラッグ&ドロップでアップロード",
   "upload_button.label": "メディアを追加 (複数の画像または1つの動画か音声ファイル)",
   "upload_error.limit": "アップロードできる上限を超えています。",
@@ -439,10 +441,12 @@
   "upload_form.audio_description": "聴取が難しいユーザーへの説明",
   "upload_form.description": "閲覧が難しいユーザーへの説明",
   "upload_form.edit": "説明",
+  "upload_form.thumbnail": "サムネイルを変更",
   "upload_form.undo": "削除",
   "upload_form.video_description": "視聴が難しいユーザーへの説明",
   "upload_modal.analyzing_picture": "画像を解析中…",
   "upload_modal.apply": "適用",
+  "upload_modal.choose_image": "画像を選択",
   "upload_modal.description_placeholder": "あのイーハトーヴォのすきとおった風",
   "upload_modal.detect_text": "画像からテキストを検出",
   "upload_modal.edit_media": "メディアを編集",
diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json
index 720dfe4c7..36f27e69d 100644
--- a/app/javascript/mastodon/locales/ka.json
+++ b/app/javascript/mastodon/locales/ka.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "ბოტი",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "გაყოლა",
   "account.followers": "მიმდევრები",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "მიდევნებები",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "მოგყვებათ",
   "account.hide_reblogs": "დაიმალოს ბუსტები @{name}-სგან",
@@ -36,16 +36,14 @@
   "account.requested": "დამტკიცების მოლოდინში. დააწკაპუნეთ რომ უარყოთ დადევნების მოთხონვა",
   "account.share": "გააზიარე @{name}-ის პროფილი",
   "account.show_reblogs": "აჩვენე ბუსტები @{name}-სგან",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "განბლოკე @{name}",
   "account.unblock_domain": "გამოაჩინე {domain}",
   "account.unendorse": "არ გამოირჩეს პროფილზე",
   "account.unfollow": "ნუღარ მიჰყვები",
   "account.unmute": "ნუღარ აჩუმებ @{name}-ს",
   "account.unmute_notifications": "ნუღარ აჩუმებ შეტყობინებებს @{name}-სგან",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "წარმოიშვა მოულოდნელი შეცდომა.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "ავტორიზაცია",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "დეველოპერები",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "დოკუმენტაცია",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} საუბრობს",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "თქვენი დრაფტი გაუქმდება თუ დატოვებთ მასტოდონს.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "გადმოწიეთ და ჩააგდეთ ასატვირთათ",
   "upload_button.label": "მედიის დამატება",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "აღწერილობა ვიზუალურად უფასურისთვის",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "გაუქმება",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json
index 1eccc74ee..dceb434d3 100644
--- a/app/javascript/mastodon/locales/kab.json
+++ b/app/javascript/mastodon/locales/kab.json
@@ -1,22 +1,22 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Tazmilt-ik·im i @{name}",
   "account.add_or_remove_from_list": "Rnu neɣ kkes seg tebdarin",
   "account.badges.bot": "Aṛubut",
   "account.badges.group": "Agraw",
   "account.block": "Seḥbes @{name}",
   "account.block_domain": "Ffer kra i d-yekkan seg {domain}",
-  "account.blocked": "Yettuseḥbes",
-  "account.browse_more_on_origin_server": "Browse more on the original profile",
-  "account.cancel_follow_request": "Sefsex asuter n uḍfaṛ",
+  "account.blocked": "Yettusewḥel",
+  "account.browse_more_on_origin_server": "Snirem ugar deg umeɣnu aneẓli",
+  "account.cancel_follow_request": "Sefsex asuter n uḍfar",
   "account.direct": "Izen usrid i @{name}",
   "account.domain_blocked": "Taɣult yeffren",
   "account.edit_profile": "Ẓreg amaɣnu",
   "account.endorse": "Welleh fell-as deg umaɣnu-inek",
-  "account.follow": "Ḍfeṛ",
-  "account.followers": "Imeḍfaṛen",
+  "account.follow": "Ḍfer",
+  "account.followers": "Imeḍfaren",
   "account.followers.empty": "Ar tura, ulac yiwen i yeṭṭafaṛen amseqdac-agi.",
-  "account.follows": "I yeṭṭafaṛ",
+  "account.followers_counter": "{count, plural, one {{count} n umeḍfar} other {{count} n imeḍfaren}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Ar tura, amseqdac-agi ur yeṭṭafaṛ yiwen.",
   "account.follows_you": "Yeṭṭafaṛ-ik",
   "account.hide_reblogs": "Ffer ayen i ibeṭṭu @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Di laɛḍil ad yettwaqbel. Ssit i wakken ad yefsex usuter n uḍfar",
   "account.share": "Bḍu amaɣnu n @{name}",
   "account.show_reblogs": "Ssken-d inebḍa n @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Serreḥ i @{name}",
   "account.unblock_domain": "Ssken-d {domain}",
   "account.unendorse": "Ur ttwellih ara fell-as deg umaɣnu-inek",
   "account.unfollow": "Ur ṭṭafaṛ ara",
   "account.unmute": "Kkes asgugem ɣef @{name}",
   "account.unmute_notifications": "Serreḥ ilɣa sɣur @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Ulac iwenniten",
   "alert.rate_limited.message": "Ma ulac aɣilif ɛreḍ tikelt-nniḍen akka {retry_time, time, medium}.",
   "alert.rate_limited.title": "Aktum s talast",
   "alert.unexpected.message": "Yeḍra-d unezri ur netturaǧu ara.",
@@ -83,7 +81,7 @@
   "column_subheading.settings": "Iɣewwaṛen",
   "community.column_settings.local_only": "Adigan kan",
   "community.column_settings.media_only": "Allal n teywalt kan",
-  "community.column_settings.remote_only": "Remote only",
+  "community.column_settings.remote_only": "Anmeggag kan",
   "compose_form.direct_message_warning": "Tajewwaqt-a ad d-tettwasken kan i yimseqdacen i d-yettwabedren.",
   "compose_form.direct_message_warning_learn_more": "Issin ugar",
   "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
@@ -145,7 +143,7 @@
   "emoji_button.objects": "Tiɣawsiwin",
   "emoji_button.people": "Medden",
   "emoji_button.recent": "Wid yettuseqdacen s waṭas",
-  "emoji_button.search": "Nadi…",
+  "emoji_button.search": "Nadi...",
   "emoji_button.search_results": "Igemmaḍ n unadi",
   "emoji_button.symbols": "Izamulen",
   "emoji_button.travel": "Imeḍqan d Yinigen",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Ssireg",
   "follow_request.reject": "Agi",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Yettwasekles",
   "getting_started.developers": "Ineflayen",
   "getting_started.directory": "Akaram n imaɣnuten",
   "getting_started.documentation": "Amnir",
@@ -237,15 +236,15 @@
   "keyboard_shortcuts.muted": "akken ad teldiḍ tabdart n yimseqdacen yettwasgugmen",
   "keyboard_shortcuts.my_profile": "akken ad d-teldiḍ amaɣnu-ik",
   "keyboard_shortcuts.notifications": "akken ad d-teldiḍ ajgu n tilɣa",
-  "keyboard_shortcuts.open_media": "i taɣwalin yeldin ",
+  "keyboard_shortcuts.open_media": "i tiɣwalin yeldin",
   "keyboard_shortcuts.pinned": "akken ad teldiḍ tabdart n tjewwiqin yettwasentḍen",
   "keyboard_shortcuts.profile": "akken ad d-teldiḍ amaɣnu n umeskar",
   "keyboard_shortcuts.reply": "i tririt",
   "keyboard_shortcuts.requests": "akken ad d-teldiḍ tabdert n yisuturen n teḍfeṛt",
   "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.spoilers": "to show/hide CW field",
+  "keyboard_shortcuts.spoilers": "i uskan/tuffra n wurti CW",
   "keyboard_shortcuts.start": "akken ad d-teldiḍ ajgu n \"bdu\"",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_hidden": "i uskan/tuffra n uḍris deffir CW",
   "keyboard_shortcuts.toggle_sensitivity": "i teskent/tuffra n yimidyaten",
   "keyboard_shortcuts.toot": "i wakken attebdud tajewwaqt tamaynut",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
@@ -311,11 +310,11 @@
   "notifications.column_settings.mention": "Abdar:",
   "notifications.column_settings.poll": "Igemmaḍ n usenqed:",
   "notifications.column_settings.push": "Tilɣa yettudemmren",
-  "notifications.column_settings.reblog": "Boosts:",
+  "notifications.column_settings.reblog": "Seǧhed:",
   "notifications.column_settings.show": "Ssken-d tilɣa deg ujgu",
   "notifications.column_settings.sound": "Rmed imesli",
   "notifications.filter.all": "Akk",
-  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.boosts": "Seǧhed",
   "notifications.filter.favourites": "Ismenyifen",
   "notifications.filter.follows": "Yeṭafaṛ",
   "notifications.filter.mentions": "Abdar",
@@ -376,7 +375,7 @@
   "status.delete": "Kkes",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Izen usrid i @{name}",
-  "status.embed": "Embed",
+  "status.embed": "Seddu",
   "status.favourite": "Rnu ɣer yismenyifen",
   "status.filtered": "Yettwasizdeg",
   "status.load_more": "Sali ugar",
@@ -420,24 +419,29 @@
   "time_remaining.minutes": "Mazal {number, plural, one {# n tesdat} other {# n tesdatin}}",
   "time_remaining.moments": "Moments remaining",
   "time_remaining.seconds": "Mazal {number, plural, one {# n tasint} other {# n tsinin}} id yugran",
-  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
+  "timeline_hint.remote_resource_not_displayed": "{resource} seg yiqeddacen-nniḍen ur d-ttwaskanent ara.",
   "timeline_hint.resources.followers": "Imeḍfaṛen",
   "timeline_hint.resources.follows": "T·Yeṭafaṛ",
-  "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {n umdan} other {n yemdanen}} i yettmeslayen",
+  "timeline_hint.resources.statuses": "Tijewwaqin tiqdimin",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Arewway-ik·im ad iruḥ ma yella tefeɣ-d deg Maṣṭudun.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Zuḥeb rnu sers i tasalyt",
   "upload_button.label": "Rnu taɣwalt ({formats})",
-  "upload_error.limit": "File upload limit exceeded.",
-  "upload_error.poll": "File upload not allowed with polls.",
+  "upload_error.limit": "Asali n ufaylu iεedda talast.",
+  "upload_error.poll": "Ur ittusireg ara usali n ufaylu s tefranin.",
   "upload_form.audio_description": "Glem-d i yemdanen i yesɛan ugur deg tmesliwt",
   "upload_form.description": "Glem-d i yemdaneni yesɛan ugur deg yiẓri",
   "upload_form.edit": "Ẓreg",
+  "upload_form.thumbnail": "Beddel tugna",
   "upload_form.undo": "Kkes",
   "upload_form.video_description": "Glem-d i yemdanen i yesɛan ugur deg tmesliwt neɣ deg yiẓri",
   "upload_modal.analyzing_picture": "Tasleḍt n tugna tetteddu…",
   "upload_modal.apply": "Snes",
+  "upload_modal.choose_image": "Fren tugna",
   "upload_modal.description_placeholder": "Aberraɣ arurad ineggez nnig n uqjun amuṭṭis",
   "upload_modal.detect_text": "Sefru-d aḍris seg tugna",
   "upload_modal.edit_media": "Ẓreg taɣwalt",
diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json
index 06d42eac9..d7adf5836 100644
--- a/app/javascript/mastodon/locales/kk.json
+++ b/app/javascript/mastodon/locales/kk.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Тізімге қосу немесе жою",
   "account.badges.bot": "Бот",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Жазылу",
   "account.followers": "Оқырмандар",
   "account.followers.empty": "Әлі ешкім жазылмаған.",
-  "account.follows": "Жазылғандары",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Ешкімге жазылмапты.",
   "account.follows_you": "Сізге жазылыпты",
   "account.hide_reblogs": "@{name} атты қолданушының әрекеттерін жасыру",
@@ -36,16 +36,14 @@
   "account.requested": "Растауын күтіңіз. Жазылудан бас тарту үшін басыңыз",
   "account.share": "@{name} профилін бөлісу\"",
   "account.show_reblogs": "@{name} бөліскендерін көрсету",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Бұғаттан шығару @{name}",
   "account.unblock_domain": "Бұғаттан шығару {domain}",
   "account.unendorse": "Профильде рекомендемеу",
   "account.unfollow": "Оқымау",
   "account.unmute": "@{name} ескертпелерін қосу",
   "account.unmute_notifications": "@{name} ескертпелерін көрсету",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Қайтадан көріңіз  {retry_time, time, medium} кейін.",
   "alert.rate_limited.title": "Бағалау шектеулі",
   "alert.unexpected.message": "Бір нәрсе дұрыс болмады.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Авторизация",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Жасаушылар тобы",
   "getting_started.directory": "Профильдер каталогы",
   "getting_started.documentation": "Құжаттама",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} жазған екен",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Тренд тақырыптар",
   "ui.beforeunload": "Mastodon желісінен шықсаңыз, нобайыңыз сақталмайды.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Жүктеу үшін сүйреп әкеліңіз",
   "upload_button.label": "Медиа қосу (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Файл жүктеу лимитінен асып кеттіңіз.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Есту қабілеті нашар адамдарға сипаттама беріңіз",
   "upload_form.description": "Көру қабілеті нашар адамдар үшін сипаттаңыз",
   "upload_form.edit": "Түзету",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Өшіру",
   "upload_form.video_description": "Есту немесе көру қабілеті нашар адамдарға сипаттама беріңіз",
   "upload_modal.analyzing_picture": "Суретті анализ жасау…",
   "upload_modal.apply": "Қолдану",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Щучинск съезіндегі өрт пе? Вагон-үй, аэромобиль һәм ұшақ фюзеляжы цехінен ғой",
   "upload_modal.detect_text": "Суреттен мәтін анықтау",
   "upload_modal.edit_media": "Медиафайлды өңдеу",
diff --git a/app/javascript/mastodon/locales/kn.json b/app/javascript/mastodon/locales/kn.json
index 67cf5a5c5..43738ba70 100644
--- a/app/javascript/mastodon/locales/kn.json
+++ b/app/javascript/mastodon/locales/kn.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Follow",
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Awaiting approval",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unhide {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 6949ea5b0..78209fb0e 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "@{name} 에 대한 노트",
   "account.add_or_remove_from_list": "리스트에 추가 혹은 삭제",
   "account.badges.bot": "봇",
   "account.badges.group": "그룹",
@@ -16,7 +15,8 @@
   "account.follow": "팔로우",
   "account.followers": "팔로워",
   "account.followers.empty": "아직 아무도 이 유저를 팔로우하고 있지 않습니다.",
-  "account.follows": "팔로우",
+  "account.followers_counter": "{counter} 팔로워",
+  "account.following_counter": "{counter} 팔로잉",
   "account.follows.empty": "이 유저는 아직 아무도 팔로우하고 있지 않습니다.",
   "account.follows_you": "날 팔로우합니다",
   "account.hide_reblogs": "@{name}의 부스트를 숨기기",
@@ -36,16 +36,14 @@
   "account.requested": "승인 대기 중. 클릭해서 취소하기",
   "account.share": "@{name}의 프로파일 공유",
   "account.show_reblogs": "@{name}의 부스트 보기",
+  "account.statuses_counter": "{counter} 툿",
   "account.unblock": "차단 해제",
   "account.unblock_domain": "{domain} 숨김 해제",
   "account.unendorse": "프로필에 나타내지 않기",
   "account.unfollow": "팔로우 해제",
   "account.unmute": "뮤트 해제",
   "account.unmute_notifications": "@{name}의 알림 뮤트 해제",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "작성된 댓글이 없음",
   "alert.rate_limited.message": "{retry_time, time, medium}에 다시 시도해 주세요.",
   "alert.rate_limited.title": "빈도 제한",
   "alert.unexpected.message": "예측하지 못한 에러가 발생했습니다.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "허가",
   "follow_request.reject": "거부",
   "follow_requests.unlocked_explanation": "당신의 계정이 잠기지 않았다고 할 지라도, {domain}의 스탭은 당신이 이 계정들로부터의 팔로우 요청을 수동으로 확인하길 원한다고 생각했습니다.",
+  "generic.saved": "저장됨",
   "getting_started.developers": "개발자",
   "getting_started.directory": "프로필 책자",
   "getting_started.documentation": "문서",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "팔로워",
   "timeline_hint.resources.follows": "팔로우",
   "timeline_hint.resources.statuses": "이전 툿",
-  "trends.count_by_accounts": "{count} 명의 사람들이 말하고 있습니다",
+  "trends.counter_by_accounts": "{counter} 명이 말하는 중",
   "trends.trending_now": "지금 유행중",
   "ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.",
+  "units.short.billion": "{count}십억",
+  "units.short.million": "{count}백만",
+  "units.short.thousand": "{count}천",
   "upload_area.title": "드래그 & 드롭으로 업로드",
   "upload_button.label": "미디어 추가 (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "파일 업로드 제한에 도달했습니다.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "청각 장애인을 위한 설명",
   "upload_form.description": "시각장애인을 위한 설명",
   "upload_form.edit": "편집",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "삭제",
   "upload_form.video_description": "청각, 시각 장애인을 위한 설명",
   "upload_modal.analyzing_picture": "이미지 분석 중…",
   "upload_modal.apply": "적용",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "다람쥐 헌 쳇바퀴 타고파",
   "upload_modal.detect_text": "이미지에서 텍스트 추출",
   "upload_modal.edit_media": "미디어 편집",
diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json
new file mode 100644
index 000000000..36f55e800
--- /dev/null
+++ b/app/javascript/mastodon/locales/ku.json
@@ -0,0 +1,461 @@
+{
+  "account.account_note_header": "Note",
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.badges.bot": "Bot",
+  "account.badges.group": "Group",
+  "account.block": "Block @{name}",
+  "account.block_domain": "Block domain {domain}",
+  "account.blocked": "Blocked",
+  "account.browse_more_on_origin_server": "Browse more on the original profile",
+  "account.cancel_follow_request": "Cancel follow request",
+  "account.direct": "Direct message @{name}",
+  "account.domain_blocked": "Domain blocked",
+  "account.edit_profile": "Edit profile",
+  "account.endorse": "Feature on profile",
+  "account.follow": "Follow",
+  "account.followers": "Followers",
+  "account.followers.empty": "No one follows this user yet.",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows_you": "Follows you",
+  "account.hide_reblogs": "Hide boosts from @{name}",
+  "account.last_status": "Last active",
+  "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.media": "Media",
+  "account.mention": "Mention @{name}",
+  "account.moved_to": "{name} has moved to:",
+  "account.mute": "Mute @{name}",
+  "account.mute_notifications": "Mute notifications from @{name}",
+  "account.muted": "Muted",
+  "account.never_active": "Never",
+  "account.posts": "Toots",
+  "account.posts_with_replies": "Toots and replies",
+  "account.report": "Report @{name}",
+  "account.requested": "Awaiting approval",
+  "account.share": "Share @{name}'s profile",
+  "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
+  "account.unblock": "Unblock @{name}",
+  "account.unblock_domain": "Unblock domain {domain}",
+  "account.unendorse": "Don't feature on profile",
+  "account.unfollow": "Unfollow",
+  "account.unmute": "Unmute @{name}",
+  "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account_note.placeholder": "Click to add a note",
+  "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",
+  "autosuggest_hashtag.per_week": "{count} per week",
+  "boost_modal.combo": "You can press {combo} to skip this next time",
+  "bundle_column_error.body": "Something went wrong while loading this component.",
+  "bundle_column_error.retry": "Try again",
+  "bundle_column_error.title": "Network error",
+  "bundle_modal_error.close": "Close",
+  "bundle_modal_error.message": "Something went wrong while loading this component.",
+  "bundle_modal_error.retry": "Try again",
+  "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.notifications": "Notifications",
+  "column.pins": "Pinned toot",
+  "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_subheading.settings": "Settings",
+  "community.column_settings.local_only": "Local only",
+  "community.column_settings.media_only": "Media only",
+  "community.column_settings.remote_only": "Remote only",
+  "compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
+  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
+  "compose_form.lock_disclaimer.lock": "locked",
+  "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": "Toot",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Media is marked as sensitive",
+  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
+  "compose_form.spoiler.marked": "Text is hidden behind warning",
+  "compose_form.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.delete.confirm": "Delete",
+  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
+  "confirmations.domain_block.confirm": "Hide entire domain",
+  "confirmations.domain_block.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.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": "Reply",
+  "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}",
+  "directory.federated": "From known fediverse",
+  "directory.local": "From {domain} only",
+  "directory.new_arrivals": "New arrivals",
+  "directory.recently_active": "Recently active",
+  "embed.instructions": "Embed this status on your website by copying the code below.",
+  "embed.preview": "Here is what it will look like:",
+  "emoji_button.activity": "Activity",
+  "emoji_button.custom": "Custom",
+  "emoji_button.flags": "Flags",
+  "emoji_button.food": "Food & Drink",
+  "emoji_button.label": "Insert emoji",
+  "emoji_button.nature": "Nature",
+  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Objects",
+  "emoji_button.people": "People",
+  "emoji_button.recent": "Frequently used",
+  "emoji_button.search": "Search...",
+  "emoji_button.search_results": "Search results",
+  "emoji_button.symbols": "Symbols",
+  "emoji_button.travel": "Travel & Places",
+  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
+  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
+  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.domain_blocks": "There are no blocked domains yet.",
+  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
+  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
+  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "empty_column.hashtag": "There is nothing in this hashtag yet.",
+  "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
+  "empty_column.home.public_timeline": "the public timeline",
+  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
+  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
+  "empty_column.mutes": "You haven't muted any users yet.",
+  "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
+  "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
+  "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
+  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
+  "errors.unexpected_crash.report_issue": "Report issue",
+  "follow_request.authorize": "Authorize",
+  "follow_request.reject": "Reject",
+  "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
+  "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Documentation",
+  "getting_started.heading": "Getting started",
+  "getting_started.invite": "Invite people",
+  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
+  "getting_started.security": "Security",
+  "getting_started.terms": "Terms of service",
+  "hashtag.column_header.tag_mode.all": "and {additional}",
+  "hashtag.column_header.tag_mode.any": "or {additional}",
+  "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
+  "hashtag.column_settings.tag_mode.all": "All of these",
+  "hashtag.column_settings.tag_mode.any": "Any of these",
+  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "home.column_settings.basic": "Basic",
+  "home.column_settings.show_reblogs": "Show boosts",
+  "home.column_settings.show_replies": "Show replies",
+  "home.hide_announcements": "Hide announcements",
+  "home.show_announcements": "Show announcements",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Next",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
+  "introduction.interactions.action": "Finish toot-orial!",
+  "introduction.interactions.favourite.headline": "Favourite",
+  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+  "introduction.interactions.reblog.headline": "Boost",
+  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
+  "introduction.interactions.reply.headline": "Reply",
+  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
+  "introduction.welcome.action": "Let's go!",
+  "introduction.welcome.headline": "First steps",
+  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "keyboard_shortcuts.back": "to navigate back",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
+  "keyboard_shortcuts.boost": "to boost",
+  "keyboard_shortcuts.column": "to focus a status in one of the columns",
+  "keyboard_shortcuts.compose": "to focus the compose textarea",
+  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.favourite": "to favourite",
+  "keyboard_shortcuts.favourites": "to open favourites list",
+  "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.legend": "to display this legend",
+  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.mention": "to mention author",
+  "keyboard_shortcuts.muted": "to open muted users list",
+  "keyboard_shortcuts.my_profile": "to open your profile",
+  "keyboard_shortcuts.notifications": "to open notifications column",
+  "keyboard_shortcuts.open_media": "to open media",
+  "keyboard_shortcuts.pinned": "to open pinned toots list",
+  "keyboard_shortcuts.profile": "to open author's profile",
+  "keyboard_shortcuts.reply": "to reply",
+  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.search": "to focus search",
+  "keyboard_shortcuts.spoilers": "to show/hide CW field",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "to start a brand new toot",
+  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
+  "keyboard_shortcuts.up": "to move up in the list",
+  "lightbox.close": "Close",
+  "lightbox.next": "Next",
+  "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "Add to list",
+  "lists.account.remove": "Remove from list",
+  "lists.delete": "Delete list",
+  "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
+  "lists.new.create": "Add list",
+  "lists.new.title_placeholder": "New list title",
+  "lists.search": "Search among people you follow",
+  "lists.subheading": "Your lists",
+  "load_pending": "{count, plural, one {# new item} other {# new items}}",
+  "loading_indicator.label": "Loading...",
+  "media_gallery.toggle_visible": "Hide {number, plural, one {image} other {images}}",
+  "missing_indicator.label": "Not found",
+  "missing_indicator.sublabel": "This resource could not be found",
+  "mute_modal.hide_notifications": "Hide notifications from this user?",
+  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.blocks": "Blocked users",
+  "navigation_bar.bookmarks": "Bookmarks",
+  "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
+  "navigation_bar.direct": "Direct messages",
+  "navigation_bar.discover": "Discover",
+  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.edit_profile": "Edit profile",
+  "navigation_bar.favourites": "Favourites",
+  "navigation_bar.filters": "Muted words",
+  "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "About this server",
+  "navigation_bar.keyboard_shortcuts": "Hotkeys",
+  "navigation_bar.lists": "Lists",
+  "navigation_bar.logout": "Logout",
+  "navigation_bar.mutes": "Muted users",
+  "navigation_bar.personal": "Personal",
+  "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.preferences": "Preferences",
+  "navigation_bar.public_timeline": "Federated timeline",
+  "navigation_bar.security": "Security",
+  "notification.favourite": "{name} favourited your status",
+  "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.reblog": "{name} boosted your status",
+  "notifications.clear": "Clear notifications",
+  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+  "notifications.column_settings.alert": "Desktop notifications",
+  "notifications.column_settings.favourite": "Favourites:",
+  "notifications.column_settings.filter_bar.advanced": "Display all categories",
+  "notifications.column_settings.filter_bar.category": "Quick filter bar",
+  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.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.push": "Push notifications",
+  "notifications.column_settings.reblog": "Boosts:",
+  "notifications.column_settings.show": "Show in column",
+  "notifications.column_settings.sound": "Play sound",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
+  "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "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_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
+  "privacy.change": "Adjust status privacy",
+  "privacy.direct.long": "Visible for mentioned users only",
+  "privacy.direct.short": "Direct",
+  "privacy.private.long": "Visible for followers only",
+  "privacy.private.short": "Followers-only",
+  "privacy.public.long": "Visible for all, shown in public timelines",
+  "privacy.public.short": "Public",
+  "privacy.unlisted.long": "Visible for all, but not in public timelines",
+  "privacy.unlisted.short": "Unlisted",
+  "refresh": "Refresh",
+  "regeneration_indicator.label": "Loading…",
+  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "relative_time.days": "{number}d",
+  "relative_time.hours": "{number}h",
+  "relative_time.just_now": "now",
+  "relative_time.minutes": "{number}m",
+  "relative_time.seconds": "{number}s",
+  "relative_time.today": "today",
+  "reply_indicator.cancel": "Cancel",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.placeholder": "Additional comments",
+  "report.submit": "Submit",
+  "report.target": "Report {target}",
+  "search.placeholder": "Search",
+  "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.text": "Simple text returns matching display names, usernames and hashtags",
+  "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
+  "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.",
+  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
+  "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_status": "Open this status in the moderation interface",
+  "status.block": "Block @{name}",
+  "status.bookmark": "Bookmark",
+  "status.cancel_reblog_private": "Unboost",
+  "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
+  "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
+  "status.direct": "Direct message @{name}",
+  "status.embed": "Embed",
+  "status.favourite": "Favourite",
+  "status.filtered": "Filtered",
+  "status.load_more": "Load more",
+  "status.media_hidden": "Media hidden",
+  "status.mention": "Mention @{name}",
+  "status.more": "More",
+  "status.mute": "Mute @{name}",
+  "status.mute_conversation": "Mute conversation",
+  "status.open": "Expand this status",
+  "status.pin": "Pin on profile",
+  "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
+  "status.reblog": "Boost",
+  "status.reblog_private": "Boost to original audience",
+  "status.reblogged_by": "{name} boosted",
+  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
+  "status.redraft": "Delete & re-draft",
+  "status.remove_bookmark": "Remove bookmark",
+  "status.reply": "Reply",
+  "status.replyAll": "Reply to thread",
+  "status.report": "Report @{name}",
+  "status.sensitive_warning": "Sensitive content",
+  "status.share": "Share",
+  "status.show_less": "Show less",
+  "status.show_less_all": "Show less for all",
+  "status.show_more": "Show more",
+  "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
+  "status.uncached_media_warning": "Not available",
+  "status.unmute_conversation": "Unmute conversation",
+  "status.unpin": "Unpin from profile",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
+  "tabs_bar.federated_timeline": "Federated",
+  "tabs_bar.home": "Home",
+  "tabs_bar.local_timeline": "Local",
+  "tabs_bar.notifications": "Notifications",
+  "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
+  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
+  "timeline_hint.resources.followers": "Followers",
+  "timeline_hint.resources.follows": "Follows",
+  "timeline_hint.resources.statuses": "Older toots",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
+  "trends.trending_now": "Trending now",
+  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
+  "upload_area.title": "Drag & drop to upload",
+  "upload_button.label": "Add images, a video or an audio file",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
+  "upload_form.audio_description": "Describe for people with hearing loss",
+  "upload_form.description": "Describe for the visually impaired",
+  "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
+  "upload_form.undo": "Delete",
+  "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
+  "upload_modal.analyzing_picture": "Analyzing picture…",
+  "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
+  "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
+  "upload_modal.detect_text": "Detect text from picture",
+  "upload_modal.edit_media": "Edit media",
+  "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
+  "upload_modal.preview_label": "Preview ({ratio})",
+  "upload_progress.label": "Uploading…",
+  "video.close": "Close video",
+  "video.download": "Download file",
+  "video.exit_fullscreen": "Exit full screen",
+  "video.expand": "Expand video",
+  "video.fullscreen": "Full screen",
+  "video.hide": "Hide video",
+  "video.mute": "Mute sound",
+  "video.pause": "Pause",
+  "video.play": "Play",
+  "video.unmute": "Unmute sound"
+}
diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json
index 67cf5a5c5..43738ba70 100644
--- a/app/javascript/mastodon/locales/lt.json
+++ b/app/javascript/mastodon/locales/lt.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Follow",
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Awaiting approval",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unhide {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index 6a17a4a0c..01fe7a07c 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -1,14 +1,13 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Piezīme",
   "account.add_or_remove_from_list": "Pievienot vai noņemt no saraksta",
   "account.badges.bot": "Bots",
-  "account.badges.group": "Group",
+  "account.badges.group": "Grupa",
   "account.block": "Bloķēt @{name}",
   "account.block_domain": "Slēpt visu no {domain}",
   "account.blocked": "Bloķēts",
-  "account.browse_more_on_origin_server": "Browse more on the original profile",
-  "account.cancel_follow_request": "Cancel follow request",
+  "account.browse_more_on_origin_server": "Pārlūkot vairāk sākotnējā profilā",
+  "account.cancel_follow_request": "Atcelt pieprasījumu",
   "account.direct": "Privātā ziņa @{name}",
   "account.domain_blocked": "Domēns ir paslēpts",
   "account.edit_profile": "Labot profilu",
@@ -16,11 +15,12 @@
   "account.follow": "Sekot",
   "account.followers": "Sekotāji",
   "account.followers.empty": "Šim lietotājam nav sekotāju.",
-  "account.follows": "Seko",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.",
   "account.follows_you": "Seko tev",
   "account.hide_reblogs": "Paslēpt paceltos ierakstus no lietotāja @{name}",
-  "account.last_status": "Last active",
+  "account.last_status": "Pēdējā aktivitāte",
   "account.link_verified_on": "Šīs saites piederība ir pārbaudīta {date}",
   "account.locked_info": "Šī konta privātuma status ir iestatīts slēgts. Īpašnieks izskatīs un izvēlēsies kas viņam drīkst sekot.",
   "account.media": "Mēdiji",
@@ -29,23 +29,21 @@
   "account.mute": "Apklusināt @{name}",
   "account.mute_notifications": "Nerādīt paziņojumus no @{name}",
   "account.muted": "Apklusināts",
-  "account.never_active": "Never",
+  "account.never_active": "Nekad",
   "account.posts": "Ieraksti",
   "account.posts_with_replies": "Ieraksti un atbildes",
   "account.report": "Ziņot par lietotāju @{name}",
   "account.requested": "Gaidām apstiprinājumu. Nospied lai atceltu sekošanas pieparasījumu",
   "account.share": "Dalīties ar lietotāja @{name}'s profilu",
   "account.show_reblogs": "Parādīt lietotāja @{name} paceltos ierakstus",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Atbloķēt lietotāju @{name}",
   "account.unblock_domain": "Atbloķēt domēnu {domain}",
   "account.unendorse": "Neizcelt profilā",
   "account.unfollow": "Nesekot",
   "account.unmute": "Noņemt apklusinājumu no lietotāja @{name}",
   "account.unmute_notifications": "Rādīt paziņojumus no lietotāja @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Noklikšķiniet, lai pievienotu piezīmi",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "Negaidīta kļūda.",
@@ -60,7 +58,7 @@
   "bundle_modal_error.message": "Kaut kas nogāja greizi ielādējot šo komponenti.",
   "bundle_modal_error.retry": "Mēģini vēlreiz",
   "column.blocks": "Bloķētie lietotāji",
-  "column.bookmarks": "Bookmarks",
+  "column.bookmarks": "Grāmatzīmes",
   "column.community": "Lokālā laika līnija",
   "column.direct": "Privātās ziņas",
   "column.directory": "Browse profiles",
@@ -81,16 +79,16 @@
   "column_header.show_settings": "Rādīt iestatījumus",
   "column_header.unpin": "Atspraust",
   "column_subheading.settings": "Iestatījumi",
-  "community.column_settings.local_only": "Local only",
+  "community.column_settings.local_only": "Tikai vietējie",
   "community.column_settings.media_only": "Tikai mēdiji",
-  "community.column_settings.remote_only": "Remote only",
+  "community.column_settings.remote_only": "Tikai tālvadības",
   "compose_form.direct_message_warning": "Šis ziņojums tiks nosūtīts tikai pieminētajiem lietotājiem.",
   "compose_form.direct_message_warning_learn_more": "Papildus informācija",
   "compose_form.hashtag_warning": "Ziņojumu nebūs iespējams atrast zem haštagiem jo tas nav publisks. Tikai publiskos ziņojumus ir iespējams meklēt pēc tiem.",
   "compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var Tev sekot lai apskatītu tikai sekotājiem paredzētos ziņojumus.",
   "compose_form.lock_disclaimer.lock": "slēgts",
   "compose_form.placeholder": "Ko vēlies publicēt?",
-  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.add_option": "Pievienot izvēli",
   "compose_form.poll.duration": "Poll duration",
   "compose_form.poll.option_placeholder": "Choice {number}",
   "compose_form.poll.remove_option": "Remove this choice",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizēt",
   "follow_request.reject": "Noraidīt",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/mk.json b/app/javascript/mastodon/locales/mk.json
index 65d546795..7e9c0dc42 100644
--- a/app/javascript/mastodon/locales/mk.json
+++ b/app/javascript/mastodon/locales/mk.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Додади или одстрани од листа",
   "account.badges.bot": "Бот",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Следи",
   "account.followers": "Следбеници",
   "account.followers.empty": "Никој не го следи овој корисник сеуште.",
-  "account.follows": "Следи",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Корисникот не следи никој сеуште.",
   "account.follows_you": "Те следи тебе",
   "account.hide_reblogs": "Сокриј буст од @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Се чека одобрување. Кликни за да одкажиш барање за следење",
   "account.share": "Сподели @{name} профил",
   "account.show_reblogs": "Прикажи бустови од @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Одблокирај @{name}",
   "account.unblock_domain": "Прикажи {domain}",
   "account.unendorse": "Не прикажувај на профил",
   "account.unfollow": "Одследи",
   "account.unmute": "Зачути го @{name}",
   "account.unmute_notifications": "Исклучи известувања од @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Обидете се повторно после {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "Неочекувана грешка.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Одобри",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Програмери",
   "getting_started.directory": "Профил директориум",
   "getting_started.documentation": "Документација",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json
index 699dd91cb..78dced532 100644
--- a/app/javascript/mastodon/locales/ml.json
+++ b/app/javascript/mastodon/locales/ml.json
@@ -1,9 +1,8 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "കുറിപ്പ്",
   "account.add_or_remove_from_list": "പട്ടികയിൽ ചേർക്കുകയോ അല്ലെങ്കിൽ മാറ്റുകയോ ചെയ്യുക",
   "account.badges.bot": "റോബോട്ട്",
-  "account.badges.group": "Group",
+  "account.badges.group": "കൂട്ടം",
   "account.block": "@{name} നെ ബ്ലോക്ക് ചെയ്യുക",
   "account.block_domain": "{domain} ൽ നിന്നുള്ള എല്ലാം മറയ്കുക",
   "account.blocked": "തടഞ്ഞു",
@@ -16,7 +15,8 @@
   "account.follow": "പിന്തുടരുക",
   "account.followers": "പിന്തുടരുന്നവർ",
   "account.followers.empty": "ഈ ഉപയോക്താവിനെ ആരും ഇതുവരെ പിന്തുടരുന്നില്ല.",
-  "account.follows": "പിന്തുടരുന്നു",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "ഈ ഉപയോക്താവ് ആരേയും ഇതുവരെ പിന്തുടരുന്നില്ല.",
   "account.follows_you": "നിങ്ങളെ പിന്തുടരുന്നു",
   "account.hide_reblogs": "@{name} ബൂസ്റ്റ് ചെയ്തവ മറയ്കുക",
@@ -36,21 +36,19 @@
   "account.requested": "അനുവാദത്തിനായി കാത്തിരിക്കുന്നു. പിന്തുടരാനുള്ള അപേക്ഷ റദ്ദാക്കുവാൻ ഞെക്കുക",
   "account.share": "@{name} ന്റെ പ്രൊഫൈൽ പങ്കുവെക്കുക",
   "account.show_reblogs": "@{name} ൽ നിന്നുള്ള ബൂസ്റ്റുകൾ കാണിക്കുക",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "ബ്ലോക്ക് മാറ്റുക @{name}",
   "account.unblock_domain": "{domain} വെളിപ്പെടുത്തുക",
   "account.unendorse": "പ്രൊഫൈലിൽ പ്രകടമാക്കാതിരിക്കുക",
   "account.unfollow": "പിന്തുടരുന്നത് നിര്‍ത്തുക",
   "account.unmute": "നിശ്ശബ്ദമാക്കുന്നത് നിർത്തുക @{name}",
   "account.unmute_notifications": "@{name} യിൽ നിന്നുള്ള അറിയിപ്പുകൾ പ്രസിദ്ധപ്പെടുത്തുക",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "കുറിപ്പ് ചേർക്കാൻ ക്ലിക്കുചെയ്യുക",
   "alert.rate_limited.message": "{retry_time, time, medium} നു ശേഷം വീണ്ടും ശ്രമിക്കുക.",
   "alert.rate_limited.title": "തോത് പരിമിതപ്പെടുത്തിയിരിക്കുന്നു",
   "alert.unexpected.message": "അപ്രതീക്ഷിതമായി എന്തോ സംഭവിച്ചു.",
   "alert.unexpected.title": "ശ്ശോ!",
-  "announcement.announcement": "Announcement",
+  "announcement.announcement": "അറിയിപ്പ്",
   "autosuggest_hashtag.per_week": "ആഴ്ച തോറും {count}",
   "boost_modal.combo": "അടുത്ത തവണ ഇത് ഒഴിവാക്കുവാൻ {combo} ഞെക്കാവുന്നതാണ്",
   "bundle_column_error.body": "ഈ ഘടകം പ്രദശിപ്പിക്കുമ്പോൾ എന്തോ കുഴപ്പം സംഭവിച്ചു.",
@@ -60,7 +58,7 @@
   "bundle_modal_error.message": "ഈ വെബ്പേജ് പ്രദർശിപ്പിക്കുമ്പോൾ എന്തോ കുഴപ്പം സംഭവിച്ചു.",
   "bundle_modal_error.retry": "വീണ്ടും ശ്രമിക്കുക",
   "column.blocks": "തടയപ്പെട്ട ഉപയോക്താക്കൾ",
-  "column.bookmarks": "Bookmarks",
+  "column.bookmarks": "ബുക്ക്മാർക്കുകൾ",
   "column.community": "പ്രാദേശികമായ സമയരേഖ",
   "column.direct": "നേരിട്ടുള്ള സന്ദേശങ്ങൾ",
   "column.directory": "പ്രൊഫൈലുകൾ മറിച്ചുനോക്കുക",
@@ -81,19 +79,19 @@
   "column_header.show_settings": "ക്രമീകരണങ്ങൾ കാണിക്കുക",
   "column_header.unpin": "ഇളക്കി മാറ്റുക",
   "column_subheading.settings": "ക്രമീകരണങ്ങള്‍",
-  "community.column_settings.local_only": "Local only",
+  "community.column_settings.local_only": "പ്രാദേശികം മാത്രം",
   "community.column_settings.media_only": "മാധ്യമങ്ങൾ മാത്രം",
   "community.column_settings.remote_only": "Remote only",
   "compose_form.direct_message_warning": "പരാമർശിക്കപ്പെട്ടിരിക്കുന്ന ഉപയോഗ്താക്കൾക്കെ ഈ ടൂട്ട് അയക്കപ്പെടുകയുള്ളു.",
   "compose_form.direct_message_warning_learn_more": "കൂടുതൽ പഠിക്കുക",
   "compose_form.hashtag_warning": "ഈ ടൂട്ട് പട്ടികയിൽ ഇല്ലാത്തതിനാൽ ഒരു ചർച്ചാവിഷയത്തിന്റെ പട്ടികയിലും പെടുകയില്ല. പരസ്യമായ ടൂട്ടുകൾ മാത്രമേ ചർച്ചാവിഷയം അടിസ്ഥാനമാക്കി തിരയുവാൻ സാധിക്കുകയുള്ളു.",
   "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.lock_disclaimer.lock": "ലോക്കുചെയ്തു",
   "compose_form.placeholder": "നിങ്ങളുടെ മനസ്സിൽ എന്താണ്?",
-  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.add_option": "ഒരു ചോയ്‌സ് ചേർക്കുക",
   "compose_form.poll.duration": "തിരഞ്ഞെടുപ്പിന്റെ സമയദൈർഖ്യം",
-  "compose_form.poll.option_placeholder": "Choice {number}",
-  "compose_form.poll.remove_option": "Remove this choice",
+  "compose_form.poll.option_placeholder": "ചോയ്‌സ് {number}",
+  "compose_form.poll.remove_option": "ഈ ഡിവൈസ് മാറ്റുക",
   "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
   "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
   "compose_form.publish": "ടൂട്ട്",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "ചുമതലപ്പെടുത്തുക",
   "follow_request.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.",
+  "generic.saved": "സംരക്ഷിച്ചു",
   "getting_started.developers": "വികസിപ്പിക്കുന്നവർ",
   "getting_started.directory": "രൂപരേഖ നാമഗൃഹസൂചി",
   "getting_started.documentation": "രേഖാ സമാഹരണം",
@@ -194,8 +193,8 @@
   "home.column_settings.basic": "അടിസ്ഥാനം",
   "home.column_settings.show_reblogs": "ബൂസ്റ്റുകൾ കാണിക്കുക",
   "home.column_settings.show_replies": "മറുപടികൾ കാണിക്കുക",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
+  "home.hide_announcements": "പ്രഖ്യാപനങ്ങൾ മറയ്‌ക്കുക",
+  "home.show_announcements": "പ്രഖ്യാപനങ്ങൾ കാണിക്കുക",
   "intervals.full.days": "{number, plural, one {# day} other {# days}}",
   "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
   "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
@@ -373,15 +372,15 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.copy": "Copy link to status",
-  "status.delete": "Delete",
-  "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Embed",
-  "status.favourite": "Favourite",
+  "status.delete": "മായ്ക്കുക",
+  "status.detailed_status": "വിശദമായ സംഭാഷണ കാഴ്‌ച",
+  "status.direct": "@{name} ന് നേരിട്ട് മെസേജ് അയക്കുക",
+  "status.embed": "ഉൾച്ചേർക്കുക",
+  "status.favourite": "പ്രിയപ്പെട്ടത്",
   "status.filtered": "Filtered",
-  "status.load_more": "Load more",
+  "status.load_more": "കൂടുതൽ ലോഡു ചെയ്യുക",
   "status.media_hidden": "Media hidden",
-  "status.mention": "Mention @{name}",
+  "status.mention": "@{name} സൂചിപ്പിക്കുക",
   "status.more": "More",
   "status.mute": "Mute @{name}",
   "status.mute_conversation": "Mute conversation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json
index 5aaa6b314..a56d2544a 100644
--- a/app/javascript/mastodon/locales/mr.json
+++ b/app/javascript/mastodon/locales/mr.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "यादीत घाला किंवा यादीतून काढून टाका",
   "account.badges.bot": "स्वयंचलित खाते",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "अनुयायी व्हा",
   "account.followers": "अनुयायी",
   "account.followers.empty": "ह्या वापरकर्त्याचा आतापर्यंत कोणी अनुयायी नाही.",
-  "account.follows": "अनुयायी आहे",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "हा वापरकर्ता अजूनपर्यंत कोणाचा अनुयायी नाही.",
   "account.follows_you": "तुमचा अनुयायी आहे",
   "account.hide_reblogs": "@{name} पासून सर्व बूस्ट लपवा",
@@ -36,16 +36,14 @@
   "account.requested": "Awaiting approval",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "{name}चे सर्व बुस्ट्स दाखवा",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} ला ब्लॉक करा",
   "account.unblock_domain": "उघड करा {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "अनुयायी असणे थांबवा",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json
index fb49cd140..a19483014 100644
--- a/app/javascript/mastodon/locales/ms.json
+++ b/app/javascript/mastodon/locales/ms.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Follow",
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Awaiting approval",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unhide {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index bd09fd35f..1611ba636 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -1,22 +1,22 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Opmerking",
   "account.add_or_remove_from_list": "Toevoegen of verwijderen vanuit lijsten",
   "account.badges.bot": "Bot",
   "account.badges.group": "Groep",
   "account.block": "@{name} blokkeren",
   "account.block_domain": "Alles van {domain} verbergen",
   "account.blocked": "Geblokkeerd",
-  "account.browse_more_on_origin_server": "Blader door het originele profiel",
+  "account.browse_more_on_origin_server": "Meer op het originele profiel bekijken",
   "account.cancel_follow_request": "Volgverzoek annuleren",
   "account.direct": "@{name} een direct bericht sturen",
-  "account.domain_blocked": "Domein verborgen",
+  "account.domain_blocked": "Server verborgen",
   "account.edit_profile": "Profiel bewerken",
   "account.endorse": "Op profiel weergeven",
   "account.follow": "Volgen",
   "account.followers": "Volgers",
   "account.followers.empty": "Niemand volgt nog deze gebruiker.",
-  "account.follows": "Volgend",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Deze gebruiker volgt nog niemand.",
   "account.follows_you": "Volgt jou",
   "account.hide_reblogs": "Verberg boosts van @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Wacht op goedkeuring. Klik om het volgverzoek te annuleren",
   "account.share": "Profiel van @{name} delen",
   "account.show_reblogs": "Toon boosts van @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} deblokkeren",
   "account.unblock_domain": "{domain} niet langer verbergen",
   "account.unendorse": "Niet op profiel weergeven",
   "account.unfollow": "Ontvolgen",
   "account.unmute": "@{name} niet langer negeren",
   "account.unmute_notifications": "@{name} meldingen niet langer negeren",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Klik om een opmerking toe te voegen",
   "alert.rate_limited.message": "Probeer het nog een keer na {retry_time, time, medium}.",
   "alert.rate_limited.title": "Beperkt te gebruiken",
   "alert.unexpected.message": "Er deed zich een onverwachte fout voor",
@@ -83,7 +81,7 @@
   "column_subheading.settings": "Instellingen",
   "community.column_settings.local_only": "Alleen lokaal",
   "community.column_settings.media_only": "Alleen media",
-  "community.column_settings.remote_only": "Alleen op afstand",
+  "community.column_settings.remote_only": "Alleen andere servers",
   "compose_form.direct_message_warning": "Deze toot wordt alleen naar vermelde gebruikers verstuurd. Echter, de beheerders en moderatoren van jouw en de ontvangende server(s) kunnen dit bericht mogelijk wel bekijken.",
   "compose_form.direct_message_warning_learn_more": "Meer leren",
   "compose_form.hashtag_warning": "Deze toot valt niet onder een hashtag te bekijken, omdat deze niet op openbare tijdlijnen wordt getoond. Alleen openbare toots kunnen via hashtags gevonden worden.",
@@ -120,7 +118,7 @@
   "confirmations.mute.explanation": "Dit verbergt toots van hen en toots waar hen in wordt vermeld, maar hen kan nog steeds jouw toots bekijken en jou volgen.",
   "confirmations.mute.message": "Weet je het zeker dat je {name} wilt negeren?",
   "confirmations.redraft.confirm": "Verwijderen en herschrijven",
-  "confirmations.redraft.message": "Weet je zeker dat je deze toot wilt verwijderen en herschrijven? Je verliest wel de boosts en favorieten, en reacties op de originele toot zitten niet meer aan de nieuwe toot vast.",
+  "confirmations.redraft.message": "Weet je zeker dat je deze toot wilt verwijderen en herschrijven? Je verliest wel de boosts en favorieten, en de reacties op de originele toot zitten niet meer aan de nieuwe toot vast.",
   "confirmations.reply.confirm": "Reageren",
   "confirmations.reply.message": "Door nu te reageren overschrijf je de toot die je op dit moment aan het schrijven bent. Weet je zeker dat je verder wil gaan?",
   "confirmations.unfollow.confirm": "Ontvolgen",
@@ -162,7 +160,7 @@
   "empty_column.hashtag": "Er is nog niks te vinden onder deze hashtag.",
   "empty_column.home": "Jij volgt nog niemand. Bezoek {public} of gebruik het zoekvenster om andere mensen te ontmoeten.",
   "empty_column.home.public_timeline": "de globale tijdlijn",
-  "empty_column.list": "Er is nog niks in deze lijst. Wanneer lijstleden nieuwe toots publiceren, zijn deze hier te zien.",
+  "empty_column.list": "Er is nog niks te zien in deze lijst. Wanneer lijstleden nieuwe toots publiceren, zijn deze hier te zien.",
   "empty_column.lists": "Jij hebt nog enkele lijst. Wanneer je er eentje hebt aangemaakt, valt deze hier te zien.",
   "empty_column.mutes": "Jij hebt nog geen gebruikers genegeerd.",
   "empty_column.notifications": "Je hebt nog geen meldingen. Begin met iemand een gesprek.",
@@ -173,7 +171,8 @@
   "errors.unexpected_crash.report_issue": "Technisch probleem melden",
   "follow_request.authorize": "Goedkeuren",
   "follow_request.reject": "Afkeuren",
-  "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.",
+  "follow_requests.unlocked_explanation": "Ook al is jouw account niet besloten, de medewerkers van {domain} denken dat jij misschien de volgende volgverzoeken handmatig wil controleren.",
+  "generic.saved": "Opgeslagen",
   "getting_started.developers": "Ontwikkelaars",
   "getting_started.directory": "Gebruikersgids",
   "getting_started.documentation": "Documentatie",
@@ -224,7 +223,7 @@
   "keyboard_shortcuts.description": "Omschrijving",
   "keyboard_shortcuts.direct": "om jouw directe berichten te tonen",
   "keyboard_shortcuts.down": "om naar beneden door de lijst te bewegen",
-  "keyboard_shortcuts.enter": "om uitgebreide toot te tonen",
+  "keyboard_shortcuts.enter": "om de toot volledig te tonen",
   "keyboard_shortcuts.favourite": "om aan jouw favorieten toe te voegen",
   "keyboard_shortcuts.favourites": "om jouw lijst met favorieten te tonen",
   "keyboard_shortcuts.federated": "om de globale tijdlijn te tonen",
@@ -243,9 +242,9 @@
   "keyboard_shortcuts.reply": "om te reageren",
   "keyboard_shortcuts.requests": "om jouw volgverzoeken te tonen",
   "keyboard_shortcuts.search": "om het zoekvak te focussen",
-  "keyboard_shortcuts.spoilers": "to show/hide CW field",
+  "keyboard_shortcuts.spoilers": "om het waarschuwingstekstveld (CW) te tonen/verbergen",
   "keyboard_shortcuts.start": "om de \"Aan de slag\"-kolom te tonen",
-  "keyboard_shortcuts.toggle_hidden": "om tekst achter een waarschuwing (CW) te tonen/verbergen",
+  "keyboard_shortcuts.toggle_hidden": "om een waarschuwingstekst (CW) te tonen/verbergen",
   "keyboard_shortcuts.toggle_sensitivity": "om media te tonen/verbergen",
   "keyboard_shortcuts.toot": "om een nieuwe toot te starten",
   "keyboard_shortcuts.unfocus": "om het tekst- en zoekvak te ontfocussen",
@@ -329,7 +328,7 @@
   "poll.voted": "Je hebt hier op gestemd",
   "poll_button.add_poll": "Poll toevoegen",
   "poll_button.remove_poll": "Poll verwijderen",
-  "privacy.change": "Zichtbaarheid toot aanpassen",
+  "privacy.change": "Zichtbaarheid van toot aanpassen",
   "privacy.direct.long": "Alleen aan vermelde gebruikers tonen",
   "privacy.direct.short": "Direct",
   "privacy.private.long": "Alleen aan volgers tonen",
@@ -356,7 +355,7 @@
   "report.target": "Rapporteer {target}",
   "search.placeholder": "Zoeken",
   "search_popout.search_format": "Geavanceerd zoeken",
-  "search_popout.tips.full_text": "Gebruik gewone tekst om te zoeken in jouw toots, gebooste toots, favorieten en in toots waarin jij bent vermeldt, en tevens naar gebruikersnamen, weergavenamen en hashtags.",
+  "search_popout.tips.full_text": "Gebruik gewone tekst om te zoeken in jouw toots, gebooste toots, favorieten en in toots waarin je bent vermeldt, en tevens naar gebruikersnamen, weergavenamen en hashtags.",
   "search_popout.tips.hashtag": "hashtag",
   "search_popout.tips.status": "toot",
   "search_popout.tips.text": "Gebruik gewone tekst om te zoeken op weergavenamen, gebruikersnamen en hashtags",
@@ -385,7 +384,7 @@
   "status.more": "Meer",
   "status.mute": "@{name} negeren",
   "status.mute_conversation": "Negeer gesprek",
-  "status.open": "Uitgebreide toot tonen",
+  "status.open": "Volledige toot tonen",
   "status.pin": "Aan profielpagina vastmaken",
   "status.pinned": "Vastgemaakte toot",
   "status.read_more": "Meer lezen",
@@ -420,24 +419,29 @@
   "time_remaining.minutes": "{number, plural, one {# minuut} other {# minuten}} te gaan",
   "time_remaining.moments": "Nog enkele ogenblikken resterend",
   "time_remaining.seconds": "{number, plural, one {# seconde} other {# seconden}} te gaan",
-  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
-  "timeline_hint.resources.followers": "Followers",
-  "timeline_hint.resources.follows": "Follows",
-  "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persoon praat} other {mensen praten}} hierover",
+  "timeline_hint.remote_resource_not_displayed": "{resource} van andere servers worden niet getoond.",
+  "timeline_hint.resources.followers": "Volgers",
+  "timeline_hint.resources.follows": "Volgend",
+  "timeline_hint.resources.statuses": "Oudere toots",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trends",
   "ui.beforeunload": "Je concept zal verloren gaan als je Mastodon verlaat.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Hiernaar toe slepen om te uploaden",
-  "upload_button.label": "Media toevoegen ({formats})",
+  "upload_button.label": "Afbeeldingen, een video- of een geluidsbestand toevoegen",
   "upload_error.limit": "Uploadlimiet van bestand overschreden.",
   "upload_error.poll": "Het uploaden van bestanden is in polls niet toegestaan.",
   "upload_form.audio_description": "Omschrijf dit voor mensen met een auditieve beperking",
   "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking",
   "upload_form.edit": "Omschrijf",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Verwijderen",
   "upload_form.video_description": "Omschrijf dit voor mensen met een auditieve of visuele beperking",
   "upload_modal.analyzing_picture": "Afbeelding analyseren…",
   "upload_modal.apply": "Toepassen",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Tekst in een afbeelding detecteren",
   "upload_modal.edit_media": "Media bewerken",
diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json
index 26c337aab..ed151565d 100644
--- a/app/javascript/mastodon/locales/nn.json
+++ b/app/javascript/mastodon/locales/nn.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Legg til eller tak vekk frå listene",
   "account.badges.bot": "Robot",
   "account.badges.group": "Gruppe",
@@ -16,7 +15,8 @@
   "account.follow": "Fylg",
   "account.followers": "Fylgjarar",
   "account.followers.empty": "Ingen fylgjer denne brukaren enno.",
-  "account.follows": "Fylgjer",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Denne brukaren fylgjer ikkje nokon enno.",
   "account.follows_you": "Fylgjer deg",
   "account.hide_reblogs": "Gøym fremhevingar frå @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Ventar på samtykke. Klikk for å avbryta fylgjeførespurnaden",
   "account.share": "Del @{name} sin profil",
   "account.show_reblogs": "Vis framhevingar frå @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Slutt å blokera @{name}",
   "account.unblock_domain": "Vis {domain}",
   "account.unendorse": "Ikkje framhev på profil",
   "account.unfollow": "Slutt å fylgja",
   "account.unmute": "Av-demp @{name}",
   "account.unmute_notifications": "Vis varsel frå @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Ver venleg å prøva igjen etter {retry_time, time, medium}.",
   "alert.rate_limited.title": "Begrensa rate",
   "alert.unexpected.message": "Eit uventa problem oppstod.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autoriser",
   "follow_request.reject": "Avvis",
   "follow_requests.unlocked_explanation": "Selv om kontoen din ikke er låst, tror {domain} ansatte at du kanskje vil gjennomgå forespørsler fra disse kontoene manuelt.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Utviklarar",
   "getting_started.directory": "Profilkatalog",
   "getting_started.documentation": "Dokumentasjon",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {folk}} snakkar",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Populært no",
   "ui.beforeunload": "Kladden din forsvinn om du forlèt Mastodon no.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & slepp for å lasta opp",
   "upload_button.label": "Legg til medium ({formats})",
   "upload_error.limit": "Du har gått over opplastingsgrensa.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Grei ut for folk med nedsett høyrsel",
   "upload_form.description": "Skildr for synshemja",
   "upload_form.edit": "Rediger",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Slett",
   "upload_form.video_description": "Greit ut for folk med nedsett høyrsel eller syn",
   "upload_modal.analyzing_picture": "Analyserer bilete…",
   "upload_modal.apply": "Bruk",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Ein rask brun rev hoppar over den late hunden",
   "upload_modal.detect_text": "Gjenkjenn tekst i biletet",
   "upload_modal.edit_media": "Rediger medium",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index 85715c7bf..7ddfea5bc 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Legg til eller fjern fra lister",
   "account.badges.bot": "Bot",
   "account.badges.group": "Gruppe",
@@ -16,7 +15,8 @@
   "account.follow": "Følg",
   "account.followers": "Følgere",
   "account.followers.empty": "Ingen følger denne brukeren ennå.",
-  "account.follows": "Følger",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Denne brukeren følger ikke noen enda.",
   "account.follows_you": "Følger deg",
   "account.hide_reblogs": "Skjul fremhevinger fra @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Venter på godkjennelse",
   "account.share": "Del @{name}s profil",
   "account.show_reblogs": "Vis boosts fra @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Avblokker @{name}",
   "account.unblock_domain": "Vis {domain}",
   "account.unendorse": "Ikke vis frem på profilen",
   "account.unfollow": "Avfølg",
   "account.unmute": "Avdemp @{name}",
   "account.unmute_notifications": "Vis varsler fra @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Vennligst prøv igjen etter kl. {retry_time, time, medium}.",
   "alert.rate_limited.title": "Hastighetsbegrenset",
   "alert.unexpected.message": "En uventet feil oppstod.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorisér",
   "follow_request.reject": "Avvis",
   "follow_requests.unlocked_explanation": "Selv om kontoen din ikke er låst, tror {domain} ansatte at du kanskje vil gjennomgå forespørsler fra disse kontoene manuelt.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Utviklere",
   "getting_started.directory": "Profilmappe",
   "getting_started.documentation": "Dokumentasjon",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {personer}} snakker om det",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trender nå",
   "ui.beforeunload": "Din kladd vil bli forkastet om du forlater Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Dra og slipp for å laste opp",
   "upload_button.label": "Legg til media",
   "upload_error.limit": "Filopplastingsgrensen er oversteget.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Beskriv det for folk med hørselstap",
   "upload_form.description": "Beskriv for synshemmede",
   "upload_form.edit": "Rediger",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Angre",
   "upload_form.video_description": "Beskriv det for folk med hørselstap eller synshemminger",
   "upload_modal.analyzing_picture": "Analyserer bildet …",
   "upload_modal.apply": "Bruk",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Når du en gang kommer, neste sommer, skal vi atter drikke vin",
   "upload_modal.detect_text": "Oppdag tekst i bildet",
   "upload_modal.edit_media": "Rediger media",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index e0c9e99c6..dfee6f157 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -1,13 +1,12 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Nòta",
   "account.add_or_remove_from_list": "Ajustar o tirar de las listas",
   "account.badges.bot": "Robòt",
   "account.badges.group": "Grop",
   "account.block": "Blocar @{name}",
   "account.block_domain": "Tot amagar del domeni {domain}",
   "account.blocked": "Blocat",
-  "account.browse_more_on_origin_server": "Browse more on the original profile",
+  "account.browse_more_on_origin_server": "Navigar sul perfil original",
   "account.cancel_follow_request": "Anullar la demanda de seguiment",
   "account.direct": "Escriure un MP a @{name}",
   "account.domain_blocked": "Domeni amagat",
@@ -16,7 +15,8 @@
   "account.follow": "Sègre",
   "account.followers": "Seguidors",
   "account.followers.empty": "Degun sèc pas aqueste utilizaire pel moment.",
-  "account.follows": "Abonaments",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Aqueste utilizaire sèc pas degun pel moment.",
   "account.follows_you": "Vos sèc",
   "account.hide_reblogs": "Rescondre los partatges de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Invitacion mandada. Clicatz per anullar",
   "account.share": "Partejar lo perfil a @{name}",
   "account.show_reblogs": "Mostrar los partatges de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desblocar @{name}",
   "account.unblock_domain": "Desblocar {domain}",
   "account.unendorse": "Mostrar pas pel perfil",
   "account.unfollow": "Quitar de sègre",
   "account.unmute": "Quitar de rescondre @{name}",
   "account.unmute_notifications": "Mostrar las notificacions de @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Clicar per ajustar una nòta",
   "alert.rate_limited.message": "Mercés de tornar ensajar aprèp {retry_time, time, medium}.",
   "alert.rate_limited.title": "Taus limitat",
   "alert.unexpected.message": "Una error s’es producha.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Acceptar",
   "follow_request.reject": "Regetar",
   "follow_requests.unlocked_explanation": "Encara que vòstre compte siasque pas verrolhat, la còla de {domain} pensèt que volriatz benlèu repassar las demandas d’abonament d’aquestes comptes.",
+  "generic.saved": "Enregistrat",
   "getting_started.developers": "Desvelopaires",
   "getting_started.directory": "Annuari de perfils",
   "getting_started.documentation": "Documentacion",
@@ -243,7 +242,7 @@
   "keyboard_shortcuts.reply": "respondre",
   "keyboard_shortcuts.requests": "dorbir la lista de demanda d’abonament",
   "keyboard_shortcuts.search": "anar a la recèrca",
-  "keyboard_shortcuts.spoilers": "to show/hide CW field",
+  "keyboard_shortcuts.spoilers": "per mostrar/rescondre lo camp CW",
   "keyboard_shortcuts.start": "dobrir la colomna « Per començar »",
   "keyboard_shortcuts.toggle_hidden": "mostrar/amagar lo tèxte dels avertiments",
   "keyboard_shortcuts.toggle_sensitivity": "mostrar/rescondre los mèdias",
@@ -420,13 +419,16 @@
   "time_remaining.minutes": "demòra{number, plural, one { # minuta} other {n # minutas}}",
   "time_remaining.moments": "Moments restants",
   "time_remaining.seconds": "demòra{number, plural, one { # segonda} other {n # segondas}}",
-  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
-  "timeline_hint.resources.followers": "Followers",
-  "timeline_hint.resources.follows": "Follows",
-  "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} ne charra other {people}} ne charran",
+  "timeline_hint.remote_resource_not_displayed": "{resource} suls autres servidors son pas afichats.",
+  "timeline_hint.resources.followers": "Seguidors",
+  "timeline_hint.resources.follows": "Abonaments",
+  "timeline_hint.resources.statuses": "Tuts mai ancians",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Tendéncia del moment",
   "ui.beforeunload": "Vòstre brolhon serà perdut se quitatz Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Lisatz e depausatz per mandar",
   "upload_button.label": "Ajustar un mèdia (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Talha maximum pels mandadís subrepassada.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Descriure per las personas amb pèrdas auditivas",
   "upload_form.description": "Descripcion pels mal vesents",
   "upload_form.edit": "Modificar",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Suprimir",
   "upload_form.video_description": "Descriure per las personas amb pèrdas auditivas o mal vesent",
   "upload_modal.analyzing_picture": "Analisi de l’imatge…",
   "upload_modal.apply": "Aplicar",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Lo dròlle bilingüe manja un yaourt de ròcs exagonals e kiwis verds farà un an mai",
   "upload_modal.detect_text": "Detectar lo tèxt de l’imatge",
   "upload_modal.edit_media": "Modificar lo mèdia",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 429fc53d1..c03ab95cf 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Dodaj lub usuń z list",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grupa",
@@ -16,7 +15,8 @@
   "account.follow": "Śledź",
   "account.followers": "Śledzący",
   "account.followers.empty": "Nikt jeszcze nie śledzi tego użytkownika.",
-  "account.follows": "Śledzeni",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Ten użytkownik nie śledzi jeszcze nikogo.",
   "account.follows_you": "Śledzi Cię",
   "account.hide_reblogs": "Ukryj podbicia od @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Oczekująca prośba, kliknij aby anulować",
   "account.share": "Udostępnij profil @{name}",
   "account.show_reblogs": "Pokazuj podbicia od @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Odblokuj @{name}",
   "account.unblock_domain": "Odblokuj domenę {domain}",
   "account.unendorse": "Przestań polecać",
   "account.unfollow": "Przestań śledzić",
   "account.unmute": "Cofnij wyciszenie @{name}",
   "account.unmute_notifications": "Cofnij wyciszenie powiadomień od @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Spróbuj ponownie po {retry_time, time, medium}.",
   "alert.rate_limited.title": "Ograniczony czasowo",
   "alert.unexpected.message": "Wystąpił nieoczekiwany błąd.",
@@ -178,6 +176,7 @@
   "follow_request.authorize": "Autoryzuj",
   "follow_request.reject": "Odrzuć",
   "follow_requests.unlocked_explanation": "Mimo że Twoje konto nie jest zablokowane, zespół {domain} uznał że możesz chcieć ręcznie przejrzeć prośby o możliwość śledzenia.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Dla programistów",
   "getting_started.directory": "Katalog profilów",
   "getting_started.documentation": "Dokumentacja",
@@ -429,9 +428,12 @@
   "timeline_hint.resources.followers": "Śledzący",
   "timeline_hint.resources.follows": "Śledzeni",
   "timeline_hint.resources.statuses": "Starsze wpisy",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {osoba rozmawia} few {osoby rozmawiają} other {osób rozmawia}} o tym",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Popularne teraz",
   "ui.beforeunload": "Utracisz tworzony wpis, jeżeli opuścisz Mastodona.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Przeciągnij i upuść aby wysłać",
   "upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Przekroczono limit plików do wysłania.",
@@ -439,10 +441,12 @@
   "upload_form.audio_description": "Opisz dla osób niesłyszących i niedosłyszących",
   "upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących",
   "upload_form.edit": "Opisz",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Usuń",
   "upload_form.video_description": "Opisz dla osób niesłyszących, niedosłyszących, niewidomych i niedowidzących",
   "upload_modal.analyzing_picture": "Analizowanie obrazu…",
   "upload_modal.apply": "Zastosuj",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Pchnąć w tę łódź jeża lub ośm skrzyń fig",
   "upload_modal.detect_text": "Wykryj tekst ze obrazu",
   "upload_modal.edit_media": "Edytuj multimedia",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index c35b7af6f..dae582437 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Nota",
   "account.add_or_remove_from_list": "Adicionar ou Remover de listas",
   "account.badges.bot": "Robô",
   "account.badges.group": "Grupo",
@@ -16,7 +15,8 @@
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
   "account.followers.empty": "Nada aqui.",
-  "account.follows": "Seguindo",
+  "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidores}}",
+  "account.following_counter": "{count, plural, other {{counter} Seguindo}}",
   "account.follows.empty": "Nada aqui.",
   "account.follows_you": "Segue você",
   "account.hide_reblogs": "Ocultar boosts de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Aguardando aprovação. Clique para cancelar a solicitação",
   "account.share": "Compartilhar perfil de @{name}",
   "account.show_reblogs": "Mostrar boosts de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Desbloquear domínio {domain}",
   "account.unendorse": "Não destacar no perfil",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Tirar @{name} do mudo",
   "account.unmute_notifications": "Mostrar notificações de @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Clique para adicionar nota",
   "alert.rate_limited.message": "Por favor tente novamente após {retry_time, time, medium}.",
   "alert.rate_limited.title": "Frequência limitada",
   "alert.unexpected.message": "Ocorreu um erro inesperado.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Aprovar",
   "follow_request.reject": "Vetar",
   "follow_requests.unlocked_explanation": "Embora sua conta não esteja trancada, o staff de {domain} achou que você podia querer revisar pedidos para te seguir destas contas manualmente.",
+  "generic.saved": "Salvo",
   "getting_started.developers": "Desenvolvedores",
   "getting_started.directory": "Diretório de perfis",
   "getting_started.documentation": "Documentação",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Seguidores",
   "timeline_hint.resources.follows": "Seguindo",
   "timeline_hint.resources.statuses": "Toots mais antigos",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {pessoa} other {pessoas}} falando",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} pessoa} other {{counter} pessoas}} falando",
   "trends.trending_now": "Em alta no momento",
   "ui.beforeunload": "Seu rascunho vai ser perdido se você sair do Mastodon.",
+  "units.short.billion": "{count} bi",
+  "units.short.million": "{count} mi",
+  "units.short.thousand": "{count} mil",
   "upload_area.title": "Arraste & solte para fazer upload",
   "upload_button.label": "Adicionar mídia ({formats})",
   "upload_error.limit": "Limite de upload de arquivos excedido.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Descrever para pessoas com deficiência auditiva",
   "upload_form.description": "Descreva para deficientes visuais",
   "upload_form.edit": "Descreva",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Excluir",
   "upload_form.video_description": "Descreva para pessoas com deficiência auditiva ou visual",
   "upload_modal.analyzing_picture": "Analisando imagem…",
   "upload_modal.apply": "Aplicar",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Um pequeno jabuti xereta viu dez cegonhas felizes",
   "upload_modal.detect_text": "Detectar texto da imagem",
   "upload_modal.edit_media": "Editar mídia",
diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json
index 2697b0a0c..49fb95885 100644
--- a/app/javascript/mastodon/locales/pt-PT.json
+++ b/app/javascript/mastodon/locales/pt-PT.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "A sua nota para @{name}",
   "account.add_or_remove_from_list": "Adicionar ou remover das listas",
   "account.badges.bot": "Robô",
   "account.badges.group": "Grupo",
@@ -16,9 +15,10 @@
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
   "account.followers.empty": "Ainda ninguém segue este utilizador.",
-  "account.follows": "Segue",
+  "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidores}}",
+  "account.following_counter": "{count, plural, other {A seguir {counter}}}",
   "account.follows.empty": "Este utilizador ainda não segue alguém.",
-  "account.follows_you": "É teu seguidor",
+  "account.follows_you": "Segue-te",
   "account.hide_reblogs": "Esconder partilhas de @{name}",
   "account.last_status": "Última atividade",
   "account.link_verified_on": "A posse deste link foi verificada em {date}",
@@ -36,16 +36,14 @@
   "account.requested": "A aguardar aprovação. Clique para cancelar o pedido de seguidor",
   "account.share": "Partilhar o perfil @{name}",
   "account.show_reblogs": "Mostrar partilhas de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Mostrar {domain}",
   "account.unendorse": "Não mostrar no perfil",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Não silenciar @{name}",
   "account.unmute_notifications": "Deixar de silenciar @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Nenhum comentário fornecido",
   "alert.rate_limited.message": "Volte a tentar depois das {retry_time, time, medium}.",
   "alert.rate_limited.title": "Limite de tentativas",
   "alert.unexpected.message": "Ocorreu um erro inesperado.",
@@ -62,7 +60,7 @@
   "column.blocks": "Utilizadores Bloqueados",
   "column.bookmarks": "Itens salvos",
   "column.community": "Cronologia local",
-  "column.direct": "Mensagens directas",
+  "column.direct": "Mensagens diretas",
   "column.directory": "Procurar perfis",
   "column.domain_blocks": "Domínios escondidos",
   "column.favourites": "Favoritos",
@@ -89,7 +87,7 @@
   "compose_form.hashtag_warning": "Este toot não será listado em nenhuma hashtag por ser não listado. Apenas toots públics podem ser pesquisados por hashtag.",
   "compose_form.lock_disclaimer": "A tua conta não está {locked}. Qualquer pessoa pode seguir-te e ver as publicações direcionadas apenas a seguidores.",
   "compose_form.lock_disclaimer.lock": "bloqueado",
-  "compose_form.placeholder": "Em que está a pensar?",
+  "compose_form.placeholder": "Em que estás a pensar?",
   "compose_form.poll.add_option": "Adicionar uma opção",
   "compose_form.poll.duration": "Duração da votação",
   "compose_form.poll.option_placeholder": "Opção {number}",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rejeitar",
   "follow_requests.unlocked_explanation": "Apesar de a sua não estar bloqueada, a administração de {domain} pensa que poderá querer rever os pedidos dessas contas manualmente.",
+  "generic.saved": "Salvo",
   "getting_started.developers": "Responsáveis pelo desenvolvimento",
   "getting_started.directory": "Directório de perfil",
   "getting_started.documentation": "Documentação",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Seguidores",
   "timeline_hint.resources.follows": "Seguindo",
   "timeline_hint.resources.statuses": "Toots antigos",
-  "trends.count_by_accounts": "{count} {rawCount, plural, uma {person} outra {people}} a falar",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} pessoa} other {{counter} pessoas}} a conversar",
   "trends.trending_now": "Tendências atuais",
   "ui.beforeunload": "O teu rascunho será perdido se abandonares o Mastodon.",
+  "units.short.billion": "{count}MM",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}m",
   "upload_area.title": "Arraste e solte para enviar",
   "upload_button.label": "Adicionar media ({formats})",
   "upload_error.limit": "Limite máximo do ficheiro a carregar excedido.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Descreva para pessoas com diminuição da acuidade auditiva",
   "upload_form.description": "Descrição da imagem para pessoas com dificuldades visuais",
   "upload_form.edit": "Editar",
+  "upload_form.thumbnail": "Alterar miniatura",
   "upload_form.undo": "Apagar",
   "upload_form.video_description": "Descreva para pessoas com diminuição da acuidade auditiva ou visual",
   "upload_modal.analyzing_picture": "A analizar imagem…",
   "upload_modal.apply": "Aplicar",
+  "upload_modal.choose_image": "Escolher imagem",
   "upload_modal.description_placeholder": "Grave e cabisbaixo, o filho justo zelava pela querida mãe doente",
   "upload_modal.detect_text": "Detectar texto na imagem",
   "upload_modal.edit_media": "Editar media",
diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json
index e470a7f90..c00eca297 100644
--- a/app/javascript/mastodon/locales/ro.json
+++ b/app/javascript/mastodon/locales/ro.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Adaugă sau Elimină din liste",
   "account.badges.bot": "Robot",
   "account.badges.group": "Grup",
@@ -16,7 +15,8 @@
   "account.follow": "Urmărește",
   "account.followers": "Urmăritori",
   "account.followers.empty": "Acest utilizator nu are încă urmăritori.",
-  "account.follows": "Urmărește",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Acest utilizator nu urmărește pe nimeni încă.",
   "account.follows_you": "Te urmărește",
   "account.hide_reblogs": "Ascunde impulsurile de la @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Se așteaptă aprobarea. Apasă pentru a anula cererea de urmărire",
   "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}}",
   "account.unblock": "Deblochează pe @{name}",
   "account.unblock_domain": "Deblochează domeniul {domain}",
   "account.unendorse": "Nu promova pe profil",
   "account.unfollow": "Nu mai urmări",
   "account.unmute": "Nu mai ignora pe @{name}",
   "account.unmute_notifications": "Activează notificările de la @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Vă rugăm să reîncercați după {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rată limitată",
   "alert.unexpected.message": "A apărut o eroare neașteptată.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizează",
   "follow_request.reject": "Respinge",
   "follow_requests.unlocked_explanation": "Chiar dacă contul dvs nu este blocat, personalul {domain} a crezut că ați putea dori să revizuiți cererile de la aceste conturi în mod manual.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Dezvoltatori",
   "getting_started.directory": "Explorează",
   "getting_started.documentation": "Documentație",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Urmăritori",
   "timeline_hint.resources.follows": "Urmăriri",
   "timeline_hint.resources.statuses": "Postări mai vechi",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persoană} other {persoane}} vorbește/ecs",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "În tendință acum",
   "ui.beforeunload": "Postarea se va pierde dacă părăsești pagina.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Trage și eliberează pentru a încărca",
   "upload_button.label": "Adaugă media (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Limita de încărcare a fișierului a fost depășită.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Descrie pentru persoanele cu deficiență a auzului",
   "upload_form.description": "Adaugă o descriere pentru persoanele cu deficiențe de vedere",
   "upload_form.edit": "Editează",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Șterge",
   "upload_form.video_description": "Descrie pentru persoanele cu pierdere a auzului sau tulburări de vedere",
   "upload_modal.analyzing_picture": "Se analizează imaginea…",
   "upload_modal.apply": "Aplică",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detectare text din imagine",
   "upload_modal.edit_media": "Editați media",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 5786569e4..0d1a401a2 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Заметка",
   "account.add_or_remove_from_list": "Управление списками",
   "account.badges.bot": "Бот",
   "account.badges.group": "Группа",
@@ -16,7 +15,8 @@
   "account.follow": "Подписаться",
   "account.followers": "Подписаны",
   "account.followers.empty": "На этого пользователя пока никто не подписан.",
-  "account.follows": "Подписки",
+  "account.followers_counter": "{count, plural, one {{counter} подписчик} many {{counter} подписчиков} other {{counter} подписчика}}",
+  "account.following_counter": "{count, plural, one {{counter} подписка} many {{counter} подписок} other {{counter} подписки}}",
   "account.follows.empty": "Этот пользователь пока ни на кого не подписался.",
   "account.follows_you": "Подписан(а) на вас",
   "account.hide_reblogs": "Скрыть продвижения от @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Ожидает подтверждения. Нажмите для отмены",
   "account.share": "Поделиться профилем @{name}",
   "account.show_reblogs": "Показывать продвижения от @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} пост} many {{counter} постов} other {{counter} поста}}",
   "account.unblock": "Разблокировать @{name}",
   "account.unblock_domain": "Разблокировать {domain}",
   "account.unendorse": "Не рекомендовать в профиле",
   "account.unfollow": "Отписаться",
   "account.unmute": "Не игнорировать @{name}",
   "account.unmute_notifications": "Показывать уведомления от @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Текст заметки",
   "alert.rate_limited.message": "Пожалуйста, повторите после {retry_time, time, medium}.",
   "alert.rate_limited.title": "Вы выполняете действие слишком часто",
   "alert.unexpected.message": "Произошла непредвиденная ошибка.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Авторизовать",
   "follow_request.reject": "Отказать",
   "follow_requests.unlocked_explanation": "Этот запрос отправлен с учётной записи, для которой администрация {domain} включила ручную проверку подписок.",
+  "generic.saved": "Сохранено",
   "getting_started.developers": "Разработчикам",
   "getting_started.directory": "Каталог профилей",
   "getting_started.documentation": "Документация",
@@ -423,10 +422,13 @@
   "timeline_hint.remote_resource_not_displayed": "Мы не отображаем {resource} с других серверов.",
   "timeline_hint.resources.followers": "подписчиков",
   "timeline_hint.resources.follows": "подписки",
-  "timeline_hint.resources.statuses": "Прошлые посты",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {человек говорит} few {человека говорят} other {человек говорят}} про это",
+  "timeline_hint.resources.statuses": "прошлые посты",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} человек} many {{counter} человек} other {{counter} человека}}",
   "trends.trending_now": "Самое актуальное",
   "ui.beforeunload": "Ваш черновик будет утерян, если вы покинете Mastodon.",
+  "units.short.billion": "{count} млрд",
+  "units.short.million": "{count} млн",
+  "units.short.thousand": "{count} тыс.",
   "upload_area.title": "Перетащите сюда, чтобы загрузить",
   "upload_button.label": "Прикрепить фото, видео или аудио",
   "upload_error.limit": "Достигнут лимит загруженных файлов.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Опишите аудиофайл для людей с нарушением слуха",
   "upload_form.description": "Добавьте описание для людей с нарушениями зрения:",
   "upload_form.edit": "Опишите",
+  "upload_form.thumbnail": "Изменить обложку",
   "upload_form.undo": "Отменить",
   "upload_form.video_description": "Опишите видео для людей с нарушением слуха или зрения",
   "upload_modal.analyzing_picture": "Обработка изображения…",
   "upload_modal.apply": "Применить",
+  "upload_modal.choose_image": "Выбрать изображение",
   "upload_modal.description_placeholder": "На дворе трава, на траве дрова",
   "upload_modal.detect_text": "Найти текст на картинке",
   "upload_modal.edit_media": "Изменить файл",
diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json
index 79f593417..916576656 100644
--- a/app/javascript/mastodon/locales/sc.json
+++ b/app/javascript/mastodon/locales/sc.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Agiunghe o boga dae is listas",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grupu",
@@ -16,7 +15,8 @@
   "account.follow": "Sighi",
   "account.followers": "Sighiduras",
   "account.followers.empty": "Nemos sighit ancora custa persone.",
-  "account.follows": "Sighende",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Custa persone non sighit ancora a nemos.",
   "account.follows_you": "Ti sighit",
   "account.hide_reblogs": "Cua is cumpartziduras de @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Incarca pro annullare sa rechesta de sighidura",
   "account.share": "Cumpartzi su profilu de @{name}",
   "account.show_reblogs": "Ammustra is cumpartziduras de @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Isbloca @{name}",
   "account.unblock_domain": "Isbloca su domìniu {domain}",
   "account.unendorse": "Non cussiges in su profilu",
   "account.unfollow": "Non sigas prus",
   "account.unmute": "Torra a ativare @{name}",
   "account.unmute_notifications": "Ativa notìficas pro @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Torra·bi a proare a pustis de {retry_time, time, medium}.",
   "alert.rate_limited.title": "Màssimu de rechestas barigadu",
   "alert.unexpected.message": "B'at àpidu una faddina.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autoriza",
   "follow_request.reject": "Refuda",
   "follow_requests.unlocked_explanation": "Fintzas si su contu tuo no est blocadu, su personale de {domain} at pensadu chi forsis bolias revisionare a manu is rechestas de custos contos.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Iscuadra de isvilupu",
   "getting_started.directory": "Diretòriu de profilos",
   "getting_started.documentation": "Documentatzione",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {persone} other {persones}} nde sunt chistionende",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Est tendèntzia immoe",
   "ui.beforeunload": "S'abbotzu tuo at a èssere pèrdidu si essis dae Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Traga pro carrigare",
   "upload_button.label": "Agiunghe mèdias ({formats})",
   "upload_error.limit": "Lìmite de càrriga de archìvios barigadu.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Descritzione pro persones cun pèrdida auditiva",
   "upload_form.description": "Descritzione pro persones cun problemas visuales",
   "upload_form.edit": "Modìfica",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Cantzella",
   "upload_form.video_description": "Descritzione pro persones cun pèrdida auditiva o problemas visuales",
   "upload_modal.analyzing_picture": "Analizende immàgine…",
   "upload_modal.apply": "Àplica",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Su margiane castàngiu brincat lestru a subra de su cane mandrone",
   "upload_modal.detect_text": "Rileva testu de s'immàgine",
   "upload_modal.edit_media": "Modìfica su mèdia",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 582af0655..048704872 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Pridaj do, alebo odober zo zoznamov",
   "account.badges.bot": "Bot",
   "account.badges.group": "Skupina",
@@ -16,7 +15,8 @@
   "account.follow": "Nasleduj",
   "account.followers": "Sledujúci",
   "account.followers.empty": "Tohto používateľa ešte nikto nenásleduje.",
-  "account.follows": "Nasleduje",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Tento používateľ ešte nikoho nenasleduje.",
   "account.follows_you": "Nasleduje ťa",
   "account.hide_reblogs": "Skry vyzdvihnutia od @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Čaká na schválenie. Klikni pre zrušenie žiadosti",
   "account.share": "Zdieľaj @{name} profil",
   "account.show_reblogs": "Ukáž vyzdvihnutia od @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Odblokuj @{name}",
   "account.unblock_domain": "Prestaň skrývať {domain}",
   "account.unendorse": "Nezobrazuj na profile",
   "account.unfollow": "Prestaň následovať",
   "account.unmute": "Prestaň ignorovať @{name}",
   "account.unmute_notifications": "Zruš stĺmenie oboznámení od @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Prosím, skús to znova za {retry_time, time, medium}.",
   "alert.rate_limited.title": "Tempo obmedzené",
   "alert.unexpected.message": "Vyskytla sa nečakaná chyba.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Povoľ prístup",
   "follow_request.reject": "Odmietni",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Vývojári",
   "getting_started.directory": "Zoznam profilov",
   "getting_started.documentation": "Dokumentácia",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {človek spomína} other {ľudí spomína}}",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Teraz populárne",
   "ui.beforeunload": "Čo máš rozpísané sa stratí, ak opustíš Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Pretiahni a pusť pre nahratie",
   "upload_button.label": "Pridaj médiálny súbor (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Limit pre nahrávanie súborov bol prekročený.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Popíš, pre ľudí so stratou sluchu",
   "upload_form.description": "Opis pre slabo vidiacich",
   "upload_form.edit": "Popíš",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Vymaž",
   "upload_form.video_description": "Popíš, pre ľudí so stratou sluchu, alebo očným znevýhodnením",
   "upload_modal.analyzing_picture": "Analyzujem obrázok…",
   "upload_modal.apply": "Použi",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Rýchla hnedá líška skáče ponad lenivého psa",
   "upload_modal.detect_text": "Rozpoznaj text z obrázka",
   "upload_modal.edit_media": "Uprav médiá",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index 3f334892b..d13bf5e36 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Dodaj ali odstrani iz seznama",
   "account.badges.bot": "Robot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Sledi",
   "account.followers": "Sledilci",
   "account.followers.empty": "Nihče ne sledi temu uporabniku.",
-  "account.follows": "Sledi",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Ta uporabnik še ne sledi nikomur.",
   "account.follows_you": "Sledi tebi",
   "account.hide_reblogs": "Skrij spodbude od @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Čakanje na odobritev. Kliknite, da prekličete prošnjo za sledenje",
   "account.share": "Delite profil osebe @{name}",
   "account.show_reblogs": "Pokaži spodbude osebe @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Odblokiraj @{name}",
   "account.unblock_domain": "Razkrij {domain}",
   "account.unendorse": "Ne vključi v profil",
   "account.unfollow": "Prenehaj slediti",
   "account.unmute": "Odtišaj @{name}",
   "account.unmute_notifications": "Vklopi obvestila od @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "Zgodila se je nepričakovana napaka.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Overi",
   "follow_request.reject": "Zavrni",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Razvijalci",
   "getting_started.directory": "Imenik profilov",
   "getting_started.documentation": "Dokumentacija",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {oseba} other {ljudi}} govori",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Vaš osnutek bo izgubljen, če zapustite Mastodona.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Za pošiljanje povlecite in spustite",
   "upload_button.label": "Dodaj medije ({formats})",
   "upload_error.limit": "Omejitev prenosa datoteke je presežena.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Opišite za slabovidne",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Izbriši",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Pri Jakcu bom vzel šest čudežnih fig",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json
index 5c8181ce1..95cadfe25 100644
--- a/app/javascript/mastodon/locales/sq.json
+++ b/app/javascript/mastodon/locales/sq.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Shënimi juaj për @{name}",
   "account.add_or_remove_from_list": "Shtoni ose Hiqni prej listash",
   "account.badges.bot": "Robot",
   "account.badges.group": "Grup",
@@ -16,7 +15,8 @@
   "account.follow": "Ndiqeni",
   "account.followers": "Ndjekës",
   "account.followers.empty": "Këtë përdorues ende s’e ndjek njeri.",
-  "account.follows": "Ndjekje",
+  "account.followers_counter": "{count, plural, one {{counter} Ndjekës} other {{counter} Ndjekës}}",
+  "account.following_counter": "{count, plural, one {} other {{counter} të Ndjekur}}",
   "account.follows.empty": "Ky përdorues ende s’ndjek njeri.",
   "account.follows_you": "Ju ndjek",
   "account.hide_reblogs": "Fshih përforcime nga @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Në pritje të miratimit. Që të anuloni kërkesën për ndjekje, klikojeni",
   "account.share": "Ndajeni profilin e @{name} me të tjerët",
   "account.show_reblogs": "Shfaq përforcime nga @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Mesazh} other {{counter} Mesazhe}}",
   "account.unblock": "Zhbllokoje @{name}",
   "account.unblock_domain": "Zhblloko përkatësinë {domain}",
   "account.unendorse": "Mos e përfshi në profil",
   "account.unfollow": "Resht së ndjekuri",
   "account.unmute": "Ktheji zërin @{name}",
   "account.unmute_notifications": "Hiqua ndalimin e shfaqjes njoftimeve nga @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "S’u dha koment",
   "alert.rate_limited.message": "Ju lutemi, riprovoni pas {retry_time, time, medium}.",
   "alert.rate_limited.title": "Shpejtësi e kufizuar",
   "alert.unexpected.message": "Ndodhi një gabim të papritur.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Autorizoje",
   "follow_request.reject": "Hidhe tej",
   "follow_requests.unlocked_explanation": "Edhe pse llogaria juaj s’është e kyçur, ekipi i {domain} mendoi se mund të donit të shqyrtonit dorazi kërkesa ndjekjeje prej këtyre llogarive.",
+  "generic.saved": "U ruajt",
   "getting_started.developers": "Zhvillues",
   "getting_started.directory": "Drejtori profilesh",
   "getting_started.documentation": "Dokumentim",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Ndjekës",
   "timeline_hint.resources.follows": "Ndjekje",
   "timeline_hint.resources.statuses": "Mesazhe të vjetër",
-  "trends.count_by_accounts": "E biseduar nga {count} {rawCount, plural, one {person} other {vetë}}",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} vetë}} duke folur",
   "trends.trending_now": "Prirjet e tashme",
   "ui.beforeunload": "Skica juaj do të humbë, nëse dilni nga Mastodon-i.",
+  "units.short.billion": "{count}Md",
+  "units.short.million": "{count}Ml",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Që të ngarkohet, merreni & vëreni",
   "upload_button.label": "Shtoni figura, një video ose një kartelë audio",
   "upload_error.limit": "U tejkalua kufi ngarkimi kartelash.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Përshkruajeni për persona me dëgjim të kufizuar",
   "upload_form.description": "Përshkruajeni për persona me probleme shikimi",
   "upload_form.edit": "Përpunoni",
+  "upload_form.thumbnail": "Ndryshoni miniaturën",
   "upload_form.undo": "Fshije",
   "upload_form.video_description": "Përshkruajeni për persona me dëgjim të kufizuar ose probleme shikimi",
   "upload_modal.analyzing_picture": "Po analizohet fotoja…",
   "upload_modal.apply": "Aplikoje",
+  "upload_modal.choose_image": "Zgjidhni figurë",
   "upload_modal.description_placeholder": "Deshe Korçën, Korçën të dhamë",
   "upload_modal.detect_text": "Pikase tekstin prej fotoje",
   "upload_modal.edit_media": "Përpunoni media",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index cb49a1cb9..7a17e9134 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Zaprati",
   "account.followers": "Pratioca",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Prati",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Prati Vas",
   "account.hide_reblogs": "Sakrij podrške koje daje korisnika @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Čekam odobrenje. Kliknite da poništite zahtev za praćenje",
   "account.share": "Podeli profil korisnika @{name}",
   "account.show_reblogs": "Prikaži podrške od korisnika @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Odblokiraj korisnika @{name}",
   "account.unblock_domain": "Odblokiraj domen {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Otprati",
   "account.unmute": "Ukloni ućutkavanje korisniku @{name}",
   "account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Odobri",
   "follow_request.reject": "Odbij",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Ako napustite Mastodont, izgubićete napisani nacrt.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Prevucite ovde da otpremite",
   "upload_button.label": "Dodaj multimediju",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Opiši za slabovide osobe",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Opozovi",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index b1104f653..bcaa45ed0 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Додај или Одстрани са листа",
   "account.badges.bot": "Бот",
   "account.badges.group": "Група",
@@ -16,7 +15,8 @@
   "account.follow": "Запрати",
   "account.followers": "Пратиоци",
   "account.followers.empty": "Тренутно нико не прати овог корисника.",
-  "account.follows": "Прати",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Корисник тренутно не прати никога.",
   "account.follows_you": "Прати Вас",
   "account.hide_reblogs": "Сакриј подршке које даје корисника @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Чекам одобрење. Кликните да поништите захтев за праћење",
   "account.share": "Подели профил корисника @{name}",
   "account.show_reblogs": "Прикажи подршке од корисника @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Одблокирај корисника @{name}",
   "account.unblock_domain": "Одблокирај домен {domain}",
   "account.unendorse": "Не истичи на профилу",
   "account.unfollow": "Отпрати",
   "account.unmute": "Уклони ућуткавање кориснику @{name}",
   "account.unmute_notifications": "Укључи назад обавештења од корисника @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Молимо покушајте поново после {retry_time, time, medium}.",
   "alert.rate_limited.title": "Ограничена брзина",
   "alert.unexpected.message": "Појавила се неочекивана грешка.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Одобри",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Програмери",
   "getting_started.directory": "Профил фасцикле",
   "getting_started.documentation": "Документација",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {човек} other {људи}} прича",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Ако напустите Мастодонт, изгубићете написани нацрт.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Превуците овде да отпремите",
   "upload_button.label": "Додај мултимедију (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Опишите за особе са оштећеним видом",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Обриши",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index ebc20fcb4..f7fa1a1c6 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Lägg till i eller ta bort från listor",
   "account.badges.bot": "Robot",
   "account.badges.group": "Grupp",
@@ -16,7 +15,8 @@
   "account.follow": "Följ",
   "account.followers": "Följare",
   "account.followers.empty": "Ingen följer denna användare än.",
-  "account.follows": "Följer",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Denna användare följer inte någon än.",
   "account.follows_you": "Följer dig",
   "account.hide_reblogs": "Dölj knuffar från @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Inväntar godkännande. Klicka för att avbryta följarförfrågan",
   "account.share": "Dela @{name}s profil",
   "account.show_reblogs": "Visa knuffar från @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Avblockera @{name}",
   "account.unblock_domain": "Sluta dölja {domain}",
   "account.unendorse": "Visa inte på profil",
   "account.unfollow": "Sluta följ",
   "account.unmute": "Sluta tysta @{name}",
   "account.unmute_notifications": "Återaktivera aviseringar från @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Vänligen försök igen efter {retry_time, time, medium}.",
   "alert.rate_limited.title": "Mängd begränsad",
   "alert.unexpected.message": "Ett oväntat fel uppstod.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Godkänn",
   "follow_request.reject": "Avvisa",
   "follow_requests.unlocked_explanation": "Även om ditt konto inte är låst tror {domain} personalen att du kanske vill granska dessa följares förfrågningar manuellt.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Utvecklare",
   "getting_started.directory": "Profilkatalog",
   "getting_started.documentation": "Dokumentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, en {person} andra {people}} pratar",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trendar nu",
   "ui.beforeunload": "Ditt utkast kommer att förloras om du lämnar Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Dra & släpp för att ladda upp",
   "upload_button.label": "Lägg till media",
   "upload_error.limit": "Filöverföringsgränsen överskriden.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Beskriv för hörselskadade",
   "upload_form.description": "Beskriv för synskadade",
   "upload_form.edit": "Beskriv",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Ta bort",
   "upload_form.video_description": "Beskriv för hörselskadade eller synskadade",
   "upload_modal.analyzing_picture": "Analyserar bild…",
   "upload_modal.apply": "Verkställ",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "En snabb brun räv hoppar över den lata hunden",
   "upload_modal.detect_text": "Upptäck bildens text",
   "upload_modal.edit_media": "Redigera meida",
diff --git a/app/javascript/mastodon/locales/szl.json b/app/javascript/mastodon/locales/szl.json
index 1476d0a54..36f55e800 100644
--- a/app/javascript/mastodon/locales/szl.json
+++ b/app/javascript/mastodon/locales/szl.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Follow",
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Awaiting approval",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json
index 8fdf10997..9caef0582 100644
--- a/app/javascript/mastodon/locales/ta.json
+++ b/app/javascript/mastodon/locales/ta.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "பட்டியல்களில் சேர்/நீக்கு",
   "account.badges.bot": "பாட்",
   "account.badges.group": "குழு",
@@ -16,7 +15,8 @@
   "account.follow": "பின்தொடர்",
   "account.followers": "பின்தொடர்பவர்கள்",
   "account.followers.empty": "இதுவரை யாரும் இந்த பயனரைப் பின்தொடரவில்லை.",
-  "account.follows": "பின்தொடர்",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "இந்த பயனர் இதுவரை யாரையும் பின்தொடரவில்லை.",
   "account.follows_you": "உங்களைப் பின்தொடர்கிறார்",
   "account.hide_reblogs": "இருந்து ஊக்கியாக மறை @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "ஒப்புதலுக்காகக் காத்திருக்கிறது. பின்தொடரும் கோரிக்கையை நீக்க அழுத்தவும்",
   "account.share": "@{name} உடைய விவரத்தை பகிர்",
   "account.show_reblogs": "காட்டு boosts இருந்து @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} மீது தடை நீக்குக",
   "account.unblock_domain": "{domain} ஐ காண்பி",
   "account.unendorse": "சுயவிவரத்தில் இடம்பெற வேண்டாம்",
   "account.unfollow": "பின்தொடர்வதை நிறுத்துக",
   "account.unmute": "@{name} இன் மீது மௌனத் தடையை நீக்குக",
   "account.unmute_notifications": "@{name} இலிருந்து அறிவிப்புகளின் மீது மௌனத் தடையை நீக்குக",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "{retry_time, time, medium} க்கு பிறகு மீண்டும் முயற்சிக்கவும்.",
   "alert.rate_limited.title": "பயன்பாடு கட்டுப்படுத்தப்பட்டுள்ளது",
   "alert.unexpected.message": "எதிர்பாராத பிழை ஏற்பட்டுவிட்டது.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "அதிகாரமளி",
   "follow_request.reject": "விலக்கு",
   "follow_requests.unlocked_explanation": "உங்கள் கணக்கு பூட்டப்படவில்லை என்றாலும், இந்தக் கணக்குகளிலிருந்து உங்களைப் பின்தொடர விரும்பும் கோரிக்கைகளை நீங்கள் பரீசீலிப்பது நலம் என்று {domain} ஊழியர் எண்ணுகிறார்.",
+  "generic.saved": "Saved",
   "getting_started.developers": "உருவாக்குநர்கள்",
   "getting_started.directory": "சுயவிவர அடைவு",
   "getting_started.documentation": "ஆவணங்கள்",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} மற்ற {people}} உரையாடு",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "இப்போது செல்திசையில் இருப்பவை",
   "ui.beforeunload": "நீங்கள் வெளியே சென்றால் உங்கள் வரைவு இழக்கப்படும் மஸ்தோடோன்.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "பதிவேற்ற & இழுக்கவும்",
   "upload_button.label": "மீடியாவைச் சேர்க்கவும் (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "கோப்பு பதிவேற்ற வரம்பு மீறப்பட்டது.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "செவித்திறன் குறைபாடு உள்ளவர்களுக்காக விளக்குக‌",
   "upload_form.description": "பார்வையற்ற விவரிக்கவும்",
   "upload_form.edit": "தொகு",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "நீக்கு",
   "upload_form.video_description": "செவித்திறன் மற்றும் பார்வைக் குறைபாடு உள்ளவர்களுக்காக விளக்குக‌",
   "upload_modal.analyzing_picture": "படம் ஆராயப்படுகிறது…",
   "upload_modal.apply": "உபயோகி",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "பொருள் விளக்கம்",
   "upload_modal.detect_text": "படத்தில் இருக்கும் எழுத்தை கண்டறி",
   "upload_modal.edit_media": "படத்தைத் தொகு",
diff --git a/app/javascript/mastodon/locales/tai.json b/app/javascript/mastodon/locales/tai.json
index 1476d0a54..36f55e800 100644
--- a/app/javascript/mastodon/locales/tai.json
+++ b/app/javascript/mastodon/locales/tai.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "Follow",
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Awaiting approval",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "An unexpected error occurred.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json
index 45e0dce32..a57efd7c6 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "జాబితాల నుండి చేర్చు లేదా తీసివేయి",
   "account.badges.bot": "బాట్",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "అనుసరించు",
   "account.followers": "అనుచరులు",
   "account.followers.empty": "ఈ వినియోగదారుడిని ఇంకా ఎవరూ అనుసరించడంలేదు.",
-  "account.follows": "అనుసరిస్తున్నవి",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "ఈ వినియోగదారి ఇంకా ఎవరినీ అనుసరించడంలేదు.",
   "account.follows_you": "మిమ్మల్ని అనుసరిస్తున్నారు",
   "account.hide_reblogs": "@{name} నుంచి బూస్ట్ లను దాచిపెట్టు",
@@ -36,16 +36,14 @@
   "account.requested": "ఆమోదం కోసం వేచి ఉంది. అభ్యర్థనను రద్దు చేయడానికి క్లిక్ చేయండి",
   "account.share": "@{name} యొక్క ప్రొఫైల్ను పంచుకోండి",
   "account.show_reblogs": "@{name}నుంచి బూస్ట్ లను చూపించు",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name}పై బ్లాక్ ను తొలగించు",
   "account.unblock_domain": "{domain}ను దాచవద్దు",
   "account.unendorse": "ప్రొఫైల్లో చూపించవద్దు",
   "account.unfollow": "అనుసరించవద్దు",
   "account.unmute": "@{name}పై మ్యూట్ ని తొలగించు",
   "account.unmute_notifications": "@{name} నుంచి ప్రకటనలపై మ్యూట్ ని తొలగించు",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "అనుకోని తప్పు జరిగినది.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "అనుమతించు",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "డెవలపర్లు",
   "getting_started.directory": "ప్రొఫైల్ డైరెక్టరీ",
   "getting_started.documentation": "డాక్యుమెంటేషన్",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} మాట్లాడుతున్నారు",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "మీరు మాస్టొడొన్ను వదిలివేస్తే మీ డ్రాఫ్ట్లు పోతాయి.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "అప్లోడ్ చేయడానికి డ్రాగ్ & డ్రాప్ చేయండి",
   "upload_button.label": "మీడియాను జోడించండి (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "దృష్టి లోపమున్న వారి కోసం వివరించండి",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "తొలగించు",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 4ecd1be72..5852ec5ca 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "หมายเหตุของคุณสำหรับ @{name}",
   "account.add_or_remove_from_list": "เพิ่มหรือเอาออกจากรายการ",
   "account.badges.bot": "บอต",
   "account.badges.group": "กลุ่ม",
@@ -16,7 +15,8 @@
   "account.follow": "ติดตาม",
   "account.followers": "ผู้ติดตาม",
   "account.followers.empty": "ยังไม่มีใครติดตามผู้ใช้นี้",
-  "account.follows": "การติดตาม",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "ผู้ใช้นี้ยังไม่ได้ติดตามใคร",
   "account.follows_you": "ติดตามคุณ",
   "account.hide_reblogs": "ซ่อนการดันจาก @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "กำลังรอการอนุมัติ คลิกเพื่อยกเลิกคำขอติดตาม",
   "account.share": "แบ่งปันโปรไฟล์ของ @{name}",
   "account.show_reblogs": "แสดงการดันจาก @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "เลิกปิดกั้น @{name}",
   "account.unblock_domain": "เลิกปิดกั้นโดเมน {domain}",
   "account.unendorse": "ไม่แสดงให้เห็นในโปรไฟล์",
   "account.unfollow": "เลิกติดตาม",
   "account.unmute": "เลิกซ่อน @{name}",
   "account.unmute_notifications": "เลิกซ่อนการแจ้งเตือนจาก @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "ไม่มีความคิดเห็นที่ระบุไว้",
   "alert.rate_limited.message": "โปรดลองใหม่หลังจาก {retry_time, time, medium}",
   "alert.rate_limited.title": "มีการจำกัดอัตรา",
   "alert.unexpected.message": "เกิดข้อผิดพลาดที่ไม่คาดคิด",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "อนุญาต",
   "follow_request.reject": "ปฏิเสธ",
   "follow_requests.unlocked_explanation": "แม้ว่าไม่มีการล็อคบัญชีของคุณ พนักงานของ {domain} คิดว่าคุณอาจต้องการตรวจทานคำขอติดตามจากบัญชีเหล่านี้ด้วยตนเอง",
+  "generic.saved": "บันทึกแล้ว",
   "getting_started.developers": "นักพัฒนา",
   "getting_started.directory": "ไดเรกทอรีโปรไฟล์",
   "getting_started.documentation": "เอกสารประกอบ",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "ผู้ติดตาม",
   "timeline_hint.resources.follows": "การติดตาม",
   "timeline_hint.resources.statuses": "โพสต์ที่เก่ากว่า",
-  "trends.count_by_accounts": "{count} {rawCount, plural, other {คน}}กำลังพูดคุย",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "กำลังนิยม",
   "ui.beforeunload": "แบบร่างของคุณจะหายไปหากคุณออกจาก Mastodon",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "ลากแล้วปล่อยเพื่ออัปโหลด",
   "upload_button.label": "เพิ่มไฟล์ภาพ วิดีโอ หรือเสียง",
   "upload_error.limit": "เกินขีดจำกัดการอัปโหลดไฟล์",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "อธิบายสำหรับผู้สูญเสียการได้ยิน",
   "upload_form.description": "อธิบายสำหรับผู้บกพร่องทางการมองเห็น",
   "upload_form.edit": "แก้ไข",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "ลบ",
   "upload_form.video_description": "อธิบายสำหรับผู้สูญเสียการได้ยินหรือบกพร่องทางการมองเห็น",
   "upload_modal.analyzing_picture": "กำลังวิเคราะห์รูปภาพ…",
   "upload_modal.apply": "นำไปใช้",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "สุนัขจิ้งจอกสีน้ำตาลที่ว่องไวกระโดดข้ามสุนัขขี้เกียจ",
   "upload_modal.detect_text": "ตรวจหาข้อความจากรูปภาพ",
   "upload_modal.edit_media": "แก้ไขสื่อ",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index f6495bd63..a5bbbfcd9 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -1,13 +1,12 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "@{name} için notunuz",
   "account.add_or_remove_from_list": "Listelere ekle veya kaldır",
   "account.badges.bot": "Bot",
   "account.badges.group": "Grup",
   "account.block": "@{name} adlı kişiyi engelle",
   "account.block_domain": "{domain} alanından her şeyi gizle",
   "account.blocked": "Engellenmiş",
-  "account.browse_more_on_origin_server": "Browse more on the original profile",
+  "account.browse_more_on_origin_server": "Orijinal profilde daha fazlasına göz atın",
   "account.cancel_follow_request": "Takip isteğini iptal et",
   "account.direct": "Mesaj gönder @{name}",
   "account.domain_blocked": "Alan adı gizlendi",
@@ -16,7 +15,8 @@
   "account.follow": "Takip et",
   "account.followers": "Takipçi",
   "account.followers.empty": "Henüz kimse bu kullanıcıyı takip etmiyor.",
-  "account.follows": "Takip ettikleri",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Bu kullanıcı henüz kimseyi takip etmiyor.",
   "account.follows_you": "Seni takip ediyor",
   "account.hide_reblogs": "@{name} kişisinin yinelemelerini gizle",
@@ -36,16 +36,14 @@
   "account.requested": "Onay Bekleniyor. Takip isteğini iptal etmek için tıklayın",
   "account.share": "@{name} kullanıcısının profilini paylaş",
   "account.show_reblogs": "@{name} kullanıcısının yinelemelerini göster",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} adlı kişinin engelini kaldır",
   "account.unblock_domain": "{domain} göster",
   "account.unendorse": "Profilde özellik yok",
   "account.unfollow": "Takibi bırak",
   "account.unmute": "@{name} adlı kişinin sesini aç",
   "account.unmute_notifications": "@{name} adlı kişinin bildirimlerini aç",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Yorum yapılmamış",
   "alert.rate_limited.message": "Lütfen sonra tekrar deneyin {retry_time, time, medium}.",
   "alert.rate_limited.title": "Oran sınırlıdır",
   "alert.unexpected.message": "Beklenmedik bir hata oluştu.",
@@ -81,9 +79,9 @@
   "column_header.show_settings": "Ayarları göster",
   "column_header.unpin": "Sabitlemeyi kaldır",
   "column_subheading.settings": "Ayarlar",
-  "community.column_settings.local_only": "Local only",
+  "community.column_settings.local_only": "Sadece yerel",
   "community.column_settings.media_only": "Sadece medya",
-  "community.column_settings.remote_only": "Remote only",
+  "community.column_settings.remote_only": "Sadece uzak",
   "compose_form.direct_message_warning": "Bu toot sadece belirtilen kullanıcılara gönderilecektir.",
   "compose_form.direct_message_warning_learn_more": "Daha fazla bilgi edinin",
   "compose_form.hashtag_warning": "Bu toot liste dışı olduğu için hiç bir etikette yer almayacak. Sadece herkese açık tootlar etiketlerde bulunabilir.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Yetkilendir",
   "follow_request.reject": "Reddet",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Geliştiriciler",
   "getting_started.directory": "Profil dizini",
   "getting_started.documentation": "Belgeler",
@@ -421,12 +420,15 @@
   "time_remaining.moments": "Sadece birkaç dakika kaldı",
   "time_remaining.seconds": "{number, plural, one {# saniye} other {# saniye}} kaldı",
   "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
-  "timeline_hint.resources.followers": "Followers",
-  "timeline_hint.resources.follows": "Follows",
-  "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {kişi} other {kişi}} konuşuyor",
+  "timeline_hint.resources.followers": "Takipçiler",
+  "timeline_hint.resources.follows": "Takip Edilenler",
+  "timeline_hint.resources.statuses": "Eski tootlar",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Şu an popüler",
   "ui.beforeunload": "Mastodon'dan ayrılırsanız taslağınız kaybolacak.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Karşıya yükleme için sürükle bırak yapınız",
   "upload_button.label": "Görsel ekle",
   "upload_error.limit": "Dosya yükleme sınırı aşıldı.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "İşitme kaybı olan kişiler için tarif edin",
   "upload_form.description": "Görme engelliler için açıklama",
   "upload_form.edit": "Düzenle",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Geri al",
   "upload_form.video_description": "İşitme kaybı veya görme engeli olan kişiler için tarif edin",
   "upload_modal.analyzing_picture": "Resmi analiz ediyor…",
   "upload_modal.apply": "Uygula",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Pijamalı hasta yağız şoföre çabucak güvendi",
   "upload_modal.detect_text": "Resimdeki metni algıla",
   "upload_modal.edit_media": "Medyayı düzenle",
diff --git a/app/javascript/mastodon/locales/ug.json b/app/javascript/mastodon/locales/ug.json
new file mode 100644
index 000000000..36f55e800
--- /dev/null
+++ b/app/javascript/mastodon/locales/ug.json
@@ -0,0 +1,461 @@
+{
+  "account.account_note_header": "Note",
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.badges.bot": "Bot",
+  "account.badges.group": "Group",
+  "account.block": "Block @{name}",
+  "account.block_domain": "Block domain {domain}",
+  "account.blocked": "Blocked",
+  "account.browse_more_on_origin_server": "Browse more on the original profile",
+  "account.cancel_follow_request": "Cancel follow request",
+  "account.direct": "Direct message @{name}",
+  "account.domain_blocked": "Domain blocked",
+  "account.edit_profile": "Edit profile",
+  "account.endorse": "Feature on profile",
+  "account.follow": "Follow",
+  "account.followers": "Followers",
+  "account.followers.empty": "No one follows this user yet.",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows_you": "Follows you",
+  "account.hide_reblogs": "Hide boosts from @{name}",
+  "account.last_status": "Last active",
+  "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.media": "Media",
+  "account.mention": "Mention @{name}",
+  "account.moved_to": "{name} has moved to:",
+  "account.mute": "Mute @{name}",
+  "account.mute_notifications": "Mute notifications from @{name}",
+  "account.muted": "Muted",
+  "account.never_active": "Never",
+  "account.posts": "Toots",
+  "account.posts_with_replies": "Toots and replies",
+  "account.report": "Report @{name}",
+  "account.requested": "Awaiting approval",
+  "account.share": "Share @{name}'s profile",
+  "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
+  "account.unblock": "Unblock @{name}",
+  "account.unblock_domain": "Unblock domain {domain}",
+  "account.unendorse": "Don't feature on profile",
+  "account.unfollow": "Unfollow",
+  "account.unmute": "Unmute @{name}",
+  "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account_note.placeholder": "Click to add a note",
+  "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",
+  "autosuggest_hashtag.per_week": "{count} per week",
+  "boost_modal.combo": "You can press {combo} to skip this next time",
+  "bundle_column_error.body": "Something went wrong while loading this component.",
+  "bundle_column_error.retry": "Try again",
+  "bundle_column_error.title": "Network error",
+  "bundle_modal_error.close": "Close",
+  "bundle_modal_error.message": "Something went wrong while loading this component.",
+  "bundle_modal_error.retry": "Try again",
+  "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.notifications": "Notifications",
+  "column.pins": "Pinned toot",
+  "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_subheading.settings": "Settings",
+  "community.column_settings.local_only": "Local only",
+  "community.column_settings.media_only": "Media only",
+  "community.column_settings.remote_only": "Remote only",
+  "compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
+  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
+  "compose_form.lock_disclaimer.lock": "locked",
+  "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": "Toot",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Media is marked as sensitive",
+  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
+  "compose_form.spoiler.marked": "Text is hidden behind warning",
+  "compose_form.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.delete.confirm": "Delete",
+  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
+  "confirmations.domain_block.confirm": "Hide entire domain",
+  "confirmations.domain_block.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.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": "Reply",
+  "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}",
+  "directory.federated": "From known fediverse",
+  "directory.local": "From {domain} only",
+  "directory.new_arrivals": "New arrivals",
+  "directory.recently_active": "Recently active",
+  "embed.instructions": "Embed this status on your website by copying the code below.",
+  "embed.preview": "Here is what it will look like:",
+  "emoji_button.activity": "Activity",
+  "emoji_button.custom": "Custom",
+  "emoji_button.flags": "Flags",
+  "emoji_button.food": "Food & Drink",
+  "emoji_button.label": "Insert emoji",
+  "emoji_button.nature": "Nature",
+  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Objects",
+  "emoji_button.people": "People",
+  "emoji_button.recent": "Frequently used",
+  "emoji_button.search": "Search...",
+  "emoji_button.search_results": "Search results",
+  "emoji_button.symbols": "Symbols",
+  "emoji_button.travel": "Travel & Places",
+  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
+  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
+  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.domain_blocks": "There are no blocked domains yet.",
+  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
+  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
+  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "empty_column.hashtag": "There is nothing in this hashtag yet.",
+  "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
+  "empty_column.home.public_timeline": "the public timeline",
+  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
+  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
+  "empty_column.mutes": "You haven't muted any users yet.",
+  "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
+  "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
+  "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
+  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
+  "errors.unexpected_crash.report_issue": "Report issue",
+  "follow_request.authorize": "Authorize",
+  "follow_request.reject": "Reject",
+  "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "generic.saved": "Saved",
+  "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Documentation",
+  "getting_started.heading": "Getting started",
+  "getting_started.invite": "Invite people",
+  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
+  "getting_started.security": "Security",
+  "getting_started.terms": "Terms of service",
+  "hashtag.column_header.tag_mode.all": "and {additional}",
+  "hashtag.column_header.tag_mode.any": "or {additional}",
+  "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
+  "hashtag.column_settings.tag_mode.all": "All of these",
+  "hashtag.column_settings.tag_mode.any": "Any of these",
+  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "home.column_settings.basic": "Basic",
+  "home.column_settings.show_reblogs": "Show boosts",
+  "home.column_settings.show_replies": "Show replies",
+  "home.hide_announcements": "Hide announcements",
+  "home.show_announcements": "Show announcements",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Next",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
+  "introduction.interactions.action": "Finish toot-orial!",
+  "introduction.interactions.favourite.headline": "Favourite",
+  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+  "introduction.interactions.reblog.headline": "Boost",
+  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
+  "introduction.interactions.reply.headline": "Reply",
+  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
+  "introduction.welcome.action": "Let's go!",
+  "introduction.welcome.headline": "First steps",
+  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "keyboard_shortcuts.back": "to navigate back",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
+  "keyboard_shortcuts.boost": "to boost",
+  "keyboard_shortcuts.column": "to focus a status in one of the columns",
+  "keyboard_shortcuts.compose": "to focus the compose textarea",
+  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.favourite": "to favourite",
+  "keyboard_shortcuts.favourites": "to open favourites list",
+  "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.legend": "to display this legend",
+  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.mention": "to mention author",
+  "keyboard_shortcuts.muted": "to open muted users list",
+  "keyboard_shortcuts.my_profile": "to open your profile",
+  "keyboard_shortcuts.notifications": "to open notifications column",
+  "keyboard_shortcuts.open_media": "to open media",
+  "keyboard_shortcuts.pinned": "to open pinned toots list",
+  "keyboard_shortcuts.profile": "to open author's profile",
+  "keyboard_shortcuts.reply": "to reply",
+  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.search": "to focus search",
+  "keyboard_shortcuts.spoilers": "to show/hide CW field",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "to start a brand new toot",
+  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
+  "keyboard_shortcuts.up": "to move up in the list",
+  "lightbox.close": "Close",
+  "lightbox.next": "Next",
+  "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "Add to list",
+  "lists.account.remove": "Remove from list",
+  "lists.delete": "Delete list",
+  "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
+  "lists.new.create": "Add list",
+  "lists.new.title_placeholder": "New list title",
+  "lists.search": "Search among people you follow",
+  "lists.subheading": "Your lists",
+  "load_pending": "{count, plural, one {# new item} other {# new items}}",
+  "loading_indicator.label": "Loading...",
+  "media_gallery.toggle_visible": "Hide {number, plural, one {image} other {images}}",
+  "missing_indicator.label": "Not found",
+  "missing_indicator.sublabel": "This resource could not be found",
+  "mute_modal.hide_notifications": "Hide notifications from this user?",
+  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.blocks": "Blocked users",
+  "navigation_bar.bookmarks": "Bookmarks",
+  "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
+  "navigation_bar.direct": "Direct messages",
+  "navigation_bar.discover": "Discover",
+  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.edit_profile": "Edit profile",
+  "navigation_bar.favourites": "Favourites",
+  "navigation_bar.filters": "Muted words",
+  "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "About this server",
+  "navigation_bar.keyboard_shortcuts": "Hotkeys",
+  "navigation_bar.lists": "Lists",
+  "navigation_bar.logout": "Logout",
+  "navigation_bar.mutes": "Muted users",
+  "navigation_bar.personal": "Personal",
+  "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.preferences": "Preferences",
+  "navigation_bar.public_timeline": "Federated timeline",
+  "navigation_bar.security": "Security",
+  "notification.favourite": "{name} favourited your status",
+  "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.reblog": "{name} boosted your status",
+  "notifications.clear": "Clear notifications",
+  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+  "notifications.column_settings.alert": "Desktop notifications",
+  "notifications.column_settings.favourite": "Favourites:",
+  "notifications.column_settings.filter_bar.advanced": "Display all categories",
+  "notifications.column_settings.filter_bar.category": "Quick filter bar",
+  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.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.push": "Push notifications",
+  "notifications.column_settings.reblog": "Boosts:",
+  "notifications.column_settings.show": "Show in column",
+  "notifications.column_settings.sound": "Play sound",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
+  "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "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_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
+  "privacy.change": "Adjust status privacy",
+  "privacy.direct.long": "Visible for mentioned users only",
+  "privacy.direct.short": "Direct",
+  "privacy.private.long": "Visible for followers only",
+  "privacy.private.short": "Followers-only",
+  "privacy.public.long": "Visible for all, shown in public timelines",
+  "privacy.public.short": "Public",
+  "privacy.unlisted.long": "Visible for all, but not in public timelines",
+  "privacy.unlisted.short": "Unlisted",
+  "refresh": "Refresh",
+  "regeneration_indicator.label": "Loading…",
+  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "relative_time.days": "{number}d",
+  "relative_time.hours": "{number}h",
+  "relative_time.just_now": "now",
+  "relative_time.minutes": "{number}m",
+  "relative_time.seconds": "{number}s",
+  "relative_time.today": "today",
+  "reply_indicator.cancel": "Cancel",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.placeholder": "Additional comments",
+  "report.submit": "Submit",
+  "report.target": "Report {target}",
+  "search.placeholder": "Search",
+  "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.text": "Simple text returns matching display names, usernames and hashtags",
+  "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
+  "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.",
+  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
+  "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_status": "Open this status in the moderation interface",
+  "status.block": "Block @{name}",
+  "status.bookmark": "Bookmark",
+  "status.cancel_reblog_private": "Unboost",
+  "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
+  "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
+  "status.direct": "Direct message @{name}",
+  "status.embed": "Embed",
+  "status.favourite": "Favourite",
+  "status.filtered": "Filtered",
+  "status.load_more": "Load more",
+  "status.media_hidden": "Media hidden",
+  "status.mention": "Mention @{name}",
+  "status.more": "More",
+  "status.mute": "Mute @{name}",
+  "status.mute_conversation": "Mute conversation",
+  "status.open": "Expand this status",
+  "status.pin": "Pin on profile",
+  "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
+  "status.reblog": "Boost",
+  "status.reblog_private": "Boost to original audience",
+  "status.reblogged_by": "{name} boosted",
+  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
+  "status.redraft": "Delete & re-draft",
+  "status.remove_bookmark": "Remove bookmark",
+  "status.reply": "Reply",
+  "status.replyAll": "Reply to thread",
+  "status.report": "Report @{name}",
+  "status.sensitive_warning": "Sensitive content",
+  "status.share": "Share",
+  "status.show_less": "Show less",
+  "status.show_less_all": "Show less for all",
+  "status.show_more": "Show more",
+  "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
+  "status.uncached_media_warning": "Not available",
+  "status.unmute_conversation": "Unmute conversation",
+  "status.unpin": "Unpin from profile",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
+  "tabs_bar.federated_timeline": "Federated",
+  "tabs_bar.home": "Home",
+  "tabs_bar.local_timeline": "Local",
+  "tabs_bar.notifications": "Notifications",
+  "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
+  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
+  "timeline_hint.resources.followers": "Followers",
+  "timeline_hint.resources.follows": "Follows",
+  "timeline_hint.resources.statuses": "Older toots",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
+  "trends.trending_now": "Trending now",
+  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
+  "upload_area.title": "Drag & drop to upload",
+  "upload_button.label": "Add images, a video or an audio file",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
+  "upload_form.audio_description": "Describe for people with hearing loss",
+  "upload_form.description": "Describe for the visually impaired",
+  "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
+  "upload_form.undo": "Delete",
+  "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
+  "upload_modal.analyzing_picture": "Analyzing picture…",
+  "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
+  "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
+  "upload_modal.detect_text": "Detect text from picture",
+  "upload_modal.edit_media": "Edit media",
+  "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
+  "upload_modal.preview_label": "Preview ({ratio})",
+  "upload_progress.label": "Uploading…",
+  "video.close": "Close video",
+  "video.download": "Download file",
+  "video.exit_fullscreen": "Exit full screen",
+  "video.expand": "Expand video",
+  "video.fullscreen": "Full screen",
+  "video.hide": "Hide video",
+  "video.mute": "Mute sound",
+  "video.pause": "Pause",
+  "video.play": "Play",
+  "video.unmute": "Unmute sound"
+}
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index 2115aeec5..18e151263 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -1,13 +1,12 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Ваша примітка для @{name}",
   "account.add_or_remove_from_list": "Додати або видалити зі списків",
   "account.badges.bot": "Бот",
   "account.badges.group": "Група",
   "account.block": "Заблокувати @{name}",
   "account.block_domain": "Заглушити {domain}",
   "account.blocked": "Заблоковані",
-  "account.browse_more_on_origin_server": "Browse more on the original profile",
+  "account.browse_more_on_origin_server": "Переглянути більше в оригіналі",
   "account.cancel_follow_request": "Скасувати запит на підписку",
   "account.direct": "Пряме повідомлення @{name}",
   "account.domain_blocked": "Домен приховано",
@@ -16,7 +15,8 @@
   "account.follow": "Підписатися",
   "account.followers": "Підписники",
   "account.followers.empty": "Ніхто ще не підписався на цього користувача.",
-  "account.follows": "Підписки",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "Цей користувач ще ні на кого не підписався.",
   "account.follows_you": "Підписаний(-а) на вас",
   "account.hide_reblogs": "Сховати передмухи від @{name}",
@@ -36,16 +36,14 @@
   "account.requested": "Очікує підтвердження. Натисніть щоб відмінити запит",
   "account.share": "Поділитися профілем @{name}",
   "account.show_reblogs": "Показати передмухи від @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Розблокувати @{name}",
   "account.unblock_domain": "Розблокувати {domain}",
   "account.unendorse": "Не публікувати у профілі",
   "account.unfollow": "Відписатися",
   "account.unmute": "Зняти глушення з @{name}",
   "account.unmute_notifications": "Показувати сповіщення від @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Коментарі відсутні",
   "alert.rate_limited.message": "Спробуйте ще раз через {retry_time, time, medium}.",
   "alert.rate_limited.title": "Швидкість обмежена",
   "alert.unexpected.message": "Трапилась неочікувана помилка.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "Авторизувати",
   "follow_request.reject": "Відмовити",
   "follow_requests.unlocked_explanation": "Хоча ваш обліковий запис не заблоковано, працівники {domain} припускають, що, можливо, ви хотіли б переглянути ці запити на підписку.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Розробникам",
   "getting_started.directory": "Каталог профілів",
   "getting_started.documentation": "Документація",
@@ -243,7 +242,7 @@
   "keyboard_shortcuts.reply": "відповісти",
   "keyboard_shortcuts.requests": "відкрити список бажаючих підписатися",
   "keyboard_shortcuts.search": "сфокусуватися на пошуку",
-  "keyboard_shortcuts.spoilers": "to show/hide CW field",
+  "keyboard_shortcuts.spoilers": "показати/приховати поле CW",
   "keyboard_shortcuts.start": "відкрити колонку \"Початок\"",
   "keyboard_shortcuts.toggle_hidden": "показати/приховати текст під попередженням",
   "keyboard_shortcuts.toggle_sensitivity": "показати/приховати медіа",
@@ -420,13 +419,16 @@
   "time_remaining.minutes": "{number, plural, one {# хвилина} few {# хвилини} other {# хвилин}}",
   "time_remaining.moments": "Залишилось секунд",
   "time_remaining.seconds": "{number, plural, one {# секунда} few {# секунди} other {# секунд}}",
-  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
-  "timeline_hint.resources.followers": "Followers",
-  "timeline_hint.resources.follows": "Follows",
-  "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {людина} few {людини} many {людей} other {людей}} обговорюють це",
+  "timeline_hint.remote_resource_not_displayed": "{resource} з інших серверів не відображається.",
+  "timeline_hint.resources.followers": "Підписники",
+  "timeline_hint.resources.follows": "Підписки",
+  "timeline_hint.resources.statuses": "Старіші дмухи",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Актуальні",
   "ui.beforeunload": "Вашу чернетку буде втрачено, якщо ви покинете Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Перетягніть сюди, щоб завантажити",
   "upload_button.label": "Додати медіа ({formats})",
   "upload_error.limit": "Ліміт завантаження файлів перевищено.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Опишіть для людей із вадами слуху",
   "upload_form.description": "Опишіть для людей з вадами зору",
   "upload_form.edit": "Змінити",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Видалити",
   "upload_form.video_description": "Опишіть для людей із вадами слуху або зору",
   "upload_modal.analyzing_picture": "Аналізуємо малюнок…",
   "upload_modal.apply": "Застосувати",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "Щурячий бугай із їжаком-харцизом в'ючись підписали ґешефт у єнах",
   "upload_modal.detect_text": "Виявити текст на малюнку",
   "upload_modal.edit_media": "Редагувати медіа",
diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json
index 79e2bfaf1..5924d1487 100644
--- a/app/javascript/mastodon/locales/ur.json
+++ b/app/javascript/mastodon/locales/ur.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "فہرست میں شامل یا برطرف کریں",
   "account.badges.bot": "روبوٹ",
   "account.badges.group": "Group",
@@ -16,7 +15,8 @@
   "account.follow": "پیروی کریں",
   "account.followers": "پیروکار",
   "account.followers.empty": "\"ہنوز اس صارف کی کوئی پیروی نہیں کرتا\".",
-  "account.follows": "پیروی کرتے ہیں",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "\"یہ صارف ہنوز کسی کی پیروی نہیں کرتا ہے\".",
   "account.follows_you": "آپ کا پیروکار ہے",
   "account.hide_reblogs": "@{name} سے فروغ چھپائیں",
@@ -36,16 +36,14 @@
   "account.requested": "منظوری کا منتظر۔ درخواستِ پیروی منسوخ کرنے کیلئے کلک کریں",
   "account.share": "@{name} کے مشخص کو بانٹیں",
   "account.show_reblogs": "@{name} کی افزائشات کو دکھائیں",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} کو بحال کریں",
   "account.unblock_domain": "{domain} کو نہ چھپائیں",
   "account.unendorse": "مشخص پر نمایاں نہ کریں",
   "account.unfollow": "پیروی ترک کریں",
   "account.unmute": "@{name} کو با آواز کریں",
   "account.unmute_notifications": "@{name} سے اطلاعات کو با آواز کریں",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "\"{retry_time, time, medium} کے بعد کوشش کریں\".",
   "alert.rate_limited.title": "Rate limited",
   "alert.unexpected.message": "ایک غیر متوقع سہو ہوا ہے.",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "اجازت دیں",
   "follow_request.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.",
+  "generic.saved": "Saved",
   "getting_started.developers": "Developers",
   "getting_started.directory": "فہرست مشخصات",
   "getting_started.documentation": "اسناد",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "Trending now",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.edit": "Edit",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Detect text from picture",
   "upload_modal.edit_media": "Edit media",
diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json
index 3bdd8c233..17c4302c2 100644
--- a/app/javascript/mastodon/locales/vi.json
+++ b/app/javascript/mastodon/locales/vi.json
@@ -1,29 +1,29 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Ghi chú của bạn cho @{name}",
   "account.add_or_remove_from_list": "Thêm hoặc Xóa khỏi danh sách",
   "account.badges.bot": "Bot",
   "account.badges.group": "Nhóm",
   "account.block": "Chặn @{name}",
-  "account.block_domain": "Chặn miền {domain}",
+  "account.block_domain": "Ẩn mọi thứ từ {domain}",
   "account.blocked": "Đã chặn",
   "account.browse_more_on_origin_server": "Tìm những tài khoản có liên quan",
   "account.cancel_follow_request": "Hủy yêu cầu theo dõi",
   "account.direct": "Nhắn tin cho @{name}",
-  "account.domain_blocked": "Đã chặn miền",
-  "account.edit_profile": "Chỉnh sửa hồ sơ",
+  "account.domain_blocked": "Đã chặn người dùng",
+  "account.edit_profile": "Chỉnh sửa trang cá nhân",
   "account.endorse": "Hiển thị trên trang cá nhân",
   "account.follow": "Theo dõi",
   "account.followers": "Người theo dõi",
-  "account.followers.empty": "Chưa có người theo dõi.",
-  "account.follows": "Đang theo dõi",
+  "account.followers.empty": "Chưa có người theo dõi nào.",
+  "account.followers_counter": "{count, plural, one {{counter} Người theo dõi} other {{counter} Người theo dõi}}",
+  "account.following_counter": "{count, plural, other {{counter} Đang theo dõi}}",
   "account.follows.empty": "Người dùng này chưa theo dõi ai.",
   "account.follows_you": "Đang theo dõi bạn",
   "account.hide_reblogs": "Ẩn chia sẻ từ @{name}",
   "account.last_status": "Hoạt động gần đây",
   "account.link_verified_on": "Liên kết này đã được xác thực vào {date}",
-  "account.locked_info": "Người dùng này thiết lập trạng thái ẩn. Họ sẽ tự mình xét duyệt các yêu cầu mến mộ.",
-  "account.media": "Ảnh & Video",
+  "account.locked_info": "Người dùng này thiết lập trạng thái ẩn. Họ sẽ tự mình xét duyệt các yêu cầu theo dõi.",
+  "account.media": "Bộ sưu tập",
   "account.mention": "Nhắc đến @{name}",
   "account.moved_to": "{name} đã dời sang:",
   "account.mute": "Ẩn @{name}",
@@ -31,31 +31,29 @@
   "account.muted": "Đã ẩn",
   "account.never_active": "Chưa có bất cứ hoạt động nào",
   "account.posts": "Tút",
-  "account.posts_with_replies": "Tút và trả lời",
+  "account.posts_with_replies": "Trả lời",
   "account.report": "Báo cáo @{name}",
   "account.requested": "Đang chờ chấp thuận. Nhấp vào đây để hủy yêu cầu theo dõi",
   "account.share": "Chia sẻ hồ sơ @{name}",
   "account.show_reblogs": "Hiện chia sẻ từ @{name}",
+  "account.statuses_counter": "{count, plural, other {{counter} Tút}}",
   "account.unblock": "Bỏ chặn @{name}",
-  "account.unblock_domain": "Bỏ chặn miền {domain}",
+  "account.unblock_domain": "Bỏ ẩn {domain}",
   "account.unendorse": "Không hiện trên trang cá nhân",
-  "account.unfollow": "Ngừng theo dõi",
+  "account.unfollow": "Ngưng theo dõi",
   "account.unmute": "Bỏ ẩn @{name}",
   "account.unmute_notifications": "Hiển lại thông báo từ @{name}",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Nhấn để thêm ghi chú",
   "alert.rate_limited.message": "Vui lòng thử lại sau {retry_time, time, medium}.",
   "alert.rate_limited.title": "Vượt giới hạn",
   "alert.unexpected.message": "Đã xảy ra lỗi không mong muốn.",
   "alert.unexpected.title": "Ốiii!",
   "announcement.announcement": "Thông báo",
   "autosuggest_hashtag.per_week": "{count} mỗi tuần",
-  "boost_modal.combo": "Lần sau, bạn có thể nhấn {combo} để bỏ qua",
+  "boost_modal.combo": "Bạn có thể nhấn {combo} để bỏ qua",
   "bundle_column_error.body": "Đã có lỗi xảy ra trong khi tải nội dung này.",
   "bundle_column_error.retry": "Thử lại",
-  "bundle_column_error.title": "Lỗi mạng",
+  "bundle_column_error.title": "Không có kết nối internet",
   "bundle_modal_error.close": "Đóng",
   "bundle_modal_error.message": "Đã có lỗi xảy ra trong khi tải nội dung này.",
   "bundle_modal_error.retry": "Thử lại",
@@ -72,7 +70,7 @@
   "column.mutes": "Người dùng đã chặn",
   "column.notifications": "Thông báo",
   "column.pins": "Tút ghim",
-  "column.public": "Dòng thời gian liên kết",
+  "column.public": "Mạng liên kết",
   "column_back_button.label": "Quay lại",
   "column_header.hide_settings": "Ẩn cài đặt",
   "column_header.moveLeft_settings": "Dời cột sang bên trái",
@@ -81,46 +79,46 @@
   "column_header.show_settings": "Hiển thị cài đặt",
   "column_header.unpin": "Không ghim",
   "column_subheading.settings": "Cài đặt",
-  "community.column_settings.local_only": "Chỉ miền của bạn",
+  "community.column_settings.local_only": "Chỉ máy chủ của bạn",
   "community.column_settings.media_only": "Chỉ ảnh/video",
-  "community.column_settings.remote_only": "Chỉ người dùng ở miền khác",
+  "community.column_settings.remote_only": "Chỉ người dùng ở máy chủ khác",
   "compose_form.direct_message_warning": "Tút này sẽ chỉ gửi cho người được nhắc đến.",
   "compose_form.direct_message_warning_learn_more": "Tìm hiểu thêm",
-  "compose_form.hashtag_warning": "Tút này sẽ không xuất hiện công khai khi tìm kiếm theo chủ đề. Chỉ Tút công khai có thể được tìm kiếm theo chủ đề.",
-  "compose_form.lock_disclaimer": "Tài khoản của bạn không {locked}. Bất cứ ai cũng có thể theo dõi bạn để xem bài viết dành riêng cho người theo dõi của bạn.",
+  "compose_form.hashtag_warning": "Tút này sẽ không xuất hiện công khai. Chỉ những tút công khai mới có thể được tìm kiếm thông qua hashtag.",
+  "compose_form.lock_disclaimer": "Tài khoản của bạn không {locked}. Bất cứ ai cũng có thể theo dõi bạn và xem bài viết của bạn dành riêng cho người theo dõi.",
   "compose_form.lock_disclaimer.lock": "khóa",
   "compose_form.placeholder": "Bạn đang nghĩ gì?",
   "compose_form.poll.add_option": "Thêm lựa chọn",
-  "compose_form.poll.duration": "Thời hạn",
+  "compose_form.poll.duration": "Hết hạn vào",
   "compose_form.poll.option_placeholder": "Lựa chọn {number}",
   "compose_form.poll.remove_option": "Xóa lựa chọn này",
-  "compose_form.poll.switch_to_multiple": "Sửa thăm dò để cho phép nhiều lựa chọn",
-  "compose_form.poll.switch_to_single": "Sửa thăm dò để cho phép một lựa chọn",
+  "compose_form.poll.switch_to_multiple": "Có thể chọn nhiều lựa chọn",
+  "compose_form.poll.switch_to_single": "Chỉ cho phép chọn duy nhất một lựa chọn",
   "compose_form.publish": "Tút",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.hide": "Đánh dấu là nội dung nhạy cảm",
+  "compose_form.sensitive.hide": "Nội dung nhạy cảm",
   "compose_form.sensitive.marked": "Nội dung đã đánh dấu nhạy cảm",
   "compose_form.sensitive.unmarked": "Nội dung không đánh dấu nhạy cảm",
-  "compose_form.spoiler.marked": "Văn bản ẩn sau cảnh báo",
+  "compose_form.spoiler.marked": "Văn bản bị ẩn",
   "compose_form.spoiler.unmarked": "Văn bản không ẩn sau spoil",
-  "compose_form.spoiler_placeholder": "Viết cảnh báo của bạn ở đây",
+  "compose_form.spoiler_placeholder": "Viết nội dung ẩn của bạn ở đây",
   "confirmation_modal.cancel": "Hủy bỏ",
   "confirmations.block.block_and_report": "Chặn & Báo cáo",
   "confirmations.block.confirm": "Chặn",
-  "confirmations.block.message": "Bạn có chắc chắn muốn chặn {name}?",
+  "confirmations.block.message": "Bạn có thật sự muốn chặn {name}?",
   "confirmations.delete.confirm": "Xóa bỏ",
   "confirmations.delete.message": "Bạn có chắc chắn muốn xóa tút này?",
   "confirmations.delete_list.confirm": "Xóa bỏ",
   "confirmations.delete_list.message": "Bạn có chắc chắn muốn xóa vĩnh viễn danh sách này?",
-  "confirmations.domain_block.confirm": "Ẩn toàn bộ miền",
+  "confirmations.domain_block.confirm": "Ẩn toàn bộ máy chủ",
   "confirmations.domain_block.message": "Bạn có chắc chắn rằng muốn ẩn toàn bộ nội dung từ {domain}? Sẽ hợp lý hơn nếu bạn chỉ chặn hoặc ẩn một vài tài khoản cụ thể. Ẩn toàn bộ nội dung từ máy chủ sẽ khiến bạn không còn thấy nội dung từ máy chủ đó ở bất kỳ nơi nào, kể cả thông báo. Người quan tâm bạn từ máy chủ đó cũng sẽ bị xóa luôn.",
   "confirmations.logout.confirm": "Đăng xuất",
-  "confirmations.logout.message": "Bạn có chắc chắn bạn muốn thoát?",
+  "confirmations.logout.message": "Bạn có thật sự muốn thoát?",
   "confirmations.mute.confirm": "Ẩn",
-  "confirmations.mute.explanation": "Điều này sẽ khiến tút của người đó và những tút có đề cập đến họ bị ẩn, tuy nhiên vẫn cho phép họ xem bài đăng của bạn và mến mộ bạn.",
+  "confirmations.mute.explanation": "Điều này sẽ khiến tút của người đó và những tút có đề cập đến họ bị ẩn, tuy nhiên vẫn cho phép họ xem bài đăng của bạn và theo dõi bạn.",
   "confirmations.mute.message": "Bạn có chắc chắn muốn ẩn {name}?",
   "confirmations.redraft.confirm": "Xóa & viết lại",
-  "confirmations.redraft.message": "Bạn có chắc chắn muốn xóa tút và viết lại? Điều này sẽ xóa mất những lượt tâm đắc và chia sẻ của tút, cũng như những phản hồi sẽ không còn nội dung gốc.",
+  "confirmations.redraft.message": "Bạn có chắc chắn muốn xóa tút và viết lại? Điều này sẽ xóa mất những lượt tâm đắc và chia sẻ của tút, cũng như những trả lời sẽ không còn nội dung gốc.",
   "confirmations.reply.confirm": "Trả lời",
   "confirmations.reply.message": "Nội dung bạn đang soạn thảo sẽ bị ghi đè, bạn có tiếp tục?",
   "confirmations.unfollow.confirm": "Ngưng theo dõi",
@@ -158,22 +156,23 @@
   "empty_column.domain_blocks": "Chưa ẩn bất kỳ máy chủ nào.",
   "empty_column.favourited_statuses": "Bạn chưa tâm đắc tút nào. Hãy thử đi, nó sẽ xuất hiện ở đây.",
   "empty_column.favourites": "Chưa có ai tâm đắc tút này.",
-  "empty_column.follow_requests": "Bạn chưa có yêu cầu theo dõi nào. Khi có yêu cầu mới, nó sẽ xuất hiện ở đây.",
-  "empty_column.hashtag": "Chưa có bài đăng nào về chủ đề này.",
-  "empty_column.home": "Chưa có bất cứ gì! Hãy bắt đầu bằng cách tìm kiếm hoặc truy cập {public} để mến mộ những người bạn thích.",
+  "empty_column.follow_requests": "Bạn chưa có yêu cầu theo dõi nào.",
+  "empty_column.hashtag": "Chưa có bài đăng nào sử dụng hashtag này.",
+  "empty_column.home": "Chưa có bất cứ gì! Hãy bắt đầu bằng cách tìm kiếm hoặc truy cập {public} để theo dõi những người bạn quan tâm.",
   "empty_column.home.public_timeline": "tút công khai",
   "empty_column.list": "Chưa có gì trong danh sách. Khi thành viên của danh sách này đăng tút mới, chúng mới xuất hiện ở đây.",
   "empty_column.lists": "Bạn không có danh sách nào.",
   "empty_column.mutes": "Bạn chưa ẩn người dùng nào.",
-  "empty_column.notifications": "Bạn chưa có thông báo nào. Hãy thử mến mộ hoặc nhắn tin cho một ai đó mà bạn thích.",
-  "empty_column.public": "Trống trơn! Bạn hãy viết gì đó hoặc bắt đầu mến mộ người dùng khác",
+  "empty_column.notifications": "Bạn chưa có thông báo nào. Hãy thử theo dõi hoặc nhắn tin cho một ai đó.",
+  "empty_column.public": "Trống trơn! Bạn hãy viết gì đó hoặc bắt đầu theo dõi người dùng khác",
   "error.unexpected_crash.explanation": "Trang này có thể không hiển thị chính xác do lỗi lập trình Mastodon hoặc vấn đề tương thích trình duyệt.",
   "error.unexpected_crash.next_steps": "Hãy thử làm mới trang. Nếu vẫn không được, bạn hãy vào Mastodon bằng một ứng dụng di động hoặc trình duyệt khác.",
   "errors.unexpected_crash.copy_stacktrace": "Sao chép stacktrace vào clipboard",
   "errors.unexpected_crash.report_issue": "Báo cáo lỗi",
   "follow_request.authorize": "Cho phép",
   "follow_request.reject": "Từ chối",
-  "follow_requests.unlocked_explanation": "Mặc dù tài khoản của bạn đang ở chế độ công khai, quản trị viên của {domain} vẫn tin rằng bạn sẽ muốn xem lại yêu cầu mến mộ từ những người khác.",
+  "follow_requests.unlocked_explanation": "Mặc dù tài khoản của bạn đang ở chế độ công khai, quản trị viên của {domain} vẫn tin rằng bạn sẽ muốn xem lại yêu cầu theo dõi từ những người khác.",
+  "generic.saved": "Đã lưu",
   "getting_started.developers": "Nhà phát triển",
   "getting_started.directory": "Danh sách người dùng",
   "getting_started.documentation": "Tài liệu",
@@ -186,14 +185,14 @@
   "hashtag.column_header.tag_mode.any": "hoặc {additional}",
   "hashtag.column_header.tag_mode.none": "mà không {additional}",
   "hashtag.column_settings.select.no_options_message": "Không tìm thấy đề xuất nào",
-  "hashtag.column_settings.select.placeholder": "Nhập chủ đề…",
+  "hashtag.column_settings.select.placeholder": "Nhập hashtag…",
   "hashtag.column_settings.tag_mode.all": "Toàn bộ",
   "hashtag.column_settings.tag_mode.any": "Một phần",
   "hashtag.column_settings.tag_mode.none": "Không chọn",
-  "hashtag.column_settings.tag_toggle": "Bao gồm thêm chủ đề cho cột này",
+  "hashtag.column_settings.tag_toggle": "Bao gồm thêm hashtag cho cột này",
   "home.column_settings.basic": "Cơ bản",
   "home.column_settings.show_reblogs": "Hiện tút chia sẻ",
-  "home.column_settings.show_replies": "Hiện phản hồi",
+  "home.column_settings.show_replies": "Hiện trả lời",
   "home.hide_announcements": "Ẩn thông báo",
   "home.show_announcements": "Hiện thông báo",
   "intervals.full.days": "{number} days",
@@ -203,14 +202,14 @@
   "introduction.federation.federated.headline": "Mạng liên kết",
   "introduction.federation.federated.text": "Nếu máy chủ của bạn có liên kết với các máy chủ khác, bài đăng công khai từ họ sẽ xuất hiện ở Mạng liên kết.",
   "introduction.federation.home.headline": "Bảng tin",
-  "introduction.federation.home.text": "Bảng tin là nơi hiển thị bài đăng từ những người bạn mến mộ. Bạn có thể mến mộ bất cứ ai trên bất cứ máy chủ nào!",
+  "introduction.federation.home.text": "Bảng tin là nơi hiển thị bài đăng từ những người bạn theo dõi. Bạn có thể theo dõi bất cứ ai trên bất cứ máy chủ nào!",
   "introduction.federation.local.headline": "Máy chủ của bạn",
   "introduction.federation.local.text": "Máy chủ của bạn là nơi hiển thị bài đăng công khai từ những người thuộc cùng một máy chủ của bạn.",
   "introduction.interactions.action": "Tôi đã hiểu rồi!",
   "introduction.interactions.favourite.headline": "Tâm đắc",
   "introduction.interactions.favourite.text": "Tâm đắc một tút có nghĩa là bạn thích tút đó và lưu giữ để sau này xem lại.",
   "introduction.interactions.reblog.headline": "Chia sẻ",
-  "introduction.interactions.reblog.text": "Với tính năng chia sẻ, bạn có thể chia sẻ tút của người khác với những người mến mộ bạn.",
+  "introduction.interactions.reblog.text": "Với tính năng chia sẻ, bạn có thể chia sẻ tút của người khác cho những người theo dõi bạn.",
   "introduction.interactions.reply.headline": "Trả lời",
   "introduction.interactions.reply.text": "Bạn có thể trả lời tút của những người khác và tút của bạn, từ đó tạo nên những cuộc hội thoại.",
   "introduction.welcome.action": "Bắt đầu nào!",
@@ -241,7 +240,7 @@
   "keyboard_shortcuts.pinned": "mở danh sách tút ghim",
   "keyboard_shortcuts.profile": "mở trang cá nhân của người viết tút",
   "keyboard_shortcuts.reply": "trả lời",
-  "keyboard_shortcuts.requests": "mở danh sách yêu cầu mến mộ",
+  "keyboard_shortcuts.requests": "mở danh sách yêu cầu theo dõi",
   "keyboard_shortcuts.search": "mở tìm kiếm",
   "keyboard_shortcuts.spoilers": "Hiện/ẩn nội dung nhạy cảm",
   "keyboard_shortcuts.start": "mở mục \"Dành cho người mới\"",
@@ -261,7 +260,7 @@
   "lists.edit.submit": "Thay đổi tiêu đề",
   "lists.new.create": "Thêm vào danh sách",
   "lists.new.title_placeholder": "Tên danh sách mới",
-  "lists.search": "Tìm kiếm những người mà bạn mến mộ",
+  "lists.search": "Tìm kiếm những người mà bạn quan tâm",
   "lists.subheading": "Danh sách của bạn",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Đang tải...",
@@ -281,7 +280,7 @@
   "navigation_bar.favourites": "Những thứ tâm đắc",
   "navigation_bar.filters": "Bộ lọc từ ngữ",
   "navigation_bar.follow_requests": "Yêu cầu theo dõi",
-  "navigation_bar.follows_and_followers": "Đang theo dõi và người theo dõi bạn",
+  "navigation_bar.follows_and_followers": "Lượt theo dõi",
   "navigation_bar.info": "Về máy chủ này",
   "navigation_bar.keyboard_shortcuts": "Phím tắt",
   "navigation_bar.lists": "Danh sách",
@@ -293,8 +292,8 @@
   "navigation_bar.public_timeline": "Dòng thời gian liên kết",
   "navigation_bar.security": "Bảo mật",
   "notification.favourite": "{name} vừa tâm đắc tút của bạn",
-  "notification.follow": "{name} đã theo dõi bạn",
-  "notification.follow_request": "{name} đã yêu cầu theo dõi bạn",
+  "notification.follow": "{name} vừa theo dõi bạn",
+  "notification.follow_request": "{name} vừa yêu cầu theo dõi bạn",
   "notification.mention": "{name} nhắc đến bạn",
   "notification.own_poll": "Cuộc thăm dò của bạn đã kết thúc",
   "notification.poll": "Một cuộc thăm dò mà bạn tham gia đã kết thúc",
@@ -321,12 +320,12 @@
   "notifications.filter.mentions": "Nhắc đến",
   "notifications.filter.polls": "Kết quả cuộc thăm dò",
   "notifications.group": "{count} thông báo",
-  "poll.closed": "Đóng",
+  "poll.closed": "Cuộc thăm dò đã kết thúc",
   "poll.refresh": "Làm mới",
-  "poll.total_people": "{count, plural, other {}}",
+  "poll.total_people": "{count, plural, one {# người đã bình chọn} other {# người đã bình chọn}}",
   "poll.total_votes": "{count, plural, one {# bình chọn} other {# bình chọn}}",
   "poll.vote": "Cuộc thăm dò",
-  "poll.voted": "Bạn đã bình chọn cho câu trả lời này",
+  "poll.voted": "Bạn đã bình chọn câu trả lời này",
   "poll_button.add_poll": "Tạo thăm dò",
   "poll_button.remove_poll": "Hủy thăm dò",
   "privacy.change": "Thay đổi quyền riêng tư",
@@ -334,9 +333,9 @@
   "privacy.direct.short": "Tin nhắn",
   "privacy.private.long": "Chỉ dành cho người theo dõi",
   "privacy.private.short": "Chỉ người theo dõi",
-  "privacy.public.long": "Đăng lên các dòng thời gian công cộng",
+  "privacy.public.long": "Hiện trên bảng tin máy chủ",
   "privacy.public.short": "Công khai",
-  "privacy.unlisted.long": "Không đăng lên các dòng thời gian công cộng",
+  "privacy.unlisted.long": "Ai cũng có thể xem nhưng không hiện trên bảng tin máy chủ",
   "privacy.unlisted.short": "Mở",
   "refresh": "Làm mới",
   "regeneration_indicator.label": "Đang tải…",
@@ -356,13 +355,13 @@
   "report.target": "Báo xấu {target}",
   "search.placeholder": "Tìm kiếm",
   "search_popout.search_format": "Tìm kiếm nâng cao",
-  "search_popout.tips.full_text": "Nội dung trả về bao gồm các tút do bạn viết, thích, đã chia sẻ hoặc được nhắc đến. Cũng như địa chỉ người dùng, tên hiển thị lẫn chủ đề.",
-  "search_popout.tips.hashtag": "chủ đề",
+  "search_popout.tips.full_text": "Nội dung trả về bao gồm các tút do bạn viết, yêu thích, đã chia sẻ hoặc được nhắc đến. Cũng như địa chỉ người dùng, tên hiển thị lẫn hashtag.",
+  "search_popout.tips.hashtag": "hashtag",
   "search_popout.tips.status": "tút",
   "search_popout.tips.text": "Nội dung trả về là địa chỉ người dùng, tên hiển thị và hashtag",
   "search_popout.tips.user": "người dùng",
   "search_results.accounts": "Người dùng",
-  "search_results.hashtags": "Chủ đề",
+  "search_results.hashtags": "Hashtags",
   "search_results.statuses": "Tút",
   "search_results.statuses_fts_disabled": "Máy chủ của bạn không bật chức năng tìm kiếm tút.",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
@@ -392,7 +391,7 @@
   "status.reblog": "Chia sẻ",
   "status.reblog_private": "Chia sẻ với người viết tút gốc",
   "status.reblogged_by": "{name} chia sẻ",
-  "status.reblogs.empty": "Chưa ai chia sẻ Tút này. Nếu có, nó sẽ xuất hiện ở đây.",
+  "status.reblogs.empty": "Tút này chưa có ai chia sẻ. Nếu có, nó sẽ hiển thị ở đây.",
   "status.redraft": "Xóa và viết lại",
   "status.remove_bookmark": "Hủy lưu",
   "status.reply": "Trả lời",
@@ -415,18 +414,21 @@
   "tabs_bar.local_timeline": "Máy chủ của bạn",
   "tabs_bar.notifications": "Thông báo",
   "tabs_bar.search": "Tìm kiếm",
-  "time_remaining.days": "{number, plural, other {}} left",
-  "time_remaining.hours": "{number, plural, other {}} left",
-  "time_remaining.minutes": "{number, plural, other {}} left",
+  "time_remaining.days": "Thời hạn còn {number, plural, other {# ngày}}",
+  "time_remaining.hours": "Thời hạn còn {number, plural, other {# giờ}}",
+  "time_remaining.minutes": "Thời hạn còn {number, plural, other {# phút}}",
   "time_remaining.moments": "Còn lại",
-  "time_remaining.seconds": "{number, plural, other {}} left",
+  "time_remaining.seconds": "Chỉ còn {number, plural, other {# giây}}",
   "timeline_hint.remote_resource_not_displayed": "{resource} từ máy chủ khác sẽ không hiển thị.",
   "timeline_hint.resources.followers": "Người theo dõi",
   "timeline_hint.resources.follows": "Đang theo dõi",
   "timeline_hint.resources.statuses": "Tút cũ hơn",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} đang thảo luận",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} người} other {{counter} người}} đang thảo luận",
   "trends.trending_now": "Xu hướng",
   "ui.beforeunload": "Bản nháp của bạn sẽ bị mất nếu bạn thoát khỏi Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Kéo và thả để tải lên",
   "upload_button.label": "Thêm media (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "Tập tin tải lên vượt quá giới hạn cho phép.",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "Mô tả cho người thính giác kém",
   "upload_form.description": "Mô tả cho người khiếm thị",
   "upload_form.edit": "Biên tập",
+  "upload_form.thumbnail": "Đổi ảnh thumbnail",
   "upload_form.undo": "Xóa bỏ",
   "upload_form.video_description": "Mô tả cho người có vấn đề về thính giác",
   "upload_modal.analyzing_picture": "Phân tích hình ảnh",
   "upload_modal.apply": "Áp dụng",
+  "upload_modal.choose_image": "Chọn hình",
   "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
   "upload_modal.detect_text": "Phát hiện văn bản trong hình ảnh",
   "upload_modal.edit_media": "Chỉnh sửa ảnh/video",
diff --git a/app/javascript/mastodon/locales/whitelist_ku.json b/app/javascript/mastodon/locales/whitelist_ku.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_ku.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_ug.json b/app/javascript/mastodon/locales/whitelist_ug.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_ug.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 222d3aed8..ac19eb3e6 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "备注",
   "account.add_or_remove_from_list": "从列表中添加或删除",
   "account.badges.bot": "机器人",
   "account.badges.group": "群组",
@@ -16,7 +15,8 @@
   "account.follow": "关注",
   "account.followers": "关注者",
   "account.followers.empty": "目前无人关注此用户。",
-  "account.follows": "正在关注",
+  "account.followers_counter": "被 {count, plural, one {{counter} 人} other {{counter} 人}}关注",
+  "account.following_counter": "正在关注 {count, plural, other {{counter} 人}}",
   "account.follows.empty": "此用户目前尚未关注任何人。",
   "account.follows_you": "关注了你",
   "account.hide_reblogs": "隐藏来自 @{name} 的转嘟",
@@ -36,16 +36,14 @@
   "account.requested": "正在等待对方同意。点击以取消发送关注请求",
   "account.share": "分享 @{name} 的个人资料",
   "account.show_reblogs": "显示来自 @{name} 的转嘟",
+  "account.statuses_counter": "{count, plural, one {{counter} 条} other {{counter} 条}}嘟文",
   "account.unblock": "解除屏蔽 @{name}",
   "account.unblock_domain": "不再隐藏来自 {domain} 的内容",
   "account.unendorse": "不在个人资料中推荐此用户",
   "account.unfollow": "取消关注",
   "account.unmute": "不再隐藏 @{name}",
   "account.unmute_notifications": "不再隐藏来自 @{name} 的通知",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "点击添加备注",
   "alert.rate_limited.message": "请在{retry_time, time, medium}后重试。",
   "alert.rate_limited.title": "频率受限",
   "alert.unexpected.message": "发生了意外错误。",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "同意",
   "follow_request.reject": "拒绝",
   "follow_requests.unlocked_explanation": "虽说你没有锁嘟,但是 {domain} 的工作人员觉得你可能想手工审核关注请求。",
+  "generic.saved": "已保存",
   "getting_started.developers": "开发",
   "getting_started.directory": "用户目录",
   "getting_started.documentation": "文档",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "关注者",
   "timeline_hint.resources.follows": "关注",
   "timeline_hint.resources.statuses": "更早的嘟文",
-  "trends.count_by_accounts": "{count} 人正在讨论",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} 人} other {{counter} 人}}正在讨论",
   "trends.trending_now": "现在流行",
   "ui.beforeunload": "如果你现在离开 Mastodon,你的草稿内容将会丢失。",
+  "units.short.billion": "{count}十亿",
+  "units.short.million": "{count}百万",
+  "units.short.thousand": "{count}千",
   "upload_area.title": "将文件拖放到此处开始上传",
   "upload_button.label": "上传媒体文件 ({formats})",
   "upload_error.limit": "文件大小超过限制。",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "为听障人士添加文字描述",
   "upload_form.description": "为视觉障碍人士添加文字说明",
   "upload_form.edit": "编辑",
+  "upload_form.thumbnail": "更改缩略图",
   "upload_form.undo": "删除",
   "upload_form.video_description": "为听障人士和视障人士添加文字描述",
   "upload_modal.analyzing_picture": "分析图片…",
   "upload_modal.apply": "应用",
+  "upload_modal.choose_image": "选择图像",
   "upload_modal.description_placeholder": "天地玄黄 宇宙洪荒 日月盈仄 辰宿列张",
   "upload_modal.detect_text": "从图片中检测文本",
   "upload_modal.edit_media": "编辑媒体",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 222855c2c..b537ca4f3 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "從名單中新增或移除",
   "account.badges.bot": "機械人",
   "account.badges.group": "群組",
@@ -16,13 +15,14 @@
   "account.follow": "關注",
   "account.followers": "關注的人",
   "account.followers.empty": "尚沒有人關注這位使用者。",
-  "account.follows": "正關注",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "這位使用者尚未關注任何使用者。",
   "account.follows_you": "關注你",
   "account.hide_reblogs": "隱藏 @{name} 的轉推",
   "account.last_status": "上次活躍時間",
   "account.link_verified_on": "此連結的所有權已在 {date} 檢查過",
-  "account.locked_info": "這隻帳戶的隱私狀態被設成鎖定。該擁有者會手動審核能關注這隻帳號的人。",
+  "account.locked_info": "此用戶的私隱狀態為不公開,關注請求需經過該用戶的審核。",
   "account.media": "媒體",
   "account.mention": "提及 @{name}",
   "account.moved_to": "{name} 已經遷移到:",
@@ -36,16 +36,14 @@
   "account.requested": "等候審批",
   "account.share": "分享 @{name} 的個人資料",
   "account.show_reblogs": "顯示 @{name} 的推文",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "解除對 @{name} 的封鎖",
   "account.unblock_domain": "不再隱藏 {domain}",
   "account.unendorse": "不再於個人資料頁面推薦對方",
   "account.unfollow": "取消關注",
   "account.unmute": "取消 @{name} 的靜音",
   "account.unmute_notifications": "取消來自 @{name} 通知的靜音",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "請在 {retry_time, time, medium} 過後重試",
   "alert.rate_limited.title": "已限速",
   "alert.unexpected.message": "發生不可預期的錯誤。",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "批准",
   "follow_request.reject": "拒絕",
   "follow_requests.unlocked_explanation": "即便您的帳號未被鎖定,{domain} 的員工認為可能想要自己審核這些帳號的追蹤請求。",
+  "generic.saved": "Saved",
   "getting_started.developers": "開發者",
   "getting_started.directory": "個人資料目錄",
   "getting_started.documentation": "文件",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} 位用戶在討論",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "目前趨勢",
   "ui.beforeunload": "如果你現在離開 Mastodon,你的草稿內容將會被丟棄。",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "將檔案拖放至此上載",
   "upload_button.label": "上載媒體檔案",
   "upload_error.limit": "已達到檔案上傳限制。",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "簡單描述內容給聽障人士",
   "upload_form.description": "為視覺障礙人士添加文字說明",
   "upload_form.edit": "編輯",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "刪除",
   "upload_form.video_description": "簡單描述給聽障或視障人士",
   "upload_modal.analyzing_picture": "正在分析圖片…",
   "upload_modal.apply": "套用",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox 跳過那隻懶狗",
   "upload_modal.detect_text": "從圖片偵測文字",
   "upload_modal.edit_media": "編輯媒體",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 81c13c652..d674734c1 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -1,6 +1,5 @@
 {
-  "account.account_note_header": "Your note for @{name}",
-  "account.add_account_note": "Add note for @{name}",
+  "account.account_note_header": "Note",
   "account.add_or_remove_from_list": "從名單中新增或移除",
   "account.badges.bot": "機器人",
   "account.badges.group": "群組",
@@ -16,7 +15,8 @@
   "account.follow": "關注",
   "account.followers": "關注者",
   "account.followers.empty": "尚沒有人關注這位使用者。",
-  "account.follows": "正在關注",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following_counter": "{count, plural, other {{counter} Following}}",
   "account.follows.empty": "這位使用者尚未關注任何使用者。",
   "account.follows_you": "關注了你",
   "account.hide_reblogs": "隱藏來自 @{name} 的轉推",
@@ -36,16 +36,14 @@
   "account.requested": "正在等待核准。按一下取消關注請求",
   "account.share": "分享 @{name} 的個人資料",
   "account.show_reblogs": "顯示來自 @{name} 的嘟文",
+  "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "取消封鎖 @{name}",
   "account.unblock_domain": "取消隱藏 {domain}",
   "account.unendorse": "不再於個人資料頁面推薦對方",
   "account.unfollow": "取消關注",
   "account.unmute": "取消靜音 @{name}",
   "account.unmute_notifications": "重新接收來自 @{name} 的通知",
-  "account_note.cancel": "Cancel",
-  "account_note.edit": "Edit",
-  "account_note.placeholder": "No comment provided",
-  "account_note.save": "Save",
+  "account_note.placeholder": "Click to add a note",
   "alert.rate_limited.message": "請在 {retry_time, time, medium} 過後重試",
   "alert.rate_limited.title": "已限速",
   "alert.unexpected.message": "發生了非預期的錯誤。",
@@ -174,6 +172,7 @@
   "follow_request.authorize": "授權",
   "follow_request.reject": "拒絕",
   "follow_requests.unlocked_explanation": "即便您的帳號未被鎖定,{domain} 的員工認為可能想要自己審核這些帳號的追蹤請求。",
+  "generic.saved": "Saved",
   "getting_started.developers": "開發者",
   "getting_started.directory": "個人資料目錄",
   "getting_started.documentation": "文件",
@@ -424,9 +423,12 @@
   "timeline_hint.resources.followers": "Followers",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Older toots",
-  "trends.count_by_accounts": "{count} 位使用者在討論",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking",
   "trends.trending_now": "目前趨勢",
   "ui.beforeunload": "如果離開 Mastodon,你的草稿將會不見。",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "拖放來上傳",
   "upload_button.label": "上傳媒體檔案 (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_error.limit": "已達到檔案上傳限制。",
@@ -434,10 +436,12 @@
   "upload_form.audio_description": "簡單描述內容給聽障人士",
   "upload_form.description": "為視障人士增加文字說明",
   "upload_form.edit": "編輯",
+  "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "刪除",
   "upload_form.video_description": "簡單描述給聽障或視障人士",
   "upload_modal.analyzing_picture": "正在分析圖片…",
   "upload_modal.apply": "套用",
+  "upload_modal.choose_image": "Choose image",
   "upload_modal.description_placeholder": "A quick brown fox 跳過那隻懶狗",
   "upload_modal.detect_text": "從圖片偵測文字",
   "upload_modal.edit_media": "編輯媒體",
diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js
index 673268c5a..fd3b72f96 100644
--- a/app/javascript/mastodon/selectors/index.js
+++ b/app/javascript/mastodon/selectors/index.js
@@ -154,12 +154,13 @@ export const makeGetNotification = () => {
 export const getAccountGallery = createSelector([
   (state, id) => state.getIn(['timelines', `account:${id}:media`, 'items'], ImmutableList()),
   state       => state.get('statuses'),
-], (statusIds, statuses) => {
+  (state, id) => state.getIn(['accounts', id]),
+], (statusIds, statuses, account) => {
   let medias = ImmutableList();
 
   statusIds.forEach(statusId => {
     const status = statuses.get(statusId);
-    medias = medias.concat(status.get('media_attachments').map(media => media.set('status', status)));
+    medias = medias.concat(status.get('media_attachments').map(media => media.set('status', status).set('account', account)));
   });
 
   return medias;
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb
index 58cec7ac4..0ce279d28 100644
--- a/app/lib/activitypub/activity.rb
+++ b/app/lib/activitypub/activity.rb
@@ -185,7 +185,7 @@ class ActivityPub::Activity
   end
 
   def followed_by_local_accounts?
-    @account.passive_relationships.exists?
+    @account.passive_relationships.exists? || @options[:relayed_through_account]&.passive_relationships&.exists?
   end
 
   def requested_through_relay?
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index d3d460551..e81452e3c 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -45,7 +45,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
 
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
-        return if delete_arrived_first?(object_uri) || poll_vote?
+        return if delete_arrived_first?(object_uri) || poll_vote? # rubocop:disable Lint/NonLocalExitFromIterator
 
         @status = find_existing_status
 
diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb
index 1523f86d4..3f98dad2e 100644
--- a/app/lib/activitypub/tag_manager.rb
+++ b/app/lib/activitypub/tag_manager.rb
@@ -72,16 +72,16 @@ class ActivityPub::TagManager
         account_ids = status.active_mentions.pluck(:account_id)
         to = status.account.followers.where(id: account_ids).each_with_object([]) do |account, result|
           result << uri_for(account)
-          result << account.followers_url if account.group?
+          result << account_followers_url(account) if account.group?
         end
         to.concat(FollowRequest.where(target_account_id: status.account_id, account_id: account_ids).each_with_object([]) do |request, result|
           result << uri_for(request.account)
-          result << request.account.followers_url if request.account.group?
+          result << account_followers_url(request.account) if request.account.group?
         end)
       else
         status.active_mentions.each_with_object([]) do |mention, result|
           result << uri_for(mention.account)
-          result << mention.account.followers_url if mention.account.group?
+          result << account_followers_url(mention.account) if mention.account.group?
         end
       end
     end
@@ -110,16 +110,16 @@ class ActivityPub::TagManager
         account_ids = status.active_mentions.pluck(:account_id)
         cc.concat(status.account.followers.where(id: account_ids).each_with_object([]) do |account, result|
           result << uri_for(account)
-          result << account.followers_url if account.group?
+          result << account_followers_url(account) if account.group?
         end)
         cc.concat(FollowRequest.where(target_account_id: status.account_id, account_id: account_ids).each_with_object([]) do |request, result|
           result << uri_for(request.account)
-          result << request.account.followers_url if request.account.group?
+          result << account_followers_url(request.account) if request.account.group?
         end)
       else
         cc.concat(status.active_mentions.each_with_object([]) do |mention, result|
           result << uri_for(mention.account)
-          result << mention.account.followers_url if mention.account.group?
+          result << account_followers_url(mention.account) if mention.account.group?
         end)
       end
     end
diff --git a/app/lib/proof_provider/keybase/config_serializer.rb b/app/lib/proof_provider/keybase/config_serializer.rb
index fbce7aeee..c6c364d31 100644
--- a/app/lib/proof_provider/keybase/config_serializer.rb
+++ b/app/lib/proof_provider/keybase/config_serializer.rb
@@ -55,7 +55,7 @@ class ProofProvider::Keybase::ConfigSerializer < ActiveModel::Serializer
   end
 
   def profile_url
-    CGI.unescape(short_account_url('%{username}')) # rubocop:disable Style/FormatStringToken
+    CGI.unescape(short_account_url('%{username}'))
   end
 
   def check_url
diff --git a/app/lib/request.rb b/app/lib/request.rb
index 247c32958..bcba1eebf 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -231,6 +231,7 @@ class Request
             begin
               sock.connect_nonblock(addr_by_socket[sock])
             rescue Errno::EISCONN
+              # Do nothing
             rescue => e
               sock.close
               outer_e = e
diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb
index 4d21e0de7..8aa826561 100644
--- a/app/lib/settings/scoped_settings.rb
+++ b/app/lib/settings/scoped_settings.rb
@@ -12,7 +12,7 @@ module Settings
       @object = object
     end
 
-    # rubocop:disable Style/MethodMissing
+    # rubocop:disable Style/MethodMissingSuper
     def method_missing(method, *args)
       method_name = method.to_s
       # set a value for a variable
@@ -25,7 +25,7 @@ module Settings
         self[method_name]
       end
     end
-    # rubocop:enable Style/MethodMissing
+    # rubocop:enable Style/MethodMissingSuper
 
     def respond_to_missing?(*)
       true
@@ -49,7 +49,6 @@ module Settings
       record.update!(value: value)
 
       Rails.cache.write(Setting.cache_key(key, @object), value)
-      value
     end
 
     def [](key)
diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb
index 736da6c1d..4ea219537 100644
--- a/app/models/concerns/omniauthable.rb
+++ b/app/models/concerns/omniauthable.rb
@@ -57,7 +57,7 @@ module Omniauthable
 
       user = User.new(user_params_from_auth(email, auth))
 
-      user.account.avatar_remote_url = auth.info.image if auth.info.image =~ /\A#{URI.regexp(%w(http https))}\z/
+      user.account.avatar_remote_url = auth.info.image if auth.info.image =~ /\A#{URI::DEFAULT_PARSER.make_regexp(%w(http https))}\z/
       user.skip_confirmation!
       user.save!
       user
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index cc0a1ab27..0441fc699 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -165,6 +165,9 @@ class MediaAttachment < ApplicationRecord
                     processors: ->(f) { file_processors f },
                     convert_options: GLOBAL_CONVERT_OPTIONS
 
+  before_file_post_process :set_type_and_extension
+  before_file_post_process :check_video_dimensions
+
   validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
   validates_attachment_size :file, less_than: IMAGE_LIMIT, unless: :larger_media_format?
   validates_attachment_size :file, less_than: VIDEO_LIMIT, if: :larger_media_format?
@@ -257,9 +260,6 @@ class MediaAttachment < ApplicationRecord
 
   after_post_process :set_meta
 
-  before_file_post_process :set_type_and_extension
-  before_file_post_process :check_video_dimensions
-
   class << self
     def supported_mime_types
       IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
diff --git a/app/services/after_block_domain_from_account_service.rb b/app/services/after_block_domain_from_account_service.rb
index f50bde261..89d007c1c 100644
--- a/app/services/after_block_domain_from_account_service.rb
+++ b/app/services/after_block_domain_from_account_service.rb
@@ -19,7 +19,7 @@ class AfterBlockDomainFromAccountService < BaseService
   private
 
   def remove_follows!
-    @account.active_relationships.where(account: Account.where(domain: @domain)).includes(:target_account).reorder(nil).find_each do |follow|
+    @account.active_relationships.where(target_account: Account.where(domain: @domain)).includes(:target_account).reorder(nil).find_each do |follow|
       UnfollowService.new.call(@account, follow.target_account)
     end
   end
diff --git a/app/services/after_unallow_domain_service.rb b/app/services/after_unallow_domain_service.rb
new file mode 100644
index 000000000..ccd0b8ae9
--- /dev/null
+++ b/app/services/after_unallow_domain_service.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AfterUnallowDomainService < BaseService
+  def call(domain)
+    Account.where(domain: domain).find_each do |account|
+      SuspendAccountService.new.call(account, reserve_username: false)
+    end
+  end
+end
diff --git a/app/services/unallow_domain_service.rb b/app/services/unallow_domain_service.rb
index bd1ad328d..fc5260761 100644
--- a/app/services/unallow_domain_service.rb
+++ b/app/services/unallow_domain_service.rb
@@ -1,11 +1,18 @@
 # frozen_string_literal: true
 
 class UnallowDomainService < BaseService
+  include DomainControlHelper
+
   def call(domain_allow)
-    Account.where(domain: domain_allow.domain).find_each do |account|
-      SuspendAccountService.new.call(account, reserve_username: false)
-    end
+    suspend_accounts!(domain_allow.domain) if whitelist_mode?
 
     domain_allow.destroy
   end
+
+  private
+
+  def suspend_accounts!(domain)
+    Account.where(domain: domain).in_batches.update_all(suspended_at: Time.now.utc)
+    AfterUnallowDomainWorker.perform_async(domain)
+  end
 end
diff --git a/app/workers/after_unallow_domain_worker.rb b/app/workers/after_unallow_domain_worker.rb
new file mode 100644
index 000000000..46049cbb2
--- /dev/null
+++ b/app/workers/after_unallow_domain_worker.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AfterUnallowDomainWorker
+  include Sidekiq::Worker
+
+  def perform(domain)
+    AfterUnallowDomainService.new.call(domain)
+  end
+end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index d617a297a..60219dae1 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -99,6 +99,7 @@ Rails.application.configure do
     :openssl_verify_mode  => ENV['SMTP_OPENSSL_VERIFY_MODE'],
     :enable_starttls_auto => ENV['SMTP_ENABLE_STARTTLS_AUTO'] || true,
     :tls                  => ENV['SMTP_TLS'].presence,
+    :ssl                  => ENV['SMTP_SSL'].presence,
   }
 
   config.action_mailer.delivery_method = ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp').to_sym
diff --git a/config/locales/activerecord.ku.yml b/config/locales/activerecord.ku.yml
new file mode 100644
index 000000000..cc251e86a
--- /dev/null
+++ b/config/locales/activerecord.ku.yml
@@ -0,0 +1 @@
+ckb-IR:
diff --git a/config/locales/activerecord.ml.yml b/config/locales/activerecord.ml.yml
index baecb9e82..fc30a81fc 100644
--- a/config/locales/activerecord.ml.yml
+++ b/config/locales/activerecord.ml.yml
@@ -4,9 +4,14 @@ ml:
     attributes:
       poll:
         expires_at: സമയപരിധി
+        options: ചോയ്‌സുകൾ
     errors:
       models:
         account:
           attributes:
             username:
               invalid: അക്ഷരങ്ങളും, അക്കങ്ങളും, പിന്നെ അടിവരയും മാത്രം
+        status:
+          attributes:
+            reblog:
+              taken: സ്റ്റാറ്റസ് ഇതിനകം നിലവിലുണ്ട്
diff --git a/config/locales/activerecord.ug.yml b/config/locales/activerecord.ug.yml
new file mode 100644
index 000000000..289acf241
--- /dev/null
+++ b/config/locales/activerecord.ug.yml
@@ -0,0 +1 @@
+ug:
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index c262f2d87..b82b030a3 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -41,7 +41,10 @@ ar:
       domain: الخادم
       reason: السبب
       rejecting_media: 'لن يتم معالجة أو تخزين ملفات الوسائط القادمة من هذه الخوادم، ولن يتم عرض أي صور مصغرة، مما يتطلب النقر اليدوي على الملف الأصلي:'
+      rejecting_media_title: وسائط مصفّاة
       silenced: 'سيتم إخفاء المنشورات القادمة من هذه الخوادم في الخيوط الزمنية والمحادثات العامة، ولن يتم إنشاء أي إخطارات من جراء تفاعلات مستخدميها، ما لم تُتَابعهم:'
+      silenced_title: الخوادم المكتومة
+      suspended: 'لن يتم معالجة أي بيانات قادمة من هذه الخوادم أو تخزينها أو تبادلها، مما سيجعل أي تفاعل أو اتصال مع المستخدمين والمستخدمات المنتمين إلى هذه الخوادم مستحيلة:'
     unavailable_content_html: يسمح لك ماستدون عموماً بعرض محتوى المستخدمين القادم من أي خادم آخر في الفديفرس والتفاعل معهم. وهذه هي الاستثناءات التي وضعت على هذا الخادوم بالذات.
     user_count_after:
       few: مستخدمين
@@ -639,6 +642,7 @@ ar:
       body_remote: أبلغ شخص ما من %{domain} عن %{target}
       subject: تقرير جديد ل%{instance} (#%{id})
     new_trending_tag:
+      body: 'الوسم #%{name} متداوَل اليوم، ولكن لم يتم مراجعته من قبل. لن يتم عرضه علنا إلا إذا سمحت بذلك، أو قم بحفظ هذه الإستمارة كما هي حتى تتجاهله مستقبَلًا.'
       subject: وسم جديد في انتظار المراجعة على %{instance} (#%{name})
   aliases:
     add_new: أنشئ كُنية
@@ -910,6 +914,7 @@ ar:
   media_attachments:
     validations:
       images_and_video: ليس بالإمكان إرفاق فيديو في منشور يحتوي مسبقا على صور
+      not_ready: لا يمكن إرفاق الملفات التي لم يتم معالجتها بعد. أعد المحاولة بعد لحظات!
       too_many: لا يمكن إرفاق أكثر من 4 ملفات
   migrations:
     acct: انتقل إلى
@@ -930,6 +935,7 @@ ar:
     on_cooldown: لقد قمت مؤخرا بترحيل حسابك. سيتاح هذا الإجراء مرة أخرى في غضون %{count} أيام.
     past_migrations: التهجيرات السابقة
     proceed_with_move: انقل مشارِكيك
+    redirected_msg: الآن، حسابك موجَّه إلى %{acct}.
     redirecting_to: حسابك موجَّه إلى %{acct}.
     set_redirect: تعين إعادة التوجيه
     warning:
@@ -1121,6 +1127,13 @@ ar:
     spam_detected: هذا إبلاغ تلقائي. تم اكتشاف منشورات عشوائية غير مرغوب فيها.
   statuses:
     attached:
+      audio:
+        few: "%{count} مقطعًا صوتيًا"
+        many: "%{count} مقاطع صوتية"
+        one: "%{count} مقطع صوتي واحد"
+        other: "%{count} مقاطع صوتية"
+        two: "%{count} مقطعان صوتيان"
+        zero: "%{count} مقطع صوتي"
       description: 'مُرفَق: %{attached}'
       image:
         few: "%{count} صور"
@@ -1219,6 +1232,12 @@ ar:
       explanation: لقد قمت بطلب نسخة كاملة لحسابك على ماستدون. إنها متوفرة الآن للتنزيل!
       subject: نسخة بيانات حسابك جاهزة للتنزيل
       title: المغادرة بأرشيف الحساب
+    sign_in_token:
+      details: 'وفيما يلي تفاصيل المحاولة:'
+      explanation: 'اكتشفنا محاولة لتسجيل الدخول إلى حسابك من عنوان IP غير معروف. إذا كان هذا أنت ، يرجى إدخال رمز الأمان أدناه في صفحة تحدي تسجيل الدخول:'
+      further_actions: 'إذا لم يكن ذلك صادر منك، يرجى تغيير كلمتك السرية وتنشيط المصادقة الثنائية في حسابك. يمكنك القيام بذلك هنا:'
+      subject: الرجاء تأكيد محاولة الولوج
+      title: محاولة الولوج
     warning:
       explanation:
         disable: عندما يتم تجميد حسابك، تظل بيانات حسابك سليمة، ولكن لا يمكنك تنفيذ أي إجراءات حتى يتم فتحه.
@@ -1258,11 +1277,14 @@ ar:
       title: أهلاً بك، %{name}!
   users:
     follow_limit_reached: لا يمكنك متابعة أكثر مِن %{limit} أشخاص
+    generic_access_help_html: صادفت مشكلة في الوصول إلى حسابك؟ اتصل بـ %{email} للحصول على المساعدة
     invalid_email: عنوان البريد الإلكتروني غير صالح
     invalid_otp_token: رمز المصادقة بخطوتين غير صالح
+    invalid_sign_in_token: رمز الآمان غير صحيح
     otp_lost_help_html: إن فقدتَهُما ، يمكنك الاتصال بـ %{email}
     seamless_external_login: لقد قمت بتسجيل الدخول عبر خدمة خارجية، إنّ إعدادات الكلمة السرية و البريد الإلكتروني غير متوفرة.
     signed_in_as: 'تم تسجيل دخولك بصفة:'
+    suspicious_sign_in_confirmation: يبدو أنك لم تقم بتسجيل الدخول عبر هذا الجهاز من قبل، ولم تقم بتسجيل الدخول لفترة منذ مدة، لذلك نقوم بإرسال رمز الأمان إلى عنوان بريدك الإلكتروني للتأكد من أنه أنت من قام بالطلب.
   verification:
     explanation_html: 'يمكنك <strong>التحقق من نفسك كمالك لروابط البيانات التعريفية على صفحتك الشخصية</strong>. لذلك، يجب أن يحتوي الموقع المقترِن على رابط إلى صفحتك التعريفية الشخصية على ماستدون. الرابط الخلفي <strong>يجب أن</strong> يحتوي على رمز <code>rel="me"</code>. محتوى النص في الرابط غير مهم. على سبيل المثال:'
     verification: التحقق
diff --git a/config/locales/bn.yml b/config/locales/bn.yml
index ad613f721..3b575100f 100644
--- a/config/locales/bn.yml
+++ b/config/locales/bn.yml
@@ -21,9 +21,7 @@ bn:
     federation_hint_html: "%{instance}তে একটা নিবন্ধন থাকলে আপনি যেকোনো মাস্টাডন বা এধরণের অন্যান্য সার্ভারের মানুষের সাথে যুক্ত হতে পারবেন ।"
     get_apps: মোবাইল এপ্প একটা ব্যবহার করতে পারেন
     hosted_on: এই মাস্টাডনটি আছে %{domain} এ
-    instance_actor_flash: 'এই অ্যাকাউন্টটি ভার্চুয়াল এক্টর যা নিজে কোনও সার্ভারের প্রতিনিধিত্ব করতে ব্যবহৃত হয় এবং কোনও পৃথক ব্যবহারকারী নয়। এটি ফেডারেশনের উদ্দেশ্যে ব্যবহৃত হয় এবং আপনি যদি পুরো ইনস্ট্যান্স ব্লক করতে না চান তবে অবরুদ্ধ করা উচিত নয়, সেক্ষেত্রে আপনার ডোমেন ব্লক ব্যবহার করা উচিত।
-
-'
+    instance_actor_flash: এই অ্যাকাউন্টটি ভার্চুয়াল এক্টর যা নিজে কোনও সার্ভারের প্রতিনিধিত্ব করতে ব্যবহৃত হয় এবং কোনও পৃথক ব্যবহারকারী নয়। এটি ফেডারেশনের উদ্দেশ্যে ব্যবহৃত হয় এবং আপনি যদি পুরো ইনস্ট্যান্স ব্লক করতে না চান তবে অবরুদ্ধ করা উচিত নয়, সেক্ষেত্রে আপনার ডোমেন ব্লক ব্যবহার করা উচিত।
     learn_more: বিস্তারিত জানুন
     privacy_policy: গোপনীয়তা নীতি
     see_whats_happening: কী কী হচ্ছে দেখুন
diff --git a/config/locales/co.yml b/config/locales/co.yml
index 599b9ae7c..b1d68b2d5 100644
--- a/config/locales/co.yml
+++ b/config/locales/co.yml
@@ -1120,6 +1120,9 @@ co:
     spam_detected: Quessu ghjè un riportu automaticu. Un spam hè statu ditettatu.
   statuses:
     attached:
+      audio:
+        one: "%{count} audio"
+        other: "%{count} audio"
       description: 'Aghjuntu: %{attached}'
       image:
         one: "%{count} ritrattu"
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 8d93edda1..021c4b2b2 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -940,6 +940,10 @@ de:
       redirect: Das Profil deines aktuellen Kontos wird mit einer Weiterleitungsnachricht versehen und von Suchanfragen ausgeschlossen
   moderation:
     title: Moderation
+  move_handler:
+    carry_blocks_over_text: Dieses Benutzerkonto ist von %{acct} umgezogen, welches du blockiert hast.
+    carry_mutes_over_text: Dieses Benutzerkonto ist von %{acct} umgezogen, welches du stummgeschaltet hast.
+    copy_account_note_text: 'Dieser Benutzer ist von %{acct} umgezogen, hier waren deine letzten Notizen zu diesem Benutzer:'
   notification_mailer:
     digest:
       action: Zeige alle Benachrichtigungen
@@ -1116,6 +1120,9 @@ de:
     spam_detected: Dies ist ein automatisierter Bericht. Es wurde Spam erkannt.
   statuses:
     attached:
+      audio:
+        one: "%{count} Audiodatei"
+        other: "%{count} Audiodateien"
       description: 'Angehängt: %{attached}'
       image:
         one: "%{count} Bild"
diff --git a/config/locales/devise.br.yml b/config/locales/devise.br.yml
index acfa884b4..95b9c1cbc 100644
--- a/config/locales/devise.br.yml
+++ b/config/locales/devise.br.yml
@@ -1,7 +1,10 @@
 ---
 br:
   devise:
+    confirmations:
+      confirmed: Kadarnaet eo bet ho chomlec'h postel gant berzh.
     failure:
+      already_authenticated: Kennasket oc'h dija.
       inactive: N'eo ket gweredekaet ho kont c'hoazh.
       invalid: "%{authentication_keys} pe ger-tremen diwiriek."
       last_attempt: Un esae a chom deoc'h a-raok ma vefe prennet ho kont.
@@ -36,6 +39,10 @@ br:
       updated_not_active: Kemmet eo bet ho ker-tremen ent reizh.
     registrations:
       signed_up: Donemat ! Kevreet oc'h.
+    sessions:
+      already_signed_out: Digennasket gant berzh.
+      signed_in: Kennasket gant berzh.
+      signed_out: Digennasket gant berzh.
   errors:
     messages:
       not_found: digavet
diff --git a/config/locales/devise.kab.yml b/config/locales/devise.kab.yml
index 0149c4512..79faaaa1b 100644
--- a/config/locales/devise.kab.yml
+++ b/config/locales/devise.kab.yml
@@ -37,27 +37,62 @@ kab:
         title: Awal uffir yettubeddel
       reconfirmation_instructions:
         explanation: Sentem tansa imayl tamaynut akken ad tbeddleḍ imayl-inek.
+        extra: Ma yella mačči d kečč·kem i yebdan aya, ttxil suref i yimayl-a. Tansa n imayl n Mastodon ur tettbeddil ara skud ur tkecmeḍ ara ɣer useɣwen-nni ufella.
         subject: 'Maṣṭudun: Sentem tansa imayl n %{instance}'
         title: Senqed tansa-inek imayl
       reset_password_instructions:
         action: Beddel awal uffir
         explanation: Tessutreḍ awal uffir amaynut i umiḍan-ik.
+        extra: Ma yella ur tsutreḍ aya, suref i yimayl-a. Awal-ik·im uffir ir ittbeddil ara skud ur tekcimeḍ ara ɣer useɣwen-nni ufella sakin ad tsutreḍ amaynut.
+        subject: 'Mastodon: Iwellihen n uwennez n wawal uffir'
         title: Aɛiwed n wawal uffir
       two_factor_disabled:
+        explanation: Asesṭeb s snat n tarayin insa i umiḍan-ik·im. Tzemreḍ ad teqnneḍ tura s imayl d wawal uffir kan.
+        subject: 'Mastodon: Asesteb s snat n tarrayin yensa'
         title: Asesteb s snat n tarrayin insa
       two_factor_enabled:
+        explanation: Asesṭeb s snat n tarayin yermed i umiḍan-ik·im. anekcum isra tangalt akken ad yeddu.
+        subject: 'Mastodon: Asesteb s snat n tarrayin yermed'
         title: Asesteb s snat n tarrayin irmed
+      two_factor_recovery_codes_changed:
+        explanation: Tangalt n tuɣalin tettwaḥbes sakin nesnulfa-d yiwet d tamaynut.
+        subject: 'Mastodon: Tingalin n tuɣalin n snat n tarayin ttwarnanat i tikkelt-nniḍen'
+        title: Tangalt n tuɣalin 2FA tettwabeddel
+      unlock_instructions:
+        subject: 'Mastodon: iwelihhen n userreḥ'
+    omniauth_callbacks:
+      failure: Ur nezmir ara ad ak·akem-nsesṭeb seg %{kind} acku "%{reason}".
+      success: Asesṭeb idda akken iwata seg umiḍan %{kind}.
     passwords:
+      no_token: Ur tezmireḍ ara ad tkecmeḍ ɣer usebter-a war ma tusiḍ-d seg imayl n uwennez n wawal uffir. ma syin i d-tusiḍ, wali ma tesqedceḍ tansa URL i d ak·am-d-nuzen.
+      send_instructions: Ma nufa tansa-inek imayl tella deg uzadur-nneγ n yisefka, ad n-teṭṭfeḍ izen deg kra n tesdatin, deg-s assaγ i uɛawed n wawal uffir. Ma ur k-in-yewwiḍ ara yizen, ttxil-k ẓer deg ukaram spam.
       send_paranoid_instructions: Ma nufa tansa-inek imayl tella deg uzadur-nneγ n yisefka, ad n-teṭṭfeḍ izen deg kra n tesdatin, deg-s assaγ i uɛawed n wawal uffir. Ma ur k-in-yewwiḍ ara yizen, ttxil-k ẓer deg ukaram spam.
       updated: Awal-ik uffir yettwabeddel mebla ugur. Aqla-k tura tjerrḍeḍ.
       updated_not_active: Awal-ik uffir yettwabeddel mebla ugur.
     registrations:
       destroyed: Ar timlilit! Amiḍan-ik yettwakkes mebla ugur. Nessaram ad k-nwali tikelt-nniḍen.
       signed_up: Anṣuf! Aqla-k tkecmeḍ.
+      signed_up_but_inactive: Tjerdeḍ akken iwata. maca ur tezmireḍ ara ad teqneḍ akka tura acku amiḍan-ik·im mazal ur yermid ara.
+      signed_up_but_locked: Tjerdeḍ akken iwata. maca ur tezmireḍ ara ad teqneḍ akka tura acku amiḍan-ik·im ittwawḥel.
+      signed_up_but_pending: Aseɣwen n usentem ittwazen ɣer tensa-inen·inem n imayl. ticki tsenndeḍ ɣef useɣwen, ad nsenqed asnas-ik·im. ad ak·am-n-yaweḍ telɣut ma yella ittwaqbel.
+      signed_up_but_unconfirmed: Aseɣwen n usentem ittwazen ɣer tensa-inen·inem n imayl. Ttxil ḍfer aseɣwen i usentem n umiḍan-ik·im. Ttxil wali akaram n ispamen ma ur teṭṭifeḍ ara imayl-agi.
+      update_needs_confirmation: Tleqmeḍ akken iwata amiḍan-ik·im, maca nesra ad nsenqed tansa-ik·im imayl tamaynut. Ttxil-k·m senqed imayl-k·m sakin ḍfer aseɣwen i usentem n n tansa imayl tamaynut. Ttxil senqed akaram n spam ma yella ur tufiḍ ara imayl-nni.
+      updated: Amiḍan-ik·im yettwalqem akken iwata.
     sessions:
+      already_signed_out: Aqla-k teffγeḍ.
       signed_in: Aqla-k teqqneḍ.
       signed_out: Aqla-k teffγeḍ.
+    unlocks:
+      send_instructions: Deg kra n tesdatin, ad teṭṭfeḍ imayl deg-s iwellihen i yilaqen i userreḥ n umiḍan-ik·im. Ma yella ur tufiḍ ara izen-agi, ttxil-k·m ẓer deg ukaram spam.
+      send_paranoid_instructions: Ma yella umiḍan-ik·im yella, ad teṭṭfeḍ imayl deg tesdatin i d-iteddun, deg-s iwellihen i yilaqen i userreḥ n umiḍan-ik·im. Ma yella ur tufiḍ ara izen-agi, ttxil-k·m ẓer deg ukaram spam.
+      unlocked: Iserreḥ umiḍan-ik·im akken iwata. ttxil qqen akken ad tkemleḍ.
   errors:
     messages:
+      already_confirmed: ittwasentem yakan, ttxil εreḍ ad teqneḍ
+      confirmation_period_expired: isra asentem di %{period}, ttxil suter amaynut
+      expired: immut, ttxil suter amaynut
       not_found: ulac-it
       not_locked: ur yettucekkel ara
+      not_saved:
+        one: '1 n tuccḍa ur teǧǧa ara %{resource} ad ittwasekles:'
+        other: 'Tuccḍiwin n %{count} ur ǧǧant ara %{resource} ad ittwasekles:'
diff --git a/config/locales/devise.ku.yml b/config/locales/devise.ku.yml
new file mode 100644
index 000000000..cc251e86a
--- /dev/null
+++ b/config/locales/devise.ku.yml
@@ -0,0 +1 @@
+ckb-IR:
diff --git a/config/locales/devise.ug.yml b/config/locales/devise.ug.yml
new file mode 100644
index 000000000..289acf241
--- /dev/null
+++ b/config/locales/devise.ug.yml
@@ -0,0 +1 @@
+ug:
diff --git a/config/locales/devise.zh-HK.yml b/config/locales/devise.zh-HK.yml
index e1bb9f959..f72fd55a3 100644
--- a/config/locales/devise.zh-HK.yml
+++ b/config/locales/devise.zh-HK.yml
@@ -47,7 +47,7 @@ zh-HK:
         subject: 'Mastodon: 重設密碼'
         title: 重設密碼
       two_factor_disabled:
-        explanation: 您帳戶的兩步驟驗證已停用。現在只能使用電子信箱位址及密碼登入。
+        explanation: 您帳戶的兩步驟驗證已停用。現在只能使用電子信箱及密碼登入。
         subject: Mastodon:已停用兩步驟驗證
         title: 已停用 2FA
       two_factor_enabled:
diff --git a/config/locales/doorkeeper.ku.yml b/config/locales/doorkeeper.ku.yml
new file mode 100644
index 000000000..cc251e86a
--- /dev/null
+++ b/config/locales/doorkeeper.ku.yml
@@ -0,0 +1 @@
+ckb-IR:
diff --git a/config/locales/doorkeeper.ml.yml b/config/locales/doorkeeper.ml.yml
index 80a749b04..5dfaa61ae 100644
--- a/config/locales/doorkeeper.ml.yml
+++ b/config/locales/doorkeeper.ml.yml
@@ -1,6 +1,10 @@
 ---
 ml:
   activerecord:
+    attributes:
+      doorkeeper/application:
+        name: അപ്ലിക്കേഷന്റെ പേര്
+        website: അപ്ലിക്കേഷന്റെ വെബ്സൈറ്റ്
     errors:
       models:
         doorkeeper/application:
@@ -19,7 +23,12 @@ ml:
         submit: സമർപ്പിക്കുക
       confirmations:
         destroy: നിങ്ങൾക്ക് ഉറപ്പാണോ?
+      edit:
+        title: അപ്ലിക്കേഷൻ എഡിറ്റുചെയ്യുക
+      form:
+        error: ക്ഷമിക്കണം! സാധ്യമായ പിശകുകൾക്കായി നിങ്ങളുടെ ഫോം പരിശോധിക്കുക
       index:
+        application: അപ്ലിക്കേഷന്‍
         delete: മായ്ക്കുക
         name: പേര്
     authorized_applications:
diff --git a/config/locales/doorkeeper.ug.yml b/config/locales/doorkeeper.ug.yml
new file mode 100644
index 000000000..289acf241
--- /dev/null
+++ b/config/locales/doorkeeper.ug.yml
@@ -0,0 +1 @@
+ug:
diff --git a/config/locales/doorkeeper.vi.yml b/config/locales/doorkeeper.vi.yml
index 7a6ae7817..12592c0f4 100644
--- a/config/locales/doorkeeper.vi.yml
+++ b/config/locales/doorkeeper.vi.yml
@@ -73,7 +73,7 @@ vi:
       index:
         application: Ứng dụng
         created_at: Đã cho phép
-        date_format: "% Y-% m-%d% H:% M:% S"
+        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Phạm vi
         title: Các ứng dụng mà bạn cho phép
     errors:
diff --git a/config/locales/el.yml b/config/locales/el.yml
index 5867dfee3..cf6622f10 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -940,6 +940,10 @@ el:
       redirect: Το προφίλ του τρέχοντος λογαριασμό σου θα ενημερωθεί με μια σημείωση ανακατεύθυνσης και θα εξαιρεθεί από τα αποτελέσματα αναζητήσεων
   moderation:
     title: Συντονισμός
+  move_handler:
+    carry_blocks_over_text: Ο/Η χρήστης μετακόμισε από το %{acct}, που είχες αποκλείσει.
+    carry_mutes_over_text: Ο/Η χρήστης μετακόμισε από το %{acct}, που είχες αποσιωπήσει.
+    copy_account_note_text: 'Ο/Η χρήστης μετακόμισε από το %{acct}, ορίστε οι προηγούμενες σημειώσεις σου:'
   notification_mailer:
     digest:
       action: Δες όλες τις ειδοποιήσεις
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 23bed812e..2cae0a3e3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -21,7 +21,9 @@ en:
     federation_hint_html: With an account on %{instance} you'll be able to follow people on any Mastodon server and beyond.
     get_apps: Try a mobile app
     hosted_on: Mastodon hosted on %{domain}
-    instance_actor_flash: This account is a virtual actor used to represent the server itself and not any individual user. It is used for federation purposes and should not be blocked unless you want to block the whole instance, in which case you should use a domain block.
+    instance_actor_flash: |
+      This account is a virtual actor used to represent the server itself and not any individual user.
+      It is used for federation purposes and should not be blocked unless you want to block the whole instance, in which case you should use a domain block.
     learn_more: Learn more
     privacy_policy: Privacy policy
     see_whats_happening: See what's happening
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index 1a4ecd2df..5c11fa6fc 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -208,7 +208,12 @@ eo:
         enable_custom_emoji: Ebligi Propran Emoĝion
         enable_user: Ebligi uzanton
         promote_user: Promocii Uzanton
+        remove_avatar_user: Forigi profilbildon
         reopen_report: Remalfermi signalon
+        reset_password_user: Restarigi pasvorton
+        resolve_report: Solvitaj reporto
+        silence_account: Silentigi konton
+        suspend_account: Haltigi konton
       actions:
         assigned_to_self_report: "%{name} asignis signalon %{target} al si mem"
         change_email_user: "%{name} ŝanĝis retadreson de uzanto %{target}"
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index 1a654ec9b..fde1a820e 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -21,9 +21,7 @@ eu:
     federation_hint_html: "%{instance} instantzian kontu bat izanda edozein Mastodon zerbitzariko jendea jarraitu ahal izango duzu, eta harago ere."
     get_apps: Probatu mugikorrerako aplikazio bat
     hosted_on: Mastodon %{domain} domeinuan ostatatua
-    instance_actor_flash: 'Kontu hau zerbitzaria bera adierazten duen aktore birtual bat da, ez norbanako bat. Federaziorako erabiltzen da eta ez zenuke blokeatu behar instantzia osoa blokeatu nahi ez baduzu, kasu horretan domeinua blokeatzea egokia litzateke.
-
-'
+    instance_actor_flash: Kontu hau zerbitzaria bera adierazten duen aktore birtual bat da, ez norbanako bat. Federaziorako erabiltzen da eta ez zenuke blokeatu behar instantzia osoa blokeatu nahi ez baduzu, kasu horretan domeinua blokeatzea egokia litzateke.
     learn_more: Ikasi gehiago
     privacy_policy: Pribatutasun politika
     see_whats_happening: Ikusi zer gertatzen ari den
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index 3b63d8809..25e66f328 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -22,8 +22,8 @@ fa:
     get_apps: یک اپ موبایل را بیازمایید
     hosted_on: ماستودون، میزبانی‌شده روی %{domain}
     instance_actor_flash: |
-      این حساب یک بازیگر مجازی برای نمایندگی از این سرور است و متعلق به هیچ کاربری نیست.
-      این حساب برای ارتباط میان‌سروری به کار می‌رود و نباید مسدود شود، مگر این که شما بخواهید کل سرور را مسدود کنید، که در آن صورت باید از راه مسدودسازی دامین پیش بروید.
+      این حساب، بازیگری مجازی به نمایندگی خود کارساز بوده و کاربری واقعی نیست.
+      این حساب برای مقاصد خودگردانی به کار می‌رفته و نباید مسدود شود؛ مگر این که بخواهید کل نمونه را مسدود کنید که در آن صورت نیز باید از انسداد دامنه استفاده کنید.
     learn_more: بیشتر بدانید
     privacy_policy: سیاست رازداری
     see_whats_happening: ببینید چه خبر است
@@ -860,6 +860,8 @@ fa:
     inactive: غیرفعال
     publicize_checkbox: 'این را ببوقید:'
     publicize_toot: 'تأیید شد! من %{username} روی %{service} هستم: %{url}'
+    remove: برداشتن مدرک از حساب
+    removed: مدرک با موفّقیت از حساب برداشته شد
     status: وضعیت تأیید
     view_proof: دیدن مدرک
   imports:
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 8186f0247..224fefd9e 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -41,8 +41,8 @@ fr:
       reason: Motif
       rejecting_media: 'Les fichiers média de ces serveurs ne seront pas traités ou stockés et aucune miniature ne sera affichée, nécessitant un clic vers le fichier d’origine :'
       rejecting_media_title: Média filtré
-      silenced: 'Les messages de ces serveurs seront cachés des flux publics et conversations, et les interactions de leurs utilisateur·ice·s ne donneront lieu à aucune notification, à moins que vous ne les suiviez :'
-      silenced_title: Serveurs en sourdine
+      silenced: 'Les messages de ces serveurs seront cachés des flux publics et conversations, et les interactions de leurs utilisateur·rice·s ne donneront lieu à aucune notification, à moins que vous ne les suiviez :'
+      silenced_title: Serveurs masqués
       suspended: 'Aucune donnée venant de ces serveurs ne sera traitée, stockée ou échangée, rendant toute interaction ou communication avec les utilisateur·rice·s de ces serveurs impossible :'
       suspended_title: Serveurs suspendus
     unavailable_content_html: Mastodon vous permet généralement de visualiser le contenu et d'interagir avec les utilisateur·rice·s de n'importe quel autre serveur dans le fédiverse. Voici les exceptions qui ont été faites sur ce serveur en particulier.
@@ -90,7 +90,7 @@ fr:
       action: Effectuer une action
       title: Effectuer une action de modération sur %{acct}
     account_moderation_notes:
-      create: Laisser un commentaire
+      create: Laisser une remarque
       created_msg: Note de modération créée avec succès !
       delete: Supprimer
       destroyed_msg: Note de modération supprimée avec succès !
@@ -183,14 +183,14 @@ fr:
         created_reports: Signalements faits
         targeted_reports: Signalés par d’autres
       silence: Masquer
-      silenced: Silencié
+      silenced: Masqué
       statuses: Statuts
       subscribe: S’abonner
       suspended: Suspendu
       time_in_queue: En file d’attente %{time}
       title: Comptes
       unconfirmed_email: Courriel non confirmé
-      undo_silenced: Démasquer
+      undo_silenced: Ne plus masquer
       undo_suspension: Annuler la suspension
       unsubscribe: Se désabonner
       username: Nom d’utilisateur·ice
@@ -226,10 +226,10 @@ fr:
         reopen_report: Rouvrir le signalement
         reset_password_user: Réinitialiser le mot de passe
         resolve_report: Résoudre le signalement
-        silence_account: Rendre le compte silencieux
+        silence_account: Masque le compte
         suspend_account: Suspendre le compte
         unassigned_report: Ne plus assigner le signalement
-        unsilence_account: Désactiver le silence du compte
+        unsilence_account: Ne plus masquer le compte
         unsuspend_account: Annuler la suspension du compte
         update_announcement: Modifier l’annonce
         update_custom_emoji: Mettre à jour les émojis personnalisés
@@ -262,10 +262,10 @@ fr:
         reopen_report: "%{name} a rouvert le signalement %{target}"
         reset_password_user: "%{name} a réinitialisé le mot de passe de %{target}"
         resolve_report: "%{name} a résolu le signalement %{target}"
-        silence_account: "%{name} a mis le compte %{target} en mode silence"
+        silence_account: "%{name} a masqué le compte de %{target}"
         suspend_account: "%{name} a suspendu le compte %{target}"
         unassigned_report: "%{name} a désassigné le signalement %{target}"
-        unsilence_account: "%{name} a mis fin au mode silence de %{target}"
+        unsilence_account: "%{name} ne masque plus le compte de %{target}"
         unsuspend_account: "%{name} a réactivé le compte de %{target}"
         update_announcement: "%{name} a actualisé l’annonce %{target}"
         update_custom_emoji: "%{name} a mis à jour l’émoji %{target}"
@@ -367,7 +367,7 @@ fr:
         create: Créer le blocage
         hint: Le blocage de domaine n’empêchera pas la création de comptes dans la base de données, mais il appliquera automatiquement et rétrospectivement des méthodes de modération spécifiques sur ces comptes.
         severity:
-          desc_html: "<strong>Masqué</strong> rendra les messages des comptes concernés invisibles à ceux qui ne les suivent pas. <strong>Suspendre</strong> supprimera tout le contenu des comptes concernés, les médias, et les données du profil. Utilisez <strong>Aucune</strong> si vous voulez simplement rejeter les fichiers multimédia."
+          desc_html: "<strong>Masquer</strong> rendra les messages des comptes concernés invisibles à ceux qui ne les suivent pas. <strong>Suspendre</strong> supprimera tout le contenu des comptes concernés, les médias, et les données du profil. Utilisez <strong>Aucune</strong> si vous voulez simplement rejeter les fichiers multimédia."
           noop: Aucune
           silence: Masqué
           suspend: Suspendre
@@ -383,14 +383,14 @@ fr:
       rejecting_media: rejet des fichiers multimédia
       rejecting_reports: rejet des signalements
       severity:
-        silence: silencié
+        silence: masqué
         suspend: suspendu
       show:
         affected_accounts:
           one: Un compte affecté dans la base de données
           other: "%{count} comptes affectés dans la base de données"
         retroactive:
-          silence: Annuler le masquage des comptes existants affectés pour ce domaine
+          silence: Ne plus masquer les comptes existants affectés de ce domaine
           suspend: Annuler la suspension des comptes existants affectés pour ce domaine
         title: Annuler le blocage du domaine %{domain}
         undo: Annuler
@@ -568,7 +568,7 @@ fr:
         title: Politique de confidentialité
       site_title: Nom du serveur
       spam_check_enabled:
-        desc_html: Mastodon peut signaler automatiquement des comptes qui envoient des messages répétés non sollicités. Il peut y avoir de faux positifs.
+        desc_html: Mastodon peut signaler automatiquement les comptes qui envoient des messages non sollicités de façon répétée. Il peut y avoir des faux positifs.
         title: Automatisation anti-spam
       thumbnail:
         desc_html: Utilisée pour les prévisualisations via OpenGraph et l’API. 1200x630px recommandé
@@ -753,7 +753,7 @@ fr:
     proceed: Supprimer le compte
     success_msg: Votre compte a été supprimé avec succès
     warning:
-      before: 'Avant de procéder, veuillez lire attentivement ces notes :'
+      before: 'Veuillez lire attentivement ces notes avant de continuer :'
       caches: Le contenu mis en cache par d'autres serveurs peut persister
       data_removal: Vos messages et autres données seront définitivement supprimés
       email_change_html: Vous pouvez <a href="%{path}">modifier votre adresse courriel</a> sans supprimer votre compte
@@ -941,7 +941,9 @@ fr:
   moderation:
     title: Modération
   move_handler:
-    copy_account_note_text: 'Cet utilisateur est parti de %{acct}, voici vos notes précédentes à son sujet :'
+    carry_blocks_over_text: Cet utilisateur que vous aviez bloqué est parti de %{acct}.
+    carry_mutes_over_text: Cet utilisateur que vous aviez masqué est parti de %{acct}.
+    copy_account_note_text: 'Cet·te utilisateur·rice est parti de %{acct}, voici vos notes précédentes à son sujet :'
   notification_mailer:
     digest:
       action: Voir toutes les notifications
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index d2ad1bc45..c2fb18d57 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -21,9 +21,7 @@ gl:
     federation_hint_html: Cunha conta en %{instance} poderás seguir ás persoas en calquera servidor do Mastodon e alén.
     get_apps: Probar unha aplicación móbil
     hosted_on: Mastodon aloxado en %{domain}
-    instance_actor_flash: 'Esta conta é un actor virtual utilizado para representar ao servidor e non a unha usuaria individual. Utilízase para propósitos de federación e non debería estar bloqueada a menos que queiras bloquear a toda a instancia, en tal caso deberías utilizar o bloqueo do dominio.
-
-'
+    instance_actor_flash: Esta conta é un actor virtual utilizado para representar ao servidor e non a unha usuaria individual. Utilízase para propósitos de federación e non debería estar bloqueada a menos que queiras bloquear a toda a instancia, en tal caso deberías utilizar o bloqueo do dominio.
     learn_more: Saber máis
     privacy_policy: Política de privacidade
     see_whats_happening: Ver o que está a acontecer
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 32c28c3e5..9ae551a34 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -21,9 +21,7 @@ hu:
     federation_hint_html: Egy %{instance} fiókkal bármely más Mastodon szerveren vagy a föderációban lévő felhasználót követni tudsz.
     get_apps: Próbálj ki egy mobil appot
     hosted_on: "%{domain} Mastodon szerver"
-    instance_actor_flash: 'Ez a fiók egy virtuális szereplő, mely magát a szervert reprezentálja, nem egy felhasználót. Ez a föderáció támogatására készült, ezért nem szabad blokkolni, hacsak egy teljes szervert nem akarsz kitiltani, amire persze a domain blokkolása jobb megoldás.
-
-'
+    instance_actor_flash: Ez a fiók egy virtuális szereplő, mely magát a szervert reprezentálja, nem egy felhasználót. Ez a föderáció támogatására készült, ezért nem szabad blokkolni, hacsak egy teljes szervert nem akarsz kitiltani, amire persze a domain blokkolása jobb megoldás.
     learn_more: Tudj meg többet
     privacy_policy: Adatvédelmi szabályzat
     see_whats_happening: Nézd, mi történik
diff --git a/config/locales/id.yml b/config/locales/id.yml
index d55abce59..ad18cefb7 100644
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -21,9 +21,7 @@ id:
     federation_hint_html: Dengan akun di %{instance} Anda dapat mengikuti orang di server Mastodon mana pun dan di luarnya.
     get_apps: Coba aplikasi mobile
     hosted_on: Mastodon dihosting di %{domain}
-    instance_actor_flash: 'Akun ini adalah aktor virtual yang dipakai untuk merepresentasikan server, bukan pengguna individu. Ini dipakai untuk tujuan federasi dan jangan diblokir kecuali Anda ingin memblokir seluruh instansi, yang seharusnya Anda pakai blokir domain.
-
-'
+    instance_actor_flash: Akun ini adalah aktor virtual yang dipakai untuk merepresentasikan server, bukan pengguna individu. Ini dipakai untuk tujuan federasi dan jangan diblokir kecuali Anda ingin memblokir seluruh instansi, yang seharusnya Anda pakai blokir domain.
     learn_more: Pelajari selengkapnya
     privacy_policy: Kebijakan Privasi
     see_whats_happening: Lihat apa yang sedang terjadi
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index e3b6bc234..fb6255546 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -21,9 +21,7 @@ ja:
     federation_hint_html: "%{instance} のアカウントひとつでどんなMastodon互換サーバーのユーザーでもフォローできるでしょう。"
     get_apps: モバイルアプリを試す
     hosted_on: Mastodon hosted on %{domain}
-    instance_actor_flash: 'このアカウントはサーバーそのものを示す仮想的なもので、特定のユーザーを示すものではありません。これはサーバーの連合のために使用されます。サーバー全体をブロックするときは、このアカウントをブロックせずに、ドメインブロックを使用してください。
-
-'
+    instance_actor_flash: このアカウントはサーバーそのものを示す仮想的なもので、特定のユーザーを示すものではありません。これはサーバーの連合のために使用されます。サーバー全体をブロックするときは、このアカウントをブロックせずに、ドメインブロックを使用してください。
     learn_more: もっと詳しく
     privacy_policy: プライバシーポリシー
     see_whats_happening: やりとりを見てみる
@@ -931,6 +929,8 @@ ja:
   moderation:
     title: モデレーション
   move_handler:
+    carry_blocks_over_text: このユーザーは、あなたがブロックしていた %{acct} から引っ越しました。
+    carry_mutes_over_text: このユーザーは、あなたがミュートしていた %{acct} から引っ越しました。
     copy_account_note_text: このユーザーは %{acct} から引っ越しました。これは以前のメモです。
   notification_mailer:
     digest:
diff --git a/config/locales/kab.yml b/config/locales/kab.yml
index 833857b23..1d34355b3 100644
--- a/config/locales/kab.yml
+++ b/config/locales/kab.yml
@@ -12,6 +12,7 @@ kab:
     apps_platforms: Seqdec Maṣṭudun deg iOS, Android d tɣeṛγṛin-nniḍen
     browse_directory: Qelleb deg ukaram n imaɣnuten teǧǧeḍ-d gar-asen widak tebɣiḍ
     contact: Anermis
+    contact_missing: Ur yettusbadu ara
     contact_unavailable: Wlac
     discover_users: Af-d imseqdacen
     documentation: Amnir
@@ -69,7 +70,7 @@ kab:
     unfollow: Ur ṭṭafaṛ ara
   admin:
     account_moderation_notes:
-      create: Eǧǧ awennit
+      create: Eǧǧ tazmilt
       delete: Kkes
     accounts:
       approve: Qbel
@@ -88,6 +89,7 @@ kab:
       confirmed: Yettwasentem
       confirming: Asentem
       deleted: Yettwakkes
+      demote: Sider s weswir
       disable: Gdel
       disable_two_factor_authentication: Gdel 2FA
       disabled: Yensa
@@ -116,10 +118,14 @@ kab:
         all: Akk
         pending: Yettraǧu
         silenced: Yettwasgugem
+        suspended: Yeḥbes
       most_recent_activity: Armud aneggaru
       most_recent_ip: Tansa IP taneggarut
       no_account_selected: Ula yiwen n umiḍan ur yettwabeddel acku ula yiwen ur yettwafren
       no_limits_imposed: War tilisa
+      pending: Ittraǧu acegger
+      perform_full_suspension: Ḥbes di leεḍil
+      promote: Ali s uswir
       protocol: Aneggaf
       public: Azayez
       redownload: Smiren amaɣnu
@@ -143,6 +149,7 @@ kab:
       silenced: Yettwasgugem
       statuses: Tisuffɣin
       subscribe: Jerred
+      suspended: Yeḥbes
       time_in_queue: Deg tebdert n uraju %{time}
       title: Imiḍanen
       unconfirmed_email: Imayl ur yettwasentem ara
@@ -153,7 +160,9 @@ kab:
       whitelisted: Deg tebdert tamellalt
     action_logs:
       action_types:
+        disable_2fa_user: Gdel 2FA
         remove_avatar_user: Kkes avaṭar
+        reset_password_user: Ales awennez n wawal n uffir
         silence_account: Sgugem amiḍan
       actions:
         change_email_user: "%{name} ibeddel imayl n umseqdac %{target}"
@@ -178,6 +187,8 @@ kab:
         update_custom_emoji: "%{name} yelqem imuji %{target}"
         update_status: "%{name} yelqem tasuffeɣt n %{target}"
       deleted_status: "(tasuffeɣt tettwakkes)"
+      empty: Ulac iɣmisen i yellan.
+      title: Aɣmis n usenqed
     announcements:
       edit:
         title: Ẓreg ulγu
@@ -207,7 +218,9 @@ kab:
       new:
         title: Timerna n imuji udmawan amaynut
       overwrite: Semselsi
+      shortcode: Tangalt tawezlant
       title: Imujiten udmawanen
+      uncategorized: War-taggayt
       unlist: Kkes seg wumuγ
       unlisted: Yettwakkes seg wumuγ
       update_failed_msg: Ur izmir ara ad-issali umuji-a
@@ -238,16 +251,19 @@ kab:
         severity:
           noop: Ula yiwen
           silence: Sgugem
+          suspend: Ḥbes di leεḍil
       private_comment: Awennit uslig
       public_comment: Awennit azayez
       severity:
         silence: yettwasgugem
+        suspend: yeḥbes
       show:
         undo: Sefsex
     email_domain_blocks:
       add_new: Rnu amaynut
       delete: Kkes
       domain: Taγult
+      from_html: seg %{domain}
       new:
         create: Rnu taγult
         title: Timerna n taɣult tamaynut n imayl ɣer tebdart taberkant
@@ -288,6 +304,9 @@ kab:
       title: Imnegliyen
     reports:
       account:
+        notes:
+          one: "%{count} n tamawt"
+          other: "%{count} n timawin"
         reports:
           one: "%{count} uneqqis"
           other: "%{count} n ineqqisen"
@@ -297,7 +316,7 @@ kab:
       mark_as_resolved: Creḍ-it yefra
       mark_as_unresolved: Creḍ-it ur yefra ara
       notes:
-        create: Rnu tamawt
+        create: Rnu tazmilt
         delete: Kkes
       report: 'Aneqqis #%{id}'
       resolved: Fran
@@ -339,13 +358,16 @@ kab:
       title: Tisuffiγin n umiḍan
       with_media: S taγwalt
     tags:
+      context: Asatal
       directory: Deg ukaram
       in_directory: "%{count} deg ukaram"
       last_active: Armud aneggaru
       most_popular: Ittwasnen aṭas
       most_recent: Melmi kan
       name: Ahacṭag
+      reviewed: Yettwacegger
       title: Ihacṭagen
+    title: Tadbelt
     warning_presets:
       add_new: Rnu amaynut
       delete: Kkes
@@ -364,6 +386,7 @@ kab:
     view_profile: Ssken-d amaɣnu
     view_status: Ssken-d tasuffiɣt
   auth:
+    apply_for_account: Suter asnebgi
     change_password: Awal uffir
     checkbox_agreement_html: Qebleγ <a href="%{rules_path}" target="_blank">ilugan n uqeddac-a</a> akked <a href="%{terms_path}" target="_blank">tiwtilin n useqdec</a>
     checkbox_agreement_without_rules_html: Qebleγ <a href="%{terms_path}" target="_blank">tiwtilin n useqdec</a>
@@ -382,6 +405,8 @@ kab:
     reset_password: Wennez awal uffir
     security: Taγellist
     set_new_password: Egr-d awal uffir amaynut
+    setup:
+      title: Sbadu
     status:
       account_status: Addad n umiḍan
       functional: Amiḍan-inek·m yettwaheyya.
@@ -458,6 +483,7 @@ kab:
   footer:
     developers: Ineflayen
     more: Ugar…
+    resources: Iɣbula
   generic:
     all: Akk
     changes_saved_msg: Ttwaskelsen ibelliden-ik·im akken ilaq!
@@ -474,12 +500,15 @@ kab:
     publicize_checkbox: 'Tjewqeḍ aya:'
   imports:
     modes:
+      merge: Smezdi
       overwrite: Semselsi
     types:
       following: Tabdert n wid teṭṭafareḍ
       muting: Tabdert n wid tesgugmeḍ
     upload: Sali
   invites:
+    delete: Sexsi
+    expired: Yemmut
     expires_in:
       '1800': 30 n tisdatin
       '21600': 6 n isragen
@@ -488,6 +517,9 @@ kab:
       '604800': 1 umalas
       '86400': 1 wass
     expires_in_prompt: Werǧin
+    max_uses_prompt: Ulac talast
+    table:
+      expires_at: Ad ifat di
     title: Ɛreḍ-d kra n yimdanen
   migrations:
     acct: Ibeddel γer
@@ -509,6 +541,12 @@ kab:
       subject: Yuder-ik·ikem-id %{name}
   notifications:
     other_settings: Iγewwaṛen nniḍen n tilγa
+  number:
+    human:
+      decimal_units:
+        units:
+          million: A
+          trillion: Am
   pagination:
     newer: Amaynut
     next: Wayed
@@ -518,9 +556,14 @@ kab:
   preferences:
     other: Wiyaḍ
   relationships:
+    activity: Armud n umiḍan
     followers: Imeḍfaṛen
     following: Yeṭafaṛ
+    last_active: Armud aneggaru
+    most_recent: Melmi kan
     moved: Igujj
+    primary: Agejdan
+    relationship: Assaɣ
     status: Addad n umiḍan
   remote_follow:
     no_account_html: Ur tesɛid ara amiḍan? Tzmreḍ <a href='%{sign_up_path}' target='_blank'>ad jerdeḍ da</a>
@@ -598,6 +641,7 @@ kab:
       total_people:
         one: "%{count} n wemdan"
         other: "%{count} n yemdanen"
+      vote: Dɣeṛ
     show_more: Ssken-d ugar
     show_thread: Ssken-d lxiḍ
     sign_in_to_participate: Qqen i waken ad tzeddiḍ deg udiwenni
@@ -605,6 +649,7 @@ kab:
     visibilities:
       private: Imeḍfaṛen kan
       private_long: Ssken i ymeḍfaṛen kan
+      public: Azayez
       public_long: Yal yiwen·t yezmer at iwali
       unlisted: War tabdert
   stream_entries:
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index bf2aaa5bd..1742e5d08 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -933,6 +933,8 @@ ko:
   moderation:
     title: 중재
   move_handler:
+    carry_blocks_over_text: 이 사용자는 당신이 차단한 %{acct}로부터 이주 했습니다.
+    carry_mutes_over_text: 이 사용자는 당신이 뮤트한 %{acct}로부터 이주 했습니다.
     copy_account_note_text: '이 사용자는 %{acct}로부터 이동하였습니다. 당신의 이전 노트는 이렇습니다:'
   notification_mailer:
     digest:
diff --git a/config/locales/ku.yml b/config/locales/ku.yml
new file mode 100644
index 000000000..2fbf0ffd7
--- /dev/null
+++ b/config/locales/ku.yml
@@ -0,0 +1 @@
+--- {}
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 7ab26c4ba..c92b6c1db 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -21,9 +21,7 @@ nl:
     federation_hint_html: Met een account op %{instance} ben je in staat om mensen die zich op andere Mastodonservers (en op andere plekken) bevinden te volgen.
     get_apps: Mobiele apps
     hosted_on: Mastodon op %{domain}
-    instance_actor_flash: 'Dit account is een virtuel actor die wordt gebruikt om de server zelf te vertegenwoordigen en is geen individuele gebruiker. Het wordt voor federatiedoeleinden gebruikt en moet niet worden geblokkeerd, tenzij je de hele server wil blokkeren. In zo''n geval dien je echter een domeinblokkade te gebruiken.
-
-'
+    instance_actor_flash: Dit account is een virtuel actor dat wordt gebruikt om de server zelf te vertegenwoordigen en is geen individuele gebruiker. Het wordt voor federatiedoeleinden gebruikt en moet niet worden geblokkeerd, tenzij je de hele server wilt blokkeren. In zo'n geval dien je echter een domeinblokkade te gebruiken.
     learn_more: Meer leren
     privacy_policy: Privacybeleid
     see_whats_happening: Kijk wat er aan de hand is
@@ -35,13 +33,16 @@ nl:
     status_count_before: Zij schreven
     tagline: Vrienden volgen en nieuwe ontdekken
     terms: Gebruiksvoorwaarden
-    unavailable_content: Niet beschikbare inhoud
+    unavailable_content: Gemodereerde servers
     unavailable_content_description:
       domain: Server
       reason: 'Reden:'
       rejecting_media: 'Mediabestanden van deze server worden niet verwerkt en er worden geen thumbnails getoond. Je moet handmatig naar deze server doorklikken om de mediabestanden te kunnen bekijken:'
+      rejecting_media_title: Mediabestanden geweigerd
       silenced: Toots van deze server worden nergens weergegeven, behalve op jouw eigen starttijdlijn wanneer je het account volgt.
+      silenced_title: Genegeerde servers
       suspended: Je bent niet in staat om iemand van deze server te volgen, en er worden geen gegevens van deze server verwerkt of opgeslagen, en met deze server uitgewisseld.
+      suspended_title: Opgeschorte servers
     unavailable_content_html: Met Mastodon kun je in het algemeen berichten bekijken van en communiceren met gebruikers van elke andere server in de fediverse. Dit zijn de uitzonderingen die door deze server zijn gemaakt en expliciet alleen hier gelden.
     user_count_after:
       one: gebruiker
@@ -92,6 +93,7 @@ nl:
       delete: Verwijderen
       destroyed_msg: Verwijderen van opmerking voor moderatoren geslaagd!
     accounts:
+      add_email_domain_block: E-maildomein blokkeren
       approve: Goedkeuren
       approve_all: Alles goedkeuren
       are_you_sure: Weet je het zeker?
@@ -172,6 +174,7 @@ nl:
         staff: Medewerkers
         user: Gebruiker
       search: Zoeken
+      search_same_email_domain: Andere gebruikers met hetzelfde e-maildomein
       search_same_ip: Andere gebruikers met hetzelfde IP-adres
       shared_inbox_url: Gedeelde inbox-URL
       show:
@@ -191,8 +194,44 @@ nl:
       username: Gebruikersnaam
       warn: Waarschuwen
       web: Webapp
-      whitelisted: Op de witte lijst
+      whitelisted: Goedgekeurd voor federatie
     action_logs:
+      action_types:
+        assigned_to_self_report: Rapportage toewijzen
+        change_email_user: E-mailadres van gebruiker wijzigen
+        confirm_user: Gebruiker bevestigen
+        create_account_warning: Waarschuwing aanmaken
+        create_announcement: Mededeling aanmaken
+        create_custom_emoji: Lokale emoji aanmaken
+        create_domain_allow: Domeingoedkeuring aanmaken
+        create_domain_block: Domeinblokkade aanmaken
+        create_email_domain_block: E-maildomeinblokkade aanmaken
+        demote_user: Gebruiker degraderen
+        destroy_announcement: Mededeling verwijderen
+        destroy_custom_emoji: Lokale emoji verwijderen
+        destroy_domain_allow: Domeingoedkeuring verwijderen
+        destroy_domain_block: Domeinblokkade verwijderen
+        destroy_email_domain_block: E-maildomeinblokkade verwijderen
+        destroy_status: Toot verwijderen
+        disable_2fa_user: Tweestapsverificatie uitschakelen
+        disable_custom_emoji: Lokale emojij uitschakelen
+        disable_user: Gebruiker uitschakelen
+        enable_custom_emoji: Lokale emoji inschakelen
+        enable_user: Gebruiker inschakelen
+        memorialize_account: Account in gedenkpagina veranderen
+        promote_user: Gebruiker promoveren
+        remove_avatar_user: Avatar verwijderen
+        reopen_report: Rapportage heropenen
+        reset_password_user: Wachtwoord opnieuw instellen
+        resolve_report: Rapportage oplossen
+        silence_account: Account negeren
+        suspend_account: Account opschorten
+        unassigned_report: Rapportage niet langer toewijzen
+        unsilence_account: Account niet langer negeren
+        unsuspend_account: Account niet langer opschorten
+        update_announcement: Mededeling bijwerken
+        update_custom_emoji: Lokale emoji bijwerken
+        update_status: Toot bijwerken
       actions:
         assigned_to_self_report: "%{name} heeft rapportage %{target} aan zichzelf toegewezen"
         change_email_user: "%{name} veranderde het e-mailadres van gebruiker %{target}"
@@ -200,15 +239,15 @@ nl:
         create_account_warning: "%{name} verzond een waarschuwing naar %{target}"
         create_announcement: "%{name} heeft de nieuwe mededeling %{target} aangemaakt"
         create_custom_emoji: Nieuwe emoji %{target} is door %{name} geüpload
-        create_domain_allow: "%{name} heeft het domein %{target} aan de witte lijst toegevoegd"
+        create_domain_allow: "%{name} heeft federatie met het domein %{target} goedgekeurd"
         create_domain_block: Domein %{target} is door %{name} geblokkeerd
-        create_email_domain_block: E-maildomein %{target} is door %{name} op de zwarte lijst geplaatst
+        create_email_domain_block: "%{name} heeft het e-maildomein %{target} geblokkeerd"
         demote_user: Gebruiker %{target} is door %{name} gedegradeerd
         destroy_announcement: "%{name} heeft de mededeling %{target} verwijderd"
         destroy_custom_emoji: "%{name} verwijderde emoji %{target}"
-        destroy_domain_allow: "%{name} heeft het domein %{target} van de witte lijst verwijderd"
+        destroy_domain_allow: "%{name} heeft federatie met het domein %{target} afgekeurd"
         destroy_domain_block: Domein %{target} is door %{name} gedeblokkeerd
-        destroy_email_domain_block: E-maildomein %{target} is door %{name} op de witte lijst geplaatst
+        destroy_email_domain_block: "%{name} heeft het e-maildomein %{target} gedeblokkeerd"
         destroy_status: Toot van %{target} is door %{name} verwijderd
         disable_2fa_user: Vereisten tweestapsverificatie van %{target} zijn door %{name} uitgeschakeld
         disable_custom_emoji: Emoji %{target} is door %{name} uitgeschakeld
@@ -230,6 +269,9 @@ nl:
         update_custom_emoji: Emoji %{target} is door %{name} bijgewerkt
         update_status: De toots van %{target} zijn door %{name} bijgewerkt
       deleted_status: "(verwijderde toot}"
+      empty: Geen logs gevonden.
+      filter_by_action: Op actie filteren
+      filter_by_user: Op gebruiker filteren
       title: Auditlog
     announcements:
       destroyed_msg: Verwijderen van mededeling geslaagd!
@@ -268,6 +310,7 @@ nl:
       listed: Weergegeven
       new:
         title: Lokale emoji toevoegen
+      not_permitted: Het hebt geen rechten om deze actie uit te voeren
       overwrite: Overschrijven
       shortcode: Verkorte code
       shortcode_hint: Tenminste 2 tekens (alleen alfanumeriek en underscores)
@@ -305,12 +348,12 @@ nl:
       week_interactions: interacties deze week
       week_users_active: actieve gebruikers deze week
       week_users_new: nieuwe gebruikers deze week
-      whitelist_mode: Modus voor de witte lijst
+      whitelist_mode: Beperkte federatiemodus
     domain_allows:
-      add_new: Domein voor de witte lijst
-      created_msg: Het domein is succesvol aan de witte lijst toegevoegd
-      destroyed_msg: Het domein is van de witte lijst verwijderd
-      undo: Van de witte lijst verwijderen
+      add_new: Federatie met domein goedkeuren
+      created_msg: Federatie met domein is succesvol goedgekeurd
+      destroyed_msg: Federatie met domein is afgekeurd
+      undo: Federatie met domein afkeuren
     domain_blocks:
       add_new: Nieuwe domeinblokkade toevoegen
       created_msg: Domeinblokkade wordt nu verwerkt
@@ -357,11 +400,12 @@ nl:
       delete: Verwijderen
       destroyed_msg: Deblokkeren e-maildomein geslaagd
       domain: Domein
-      empty: Momenteel staan er geen e-maildomeinen op de zwarte lijst.
+      empty: Momenteel worden er geen e-maildomeinen geblokkeerd.
+      from_html: van %{domain}
       new:
         create: Blokkeren
         title: Nieuw e-maildomein blokkeren
-      title: E-maildomeinen blokkeren
+      title: Geblokkeerde e-maildomeinen
     instances:
       by_domain: Domein
       delivery_available: Bezorging is mogelijk
@@ -374,7 +418,7 @@ nl:
         title: Moderatie
       private_comment: Privé-opmerking
       public_comment: Openbare opmerking
-      title: Andere domeinen
+      title: Federatie
       total_blocked_by_us: Door ons geblokkeerd
       total_followed_by_them: Door hun gevolgd
       total_followed_by_us: Door ons gevolgd
@@ -405,7 +449,7 @@ nl:
       pending: Aan het wachten op toestemming van de relayserver
       save_and_enable: Opslaan en inschakelen
       setup: Een verbinding met een relayserver maken
-      signatures_not_enabled: Federatierelays werken niet goed wanneer de veilige modus of de witte lijstmodus is ingeschakeld
+      signatures_not_enabled: Federatierelays werken niet goed wanneer de veilige modus of de beperkte federatiemodus is ingeschakeld
       status: Status
       title: Relayservers
     report_notes:
@@ -593,6 +637,7 @@ nl:
     add_new: Alias aanmaken
     created_msg: Succesvol een nieuwe alias aangemaakt. Je kunt nu met de verhuizing vanaf het oude account beginnen.
     deleted_msg: De alias is succesvol verwijderd. Verhuizen vanaf dat account naar dit account is niet meer mogelijk.
+    empty: Je hebt geen aliassen.
     hint_html: Wanneer je vanaf een ander account naar dit account wilt verhuizen, kun je hier een alias aanmaken. Dit is nodig voordat je verder kunt gaan met het verhuizen van volgers van het oude naar dit nieuwe account. Deze actie is op zich <strong>ongevaarlijk en omkeerbaar</strong>. <strong>De accountmigratie wordt gestart vanaf het oude account</strong>.
     remove: Alias ontkoppelen
   appearance:
@@ -678,6 +723,10 @@ nl:
     hint_html: "<strong>Tip:</strong> We vragen jou het komende uur niet meer naar jouw wachtwoord."
     invalid_password: Ongeldig wachtwoord
     prompt: Bevestig wachtwoord om door te gaan
+  crypto:
+    errors:
+      invalid_key: is geen geldige Ed25519- of Curve25519-sleutel
+      invalid_signature: is geen geldige Ed25519-handtekening
   date:
     formats:
       default: "%d %b %Y"
@@ -800,13 +849,15 @@ nl:
       keybase:
         invalid_token: Keybasetokens zijn hashes van handtekeningen en moeten een lengte hebben van 66 hexadecimale tekens
         verification_failed: Keybase herkent deze token niet als een handtekening van Keybasegebruiker %{kb_username}. Probeer het opnieuw vanuit Keybase.
-      wrong_user: Er kan geen bewijs worden aangemaakt voor %{proving}   terwijl je bent ingelogd als %{current}. Log in als %{proving} en probeer het opnieuw.
+      wrong_user: Er kan geen bewijs worden aangemaakt voor %{proving} terwijl je bent ingelogd als %{current}. Log in als %{proving} en probeer het opnieuw.
     explanation_html: Hier kun je met behulp van cryptografie jouw andere identiteiten verbinden, zoals een Keybaseprofiel. Hiermee kunnen andere mensen jou versleutelde berichten sturen en inhoud die jij verstuurt vertrouwen.
     i_am_html: Ik ben %{username} op %{service}.
     identity: Identiteit
     inactive: Inactief
     publicize_checkbox: 'En toot dit:'
     publicize_toot: 'Het is bewezen! Ik ben %{username} op %{service}: %{url}'
+    remove: Bewijs uit account verwijderen
+    removed: Bewijs is succesvol uit account verwijderd
     status: Verificatiestatus
     view_proof: Bekijk bewijs
   imports:
@@ -852,6 +903,7 @@ nl:
   media_attachments:
     validations:
       images_and_video: Een video kan niet aan een toot met afbeeldingen worden gekoppeld
+      not_ready: Kan geen bestanden toevoegen die nog niet zijn verwerkt. Probeer het later opnieuw!
       too_many: Er kunnen niet meer dan 4 afbeeldingen toegevoegd worden
   migrations:
     acct: Verhuisd naar
@@ -860,7 +912,7 @@ nl:
     cancelled_msg: De doorverwijzing is succesvol geannuleerd.
     errors:
       already_moved: is hetzelfde account waarnaar je al naar toe bent verhuisd
-      missing_also_known_as: verwijst niet terug naar dit account
+      missing_also_known_as: is geen alias van dit account
       move_to_self: kan niet het huidige account zijn
       not_found: kon niet worden gevonden
       on_cooldown: Jouw laatste migratie is nog te kort geleden
@@ -872,6 +924,7 @@ nl:
     on_cooldown: Je hebt recentelijk jouw account verhuisd. Deze mogelijkheid is weer beschikbaar over %{count} dagen.
     past_migrations: Vorige migraties
     proceed_with_move: Volgers verhuizen
+    redirected_msg: Jouw account wordt nu doorverwezen naar %{acct}.
     redirecting_to: Jouw account wordt nu naar %{acct} doorverwezen.
     set_redirect: Doorverwijzing instellen
     warning:
@@ -885,6 +938,10 @@ nl:
       redirect: Jouw huidige accountprofiel wordt bijgewerkt met een doorverwijzingsmelding en wordt uitgesloten van zoekresultaten
   moderation:
     title: Moderatie
+  move_handler:
+    carry_blocks_over_text: Deze gebruiker is verhuisd vanaf %{acct}. Je hebt dat account geblokkeerd.
+    carry_mutes_over_text: Deze gebruiker is verhuisd vanaf %{acct}. Je hebt dat account genegeerd.
+    copy_account_note_text: 'Deze gebruiker is verhuisd vanaf %{acct}. Je hebt de volgende opmerkingen over dat account gemaakt:'
   notification_mailer:
     digest:
       action: Alle meldingen bekijken
@@ -1061,6 +1118,9 @@ nl:
     spam_detected: Dit is een automatisch gegenereerde rapportage. Er is spam gedetecteerd.
   statuses:
     attached:
+      audio:
+        one: "%{count} geluidsbestand"
+        other: "%{count} geluidsbestanden"
       description: 'Bijlagen: %{attached}'
       image:
         one: "%{count} afbeelding"
@@ -1073,6 +1133,8 @@ nl:
     disallowed_hashtags:
       one: 'bevatte een niet toegestane hashtag: %{tags}'
       other: 'bevatte niet toegestane hashtags: %{tags}'
+    errors:
+      in_reply_not_found: De toot waarop je probeert te reageren lijkt niet te bestaan.
     language_detection: Taal automatisch detecteren
     open_in_web: In de webapp openen
     over_character_limit: Limiet van %{max} tekens overschreden
@@ -1218,6 +1280,8 @@ nl:
       explanation: Je hebt een volledige back-up van jouw Mastodon-account opgevraagd. Het staat nu klaar om te worden gedownload!
       subject: Jouw archief staat klaar om te worden gedownload
       title: Archief ophalen
+    sign_in_token:
+      details: 'Hier zijn details van de poging:'
     warning:
       explanation:
         disable: Zolang jouw account is bevroren blijven jouw accountgegevens intact, maar kun je geen handelingen uitvoeren totdat het account is vrijgegeven.
diff --git a/config/locales/no.yml b/config/locales/no.yml
index ddd404848..32368fc9a 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -21,9 +21,7 @@
     federation_hint_html: Med en konto på %{instance} vil du kunne følge folk på enhver Mastodon-tjener, og mer til.
     get_apps: Prøv en mobilapp
     hosted_on: Mastodon driftet på %{domain}
-    instance_actor_flash: 'Denne brukeren er en virtuell aktør brukt til å representere selve serveren og ingen individuell bruker. Det brukes til foreningsformål og bør ikke blokkeres med mindre du vil blokkere hele instansen, hvor domeneblokkering bør brukes i stedet.
-
-'
+    instance_actor_flash: Denne brukeren er en virtuell aktør brukt til å representere selve serveren og ingen individuell bruker. Det brukes til foreningsformål og bør ikke blokkeres med mindre du vil blokkere hele instansen, hvor domeneblokkering bør brukes i stedet.
     learn_more: Lær mer
     privacy_policy: Privatlivsretningslinjer
     see_whats_happening: Se hva som skjer
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 0081cabb3..95d15ef85 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -39,6 +39,7 @@ oc:
       rejecting_media: 'Los fichièrs mèdias d’aquestes servidors estant seràn pas tractats o gardats e pas cap de miniatura serà pas mostrada, demanda de clicar sul fichièr original :'
       rejecting_media_title: Mèdias filtrats
       silenced_title: Servidors muts
+      suspended_title: Servidors suspenduts
     user_count_after:
       one: utilizaire
       other: utilizaires
@@ -1256,6 +1257,7 @@ oc:
     follow_limit_reached: Podètz pas sègre mai de %{limit} personas
     invalid_email: L’adreça de corrièl es invalida
     invalid_otp_token: Còdi d’autentificacion en dos temps invalid
+    invalid_sign_in_token: Còdi de seguretat invalid
     otp_lost_help_html: Se perdatz l’accès al dos, podètz benlèu contactar %{email}
     seamless_external_login: Sètz connectat via un servici extèrn, los paramètres de senhal e de corrièl son doncas pas disponibles.
     signed_in_as: 'Session a :'
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 1382fefa6..2e2a8d4eb 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -22,8 +22,8 @@ pt-BR:
     get_apps: Experimente um aplicativo
     hosted_on: Instância Mastodon em %{domain}
     instance_actor_flash: |
-      Esta conta é um ator virtual usado para representar a própria instância.
-      É usado para fins de federação e não deve ser bloqueado a menos que você queira bloquear toda a instância, nesse caso é melhor usar um bloqueador de domínios.
+      Esta conta é um ator virtual usado para representar o próprio servidor e não qualquer usuário individual.
+      É usado para propósitos de federação e não deve ser bloqueado a menos que queira bloquear toda a instância, o que no caso devia usar um bloqueio de domínio.
     learn_more: Saiba mais
     privacy_policy: Política de Privacidade
     see_whats_happening: Veja o que está acontecendo
diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml
index 963e6f0b5..8d149d11f 100644
--- a/config/locales/simple_form.ar.yml
+++ b/config/locales/simple_form.ar.yml
@@ -15,6 +15,7 @@ ar:
         type_html: اختر ما تود إجراؤه على <strong>%{acct}</strong>
         warning_preset_id: اختياري. يمكنك إضافة نص مخصص إلى نهاية النموذج
       announcement:
+        all_day: إن أختير، سيتم عرض تواريخ النطاق الزمني فقط
         ends_at: اختياري. سيتم إلغاء نشر الإعلان تلقائيا على هذه الساعة
         scheduled_at: اتركه فارغا لنشر الإعلان في الحين
         starts_at: اختياري. في حالة ما كان إعلانك ذو صلة بنطاق زمني مخصّص
@@ -62,6 +63,8 @@ ar:
         text: هذا سوف يساعدنا في مراجعة تطبيقك
       sessions:
         otp: 'قم بإدخال رمز المصادقة بخطوتين الذي قام بتوليده تطبيق جهازك أو استخدم أحد رموز النفاذ الاحتياطية:'
+      tag:
+        name: يمكنك فقط تغيير غلاف الحروف ، على سبيل المثال ، لجعلها أكثر قابلية للقراءة
       user:
         chosen_languages: لن تظهر على الخيوط العمومية إلّا التبويقات المنشورة في اللغات المختارة
     labels:
@@ -88,6 +91,7 @@ ar:
           suspend: تعليق و حذف كافة بيانات الحساب
         warning_preset_id: استخدم نموذج تنبيه
       announcement:
+        all_day: حدث اليوم كله
         ends_at: نهاية الفعالية
         scheduled_at: جَدوِل المنشور
         starts_at: بداية الفعالية
@@ -143,6 +147,7 @@ ar:
         setting_use_blurhash: أظهر ألوانًا متدرّجة على الوسائط المَخفية
         setting_use_pending_items: الوضع البطيء
         severity: القوّة
+        sign_in_token_attempt: رمز الأمان
         type: صيغة الاستيراد
         username: اسم المستخدم
         username_or_email: اسم المستخدم أو كلمة السر
diff --git a/config/locales/simple_form.hy.yml b/config/locales/simple_form.hy.yml
index 90c89ced8..cd73ee679 100644
--- a/config/locales/simple_form.hy.yml
+++ b/config/locales/simple_form.hy.yml
@@ -12,3 +12,31 @@ hy:
       admin_account_action:
         include_statuses: օգտատէրը տեսնելու ա որ թթերն են առաջացրել մոդերացիայի գործողութիւն կամ զգուշացում։
         send_email_notification: օգտատէրը կը ստանայ բացատրութիւն այն մասին թէ ինչ է պատահել իրենց հաշուի հետ։
+    labels:
+      account:
+        fields:
+          name: Պիտակ
+          value: Պարունակություն
+      account_warning_preset:
+        title: Վերնագիր
+      admin_account_action:
+        type: Գործողություն
+        types:
+          none: Ոչինչ չանել
+          silence: Լուռ
+      defaults:
+        header: Վերնագիր
+        note: Բիո
+        password: Գաղտնաբառ
+        setting_theme: Կայքի թեման
+        severity: Սրություն
+        sign_in_token_attempt: Անվտանգության կոդ
+        username: Մուտքանուն
+      invite:
+        comment: Մեկնաբանություն
+    'no': Ոչ
+    recommended: Խորհուրդ է տրվում
+    required:
+      mark: "*"
+      text: պարտադիր
+    'yes': Այո
diff --git a/config/locales/simple_form.kab.yml b/config/locales/simple_form.kab.yml
index 06b4cfa69..d76af2c57 100644
--- a/config/locales/simple_form.kab.yml
+++ b/config/locales/simple_form.kab.yml
@@ -33,6 +33,8 @@ kab:
           value: Agbur
       account_migration:
         acct: Tansa n umiḍan amaynut
+      account_warning_preset:
+        title: Azwel
       admin_account_action:
         send_email_notification: Sileɣ aseqdac s imaylen
         type: Tigawt
@@ -42,6 +44,7 @@ kab:
           silence: Sgugem
       announcement:
         ends_at: Tagara n tedyant
+        text: Alɣu
       defaults:
         avatar: Avaṭar
         bot: Wagi d amiḍan aṛubut
@@ -58,6 +61,7 @@ kab:
         locked: Rgel amiḍan
         max_uses: Amḍan afellay n iseqdacen
         new_password: Awal uffir amaynut
+        note: Tameddurt
         otp_attempt: Tangalt n snat n tarayin
         password: Awal uffir
         setting_default_language: Tutlayt n tira
diff --git a/config/locales/simple_form.ku.yml b/config/locales/simple_form.ku.yml
new file mode 100644
index 000000000..cc251e86a
--- /dev/null
+++ b/config/locales/simple_form.ku.yml
@@ -0,0 +1 @@
+ckb-IR:
diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml
index c65608d95..3f4bd9b9e 100644
--- a/config/locales/simple_form.nl.yml
+++ b/config/locales/simple_form.nl.yml
@@ -8,6 +8,7 @@ nl:
         acct: Vul de gebruikersnaam@domein van het account in, waarnaartoe je wilt verhuizen
       account_warning_preset:
         text: Je kunt voor toots specifieke tekst gebruiken, zoals URL's, hashtags en vermeldingen
+        title: Optioneel. Niet zichtbaar voor de ontvanger
       admin_account_action:
         include_statuses: De gebruiker ziet welke toots verantwoordelijk zijn voor de moderatieactie of waarschuwing
         send_email_notification: De gebruiker ontvangt een uitleg over wat er met hun account is gebeurd
@@ -53,6 +54,9 @@ nl:
         whole_word: Wanneer het trefwoord of zinsdeel alfanumeriek is, wordt het alleen gefilterd wanneer het hele woord overeenkomt
       domain_allow:
         domain: Dit domein is in staat om gegevens van deze server op te halen, en binnenkomende gegevens worden verwerkt en opgeslagen
+      email_domain_block:
+        domain: Dit kan de domeinnaam zijn, onderdeel van het e-mailadres, het MX-record dat het desbetreffende domein afhandelt, of het IP-adres van de server dat het MX-record afhandelt. Deze worden gecontroleerd tijdens het registreren, waarna de registratie wordt afgewezen.
+        with_dns_records: Er wordt een poging gewaagd om de desbetreffende DNS-records op te zoeken, waarna de resultaten ook worden geblokkeerd
       featured_tag:
         name: 'Je wilt misschien een van deze gebruiken:'
       form_challenge:
@@ -78,6 +82,7 @@ nl:
         acct: Mastodonadres van het nieuwe account
       account_warning_preset:
         text: Tekst van voorinstelling
+        title: Titel
       admin_account_action:
         include_statuses: Gerapporteerde toots aan de e-mail toevoegen
         send_email_notification: Meld dit per e-mail aan de gebruiker
@@ -146,10 +151,13 @@ nl:
         setting_use_blurhash: Wazige kleurovergangen voor verborgen media tonen
         setting_use_pending_items: Langzame modus
         severity: Zwaarte
+        sign_in_token_attempt: Beveiligingscode
         type: Importtype
         username: Gebruikersnaam
         username_or_email: Gebruikersnaam of e-mailadres
         whole_word: Heel woord
+      email_domain_block:
+        with_dns_records: MX-records en IP-adressen van het domein toevoegen
       featured_tag:
         name: Hashtag
       interactions:
diff --git a/config/locales/simple_form.tr.yml b/config/locales/simple_form.tr.yml
index 60f7c9eac..ea913048d 100644
--- a/config/locales/simple_form.tr.yml
+++ b/config/locales/simple_form.tr.yml
@@ -8,6 +8,7 @@ tr:
         acct: Taşınmak istediğiniz hesabın kullanıcı-adı@alan-adını belirtin
       account_warning_preset:
         text: URL'ler, etiketler ve bahsetmeler gibi toot sözdizimleri kullanabilirsiniz
+        title: İsteğe bağlı. Alıcı tarafından görülemez
       admin_account_action:
         include_statuses: Kullanıcı hangi tootların denetleme eylemi ya da uyarısına neden olduğunu görecektir
         send_email_notification: Kullanıcı, hesabına ne olduğu hakkında bir bildirim alacak
@@ -147,10 +148,13 @@ tr:
         setting_use_blurhash: Gizli ortamlar için renkli gradyen göster
         setting_use_pending_items: Yavaş mod
         severity: Zorluk
+        sign_in_token_attempt: Güvenlik kodu
         type: Dosya türü
         username: Kullanıcı adınız
         username_or_email: Kullanıcı adı ya da email
         whole_word: Tüm dünya
+      email_domain_block:
+        with_dns_records: Alan adının MX kayıtlarını ve IP'lerini ekleyin
       featured_tag:
         name: Hashtag
       interactions:
diff --git a/config/locales/simple_form.ug.yml b/config/locales/simple_form.ug.yml
new file mode 100644
index 000000000..289acf241
--- /dev/null
+++ b/config/locales/simple_form.ug.yml
@@ -0,0 +1 @@
+ug:
diff --git a/config/locales/simple_form.uk.yml b/config/locales/simple_form.uk.yml
index 10977aedc..a490efed5 100644
--- a/config/locales/simple_form.uk.yml
+++ b/config/locales/simple_form.uk.yml
@@ -54,6 +54,8 @@ uk:
         whole_word: Якщо пошукове слово або фраза містить тільки літери та цифри, воно має співпадати цілком
       domain_allow:
         domain: Цей домен зможе отримувати дані з цього серверу. Вхідні дані будуть оброблені та збережені
+      email_domain_block:
+        with_dns_records: Спроба визначення DNS-записів заданого домену буде здійснена, а результати також будуть занесені до чорного списку
       featured_tag:
         name: 'Можливо, ви захочете використовувати один з цих:'
       form_challenge:
@@ -148,10 +150,13 @@ uk:
         setting_use_blurhash: Відображати барвисті градієнти замість прихованих медіа
         setting_use_pending_items: Повільний режим
         severity: Серйозність
+        sign_in_token_attempt: Код безпеки
         type: Тип імпорту
         username: Ім'я користувача
         username_or_email: Ім'я користувача або електронна пошта
         whole_word: Ціле слово
+      email_domain_block:
+        with_dns_records: Включити MX записи та IP-адреси домену
       featured_tag:
         name: Хештеґ
       interactions:
diff --git a/config/locales/simple_form.vi.yml b/config/locales/simple_form.vi.yml
index a1fc0d9bb..5251ab114 100644
--- a/config/locales/simple_form.vi.yml
+++ b/config/locales/simple_form.vi.yml
@@ -22,30 +22,30 @@ vi:
         starts_at: Tùy chọn. Trong trường hợp thông báo của bạn đăng vào một khoảng thời gian cụ thể
         text: Bạn có thể sử dụng tút dạng cú pháp. Cố gắng ngắn gọn bởi vì thông báo sẽ xuất hiện trên màn hình điện thoại của người dùng
       defaults:
-        autofollow: Những người đăng ký thông qua lời mời sẽ tự động mến mộ bạn
+        autofollow: Những người đăng ký thông qua lời mời sẽ tự động theo dõi bạn
         avatar: PNG, GIF hoặc JPG. Kích cỡ tối đa %{size}. Sẽ bị nén xuống %{dimensions}px
-        bot: Tài khoản này chủ yếu tự động thực hiện các hành động và không cần thiết mến mộ
+        bot: Tài khoản này tự động thực hiện các hành động và không cần thiết theo dõi
         context: Một hoặc nhiều bối cảnh nơi bộ lọc nên áp dụng
         current_password: Vì mục đích bảo mật, vui lòng nhập mật khẩu của tài khoản hiện tại
         current_username: Để xác nhận, vui lòng nhập tên người dùng của tài khoản hiện tại
         digest: Chỉ được gửi sau một thời gian dài không hoạt động và chỉ khi bạn đã nhận được bất kỳ tin nhắn cá nhân nào khi bạn vắng mặt
-        discoverable: Danh sách thành viên là một cách hay để bạn tìm kiếm người bạn muốn mến mộ
+        discoverable: Danh sách thành viên là một cách hay để bạn tìm kiếm người bạn muốn theo dõi
         email: Bạn sẽ được gửi một email xác nhận
         fields: Bạn có thể tạo tối đa 4 mục được hiển thị dưới dạng bảng trên hồ sơ của bạn
         header: PNG, GIF hoặc JPG. Kích cỡ tối đa %{size}. Sẽ bị nén xuống %{dimensions}px
         inbox_url: Sao chép URL của relay mà bạn muốn sử dụng
         irreversible: Các tút đã lọc sẽ không thể phục hồi, kể cả khi bộ lọc có bị xóa
         locale: Ngôn ngữ của giao diện, email và thông báo đẩy
-        locked: Yêu cầu bạn chấp thuận thủ công người mến mộ
+        locked: Yêu cầu bạn chấp thuận thủ công người theo dõi
         password: Sử dụng ít nhất 8 ký tự
         phrase: Sẽ được hiện thị trong văn bản hoặc cảnh báo nội dung của một tút
         scopes: API nào ứng dụng sẽ được phép truy cập. Nếu bạn chọn phạm vi cấp cao nhất, bạn không cần chọn từng phạm vi.
         setting_aggregate_reblogs: Đừng hiện những chia sẻ mới cho những tút đã chia sẻ gần đây (chỉ ảnh hưởng đến các chia sẻ mới)
-        setting_default_sensitive: Ảnh & video nhạy cảm được ẩn theo mặc định và có thể được hiển thị bằng một cú nhấp chuột
+        setting_default_sensitive: Ảnh/video/âm thanh nhạy cảm được ẩn theo mặc định và chỉ hiển thị nếu nhấp chuột
         setting_display_media_default: Ẩn ảnh hoặc video được đánh dấu là nhạy cảm
         setting_display_media_hide_all: Luôn ẩn ảnh và video
         setting_display_media_show_all: Luôn hiện ảnh và video
-        setting_hide_network: Bạn mến mộ ai và ai mến mộ bạn sẽ không được hiển thị trên hồ sơ của bạn
+        setting_hide_network: Bạn theo dõi ai và ai theo dõi bạn sẽ không được hiển thị trên hồ sơ của bạn
         setting_noindex: Ảnh hưởng đến trang cá nhân và tút của bạn
         setting_show_application: Tên ứng dụng bạn sử dụng để đăng tút sẽ được hiển thị trong chi tiết bài đăng
         setting_use_blurhash: Hình ảnh mờ dựa trên màu sắc của hình ảnh nhạy cảm nhưng sẽ che hết chi tiết
@@ -101,7 +101,7 @@ vi:
         starts_at: Bắt đầu sự kiện
         text: Thông báo
       defaults:
-        autofollow: Mời mến mộ tài khoản của bạn
+        autofollow: Mời theo dõi tài khoản của bạn
         avatar: Ảnh đại diện
         bot: Đây là tài khoản bot
         chosen_languages: Chọn ngôn ngữ
@@ -147,7 +147,7 @@ vi:
         setting_system_font_ui: Sử dụng phông chữ mặc định của hệ thống
         setting_theme: Giao diện trang web
         setting_trends: Hiển thị xu hướng hôm nay
-        setting_unfollow_modal: Yêu cầu xác nhận trước khi hủy mến mộ ai đó
+        setting_unfollow_modal: Yêu cầu xác nhận trước khi hủy theo dõi ai đó
         setting_use_blurhash: Làm mờ trước ảnh/video nhạy cảm
         setting_use_pending_items: Không tự động cập nhật bảng tin
         severity: Mức độ nghiêm trọng
@@ -161,9 +161,9 @@ vi:
       featured_tag:
         name: Hashtag
       interactions:
-        must_be_follower: Chặn thông báo từ những người không mến mộ bạn
-        must_be_following: Chặn thông báo từ những người bạn không mến mộ
-        must_be_following_dm: Chặn tin nhắn từ những người bạn không mến mộ
+        must_be_follower: Chặn thông báo từ những người không theo dõi bạn
+        must_be_following: Chặn thông báo từ những người bạn không theo dõi
+        must_be_following_dm: Chặn tin nhắn từ những người bạn không theo dõi
       invite:
         comment: Bình luận
       invite_request:
@@ -171,8 +171,8 @@ vi:
       notification_emails:
         digest: Gửi email định kỳ
         favourite: Ai đó tâm đắc tút của bạn
-        follow: Ai đó mến mộ bạn
-        follow_request: Ai đó yêu cầu mến mộ bạn
+        follow: Ai đó theo dõi bạn
+        follow_request: Ai đó yêu cầu theo dõi bạn
         mention: Ai đó nhắc đến bạn
         pending_account: Có tài khoản mới cần phê duyệt
         reblog: Ai đó chia sẻ tút của bạn
diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml
index 3b581da6e..6bb1053a8 100644
--- a/config/locales/simple_form.zh-CN.yml
+++ b/config/locales/simple_form.zh-CN.yml
@@ -55,8 +55,8 @@ zh-CN:
       domain_allow:
         domain: 该站点将能够从该服务器上拉取数据,并且从那里发过来的数据也会被处理和存储。
       email_domain_block:
-        domain: 这里可以是邮箱地址中的域名部分、域名解析到的 MX 记录,或者 MX 记录解析到的域名。这些检查会在用户注册时进行,如果在黑名单中,那么注册会被拒绝。
-        with_dns_records: Mastodon 会尝试解析所给域名的 DNS 记录,然后把解析结果一并加入黑名单
+        domain: 这里可以是邮箱地址中的域名部分、域名解析到的 MX 记录,或者 MX 记录解析到的域名。这些检查会在用户注册时进行,如果邮箱域名被封禁,那么注册会被拒绝。
+        with_dns_records: Mastodon 会尝试解析所给域名的 DNS 记录,然后把解析结果一并封禁
       featured_tag:
         name: 你可能想要使用以下之一:
       form_challenge:
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index c2de32f97..ebedfb4f9 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -21,9 +21,7 @@ sv:
     federation_hint_html: Med ett konto på %{instance} kommer du att kunna följa personer på alla Mastodon-servers och mer än så.
     get_apps: Prova en mobilapp
     hosted_on: Mastodon-värd på %{domain}
-    instance_actor_flash: 'Detta konto är en virtuell agent som används för att representera servern själv och inte någon individuell användare. Det används av sammanslutningsskäl och ska inte blockeras såvitt du inte vill blockera hela instansen, och för detta fall ska domänblockering användas.
-
-'
+    instance_actor_flash: Detta konto är en virtuell agent som används för att representera servern själv och inte någon individuell användare. Det används av sammanslutningsskäl och ska inte blockeras såvitt du inte vill blockera hela instansen, och för detta fall ska domänblockering användas.
     learn_more: Lär dig mer
     privacy_policy: Integritetspolicy
     see_whats_happening: Se vad som händer
diff --git a/config/locales/th.yml b/config/locales/th.yml
index cb6e93f78..f5bab5d30 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -31,7 +31,7 @@ th:
     status_count_before: ผู้สร้าง
     tagline: ติดตามเพื่อน ๆ และค้นพบเพื่อนใหม่ ๆ
     terms: เงื่อนไขการให้บริการ
-    unavailable_content: เนื้อหาไม่พร้อมใช้งาน
+    unavailable_content: เซิร์ฟเวอร์ที่มีการควบคุม
     unavailable_content_description:
       domain: เซิร์ฟเวอร์
       reason: เหตุผล
@@ -528,6 +528,7 @@ th:
         title: สื่อ
       no_media: ไม่มีสื่อ
       title: สถานะบัญชี
+      with_media: มีสื่อ
     tags:
       context: บริบท
       directory: ในไดเรกทอรี
@@ -781,6 +782,10 @@ th:
     set_redirect: ตั้งการเปลี่ยนเส้นทาง
   moderation:
     title: การควบคุม
+  move_handler:
+    carry_blocks_over_text: ผู้ใช้นี้ได้ย้ายจาก %{acct} ซึ่งคุณได้ปิดกั้น
+    carry_mutes_over_text: ผู้ใช้นี้ได้ย้ายจาก %{acct} ซึ่งคุณได้ซ่อน
+    copy_account_note_text: 'ผู้ใช้นี้ได้ย้ายจาก %{acct} นี่คือหมายเหตุก่อนหน้าของคุณเกี่ยวกับผู้ใช้:'
   notification_mailer:
     digest:
       action: ดูการแจ้งเตือนทั้งหมด
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index 41c39ba1f..650166781 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -40,6 +40,7 @@ tr:
       domain: Sunucu
       reason: Sebep
       rejecting_media: 'Bu sunuculardaki medya dosyaları işlenmeyecek ya da saklanmayacak, ve hiçbir küçük resim gösterilmeyecektir, dolayısıyla orjinal dosyaya manuel tıklama gerekecektir:'
+      rejecting_media_title: Filtrelenmiş medya
       silenced: 'Bu sunuculardan gelen gönderiler genel zaman çizelgelerinde ve konuşmalarda gizlenecek ve siz onları takip etmediğiniz sürece, kullanıcıların etkileşimlerinden hiçbir bildirim alınmayacaktır:'
       suspended: 'Bu sunuculardaki hiçbir veri işlenmeyecek, saklanmayacak veya değiş tokuş edilmeyecektir, dolayısıyla bu sunuculardaki kullanıcılarla herhangi bir etkileşim ya da iletişim imkansız olacaktır:'
     unavailable_content_html: Mastodon, genel olarak fediverse'teki herhangi bir sunucudan içerik görüntülemenize ve kullanıcılarıyla etkileşim kurmanıza izin verir. Bunlar, bu sunucuda yapılmış olan istisnalardır.
@@ -236,6 +237,9 @@ tr:
         update_custom_emoji: "%{name} %{target} emojiyi güncelledi"
         update_status: "%{name}, %{target} kullanıcısının durumunu güncelledi"
       deleted_status: "(silinmiş durum)"
+      empty: Kayıt bulunamadı.
+      filter_by_action: Eyleme göre filtre
+      filter_by_user: Kullanıcıya göre filtre
       title: Denetim günlüğü
     announcements:
       destroyed_msg: Duyuru başarıyla silindi!
@@ -364,6 +368,7 @@ tr:
       destroyed_msg: E-posta alan adı kara listeden başarıyla silindi
       domain: Alan adı
       empty: Şu anda hiçbir e-posta alan adı kara listeye alınmadı.
+      from_html: "%{domain} alan adından"
       new:
         create: Alan adı ekle
         title: Yeni e-posta kara liste girişi
@@ -543,6 +548,9 @@ tr:
       trends:
         desc_html: Şu anda trend olan ve daha önce incelenen etiketleri herkese açık olarak göster
         title: Trend etiketler
+    site_uploads:
+      delete: Yüklenen dosyayı sil
+      destroyed_msg: Site yüklemesi başarıyla silindi!
     statuses:
       back_to_account: Hesap sayfasına geri dön
       batch:
@@ -596,6 +604,7 @@ tr:
     add_new: Takma ad oluştur
     created_msg: Yeni takma ad başarıyla oluşturuldu. Artık eski hesaptan taşınmayı başlatabilirsiniz.
     deleted_msg: Yeni takma ad başarıyla kaldırıldı. O hesaptan bu hesaba taşınmak artık mümkün değil.
+    empty: Takma adınız yok.
     hint_html: Başka bir hesaptan bu hesaba taşınmak istiyorsanız, takipçileri eski hesaptan bu hesaba taşımadan önce gerekli olan takma adı burada oluşturabilirsiniz. Bu eylem kendi başına <strong>zararsızdır ve geri döndürülebilir</strong>. <strong>Hesap taşıma işlemi eski hesaptan başlatılır</strong>.
     remove: Takma adların bağlantısını kaldır
   appearance:
@@ -1063,6 +1072,9 @@ tr:
     spam_detected: Bu otomatik bir şikayettir. Spam tespit edildi.
   statuses:
     attached:
+      audio:
+        one: "%{count} ses"
+        other: "%{count} ses"
       description: 'Ekli: %{attached}'
       image:
         one: "%{count} görsel"
@@ -1259,6 +1271,7 @@ tr:
     follow_limit_reached: "%{limit} kişiden daha fazlasını takip edemezsiniz"
     invalid_email: E-posta adresiniz geçersiz
     invalid_otp_token: İki-faktörlü kodunuz geçersiz
+    invalid_sign_in_token: Geçersiz güvenlik kodu
     otp_lost_help_html: Her ikisine de erişiminizi kaybettiyseniz, %{email} ile irtibata geçebilirsiniz
     seamless_external_login: Harici bir servis aracılığıyla oturum açtınız, bu nedenle parola ve e-posta ayarları mevcut değildir.
     signed_in_as: 'Giriş yapan:'
diff --git a/config/locales/ug.yml b/config/locales/ug.yml
new file mode 100644
index 000000000..7b709a35e
--- /dev/null
+++ b/config/locales/ug.yml
@@ -0,0 +1,20 @@
+---
+ug:
+  errors:
+    '400': The request you submitted was invalid or malformed.
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '406': This page is not available in the requested format.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Too many requests
+    '500': 
+    '503': The page could not be served due to a temporary server failure.
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index 6ff21b068..7b13c40c0 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -21,9 +21,7 @@ uk:
     federation_hint_html: З обліковим записом на %{instance} ви зможете слідкувати за людьми на будь-якому сервері Mastodon та поза ним.
     get_apps: Спробуйте мобільний додаток
     hosted_on: Mastodon розміщено на %{domain}
-    instance_actor_flash: 'Цей обліковий запис є віртуальною особою, яка використовується для представлення самого сервера, а не певного користувача. Він використовується для потреб федерації і не повинен бути заблокований, якщо тільки ви не хочете заблокувати весь сервер, у цьому випадку ви повинні скористатися блокуванням домену.
-
-'
+    instance_actor_flash: Цей обліковий запис є віртуальною особою, яка використовується для представлення самого сервера, а не певного користувача. Він використовується для потреб федерації і не повинен бути заблокований, якщо тільки ви не хочете заблокувати весь сервер, у цьому випадку ви повинні скористатися блокуванням домену.
     learn_more: Дізнатися більше
     privacy_policy: Політика приватності
     see_whats_happening: Погляньте, що відбувається
@@ -42,8 +40,11 @@ uk:
       domain: Сервер
       reason: Причина
       rejecting_media: 'Медіа файли з цих серверів не будуть оброблятися або зберігатись, а мініатюри відображатись. Щоб побачити оригінальний файл, треба буде натиснути на посилання:'
+      rejecting_media_title: Відфільтровані медіа
       silenced: 'Повідомлення з цих серверів будуть приховані в публічних стрічках та розмовах, також ви не отримуватимете сповіщень щодо взаємодій з їх користувачами, якщо ви їх не відстежуєте:'
+      silenced_title: Заглушені сервери
       suspended: 'Жодна інформація з цих серверів не буде оброблена, збережена чи передана, що робить спілкування з користувачами цих серверів неможливим:'
+      suspended_title: Призупинені сервери
     unavailable_content_html: Mastodon зазвичай дозволяє вам взаємодіяти з користувачами будь-яких серверів в Федіверсі та переглядати їх контент. Ось винятки, які було зроблено на цьому конкретному сервері.
     user_count_after:
       few: користувача
@@ -313,6 +314,7 @@ uk:
       listed: У списку
       new:
         title: Додати новий емодзі
+      not_permitted: Вам не дозволено виконувати цю дію
       overwrite: Переписати
       shortcode: Шорткод
       shortcode_hint: Мінімум два символи, тільки цифрові й латинські символи або підкреслення
@@ -595,6 +597,7 @@ uk:
         title: Популярні хештеги
     site_uploads:
       delete: Видалити завантажений файл
+      destroyed_msg: Завантаження сайту успішно видалено!
     statuses:
       back_to_account: Назад до сторінки облікового запису
       batch:
@@ -734,6 +737,10 @@ uk:
     hint_html: "<strong>Підказка:</strong> ми не будемо запитувати ваш пароль впродовж наступної години."
     invalid_password: Невірний пароль
     prompt: Підтвердіть пароль для продовження
+  crypto:
+    errors:
+      invalid_key: не є припустимим ключем Ed25519 або Curve25519
+      invalid_signature: не є дійсним підписом Ed25519
   date:
     formats:
       default: "%b %d, %Y"
@@ -935,6 +942,7 @@ uk:
     on_cooldown: Нещодавно ви вже перенесли ваш обліковий запис. Функція переносу стане доступною знову через %{count} днів.
     past_migrations: Попередні міграції
     proceed_with_move: Перемістити підписників
+    redirected_msg: Ваш обліковий запис зараз перенаправляється до %{acct}.
     redirecting_to: Ваш обліковий запис перенаправляється до %{acct}.
     set_redirect: Встановити перенаправлення
     warning:
@@ -948,6 +956,10 @@ uk:
       redirect: Профіль цього облікового запису буде оновлено з заміткою про перенаправлення, а також виключений з пошуку
   moderation:
     title: Модерація
+  move_handler:
+    carry_blocks_over_text: Цей користувач переїхав з %{acct}, який ви заблокували.
+    carry_mutes_over_text: Цей користувач переїхав з %{acct}, який ви заглушили.
+    copy_account_note_text: 'Цей користувач був переміщений з %{acct}, ось ваші попередні нотатки:'
   notification_mailer:
     digest:
       action: Показати усі сповіщення
@@ -1217,6 +1229,12 @@ uk:
       explanation: Ви робили запит повної резервної копії вашого облікового запису Mastodon. Вона вже готова для завантаження!
       subject: Ваш архів готовий до завантаження
       title: Винесення архіву
+    sign_in_token:
+      details: 'Детальніше про спробу входу:'
+      explanation: 'Ми виявили спробу входу до вашого облікового запису з невідомої IP-адреси. Якщо це ви, будь ласка, введіть наведений нижче код безпеки на сторінці входу:'
+      further_actions: 'Якщо це були не ви, будь ласка, змініть свій пароль та увімкніть двофакторну автентифікацію для вашого облікового запису. Ви можете зробити це тут:'
+      subject: Будь ласка, підтвердіть спробу входу
+      title: Спроба входу
     warning:
       explanation:
         disable: Поки ваш обліковий запис заморожений, його дані залишаються незмінними. Проте ви не зможете виконувати будь-які дії над обліковим записом, доки його не буде розблоковано.
@@ -1254,11 +1272,14 @@ uk:
       title: Ласкаво просимо, %{name}!
   users:
     follow_limit_reached: Не можна слідкувати більш ніж за %{limit} людей
+    generic_access_help_html: Не вдається отримати доступ до облікового запису? Ви можете зв'язатися з %{email} для допомоги
     invalid_email: Введена адреса e-mail неправильна
     invalid_otp_token: Введено неправильний код
+    invalid_sign_in_token: Хибний код безпеки
     otp_lost_help_html: Якщо ви втратили доступ до обох, ви можете отримати доступ з %{email}
     seamless_external_login: Ви увійшли за допомогою зовнішнього сервісу, тому налаштування паролю та електронної пошти недоступні.
     signed_in_as: 'Ви увійшли як:'
+    suspicious_sign_in_confirmation: Здається, ви не входили до цього облікового запису з цього пристрою, а також не входили взагалі деякий час, таким чином ми надсилаємо код безпеки на вашу адресу електронної пошти, щоб підтвердити, що це ви.
   verification:
     explanation_html: 'Володіння посиланнями у профілі <strong>можна підтвердити</strong>. Для цього на зазначеному сайті повинна міститися посилання на ваш профіль Mastodon, а у самому посиланні <strong>повинен</strong> бути атрибут <code>rel="me"</code>. Що всередині посилання - значення не має. Ось вам приклад посилання:'
     verification: Підтвердження
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index 853a1ee13..1b5cfe1d1 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -3,27 +3,25 @@ vi:
   about:
     about_hashtag_html: Đây là các tút công khai được gắn thẻ <strong>#%{hashtag}</strong>. Chỉ cần bạn có tài khoản ở bất cứ đâu trong mạng liên kết là bạn có thể tương tác với chúng.
     about_mastodon_html: 'Mạng xã hội của tương lai: Không quảng cáo, không theo dõi người dùng và phi tập quyền! Làm chủ quyền riêng tư của bạn với Mastodon!'
-    about_this: Giới thiệu
+    about_this: Trong khoảng
     active_count_after: hoạt động
     active_footnote: Người dùng hoạt động hàng tháng
     administered_by: 'Quản trị viên:'
     api: API
-    apps: App điện thoại
-    apps_platforms: Sử dụng Mastodon trên iOS, Android và các nền tảng khác
-    browse_directory: Duyệt danh sách thành viên để tìm bạn bè
+    apps: Ứng dụng di động
+    apps_platforms: Lướt Mastodon trên iOS, Android và các nền tảng khác
+    browse_directory: Những ai đã tham gia máy chủ này?
     browse_local_posts: Xem thử những tút công khai gần đây
     browse_public_posts: Xem thử những tút công khai trên mạng Mastodon
-    contact: 'Liên lạc:'
+    contact: Liên lạc
     contact_missing: Chưa thiết lập
     contact_unavailable: N/A
     discover_users: Khám phá người dùng
     documentation: Tài liệu
-    federation_hint_html: Với tài khoản trên %{instance}, bạn sẽ có thể giao tiếp với mọi người trên bất kỳ máy chủ Mastodon nào và hơn thế nữa.
+    federation_hint_html: Đăng ký tài khoản %{instance}, bạn có thể giao tiếp với mọi người trên bất kỳ máy chủ Mastodon nào và hơn thế nữa.
     get_apps: Dùng thử ứng dụng di động
     hosted_on: "%{domain} vận hành nhờ Mastodon"
-    instance_actor_flash: 'Tài khoản này là một tác nhân ảo được sử dụng để đại diện cho chính máy chủ chứ không phải bất kỳ người dùng cá nhân nào. Nó được sử dụng cho mục đích liên kết và không nên bị chặn trừ khi bạn muốn chặn toàn bộ máy chủ.
-
-'
+    instance_actor_flash: Tài khoản này là một tác nhân ảo được sử dụng để đại diện cho chính máy chủ chứ không phải bất kỳ người dùng cá nhân nào. Nó được sử dụng cho mục đích liên kết và không nên bị chặn trừ khi bạn muốn chặn toàn bộ máy chủ.
     learn_more: Tìm hiểu thêm
     privacy_policy: Chính sách bảo mật
     see_whats_happening: Xem những gì đang xảy ra
@@ -39,37 +37,40 @@ vi:
       domain: Máy chủ
       reason: Lý do
       rejecting_media: 'Ảnh và video từ những máy chủ sau sẽ không được xử lý, lưu trữ và hiển thị hình thu nhỏ, bắt buộc nhấp thủ công vào tệp gốc để xem:'
-      silenced: 'Tút từ những máy chủ sau sẽ bị ẩn trên bảng tin, trong tin nhắn và không có thông báo nào được tạo từ các tương tác của người dùng của họ, trừ khi bạn có mến mộ người dùng của họ:'
+      rejecting_media_title: Ảnh và các thứ đã lọc
+      silenced: 'Tút từ những máy chủ sau sẽ bị ẩn trên bảng tin, trong tin nhắn và không có thông báo nào được tạo từ các tương tác của người dùng của họ, trừ khi bạn có theo dõi người dùng của họ:'
+      silenced_title: Những máy chủ đã bị tạm ẩn
       suspended: 'Những máy chủ sau sẽ không được xử lý, lưu trữ hoặc trao đổi nội dung. Mọi tương tác hoặc giao tiếp với người dùng từ các máy chủ này cũng bị cấm:'
+      suspended_title: Những máy chủ bị vô hiệu hóa
     unavailable_content_html: Mastodon cho phép bạn xem nội dung và tương tác với người dùng từ bất kỳ máy chủ nào khác trong mạng liên kết. Còn máy chủ này có những ngoại lệ riêng.
     user_count_after:
       other: người dùng
     user_count_before: Nhà của
     what_is_mastodon: Mastodon là gì?
   accounts:
-    choices_html: 'Những người %{name} đang mến mộ:'
-    endorsements_hint: Bạn có thể vinh danh những người bạn mến mộ và họ sẽ hiển thị ở giao diện web.
+    choices_html: 'Những người %{name} theo dõi:'
+    endorsements_hint: Bạn có thể vinh danh những người bạn theo dõi và họ sẽ hiển thị ở giao diện web.
     featured_tags_hint: Bạn có thể cho biết những hashtag thường dùng ở đây.
-    follow: Mến mộ
+    follow: Theo dõi
     followers:
-      other: Người mến mộ
-    following: Đang mến mộ
+      other: Người theo dõi
+    following: Đang theo dõi
     joined: Đã tham gia %{date}
     last_active: hoạt động gần đây
     link_verified_on: Liên kết này đã được xác thực quyền sở hữu vào %{date}
-    media: Ảnh & video
+    media: Bộ sưu tập
     moved_html: "%{name} đã dời sang %{new_profile_link}:"
     network_hidden: Thông tin này không còn tồn tại
     never_active: Chưa có
     nothing_here: Chưa đăng tút nào cả!
-    people_followed_by: Những người mà %{name} mến mộ
-    people_who_follow: Những người mến mộ %{name}
+    people_followed_by: Những người %{name} theo dõi
+    people_who_follow: Những người theo dõi %{name}
     pin_errors:
-      following: Để vinh danh người nào đó, bạn cần mến mộ họ trước
+      following: Để vinh danh người nào đó, bạn phải theo dõi họ trước
     posts:
       other: Tút
     posts_tab_heading: Tút
-    posts_with_replies: Phản hồi
+    posts_with_replies: Trả lời
     reserved_username: Tên người dùng đã có rồi
     roles:
       admin: Quản trị viên
@@ -77,7 +78,7 @@ vi:
       group: Nhóm
       moderator: Kiểm duyệt viên
     unavailable: Tài khoản không còn nữa
-    unfollow: Bỏ mến mộ
+    unfollow: Ngưng theo dõi
   admin:
     account_actions:
       action: Thực hiện các hành động
@@ -116,8 +117,8 @@ vi:
       email_status: Trạng thái email
       enable: Phê duyệt
       enabled: Đã duyệt
-      followers: Người mến mộ
-      follows: Đang mến mộ
+      followers: Người theo dõi
+      follows: Đang theo dõi
       header: Ảnh bìa
       inbox_url: URL hộp thư đến
       invited_by: Được mời bởi
@@ -360,7 +361,7 @@ vi:
         create: Tạo chặn
         hint: Chặn máy chủ sẽ không ngăn việc hiển thị tút của máy chủ đó trong cơ sở dữ liệu, nhưng sẽ khiến tự động áp dụng các phương pháp kiểm duyệt cụ thể trên các tài khoản đó.
         severity:
-          desc_html: "<strong>Tạm ẩn</strong> sẽ làm cho bài đăng của tài khoản trở nên vô hình đối với bất kỳ ai không mến mộ họ. <strong>Vô hiệu hóa</strong> sẽ xóa tất cả nội dung, phương tiện và dữ liệu khác của tài khoản. Sử dụng <strong>Cấm upload</strong> nếu bạn chỉ muốn cấm tải lên ảnh và video."
+          desc_html: "<strong>Tạm ẩn</strong> sẽ làm cho bài đăng của tài khoản trở nên vô hình đối với bất kỳ ai không theo dõi họ. <strong>Vô hiệu hóa</strong> sẽ xóa tất cả nội dung, phương tiện và dữ liệu khác của tài khoản. Sử dụng <strong>Cấm upload</strong> nếu bạn chỉ muốn cấm tải lên ảnh và video."
           noop: Không hoạt động
           silence: Tạm ẩn
           suspend: Vô hiệu hóa
@@ -413,8 +414,8 @@ vi:
       public_comment: Bình luận công khai
       title: Mạng liên kết
       total_blocked_by_us: Bị chặn bởi chúng ta
-      total_followed_by_them: Được họ mến mộ
-      total_followed_by_us: Được chúng ta mến mộ
+      total_followed_by_them: Được họ theo dõi
+      total_followed_by_us: Được quản trị viên theo dõi
       total_reported: Báo cáo tổng hợp
       total_storage: Ảnh và video
     invites:
@@ -432,7 +433,7 @@ vi:
     relays:
       add_new: Thêm liên hợp mới
       delete: Loại bỏ
-      description_html: "<strong>Liên hợp</strong> nghĩa là cho phép bài đăng công khai của máy chủ này xuất hiện trên bảng tin của máy chủ khác và ngược lại. <strong>Nó giúp các máy chủ vừa và nhỏ tiếp cận nội dung từ các máy chủ lớn hơn</strong>. Nếu không chọn, người dùng ở máy chủ này vẫn có thể mến mộ người dùng khác trên các máy chủ khác."
+      description_html: "<strong>Liên hợp</strong> nghĩa là cho phép bài đăng công khai của máy chủ này xuất hiện trên bảng tin của máy chủ khác và ngược lại. <strong>Nó giúp các máy chủ vừa và nhỏ tiếp cận nội dung từ các máy chủ lớn hơn</strong>. Nếu không chọn, người dùng ở máy chủ này vẫn có thể theo dõi người dùng khác trên các máy chủ khác."
       disable: Tắt
       disabled: Đã tắt
       enable: Kích hoạt
@@ -487,7 +488,7 @@ vi:
         title: Công khai số liệu thống kê về hoạt động người dùng
       bootstrap_timeline_accounts:
         desc_html: Tách tên người dùng bằng dấu phẩy. Chỉ có hiệu lực với các tài khoản công khai thuộc máy chủ. Mặc định khi trống là tất cả quản trị viên.
-        title: Gợi ý mến mộ cho người dùng mới
+        title: Gợi ý theo dõi cho người dùng mới
       contact_information:
         email: Email liên hệ
         username: Tên tài khoản liên hệ
@@ -505,7 +506,7 @@ vi:
       domain_blocks_rationale:
         title: Hiển thị lý do
       enable_bootstrap_timeline_accounts:
-        title: Gợi ý mến mộ cho người dùng mới
+        title: Gợi ý theo dõi cho người dùng mới
       hero:
         desc_html: Hiển thị trên trang chủ. Kích cỡ tối thiểu 600x100px. Khi không được đặt, sử dụng hình thu nhỏ của máy chủ
         title: Hình ảnh giới thiệu
@@ -584,7 +585,7 @@ vi:
       deleted: Đã xóa
       failed_to_execute: Không thể thực thi
       media:
-        title: Ảnh & video
+        title: Bộ sưu tập
       no_media: Không có ảnh hoặc video
       no_status_selected: Không có tút nào thay đổi vì không có tút nào được chọn
       title: Trạng thái tài khoản
@@ -661,14 +662,14 @@ vi:
   auth:
     apply_for_account: Đăng ký
     change_password: Mật khẩu
-    checkbox_agreement_html: Tôi đồng ý với các <a href="%{rules_path}" target="_blank">quy tắc</a> và <a href="%{terms_path}" target="_blank">điều khoản dịch vụ</a>.
+    checkbox_agreement_html: Tôi đồng ý với các <a href="%{rules_path}" target="_blank">quy tắc</a> và <a href="%{terms_path}" target="_blank">điều khoản dịch vụ</a>
     checkbox_agreement_without_rules_html: Tôi đồng ý với <a href="%{terms_path}" target="_blank">điều khoản dịch vụ</a>
     delete_account: Xóa tài khoản
     delete_account_html: Nếu bạn muốn xóa tài khoản của mình, hãy <a href="%{path}">yêu cầu tại đây</a>. Bạn sẽ được yêu cầu xác nhận.
     description:
       prefix_invited_by_user: "@%{name} mời bạn tham gia máy chủ Mastodon này!"
       prefix_sign_up: Tham gia Mastodon ngay hôm nay!
-      suffix: Với tài khoản, bạn sẽ có thể mến mộ mọi người, đăng tút và nhắn tin với người dùng từ bất kỳ máy chủ Mastodon khác!
+      suffix: Với tài khoản, bạn sẽ có thể theo dõi mọi người, đăng tút và nhắn tin với người dùng từ bất kỳ máy chủ Mastodon khác!
     didnt_get_confirmation: Gửi lại email xác thực?
     forgot_password: Quên mật khẩu
     invalid_reset_password_token: Mã đặt lại mật khẩu không hợp lệ hoặc hết hạn. Vui lòng yêu cầu một cái mới.
@@ -698,17 +699,17 @@ vi:
       redirecting_to: Tài khoản của bạn không hoạt động vì hiện đang chuyển hướng đến %{acct}.
     trouble_logging_in: Gặp sự cố khi đăng nhập?
   authorize_follow:
-    already_following: Bạn đã mến mộ người dùng này
-    already_requested: Bạn vừa gửi một yêu cầu mến mộ tới người dùng này
+    already_following: Bạn đang theo dõi người dùng này
+    already_requested: Bạn vừa gửi một yêu cầu theo dõi tới người dùng này
     error: Rất tiếc, đã xảy ra lỗi khi tìm kiếm tài khoản từ nơi khác
-    follow: Mến mộ
-    follow_request: Bạn đã gửi yêu cầu mến mộ tới
-    following: Chúc mừng! Bạn đã trở thành người mến mộ của
+    follow: Theo dõi
+    follow_request: Bạn đã gửi yêu cầu theo dõi tới
+    following: Chúc mừng! Bạn đã trở thành người theo dõi của
     post_follow:
       close: Bạn có muốn đóng cửa sổ này?
       return: Hiện trên trang cá nhân
       web: Truy cập web
-    title: Mến mộ %{acct}
+    title: Theo dõi %{acct}
   challenge:
     confirm: Tiếp tục
     hint_html: "<strong>Mẹo:</strong> Chúng tôi sẽ không hỏi lại mật khẩu của bạn sau này."
@@ -720,7 +721,7 @@ vi:
       invalid_signature: không phải là chữ ký số Ed25519 đúng
   date:
     formats:
-      default: "%d.%m.%Y"
+      default: "%b.%-m.%Y"
   datetime:
     distance_in_words:
       about_x_hours: "%{count}h"
@@ -816,7 +817,7 @@ vi:
   footer:
     developers: Nhà phát triển
     more: Nhiều hơn
-    resources: Tham khảo
+    resources: Đọc
     trending_now: Xu hướng
   generic:
     all: Tất cả
@@ -861,7 +862,7 @@ vi:
     types:
       blocking: Danh sách chặn
       domain_blocking: Danh sách máy chủ đã chặn
-      following: Danh sách người mến mộ
+      following: Danh sách người theo dõi
       muting: Danh sách người dùng ẩn
     upload: Tải lên
   in_memoriam_html: Tưởng Niệm
@@ -897,7 +898,7 @@ vi:
   migrations:
     acct: Dời sang
     cancel: Hủy chuyển hướng
-    cancel_explanation: Hủy chuyển hướng sẽ kích hoạt lại tài khoản hiện tại của bạn, nhưng sẽ không chuyển được những người mến mộ ở tài khoản mới.
+    cancel_explanation: Hủy chuyển hướng sẽ kích hoạt lại tài khoản hiện tại của bạn, nhưng sẽ không chuyển được những người theo dõi ở tài khoản mới.
     cancelled_msg: Đã hủy chuyển hướng xong.
     errors:
       already_moved: là tài khoản bạn đã dời sang rồi
@@ -905,14 +906,14 @@ vi:
       move_to_self: không thể là tài khoản hiện tại
       not_found: không thể tìm thấy
       on_cooldown: Bạn đang trong thời gian chiêu hồi
-    followers_count: Số người mến mộ tại thời điểm dời sang
+    followers_count: Số người theo dõi tại thời điểm chuyển hướng
     incoming_migrations: Chuyển từ một tài khoản khác
     incoming_migrations_html: Để chuyển từ tài khoản khác sang tài khoản này, trước tiên bạn cần <a href="%{path}">tạo tham chiếu tài khoản</a>.
-    moved_msg: Tài khoản của bạn hiện đang chuyển hướng đến %{acct} và những người mến mộ bạn cũng đang được chuyển đi.
+    moved_msg: Tài khoản của bạn hiện đang chuyển hướng đến %{acct} và những người theo dõi bạn cũng sẽ được chuyển đi.
     not_redirecting: Tài khoản của bạn hiện không chuyển hướng đến bất kỳ tài khoản nào khác.
     on_cooldown: Gần đây bạn đã di chuyển tài khoản của bạn. Chức năng này sẽ trở nên khả dụng một lần nữa sau %{count} ngày.
     past_migrations: Những lần dời nhà cũ
-    proceed_with_move: Chuyển người mến mộ
+    proceed_with_move: Chuyển hướng người theo dõi
     redirected_msg: Tài khoản của bạn đã chuyển hướng đến %{acct}.
     redirecting_to: Tài khoản của bạn đang chuyển hướng đến %{acct}.
     set_redirect: Thiết lập chuyển hướng
@@ -921,13 +922,15 @@ vi:
       before: 'Trước khi tiếp tục, xin vui lòng đọc các lưu ý:'
       cooldown: Sau khi di chuyển, có thời gian chiêu hồi, trong đó bạn sẽ không thể di chuyển nữa
       disabled_account: Tài khoản hiện tại của bạn sẽ không thể sử dụng đầy đủ sau đó. Tuy nhiên, bạn sẽ có quyền truy cập để xuất dữ liệu cũng như kích hoạt lại.
-      followers: Hành động này sẽ chuyển tất cả người mến mộ từ tài khoản hiện tại sang tài khoản mới
+      followers: Hành động này sẽ chuyển tất cả người theo dõi từ tài khoản hiện tại sang tài khoản mới
       only_redirect_html: Ngoài ra, bạn có thể <a href="%{path}">đặt chuyển hướng trên trang cá nhân của bạn</a>.
       other_data: Dữ liệu khác sẽ không được di chuyển tự động
       redirect: Trang cá nhân hiện tại của bạn sẽ được cập nhật với thông báo chuyển hướng và bị loại khỏi các tìm kiếm
   moderation:
     title: Kiểm duyệt
   move_handler:
+    carry_blocks_over_text: Tài khoản này chuyển từ %{acct}, máy chủ mà bạn đã chặn trước đó.
+    carry_mutes_over_text: Tài khoản này chuyển từ %{acct}, máy chủ mà bạn đã ẩn trước đó.
     copy_account_note_text: 'Tài khoản này chuyển từ %{acct}, đây là ghi chú về họ trước đó:'
   notification_mailer:
     digest:
@@ -935,7 +938,7 @@ vi:
       body: Dưới đây là những tin nhắn bạn đã bỏ lỡ kể từ lần truy cập trước vào %{since}
       mention: "%{name} vừa nhắc đến bạn trong:"
       new_followers_summary:
-        other: Ngoài ra, bạn đã có %{count} người mến mộ mới trong khi đi chơi! Ngạc nhiên chưa!
+        other: Ngoài ra, bạn đã có %{count} người theo dõi mới trong khi đi chơi! Ngạc nhiên chưa!
       subject:
         other: "%{count} thông báo mới kể từ lần truy cập trước \U0001F418"
       title: Khi bạn offline...
@@ -944,14 +947,14 @@ vi:
       subject: "%{name} vừa tâm đắc tút của bạn"
       title: Lượt tâm đắc mới
     follow:
-      body: Bạn vừa mới được %{name} mến mộ
-      subject: "%{name} vừa mới mến mộ bạn"
-      title: Người mến mộ mới
+      body: Bạn vừa mới được %{name} theo dõi
+      subject: "%{name} vừa mới theo dõi bạn"
+      title: Người theo dõi mới
     follow_request:
-      action: Quản lý yêu cầu mến mộ
-      body: "%{name} vừa yêu cầu mến mộ bạn"
-      subject: 'Người mến mộ đang chờ đồng ý: %{name}'
-      title: Yêu cầu mến mộ mới
+      action: Quản lý yêu cầu theo dõi
+      body: "%{name} vừa yêu cầu theo dõi bạn"
+      subject: 'Người theo dõi đang chờ đồng ý: %{name}'
+      title: Yêu cầu theo dõi mới
     mention:
       action: Phản hồi
       body: 'Bạn vừa được nhắc đến bởi %{name} trong:'
@@ -968,7 +971,7 @@ vi:
   number:
     human:
       decimal_units:
-        format: "%n%A"
+        format: "%n%u"
         units:
           billion: B
           million: M
@@ -1003,8 +1006,8 @@ vi:
   relationships:
     activity: Hoạt động tài khoản
     dormant: Không có tương tác
-    followers: Người mến mộ bạn
-    following: Người bạn mến mộ
+    followers: Người này đang theo dõi bạn
+    following: Bạn đang theo dõi người này
     invited: Người bạn mời đăng ký
     last_active: Hoạt động lần cuối
     most_recent: Gần đây nhất
@@ -1012,27 +1015,27 @@ vi:
     mutual: Bằng Hữu
     primary: Sơ cấp
     relationship: Mối quan hệ
-    remove_selected_domains: Xóa hết người mến mộ từ các máy chủ đã chọn
-    remove_selected_followers: Xóa những người mến mộ đã chọn
-    remove_selected_follows: Hủy mến mộ người dùng đã chọn
+    remove_selected_domains: Xóa hết người theo dõi từ các máy chủ đã chọn
+    remove_selected_followers: Xóa những người theo dõi đã chọn
+    remove_selected_follows: Hủy theo dõi người dùng đã chọn
     status: Tình trạng tài khoản
   remote_follow:
-    acct: Nhập tên người dùng@máy chủ bạn muốn tương tác
+    acct: Nhập địa chỉ Mastodon của bạn (tên@máy chủ)
     missing_resource: Không thể tìm thấy URL chuyển hướng cần thiết cho tài khoản của bạn
-    no_account_html: Chưa có tài khoản? Bạn có thể <a href='%{sign_up_path}' target='_blank'>đăng ký tại đây</a>
+    no_account_html: Nếu chưa có tài khoản, bạn có thể <a href='%{sign_up_path}' target='_blank'>đăng ký tại đây</a>
     proceed: Tiến hành theo
-    prompt: 'Bạn sắp mến mộ:'
+    prompt: 'Bạn sắp theo dõi:'
     reason_html: "<strong>Tại sao bước này là cần thiết?</strong> <code>%{instance}</code> có thể không phải là máy chủ nơi bạn đã đăng ký, vì vậy chúng tôi cần chuyển hướng bạn đến máy chủ của bạn trước."
   remote_interaction:
     favourite:
-      proceed: Tiếp tục tâm đắc
-      prompt: 'Bạn tâm đắc tút này:'
+      proceed: Yêu thích tút này
+      prompt: Bạn có muốn tâm đắc tút này?
     reblog:
       proceed: Tiếp tục chia sẻ
-      prompt: 'Bạn chia sẻ tút này:'
+      prompt: Bạn có muốn chia sẻ tút này?
     reply:
-      proceed: Tiếp tục bình luận
-      prompt: 'Bạn bình luận tút này:'
+      proceed: Tiếp tục trả lời
+      prompt: Bạn có muốn trả lời tút này?
   scheduled_statuses:
     over_daily_limit: Bạn đã vượt quá giới hạn của các tút được lên lịch %{limit} cho ngày hôm đó
     over_total_limit: Bạn đã vượt quá giới hạn %{limit} của các tút được lên lịch
@@ -1097,7 +1100,7 @@ vi:
     notifications: Thông báo
     preferences: Chung
     profile: Trang cá nhân
-    relationships: Mến mộ
+    relationships: Lượt theo dõi
     two_factor_authentication: Xác thực hai bước
   spam_check:
     spam_detected: Đây là một báo cáo tự động. Đã phát hiện thư rác.
@@ -1115,7 +1118,7 @@ vi:
     disallowed_hashtags:
       other: 'chứa các hashtag bị cấm: %{tags}'
     errors:
-      in_reply_not_found: Bạn đang bình luận một tút không còn tồn tại.
+      in_reply_not_found: Bạn đang trả lời một tút không còn tồn tại.
     language_detection: Tự động phát hiện ngôn ngữ
     open_in_web: Mở trên web
     over_character_limit: vượt quá giới hạn %{max} ký tự
@@ -1136,7 +1139,7 @@ vi:
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Đóng
-      private_long: Chỉ người đã mến mộ mới xem được tút
+      private_long: Chỉ người theo dõi mới xem được tút
       public: Công khai
       public_long: Ai cũng có thể thấy
       unlisted: Mở
@@ -1156,7 +1159,7 @@ vi:
     mastodon-light: Mastodon (Sáng)
   time:
     formats:
-      default: "%b %d, %Y, %H:%M"
+      default: lúc %H:%M %b %d năm%_Y
       month: "%B %Y"
   two_factor_authentication:
     code_hint: Nhập mã được tạo bởi ứng dụng xác thực của bạn để xác nhận
@@ -1188,8 +1191,8 @@ vi:
     warning:
       explanation:
         disable: Nếu tài khoản của bạn bị đình chỉ, dữ liệu tài khoản của bạn vẫn còn nguyên, nhưng bạn không thể thực hiện bất kỳ hành động nào cho đến khi được mở khóa.
-        silence: Nếu tài khoản của bạn bị tạm ẩn, bạn có thể bị loại khỏi các bảng tin công khai, chỉ những người đã mến mộ bạn mới thấy tút của bạn. Tuy nhiên, những người khác vẫn có thể tiếp tục mến mộ bạn.
-        suspend: Tài khoản của bạn đã bị vô hiệu hóa. Tất cả tút và tập tin đã tải lên của bạn sẽ bị xóa khỏi máy chủ này lẫn các máy chủ nơi bạn có người mến mộ.
+        silence: Nếu tài khoản của bạn bị tạm ẩn, bạn có thể bị loại khỏi các bảng tin công khai, chỉ những người đã theo dõi bạn mới thấy tút của bạn. Tuy nhiên, những người khác vẫn có thể tiếp tục theo dõi bạn.
+        suspend: Tài khoản của bạn đã bị vô hiệu hóa. Tất cả tút và tập tin đã tải lên của bạn sẽ bị xóa khỏi máy chủ này lẫn các máy chủ nơi bạn có người theo dõi.
       get_in_touch: Bạn có thể trả lời e-mail này để liên hệ với đội ngũ của %{instance}.
       review_server_policies: Xem lại chính sách máy chủ
       statuses: 'Cụ thể, cho:'
@@ -1205,23 +1208,23 @@ vi:
         suspend: Toài khoản bị vô hiệu hóa
     welcome:
       edit_profile_action: Cài đặt trang cá nhân
-      edit_profile_step: Bạn có thể tùy chỉnh trang cá nhân của mình bằng cách tải lên ảnh đại diện, ảnh bìa, thay đổi tên hiển thị và hơn thế nữa. Nếu bạn muốn những người mến mộ mới phải được phê duyệt, hãy chuyển tài khoản sang trạng thái khóa.
+      edit_profile_step: Bạn có thể tùy chỉnh trang cá nhân của mình bằng cách tải lên ảnh đại diện, ảnh bìa, thay đổi tên hiển thị và hơn thế nữa. Nếu bạn muốn những người theo dõi mới phải được phê duyệt, hãy chuyển tài khoản sang trạng thái khóa.
       explanation: Dưới đây là một số mẹo để giúp bạn bắt đầu
       final_action: Viết tút mới
-      final_step: 'Viết tút mới! Ngay cả khi không có người mến mộ, người khác vẫn có thể xem tút công khai của bạn trên bảng tin máy chủ và trong hashtag. Hãy giới thiệu bản thân với hashtag #introduction.'
+      final_step: 'Viết tút mới! Ngay cả khi chưa có người theo dõi, người khác vẫn có thể xem tút công khai của bạn trên bảng tin máy chủ và trong hashtag. Hãy giới thiệu bản thân với hashtag #introduction.'
       full_handle: Tên đầy đủ của bạn
       full_handle_hint: Đây cũng là địa chỉ được dùng để tương tác với tất cả mọi người.
       review_preferences_action: Tùy chỉnh giao diện
       review_preferences_step: Tùy chỉnh mọi thứ! Chẳng hạn như chọn loại email nào bạn muốn nhận hoặc trạng thái tút mà bạn muốn sử dụng mặc định. Hãy tắt tự động phát GIF nếu bạn hay bị chóng mặt.
       subject: Chào mừng đến với Mastodon
-      tip_federated_timeline: Mạng liên kết là một dạng "liên hợp quốc" của Mastodon. Hiểu một cách đơn giản, nó là những người bạn đã mến mộ từ các máy chủ khác.
-      tip_following: Theo mặc định, bạn sẽ mến mộ (các) quản trị viên máy chủ của bạn. Để tìm những người thú vị hơn, hãy xem qua bảng tin và mạng liên kết.
+      tip_federated_timeline: Mạng liên kết là một dạng "liên hợp quốc" của Mastodon. Hiểu một cách đơn giản, nó là những người bạn đã theo dõi từ các máy chủ khác.
+      tip_following: Theo mặc định, bạn sẽ theo dõi (các) quản trị viên máy chủ của bạn. Để tìm những người thú vị hơn, hãy xem qua bảng tin và mạng liên kết.
       tip_local_timeline: Bảng tin là nơi hiện lên những tút công khai của thành viên %{instance}. Họ là những người hàng xóm trực tiếp của bạn!
       tip_mobile_webapp: Nếu trình duyệt trên điện thoại di động của bạn thêm Mastodon vào màn hình chính, bạn có thể nhận được thông báo đẩy. Nó hoạt động gần giống như một app điện thoại!
       tips: Mẹo
       title: Xin chào %{name}!
   users:
-    follow_limit_reached: Bạn chỉ có thể mến mộ tối đa %{limit} người
+    follow_limit_reached: Bạn chỉ có thể theo dõi tối đa %{limit} người
     generic_access_help_html: Gặp trục trặc với tài khoản? Liên hệ %{email} để được trợ giúp
     invalid_email: Địa chỉ email không hợp lệ
     invalid_otp_token: Mã xác thực hai bước không hợp lệ
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index f93f51af3..3d62230d8 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -21,9 +21,7 @@ zh-CN:
     federation_hint_html: 在%{instance} 上拥有账号后,你可以关注任何 Mastodon 服务器或其他服务器上的人。
     get_apps: 尝试移动应用
     hosted_on: 一个在 %{domain} 上运行的 Mastodon 实例
-    instance_actor_flash: '这个账号是个虚拟帐号,不代表任何用户,只用来代表服务器本身。它用于和其它服务器互通,所以不应该被封禁,除非你想封禁整个实例。但是想封禁整个实例的时候,你应该用域名封禁。
-
-'
+    instance_actor_flash: 这个账号是个虚拟帐号,不代表任何用户,只用来代表服务器本身。它用于和其它服务器互通,所以不应该被封禁,除非你想封禁整个实例。但是想封禁整个实例的时候,你应该用域名封禁。
     learn_more: 了解详情
     privacy_policy: 隐私政策
     see_whats_happening: 看一看现在在发生什么
@@ -40,7 +38,7 @@ zh-CN:
       reason: 原因
       rejecting_media: 来自这些服务器的媒体文件将不会被处理或存储,缩略图也不会显示,需要手动点击打开原始文件。
       rejecting_media_title: 被过滤的媒体文件
-      silenced: 来自这些服务器上的帖子将不会出现在公共时间线和会话中;此外,除非你关注了这些服务器上的用户,否则他们的互动不会产生通知。
+      silenced: 来自这些服务器上的帖子将不会出现在公共时间线和会话中;此外,除非你关注了这些服务器上的用户,否则这些用户的互动不会产生通知。
       silenced_title: 已隐藏的服务器
       suspended: 这些服务器的数据将不会被处理、存储或者交换,本站也将无法和来自这些服务器的用户互动或者交流。
       suspended_title: 已封禁的服务器
@@ -91,7 +89,7 @@ zh-CN:
       delete: 删除
       destroyed_msg: 管理备忘删除成功!
     accounts:
-      add_email_domain_block: 把电子邮箱域名加入黑名单
+      add_email_domain_block: 封禁电子邮箱域名
       approve: 批准
       approve_all: 批准全部
       are_you_sure: 你确定吗?
@@ -192,7 +190,7 @@ zh-CN:
       username: 用户名
       warn: 警告
       web: 站内页面
-      whitelisted: 已加入白名单
+      whitelisted: 允许跨站交互
     action_logs:
       action_types:
         assigned_to_self_report: 指派举报
@@ -237,13 +235,13 @@ zh-CN:
         create_account_warning: "%{name} 向 %{target} 发送了警告"
         create_announcement: "%{name} 创建了新公告 %{target}"
         create_custom_emoji: "%{name} 添加了新的自定义表情 %{target}"
-        create_domain_allow: "%{name} 添加了对域名 %{target} 的白名单。"
+        create_domain_allow: "%{name} 允许了和域名 %{target} 的跨站交互"
         create_domain_block: "%{name} 屏蔽了域名 %{target}"
         create_email_domain_block: "%{name} 屏蔽了电子邮件域名 %{target}"
         demote_user: "%{name} 对用户 %{target} 进行了降任操作"
         destroy_announcement: "%{name} 删除了公告 %{target}"
         destroy_custom_emoji: "%{name} 销毁了自定义表情 %{target}"
-        destroy_domain_allow: "%{name} 从白名单中移除了域名 %{target}"
+        destroy_domain_allow: "%{name} 拒绝了和 %{target} 跨站交互"
         destroy_domain_block: "%{name} 解除了对域名 %{target} 的屏蔽"
         destroy_email_domain_block: "%{name} 解除了对电子邮件域名 %{target} 的屏蔽"
         destroy_status: "%{name} 删除了 %{target} 的嘟文"
@@ -340,18 +338,18 @@ zh-CN:
       single_user_mode: 单用户模式
       software: 软件
       space: 存储使用情况
-      title: 仪表盘
+      title: 信息面板
       total_users: 总用户数
       trends: 趋势
       week_interactions: 本周互动数
       week_users_active: 本周活跃用户数
       week_users_new: 本周新用户数
-      whitelist_mode: 白名单模式
+      whitelist_mode: 限联模式
     domain_allows:
-      add_new: 白名单域名
-      created_msg: 域名已被列入白名单
-      destroyed_msg: 域名已从白名单中移除
-      undo: 从白名单中移除
+      add_new: 允许和域名跨站交互
+      created_msg: 域名已被允许跨站交互
+      destroyed_msg: 域名已被禁止跨站交互
+      undo: 不允许和该域名跨站交互
     domain_blocks:
       add_new: 添加新屏蔽域名
       created_msg: 正在进行域名屏蔽
@@ -397,7 +395,7 @@ zh-CN:
       delete: 删除
       destroyed_msg: 电子邮件域名屏蔽删除成功
       domain: 域名
-      empty: 当前没有邮件域名黑名单。
+      empty: 当前没有邮件域名被封禁。
       from_html: 来自 %{domain}
       new:
         create: 添加域名
@@ -415,9 +413,9 @@ zh-CN:
       private_comment: 私密评论
       public_comment: 公开评论
       title: 已知实例
-      total_blocked_by_us: 被我方屏蔽的
+      total_blocked_by_us: 被我站屏蔽的
       total_followed_by_them: 被对方关注的
-      total_followed_by_us: 被我方关注的
+      total_followed_by_us: 被我站关注的
       total_reported: 关于对方的举报
       total_storage: 媒体文件
     invites:
@@ -445,7 +443,7 @@ zh-CN:
       pending: 等待中继站的确认
       save_and_enable: 保存并启用
       setup: 设置中继连接
-      signatures_not_enabled: 安全模式或白名单模式启用时,中继将不会正常工作
+      signatures_not_enabled: 安全模式或限联模式启用时,中继将不会正常工作
       status: 状态
       title: 中继站
     report_notes:
@@ -678,7 +676,7 @@ zh-CN:
     login: 登录
     logout: 登出
     migrate_account: 迁移到另一个帐户
-    migrate_account_html: 如果你希望引导他人关注另一个帐户,请<a href="%{path}">点击这里进行设置</a>。
+    migrate_account_html: 如果你希望引导别人关注另一个帐户,请<a href="%{path}">点击这里进行设置</a>。
     or_log_in_with: 或通过其他方式登录
     providers:
       cas: CAS
@@ -884,7 +882,7 @@ zh-CN:
     max_uses:
       other: "%{count} 次"
     max_uses_prompt: 无限制
-    prompt: 生成分享链接,邀请他人在本服务器注册
+    prompt: 生成分享链接,邀请别人在本服务器注册
     table:
       expires_at: 失效时间
       uses: 已使用次数
@@ -909,10 +907,10 @@ zh-CN:
       not_found: 找不到
       on_cooldown: 您正处于冷却状态
     followers_count: 迁移时的关注者
-    incoming_migrations: 从其他帐号迁移
+    incoming_migrations: 从其它帐号迁移
     incoming_migrations_html: 要把另一个帐号移动到本帐号,首先您需要 <a href="%{path}">创建一个帐号别名</a> 。
     moved_msg: 您的帐号现在会跳转到%{acct} ,同时关注者也会迁移过去 。
-    not_redirecting: 您的帐号当前未跳转到其他帐户。
+    not_redirecting: 您的帐号当前未跳转到其它帐户。
     on_cooldown: 您最近已经迁移过您的帐号。此功能将在%{count} 天后再次可用。
     past_migrations: 迁移记录
     proceed_with_move: 移动关注者
@@ -926,10 +924,14 @@ zh-CN:
       disabled_account: 此后,您的当前帐户将无法使用。但是,您仍然有权导出数据或者重新激活。
       followers: 这步操作将把所有关注者从当前账户移动到新账户
       only_redirect_html: 或者,你可以<a href="%{path}">只在你的帐号资料上设置一个跳转</a>。
-      other_data: 不会自动移动其他数据
+      other_data: 不会自动移动其它数据
       redirect: 在收到一个跳转通知后,您当前的帐号资料将会更新,并被排除在搜索范围外
   moderation:
     title: 运营
+  move_handler:
+    carry_blocks_over_text: 这个用户迁移自你屏蔽过的 %{acct}
+    carry_mutes_over_text: 这个用户迁移自你隐藏过的 %{acct}
+    copy_account_note_text: 这个用户迁移自 %{acct},你曾为其添加备注:
   notification_mailer:
     digest:
       action: 查看所有通知
@@ -1104,6 +1106,8 @@ zh-CN:
     spam_detected: 这是一个自动报告。已检测到垃圾信息。
   statuses:
     attached:
+      audio:
+        other: "%{count} 条音频"
       description: 附加媒体:%{attached}
       image:
         other: "%{count} 张图片"
@@ -1120,7 +1124,7 @@ zh-CN:
     over_character_limit: 超过了 %{max} 字的限制
     pin_errors:
       limit: 你所置顶的嘟文数量已经达到上限
-      ownership: 不能置顶他人的嘟文
+      ownership: 不能置顶别人的嘟文
       private: 不能置顶非公开的嘟文
       reblog: 不能置顶转嘟
     poll:
diff --git a/config/routes.rb b/config/routes.rb
index 626e4688c..ac6323e6e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -343,22 +343,22 @@ Rails.application.routes.draw do
         end
       end
 
-#      namespace :crypto do
-#        resources :deliveries, only: :create
-#
-#        namespace :keys do
-#          resource :upload, only: [:create]
-#          resource :query,  only: [:create]
-#          resource :claim,  only: [:create]
-#          resource :count,  only: [:show]
-#        end
-#
-#        resources :encrypted_messages, only: [:index] do
-#          collection do
-#            post :clear
-#          end
-#        end
-#      end
+      # namespace :crypto do
+      #   resources :deliveries, only: :create
+
+      #   namespace :keys do
+      #     resource :upload, only: [:create]
+      #     resource :query,  only: [:create]
+      #     resource :claim,  only: [:create]
+      #     resource :count,  only: [:show]
+      #   end
+
+      #   resources :encrypted_messages, only: [:index] do
+      #     collection do
+      #       post :clear
+      #     end
+      #   end
+      # end
 
       resources :conversations, only: [:index, :destroy] do
         member do
diff --git a/lib/mastodon/cli_helper.rb b/lib/mastodon/cli_helper.rb
index 4a20fa8d6..ed22f44b2 100644
--- a/lib/mastodon/cli_helper.rb
+++ b/lib/mastodon/cli_helper.rb
@@ -7,6 +7,7 @@ ActiveRecord::Base.logger    = dev_null
 ActiveJob::Base.logger       = dev_null
 HttpLog.configuration.logger = dev_null
 Paperclip.options[:log]      = false
+Chewy.logger                 = dev_null
 
 module Mastodon
   module CLIHelper
diff --git a/lib/mastodon/search_cli.rb b/lib/mastodon/search_cli.rb
index 8bd5f9543..22a0acec8 100644
--- a/lib/mastodon/search_cli.rb
+++ b/lib/mastodon/search_cli.rb
@@ -6,8 +6,19 @@ require_relative 'cli_helper'
 
 module Mastodon
   class SearchCLI < Thor
-    option :processes, default: 2, aliases: [:p]
-    desc 'deploy', 'Create or update an ElasticSearch index and populate it'
+    include CLIHelper
+
+    # Indices are sorted by amount of data to be expected in each, so that
+    # smaller indices can go online sooner
+    INDICES = [
+      AccountsIndex,
+      TagsIndex,
+      StatusesIndex,
+    ].freeze
+
+    option :concurrency, type: :numeric, default: 2, aliases: [:c], desc: 'Workload will be split between this number of threads'
+    option :only, type: :array, enum: %w(accounts tags statuses), desc: 'Only process these indices'
+    desc 'deploy', 'Create or upgrade ElasticSearch indices and populate them'
     long_desc <<~LONG_DESC
       If ElasticSearch is empty, this command will create the necessary indices
       and then import data from the database into those indices.
@@ -15,27 +26,126 @@ module Mastodon
       This command will also upgrade indices if the underlying schema has been
       changed since the last run.
 
-      With the --processes option, parallelize execution of the command. The
-      default is 2. If "auto" is specified, the number is automatically
-      derived from available CPUs.
+      Even if creating or upgrading indices is not necessary, data from the
+      database will be imported into the indices.
     LONG_DESC
     def deploy
-      processed = Chewy::RakeHelper.upgrade(parallel: processes)
-      Chewy::RakeHelper.sync(except: processed, parallel: processes)
-    end
+      if options[:concurrency] < 1
+        say('Cannot run with this concurrency setting, must be at least 1', :red)
+        exit(1)
+      end
+
+      indices = begin
+        if options[:only]
+          options[:only].map { |str| "#{str.camelize}Index".constantize }
+        else
+          INDICES
+        end
+      end
+
+      progress = ProgressBar.create(total: nil, format: '%t%c/%u |%b%i| %e (%r docs/s)', autofinish: false)
+
+      # First, ensure all indices are created and have the correct
+      # structure, so that live data can already be written
+      indices.select { |index| index.specification.changed? }.each do |index|
+        progress.title = "Upgrading #{index} "
+        index.purge
+        index.specification.lock!
+      end
+
+      ActiveRecord::Base.configurations[Rails.env]['pool'] = options[:concurrency] + 1
+
+      pool    = Concurrent::FixedThreadPool.new(options[:concurrency])
+      added   = Concurrent::AtomicFixnum.new(0)
+      removed = Concurrent::AtomicFixnum.new(0)
+
+      progress.title = 'Estimating workload '
+
+      # Estimate the amount of data that has to be imported first
+      indices.each do |index|
+        index.types.each do |type|
+          progress.total = (progress.total || 0) + type.adapter.default_scope.count
+        end
+      end
+
+      # Now import all the actual data. Mind that unlike chewy:sync, we don't
+      # fetch and compare all record IDs from the database and the index to
+      # find out which to add and which to remove from the index. Because with
+      # potentially millions of rows, the memory footprint of such a calculation
+      # is uneconomical. So we only ever add.
+      indices.each do |index|
+        progress.title = "Importing #{index} "
+        batch_size     = 1_000
+        slice_size     = (batch_size / options[:concurrency]).ceil
+
+        index.types.each do |type|
+          type.adapter.default_scope.reorder(nil).find_in_batches(batch_size: batch_size) do |batch|
+            futures = []
+
+            batch.each_slice(slice_size) do |records|
+              futures << Concurrent::Future.execute(executor: pool) do
+                begin
+                  if !progress.total.nil? && progress.progress + records.size > 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
+
+                  grouped_records = nil
+                  bulk_body       = nil
+                  index_count     = 0
+                  delete_count    = 0
+
+                  ActiveRecord::Base.connection_pool.with_connection do
+                    grouped_records = type.adapter.send(:grouped_objects, records)
+                    bulk_body       = Chewy::Type::Import::BulkBuilder.new(type, grouped_records).bulk_body
+                  end
 
-    private
+                  index_count  = grouped_records[:index].size  if grouped_records.key?(:index)
+                  delete_count = grouped_records[:delete].size if grouped_records.key?(:delete)
 
-    def processes
-      return true if options[:processes] == 'auto'
+                  # The following is an optimization for statuses specifically, since
+                  # we want to de-index statuses that cannot be searched by anybody,
+                  # but can't use Chewy's delete_if logic because it doesn't use
+                  # crutches and our searchable_by logic depends on them
+                  if type == StatusesIndex::Status
+                    bulk_body.map! do |entry|
+                      if entry[:index] && entry.dig(:index, :data, 'searchable_by').blank?
+                        index_count  -= 1
+                        delete_count += 1
 
-      num = options[:processes].to_i
+                        { delete: entry[:index].except(:data) }
+                      else
+                        entry
+                      end
+                    end
+                  end
 
-      if num < 2
-        nil
-      else
-        num
+                  Chewy::Type::Import::BulkRequest.new(type).perform(bulk_body)
+
+                  progress.progress += records.size
+
+                  added.increment(index_count)
+                  removed.increment(delete_count)
+
+                  sleep 1
+                rescue => e
+                  progress.log pastel.red("Error importing #{index}: #{e}")
+                end
+              end
+            end
+
+            futures.map(&:value)
+          end
+        end
       end
+
+      progress.title = ''
+      progress.stop
+
+      say("Indexed #{added.value} records, de-indexed #{removed.value}", :green, true)
     end
   end
 end
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index 9702018dc..46ad06242 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -9,15 +9,15 @@ module Mastodon
     end
 
     def minor
-      1
+      2
     end
 
     def patch
-      5
+      0
     end
 
     def flags
-      ''
+      'rc1'
     end
 
     def suffix
diff --git a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb
index 93b244cc3..f1d3d949c 100644
--- a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb
+++ b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb
@@ -82,6 +82,36 @@ describe Api::V1::Statuses::ReblogsController do
         end
       end
 
+      context 'with public status when blocked by its author' do
+        let(:status) { Fabricate(:status, account: user.account) }
+
+        before do
+          ReblogService.new.call(user.account, status)
+          status.account.block!(user.account)
+          post :destroy, params: { status_id: status.id }
+        end
+
+        it 'returns http success' do
+          expect(response).to have_http_status(200)
+        end
+
+        it 'updates the reblogs count' do
+          expect(status.reblogs.count).to eq 0
+        end
+
+        it 'updates the reblogged attribute' do
+          expect(user.account.reblogged?(status)).to be false
+        end
+
+        it 'returns json with updated attributes' do
+          hash_body = body_as_json
+
+          expect(hash_body[:id]).to eq status.id.to_s
+          expect(hash_body[:reblogs_count]).to eq 0
+          expect(hash_body[:reblogged]).to be false
+        end
+      end
+
       context 'with private status that was not reblogged' do
         let(:status) { Fabricate(:status, visibility: :private) }
 
diff --git a/spec/services/unallow_domain_service_spec.rb b/spec/services/unallow_domain_service_spec.rb
new file mode 100644
index 000000000..559e152fb
--- /dev/null
+++ b/spec/services/unallow_domain_service_spec.rb
@@ -0,0 +1,64 @@
+require 'rails_helper'
+
+RSpec.describe UnallowDomainService, type: :service do
+  let!(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') }
+  let!(:bad_status1) { Fabricate(:status, account: bad_account, text: 'You suck') }
+  let!(:bad_status2) { Fabricate(:status, account: bad_account, text: 'Hahaha') }
+  let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status2, file: attachment_fixture('attachment.jpg')) }
+  let!(:already_banned_account) { Fabricate(:account, username: 'badguy', domain: 'evil.org', suspended: true, silenced: true) }
+  let!(:domain_allow) { Fabricate(:domain_allow, domain: 'evil.org') }
+
+  subject { UnallowDomainService.new }
+
+  context 'in limited federation mode' do
+    before do
+      allow(subject).to receive(:whitelist_mode?).and_return(true)
+    end
+
+    describe '#call' do
+      before do
+        subject.call(domain_allow)
+      end
+
+      it 'removes the allowed domain' do
+        expect(DomainAllow.allowed?('evil.org')).to be false
+      end
+
+      it 'removes remote accounts from that domain' do
+        expect(Account.where(domain: 'evil.org').exists?).to be false
+      end
+
+      it 'removes the remote accounts\'s statuses and media attachments' do
+        expect { bad_status1.reload }.to raise_exception ActiveRecord::RecordNotFound
+        expect { bad_status2.reload }.to raise_exception ActiveRecord::RecordNotFound
+        expect { bad_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound
+      end
+    end
+  end
+
+  context 'without limited federation mode' do
+    before do
+      allow(subject).to receive(:whitelist_mode?).and_return(false)
+    end
+
+    describe '#call' do
+      before do
+        subject.call(domain_allow)
+      end
+
+      it 'removes the allowed domain' do
+        expect(DomainAllow.allowed?('evil.org')).to be false
+      end
+
+      it 'does not remove accounts from that domain' do
+        expect(Account.where(domain: 'evil.org').exists?).to be true
+      end
+
+      it 'removes the remote accounts\'s statuses and media attachments' do
+        expect { bad_status1.reload }.to_not raise_exception ActiveRecord::RecordNotFound
+        expect { bad_status2.reload }.to_not raise_exception ActiveRecord::RecordNotFound
+        expect { bad_attachment.reload }.to_not raise_exception ActiveRecord::RecordNotFound
+      end
+    end
+  end
+end