139 Commits 1a97bb16c4 ... 28fbb3fdd2

Author SHA1 Message Date
  Ivan Arkhipov 28fbb3fdd2 Removed old unused styles 3 years ago
  Ivan Arkhipov 8b15089bba Changed option: merges can be provided only by repository admin 6 years ago
  Ivan Arkhipov 53f1f8a8b6 Fixed bug with building merge diff for files with different charset 6 years ago
  Ivan Arkhipov 383a57abf4 Appearance modifications 6 years ago
  Ivan Arkhipov 294c606a5b Change visual style 6 years ago
  Ivan Arkhipov 1a97bb16c4 Removed old unused styles 3 years ago
  Ivan Arkhipov 1da2d8fe89 Changed option: merges can be provided only by repository admin 6 years ago
  Ivan Arkhipov 90a0f190d0 Fixed bug with building merge diff for files with different charset 6 years ago
  Ivan Arkhipov 8ab0a275b5 Appearance modifications 6 years ago
  Ivan Arkhipov 614a42cdf6 Change visual style 6 years ago
  ᴜɴᴋɴᴡᴏɴ 7445dec1b4 locale: sync from Crowdin (#6602) 3 years ago
  Kevin ba8be9489e public/js: upgrade jQuery to 3.6.0 (#6550) 3 years ago
  ᴜɴᴋɴᴡᴏɴ 12ab7efdb0 chore: go mod tidy (#6564) 3 years ago
  dependabot-preview[bot] 3993b65bbf build(deps): bump github.com/editorconfig/editorconfig-core-go/v2 from 2.3.9 to 2.4.1 (#6509) 3 years ago
  dependabot-preview[bot] fb969f8492 build(deps): bump github.com/stretchr/testify from 1.6.1 to 1.7.0 (#6473) 3 years ago
  dependabot-preview[bot] 8f8a27c904 build(deps): bump github.com/prometheus/client_golang from 1.8.0 to 1.9.0 (#6454) 3 years ago
  ᴜɴᴋɴᴡᴏɴ d8fa08111b chore: fix linguist-vendored with double asterisks (#6563) 3 years ago
  Massimiliano Losego 4077f27592 templates: add `it-IT` version of home page (#6558) 3 years ago
  ᴜɴᴋɴᴡᴏɴ 1a1a01a842 ci: use new lint action and add custom config (#6562) 3 years ago
  Peter Dave Hello c4cf659e32 docker: reduce additional image layer for the not executable gosu binary (#6557) 3 years ago
  Atin d6987ee05b chore: fix typos in code comments (#6556) 3 years ago
  ᴜɴᴋɴᴡᴏɴ 509a392272 locale: sync from Crowdin (#6510) 3 years ago
  ᴜɴᴋɴᴡᴏɴ af6510fd17 locale: sync from Crowdin (#6449) 3 years ago
  dependabot-preview[bot] cd4d79cf99 build(deps): bump github.com/go-macaron/i18n from 0.5.0 to 0.6.0 (#6440) 4 years ago
  dependabot-preview[bot] 10e7c42a83 build(deps): bump github.com/editorconfig/editorconfig-core-go/v2 from 2.3.7 to 2.3.9 (#6441) 4 years ago
  dependabot-preview[bot] 7676b59b02 build(deps): bump gorm.io/gorm from 1.20.7 to 1.20.8 (#6442) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 0ff888c989 CHANGELOG: make entries more informational (#6445) 4 years ago
  peppe8o 6b4a5b5e91 README: add a new RPI Zero W tutorial (#6443) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 72af17bbbe db: simplify GORM logger init in tests (#6444) 4 years ago
  Eduardo Bacchi Kienetz c875950c43 ssh: allow setting allowed MAC algorithms for built-in server (#6435) 4 years ago
  dependabot-preview[bot] 71eeb2f0c0 build(deps): bump gorm.io/driver/sqlite from 1.1.3 to 1.1.4 (#6432) 4 years ago
  dependabot-preview[bot] 99f1b9899f build(deps): bump gorm.io/gorm from 1.20.6 to 1.20.7 (#6425) 4 years ago
  dependabot-preview[bot] bee3bebb4e build(deps): bump github.com/russross/blackfriday from 1.5.2 to 1.6.0 (#6429) 4 years ago
  dependabot-preview[bot] efcb8bbca6 build(deps): bump github.com/Masterminds/semver/v3 from 3.1.0 to 3.1.1 (#6431) 4 years ago
  stypr cd469f7a1d repo: disallow urlencoded new lines in git protocol paths (#6420) 4 years ago
  weibaohui c7f58ca870 templates: fix typo of BranchCount (#6370) 4 years ago
  MichaIng b34d040c78 scripts: fix MySQL script for MariaDB >= 10.3.1 (#6424) 4 years ago
  ᴜɴᴋɴᴡᴏɴ afaf6da405 locale: sync from Crowdin (#6419) 4 years ago
  dependabot-preview[bot] 7bef64a0d6 build(deps): bump gopkg.in/macaron.v1 from 1.3.9 to 1.4.0 (#6416) 4 years ago
  dependabot-preview[bot] 146960368f build(deps): bump gorm.io/gorm from 1.20.5 to 1.20.6 (#6417) 4 years ago
  Matheus Mosca 997ba0fef0 context: add X-Frame-Options header (#6411) 4 years ago
  dependabot-preview[bot] 6f735cc2da build(deps): bump github.com/urfave/cli from 1.22.4 to 1.22.5 (#6410) 4 years ago
  dependabot-preview[bot] 8b35485ee5 build(deps): bump golang.org/x/text from 0.3.3 to 0.3.4 (#6403) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 428276d7a8 locale: sync from Crowdin (#6404) 4 years ago
  Rubén de Celis Hernández 053695b63d Update CHANGELOG.md (#6389) 4 years ago
  dependabot-preview[bot] b4bb83e68f build(deps): bump gorm.io/driver/mysql from 1.0.2 to 1.0.3 (#6397) 4 years ago
  dependabot-preview[bot] 2989a5e0f5 build(deps): bump gorm.io/driver/sqlserver from 1.0.4 to 1.0.5 (#6395) 4 years ago
  dependabot-preview[bot] 9844d2c96a build(deps): bump gorm.io/driver/postgres from 1.0.2 to 1.0.5 (#6400) 4 years ago
  dependabot-preview[bot] ab16ca0580 build(deps): bump github.com/prometheus/client_golang from 1.6.0 to 1.8.0 (#6394) 4 years ago
  dependabot-preview[bot] f0a9ec21cd build(deps): bump github.com/gogs/git-module from 1.1.3 to 1.1.4 (#6398) 4 years ago
  dependabot-preview[bot] 6c5fd05a31 build(deps): bump gorm.io/gorm from 1.20.2 to 1.20.5 (#6399) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 1744f238e1 locale: sync from Crowdin (#6383) 4 years ago
  E99p1ant fd765bd88f context: fix Access-Control-Allow-Credentials header typo (#6381) 4 years ago
  dependabot-preview[bot] 533b6b0de2 build(deps): bump gopkg.in/ini.v1 from 1.60.2 to 1.62.0 (#6380) 4 years ago
  ᴜɴᴋɴᴡᴏɴ bf3c9061a2 docs: update patch release issue template (#6375) 4 years ago
  ᴜɴᴋɴᴡᴏɴ f0e3cd90f8 release: update version to 0.12.3 4 years ago
  ᴜɴᴋɴᴡᴏɴ b60e2c65d3 CHANGELOG: cut entries for 0.12.3 (#6374) 4 years ago
  ᴜɴᴋɴᴡᴏɴ e44ac3c20a docs: update patch release issue template 4 years ago
  ᴜɴᴋɴᴡᴏɴ 2eaf1d693a db: migrate access table to use GORM (#6371) 4 years ago
  ᴜɴᴋɴᴡᴏɴ fbe34c8c61 lfs: ask client to always send the same value for the HTTP header (#6369) 4 years ago
  ᴜɴᴋɴᴡᴏɴ a92d818aa3 docs: update patch release issue template 4 years ago
  Jeff e6b4c467e8 markup: render SHA links without branch prefix (#6350) 4 years ago
  ᴜɴᴋɴᴡᴏɴ ca3330cecd lfs: ask client to always send the same value for the HTTP header (#6369) 4 years ago
  ᴜɴᴋɴᴡᴏɴ cf86546dff ci: change of Go dependencies needs go test (#6368) 4 years ago
  dependabot-preview[bot] 8e028c32d4 build(deps): bump gorm.io/driver/mysql from 1.0.1 to 1.0.2 (#6366) 4 years ago
  dependabot-preview[bot] c082bf72af build(deps): bump gorm.io/driver/postgres from 1.0.1 to 1.0.2 (#6365) 4 years ago
  dependabot-preview[bot] 906c6a5ba0 build(deps): bump gorm.io/gorm from 1.20.1 to 1.20.2 (#6364) 4 years ago
  ᴜɴᴋɴᴡᴏɴ a6bd00f807 locale: sync from Crowdin (#6367) 4 years ago
  ouyangjinting 7797efe1bb docs: fix README_ZH.md link (#6360) 4 years ago
  Zhukov Roman be86d67e81 Add git diff timeout in app config (#6348) 4 years ago
  Jeff 23823e9698 markup: render SHA links without branch prefix (#6350) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 6b6bfe8bb0 cmd/serv: use different log files for ORMs in hook mode (#6361) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 7bc3ee49aa cmd/serv: use different log files for ORMs in hook mode (#6361) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 8fc4013240 README: remove broken/deprecated links 4 years ago
  dependabot-preview[bot] 211a1394b8 build(deps): bump gorm.io/driver/postgres from 1.0.0 to 1.0.1 (#6351) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 73e5936220 docs: update patch release issue template (#6353) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 253b2bef4c ci: update Go workflow from main 4 years ago
  ᴜɴᴋɴᴡᴏɴ 1a051ae5f8 release: update version to 0.12.2 4 years ago
  ᴜɴᴋɴᴡᴏɴ e4e46d8fbc release: cut entries for 0.12.2 (#6355) 4 years ago
  ᴜɴᴋɴᴡᴏɴ b4abbf3ac8 ci: enable Go for release branches 4 years ago
  ᴜɴᴋɴᴡᴏɴ ca54cbd055 action: fix issue reference regexp and error handling (#6352) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 83a89127fd action: fix issue reference regexp and error handling (#6352) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 9044afa40f dep: update github.com/unknwon/cae to v1.0.2 (#6342) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 6ed98ca8f6 dep: update github.com/unknwon/cae to v1.0.2 (#6342) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 3af91d7cfd auth: decouple types and functions from db (#6320) 4 years ago
  dependabot-preview[bot] b836a56e6e build(deps): bump github.com/go-macaron/binding from 1.1.0 to 1.1.1 (#6340) 4 years ago
  ᴜɴᴋɴᴡᴏɴ c56db8f2c4 db: create new session for MySQL after changing attribute (#6338) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 672625b55c gitutil: infer submodule with baseURL when it is a relative path (#6337) 4 years ago
  ᴜɴᴋɴᴡᴏɴ dda1092e74 gitutil: infer submodule with baseURL when it is a relative path (#6337) 4 years ago
  dependabot-preview[bot] 8b75e9a442 build(deps): bump gorm.io/driver/sqlite from 1.1.1 to 1.1.3 (#6336) 4 years ago
  dependabot-preview[bot] 1da1e90d1e build(deps): bump gorm.io/driver/sqlserver from 1.0.3 to 1.0.4 (#6325) 4 years ago
  dependabot-preview[bot] 9a268ca7f5 build(deps): bump github.com/editorconfig/editorconfig-core-go/v2 from 2.3.2 to 2.3.7 (#6324) 4 years ago
  dependabot-preview[bot] d85504a9d1 build(deps): bump github.com/olekukonko/tablewriter from 0.0.1 to 0.0.4 (#6327) 4 years ago
  dependabot-preview[bot] 8658ded190 build(deps): bump gorm.io/gorm from 1.20.0 to 1.20.1 (#6328) 4 years ago
  dependabot-preview[bot] 04b11d3a07 build(deps): bump github.com/unknwon/cae from 1.0.0 to 1.0.1 (#6329) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 56eac57222 locale: sync from Crowdin (#6333) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 98c65f319f web: correctly serving go-get pages for subdirs (#6318) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 594a2dc41f web: correctly serving go-get pages for subdirs (#6318) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 06193ed825 schemadoc: add go:generate to output database schema (#6310) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 519e59b577 db: migrate to GORM v2 (#6309) 4 years ago
  dependabot-preview[bot] 771d3673f5 build(deps): bump github.com/gogs/git-module from 1.1.2 to 1.1.3 (#6306) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 2cb83f13fd repo: set default value for `is_unlisted` column (#6305) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 2665b5968c locale: sync from Crowdin (#6303) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 7a649ada09 ci: only enforce Go checks for pushes to `main` branch 4 years ago
  ᴜɴᴋɴᴡᴏɴ a533e8fb52 Taskfile: add desc to each task (#6304) 4 years ago
  ᴜɴᴋɴᴡᴏɴ bb93cabd39 ci: re-run Go checks for every push on a pull request 4 years ago
  Achilleas Koutsou c4360747a3 repo: support unlisted but publicly accessible repositories (#6176) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 23ff182d1f chore: use Task as main build tool (#6297) 4 years ago
  ᴜɴᴋɴᴡᴏɴ cb88caa2d2 install: remove MSSQL option (#6295) 4 years ago
  ᴜɴᴋɴᴡᴏɴ cf216f12a1 github: add Go 1.15 to CI (#6294) 4 years ago
  ᴜɴᴋɴᴡᴏɴ a22fd01959 install: fix generating removed options (#6293) 4 years ago
  ᴜɴᴋɴᴡᴏɴ b38139a855 README: add emoji for license header 4 years ago
  ᴜɴᴋɴᴡᴏɴ 1a681ad022 docker: revert shellcheck fix (#6288) 4 years ago
  ᴜɴᴋɴᴡᴏɴ f6d672a3cd chore: change default branch to `main` (#6285) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 016d9d8c88 Revert "README: update VPS sponsor" 4 years ago
  ᴜɴᴋɴᴡᴏɴ c769f2566a docs: add patch release docs 4 years ago
  ᴜɴᴋɴᴡᴏɴ 423f9e6de7 github: enable Go actions on push 4 years ago
  ᴜɴᴋɴᴡᴏɴ 43fc826085 release: update version to 0.12.1 4 years ago
  ᴜɴᴋɴᴡᴏɴ d7a6bb8bcb db: fix wrong column type of `login_source` (#6283) 4 years ago
  Kosadchiy db037495de issue: fix timestamp updating (#6210) 4 years ago
  ᴜɴᴋɴᴡᴏɴ bbef32b1ef CHANGELOG: cut more entries for 0.12.1 4 years ago
  ᴜɴᴋɴᴡᴏɴ 92953007de CHANGELOG: cut entries for 0.12.1 4 years ago
  ᴜɴᴋɴᴡᴏɴ 4ecd588776 db: fix wrong column type of `login_source` (#6283) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 4e5b7c5d24 docker: fix broken SSHD for Dockerfile.rpi (#6278) 4 years ago
  ᴜɴᴋɴᴡᴏɴ c1db31c130 CHANGELOG: add entry for #6210 4 years ago
  Kosadchiy a02b3e1258 issue: fix timestamp updating (#6210) 4 years ago
  ᴜɴᴋɴᴡᴏɴ afb445bb57 github: only run Actions when Go files are changed (#6275) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 92c5f94fe7 shellcheck: fix warnings (#6274) 4 years ago
  ᴜɴᴋɴᴡᴏɴ a840ae9035 pkgr: use main branch and Go 1.15 for buildpack (#6273) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 0a5977e951 docker: fix missing make command (#6272) 4 years ago
  ᴜɴᴋɴᴡᴏɴ a7fb211827 docs: add release strategy (#6271) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 3ed8c292c2 migrations: remove old migrations before 0.12.0 (#6270) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 13ae25b785 Makefile: explicitly call go generate (#6269) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 40513a117f docs: add instructions for release (#6268) 4 years ago
  ᴜɴᴋɴᴡᴏɴ f0761eb7ec conf: remove legacy options (#6267) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 05477f1d29 app: update dev version (#6266) 4 years ago
  ᴜɴᴋɴᴡᴏɴ 39bdd5c2cd assets: make generate (#6265) 4 years ago
  ᴜɴᴋɴᴡᴏɴ ac4a708307 assets: make generate (#6265) 4 years ago
  ᴜɴᴋɴᴡᴏɴ f17e7d5a2c release: remove dev version notion 4 years ago
100 changed files with 4033 additions and 1723 deletions
  1. 8 9
      .gitattributes
  2. 1 1
      .github/ISSUE_TEMPLATE/security.md
  3. 2 2
      .github/workflows/codeql.yml
  4. 19 11
      .github/workflows/go.yml
  5. 4 1
      .github/workflows/lsif.yml
  6. 1 1
      .github/workflows/shell.yml
  7. 0 2
      .gitignore
  8. 21 0
      .golangci.yml
  9. 1 1
      .pkgr.yml
  10. 38 22
      CHANGELOG.md
  11. 5 5
      Dockerfile
  12. 2 19
      Makefile
  13. 6 7
      README.md
  14. 3 3
      README_ZH.md
  15. 2 3
      SECURITY.md
  16. 87 0
      Taskfile.yml
  17. 6 2
      conf/app.ini
  18. 10 10
      conf/locale/locale_de-DE.ini
  19. 71 5
      conf/locale/locale_en-GB.ini
  20. 4 1
      conf/locale/locale_en-US.ini
  21. 6 6
      conf/locale/locale_es-ES.ini
  22. 6 6
      conf/locale/locale_fa-IR.ini
  23. 86 86
      conf/locale/locale_fi-FI.ini
  24. 35 35
      conf/locale/locale_fr-FR.ini
  25. 29 29
      conf/locale/locale_it-IT.ini
  26. 41 41
      conf/locale/locale_ja-JP.ini
  27. 4 4
      conf/locale/locale_ko-KR.ini
  28. 1419 0
      conf/locale/locale_mn-MN.ini
  29. 1 1
      conf/locale/locale_nl-NL.ini
  30. 54 54
      conf/locale/locale_pl-PL.ini
  31. 52 52
      conf/locale/locale_pt-BR.ini
  32. 2 2
      conf/locale/locale_pt-PT.ini
  33. 42 42
      conf/locale/locale_ru-RU.ini
  34. 24 24
      conf/locale/locale_sk-SK.ini
  35. 10 10
      conf/locale/locale_sv-SE.ini
  36. 64 64
      conf/locale/locale_tr-TR.ini
  37. 100 100
      conf/locale/locale_uk-UA.ini
  38. 81 81
      conf/locale/locale_vi-VN.ini
  39. 14 14
      conf/locale/locale_zh-TW.ini
  40. 5 5
      docker/Dockerfile.aarch64
  41. 6 6
      docker/Dockerfile.rpi
  42. 1 1
      docker/README.md
  43. 4 0
      docker/runtime/backup-init.sh
  44. 2 1
      docker/runtime/backup-rotator.sh
  45. 1 1
      docker/s6/.s6-svscan/finish
  46. 1 0
      docker/s6/crond/run
  47. 2 1
      docker/s6/gogs/run
  48. 3 3
      docker/s6/gogs/setup
  49. 1 0
      docker/s6/openssh/run
  50. 2 2
      docker/s6/openssh/setup
  51. 1 0
      docker/s6/syslogd/run
  52. 12 11
      docker/start.sh
  53. 33 0
      docs/admin/release_strategy.md
  54. 59 0
      docs/dev/database_schema.md
  55. 17 0
      docs/dev/import_locale.md
  56. 10 7
      docs/dev/local_development.md
  57. 38 0
      docs/dev/release/issue_template_minor_version.md
  58. 43 0
      docs/dev/release/issue_template_patch_release.md
  59. 17 0
      docs/dev/release/release_new_version.md
  60. 22 24
      go.mod
  61. 380 67
      go.sum
  62. 1 1
      gogs.go
  63. 1 1
      internal/assets/conf/conf.go
  64. 23 22
      internal/assets/conf/conf_gen.go
  65. 1 1
      internal/assets/public/public.go
  66. 11 11
      internal/assets/public/public_gen.go
  67. 1 1
      internal/assets/templates/templates.go
  68. 11 11
      internal/assets/templates/templates_gen.go
  69. 69 127
      internal/auth/auth.go
  70. 58 0
      internal/auth/github/config.go
  71. 0 50
      internal/auth/github/github.go
  72. 57 0
      internal/auth/github/provider.go
  73. 76 60
      internal/auth/ldap/config.go
  74. 78 0
      internal/auth/ldap/provider.go
  75. 13 0
      internal/auth/pam/config.go
  76. 6 12
      internal/auth/pam/pam.go
  77. 2 2
      internal/auth/pam/pam_stub.go
  78. 54 0
      internal/auth/pam/provider.go
  79. 58 0
      internal/auth/smtp/config.go
  80. 132 0
      internal/auth/smtp/provider.go
  81. 7 6
      internal/cmd/serv.go
  82. 3 3
      internal/conf/computed.go
  83. 0 8
      internal/conf/conf.go
  84. 1 1
      internal/conf/log.go
  85. 7 97
      internal/conf/static.go
  86. 4 17
      internal/conf/testdata/TestInit.golden.ini
  87. 15 14
      internal/conf/testdata/custom.ini
  88. 139 3
      internal/context/auth.go
  89. 3 3
      internal/context/context.go
  90. 16 14
      internal/context/repo.go
  91. 1 1
      internal/cron/cron.go
  92. 0 240
      internal/db/access.go
  93. 13 11
      internal/db/access_tokens.go
  94. 15 6
      internal/db/access_tokens_test.go
  95. 7 7
      internal/db/action.go
  96. 21 10
      internal/db/backup.go
  97. 28 12
      internal/db/backup_test.go
  98. 75 43
      internal/db/db.go
  99. 0 33
      internal/db/errors/login_source.go
  100. 5 10
      internal/db/issue.go

+ 8 - 9
.gitattributes

@@ -1,9 +1,8 @@
-conf/gitignore/* linguist-vendored
-conf/license/* linguist-vendored
-public/assets/* linguist-vendored
-public/plugins/* linguist-vendored
-public/css/themes/* linguist-vendored
-public/css/semantic-2.4.2.min.css linguist-vendored
-public/js/libs/* linguist-vendored
-public/js/jquery-3.4.1.min.js linguist-vendored
-public/js/semantic-2.4.2.min.js linguist-vendored
+conf/gitignore/** linguist-vendored
+conf/license/** linguist-vendored
+public/assets/** linguist-vendored
+public/plugins/** linguist-vendored
+public/css/themes/** linguist-vendored
+public/css/semantic-* linguist-vendored
+public/js/libs/** linguist-vendored
+public/js/semantic-* linguist-vendored

+ 1 - 1
.github/ISSUE_TEMPLATE/security.md

@@ -7,6 +7,6 @@ about: Report security vulnerability for this project
 <!--
 
 Please create a dummy issue with high-level description of the security vulnerability,
-then report details to u@gogs.io privately, thank you!
+then report details to security@gogs.io privately, thank you!
 
 -->

+ 2 - 2
.github/workflows/codeql.yml

@@ -2,7 +2,7 @@ name: "Code scanning - action"
 
 on:
   push:
-    branches: [master]
+    branches: [main]
   schedule:
     - cron: '0 19 * * 0'
 
@@ -24,7 +24,7 @@ jobs:
     # the head of the pull request instead of the merge commit.
     - run: git checkout HEAD^2
       if: ${{ github.event_name == 'pull_request' }}
-      
+
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
       uses: github/codeql-action/init@v1

+ 19 - 11
.github/workflows/go.yml

@@ -6,9 +6,15 @@ on:
       - 'release/**'
     paths:
       - '**.go'
+      - 'go.mod'
+      - '.golangci.yml'
+      - '.github/workflows/go.yml'
   pull_request:
     paths:
       - '**.go'
+      - 'go.mod'
+      - '.golangci.yml'
+      - '.github/workflows/go.yml'
 env:
   GOPROXY: "https://proxy.golang.org"
 
@@ -19,31 +25,25 @@ jobs:
     steps:
       - uses: actions/checkout@v2
       - name: Run golangci-lint
-        uses: actions-contrib/golangci-lint@v1
+        uses: golangci/golangci-lint-action@v2
         with:
-          args: 'run --timeout=30m'
+          version: latest
+          args: --timeout=30m
 
   test:
     name: Test
     strategy:
       matrix:
-        go-version: [1.14.x, 1.15.x]
+        go-version: [1.14.x, 1.15.x, 1.16.x]
         platform: [ubuntu-latest, macos-latest, windows-latest]
     runs-on: ${{ matrix.platform }}
     steps:
       - name: Install Go
-        uses: actions/setup-go@v1
+        uses: actions/setup-go@v2
         with:
           go-version: ${{ matrix.go-version }}
       - name: Checkout code
         uses: actions/checkout@v2
-      - name: Run unit tests
-        run: go test -v -race -coverprofile=coverage -covermode=atomic ./...
-      - name: Upload coverage report to Codecov
-        uses: codecov/codecov-action@v1.0.6
-        with:
-          file: ./coverage
-          flags: unittests
       - name: Cache downloaded modules
         uses: actions/cache@v1
         with:
@@ -51,3 +51,11 @@ jobs:
           key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
           restore-keys: |
             ${{ runner.os }}-go-
+      - name: Run unit tests
+        run: go test -v -race -coverprofile=coverage -covermode=atomic ./...
+      - name: Upload coverage report to Codecov
+        uses: codecov/codecov-action@v1.5.0
+        with:
+          file: ./coverage
+          flags: unittests
+

+ 4 - 1
.github/workflows/lsif.yml

@@ -1,5 +1,8 @@
 name: LSIF
-on: [push]
+on:
+  push:
+    paths:
+      - '**.go'
 jobs:
   lsif-go:
     if: github.repository == 'gogs/gogs'

+ 1 - 1
.github/workflows/shell.yml

@@ -1,7 +1,7 @@
 name: Shell
 on:
   push:
-    branches: [master]
+    branches: [main]
   pull_request:
 jobs:
   shellcheck:

+ 0 - 2
.gitignore

@@ -13,6 +13,4 @@ public/img/avatar/
 profile/
 *.pem
 output*
-*.sublime-project
-*.sublime-workspace
 /release

+ 21 - 0
.golangci.yml

@@ -0,0 +1,21 @@
+linters-settings:
+  nakedret:
+    max-func-lines: 0 # Disallow any unnamed return statement
+
+linters:
+  enable:
+    - deadcode
+    - errcheck
+    - gosimple
+    - govet
+    - ineffassign
+    - staticcheck
+    - structcheck
+    - typecheck
+    - unused
+    - varcheck
+    - nakedret
+    - gofmt
+    - rowserrcheck
+    - unconvert
+    - goimports

+ 1 - 1
.pkgr.yml

@@ -33,4 +33,4 @@ before:
 after:
   - mv bin/gogs gogs
 after_install: ./.packager/hooks/postinst
-buildpack: https://github.com/heroku/heroku-buildpack-go.git
+buildpack: https://github.com/heroku/heroku-buildpack-go.git#main

+ 38 - 22
CHANGELOG.md

@@ -7,6 +7,9 @@ All notable changes to Gogs are documented in this file.
 ### Added
 
 - An unlisted option is added when create or migrate a repository. Unlisted repositories are public but not being listed for users without direct access in the UI. [#5733](https://github.com/gogs/gogs/issues/5733)
+- New configuration option `[git.timeout] DIFF` for customizing operation timeout of `git diff`. [#6315](https://github.com/gogs/gogs/issues/6315)
+- New configuration option `[server] SSH_SERVER_MACS` for setting list of accepted MACs for connections to builtin SSH server. [#6434](https://github.com/gogs/gogs/issues/6434)
+- New languages support: Mongolian. [#6510](https://github.com/gogs/gogs/pull/6510)
 
 ### Changed
 
@@ -16,33 +19,45 @@ All notable changes to Gogs are documented in this file.
 
 ### Fixed
 
-- _Regression:_ Pages are correctly rendered when requesting `?go-get=1` for subdirectories. [#6314](https://github.com/gogs/gogs/issues/6314)
-- _Regression:_ Submodule with a relative path is linked correctly. [#6319](https://github.com/gogs/gogs/issues/6319)
-- Backup can be processed when `--target` is specified on Windows. [#6339](https://github.com/gogs/gogs/issues/6339)
-- Commit message contains keywords look like an issue reference no longer fails the push entirely. [#6289](https://github.com/gogs/gogs/issues/6289)
+- Add `X-Frame-Options` header to prevent Clickjacking. [#6409](https://github.com/gogs/gogs/issues/6409)
+- [Security] Potential SSRF attack by CRLF injection via repository migration. [#6413](https://github.com/gogs/gogs/issues/6413)
+
+
+### Removed
+
+- ⚠️ Migrations before 0.12 are removed, installations not on 0.12 should upgrade to it to run the migrations and then upgrade to 0.13.
+- Configuration section `[mailer]` is no longer used, please use `[email]`.
+- Configuration section `[service]` is no longer used, please use `[auth]`.
+- Configuration option `APP_NAME` is no longer used, please use `BRAND_NAME`.
+- Configuration option `[security] REVERSE_PROXY_AUTHENTICATION_USER` is no longer used, please use `[auth] REVERSE_PROXY_AUTHENTICATION_HEADER`.
+- Configuration option `[auth] ACTIVE_CODE_LIVE_MINUTES` is no longer used, please use `[auth] ACTIVATE_CODE_LIVES`.
+- Configuration option `[auth] RESET_PASSWD_CODE_LIVE_MINUTES` is no longer used, please use `[auth] RESET_PASSWORD_CODE_LIVES`.
+- Configuration option `[auth] ENABLE_CAPTCHA` is no longer used, please use `[auth] ENABLE_REGISTRATION_CAPTCHA`.
+- Configuration option `[auth] ENABLE_NOTIFY_MAIL` is no longer used, please use `[user] ENABLE_EMAIL_NOTIFICATION`.
+- Configuration option `[auth] REGISTER_EMAIL_CONFIRM` is no longer used, please use `[auth] REQUIRE_EMAIL_CONFIRMATION`.
+- Configuration option `[session] GC_INTERVAL_TIME` is no longer used, please use `[session] GC_INTERVAL`.
+- Configuration option `[session] SESSION_LIFE_TIME` is no longer used, please use `[session] MAX_LIFE_TIME`.
+- Configuration option `[server] ROOT_URL` is no longer used, please use `[server] EXTERNAL_URL`.
+- Configuration option `[server] LANDING_PAGE` is no longer used, please use `[server] LANDING_URL`.
+- Configuration option `[database] DB_TYPE` is no longer used, please use `[database] TYPE`.
+- Configuration option `[database] PASSWD` is no longer used, please use `[database] PASSWORD`.
+
+## 0.12.3
+
+### Fixed
+
 - _Regression:_ When running Gogs on Windows, push commits no longer fail on a daily basis with the error "pre-receive hook declined". [#6316](https://github.com/gogs/gogs/issues/6316)
 - Auto-linked commit SHAs now have correct links. [#6300](https://github.com/gogs/gogs/issues/6300)
 - Git LFS client (with version >= 2.5.0) wasn't able to upload files with known format (e.g. PNG, JPEG), and the server is expecting the HTTP Header `Content-Type` to be `application/octet-stream`. The server now tells the LFS client to always use `Content-Type: application/octet-stream` when upload files.
 
-### Removed
+## 0.12.2
 
-- ⚠️ Migrations before 0.12 are removed, installations not on 0.12 should upgrade to it to run the migrations and then upgrade to 0.13.
-- Configuration section `[mailer]` is no longer used.
-- Configuration section `[service]` is no longer used.
-- Configuration option `APP_NAME` is no longer used.
-- Configuration option `[security] REVERSE_PROXY_AUTHENTICATION_USER` is no longer used.
-- Configuration option `[database] PASSWD` is no longer used.
-- Configuration option `[auth] ACTIVE_CODE_LIVE_MINUTES` is no longer used.
-- Configuration option `[auth] RESET_PASSWD_CODE_LIVE_MINUTES` is no longer used.
-- Configuration option `[auth] ENABLE_CAPTCHA` is no longer used.
-- Configuration option `[auth] ENABLE_NOTIFY_MAIL` is no longer used.
-- Configuration option `[auth] REGISTER_EMAIL_CONFIRM` is no longer used.
-- Configuration option `[session] GC_INTERVAL_TIME` is no longer used.
-- Configuration option `[session] SESSION_LIFE_TIME` is no longer used.
-- Configuration option `[server] ROOT_URL` is no longer used.
-- Configuration option `[server] LANDING_PAGE` is no longer used.
-- Configuration option `[database] DB_TYPE` is no longer used.
-- Configuration option `[database] PASSWD` is no longer used.
+### Fixed
+
+- _Regression:_ Pages are correctly rendered when requesting `?go-get=1` for subdirectories. [#6314](https://github.com/gogs/gogs/issues/6314)
+- _Regression:_ Submodule with a relative path is linked correctly. [#6319](https://github.com/gogs/gogs/issues/6319)
+- Backup can be processed when `--target` is specified on Windows. [#6339](https://github.com/gogs/gogs/issues/6339)
+- Commit message contains keywords look like an issue reference no longer fails the push entirely. [#6289](https://github.com/gogs/gogs/issues/6289)
 
 ## 0.12.1
 
@@ -81,6 +96,7 @@ All notable changes to Gogs are documented in this file.
 - Configuration section `[service]` is deprecated and will end support in 0.13.0, please start using `[auth]`.
 - Configuration option `[auth] ACTIVE_CODE_LIVE_MINUTES` is deprecated and will end support in 0.13.0, please start using `[auth] ACTIVATE_CODE_LIVES`.
 - Configuration option `[auth] RESET_PASSWD_CODE_LIVE_MINUTES` is deprecated and will end support in 0.13.0, please start using `[auth] RESET_PASSWORD_CODE_LIVES`.
+- Configuration option `[auth] REGISTER_EMAIL_CONFIRM` is deprecated and will end support in 0.13.0, please start using `[auth] REQUIRE_EMAIL_CONFIRMATION`.
 - Configuration option `[auth] ENABLE_CAPTCHA` is deprecated and will end support in 0.13.0, please start using `[auth] ENABLE_REGISTRATION_CAPTCHA`.
 - Configuration option `[auth] ENABLE_NOTIFY_MAIL` is deprecated and will end support in 0.13.0, please start using `[user] ENABLE_EMAIL_NOTIFICATION`.
 - Configuration option `[session] GC_INTERVAL_TIME` is deprecated and will end support in 0.13.0, please start using `[session] GC_INTERVAL`.

+ 5 - 5
Dockerfile

@@ -7,11 +7,11 @@ RUN apk --no-cache --no-progress add --virtual \
 
 WORKDIR /gogs.io/gogs
 COPY . .
-RUN make build-no-gen TAGS="cert pam"
+RUN make build TAGS="cert pam"
 
 FROM alpine:3.11
-ADD https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64 /usr/sbin/gosu
-RUN chmod +x /usr/sbin/gosu \
+RUN wget https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64 -O /usr/sbin/gosu \
+  && chmod +x /usr/sbin/gosu \
   && echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
   && apk --no-cache --no-progress add \
   bash \
@@ -28,7 +28,7 @@ RUN chmod +x /usr/sbin/gosu \
 
 ENV GOGS_CUSTOM /data/gogs
 
-# Configure LibC Name Service
+# Configure LibC Name Service
 COPY docker/nsswitch.conf /etc/nsswitch.conf
 
 WORKDIR /app/gogs
@@ -37,7 +37,7 @@ COPY --from=binarybuilder /gogs.io/gogs/gogs .
 
 RUN ./docker/finalize.sh
 
-# Configure Docker Container
+# Configure Docker Container
 VOLUME ["/data", "/backup"]
 EXPOSE 22 3000
 ENTRYPOINT ["/app/gogs/docker/start.sh"]

+ 2 - 19
Makefile

@@ -5,8 +5,6 @@ CONF_FILES := $(shell find conf | sed 's/ /\\ /g')
 TEMPLATES_FILES := $(shell find templates | sed 's/ /\\ /g')
 PUBLIC_FILES := $(shell find public | sed 's/ /\\ /g')
 LESS_FILES := $(wildcard public/less/*.less)
-ASSETS_GENERATED := internal/assets/conf/conf_gen.go internal/assets/templates/templates_gen.go internal/assets/public/public_gen.go
-GENERATED := $(ASSETS_GENERATED) public/css/gogs.min.css
 
 TAGS = ""
 BUILD_FLAGS = "-v"
@@ -28,10 +26,7 @@ dist: release
 web: build
 	./gogs web
 
-build: $(GENERATED)
-	go build $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' -trimpath -o gogs
-
-build-no-gen:
+build:
 	go build $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' -trimpath -o gogs
 
 pack:
@@ -42,22 +37,10 @@ pack:
 
 release: build pack
 
-generate: clean $(ASSETS_GENERATED)
-
-internal/assets/conf/conf_gen.go: $(CONF_FILES)
-	-rm -f $@
+generate: clean
 	go generate internal/assets/conf/conf.go
-	gofmt -s -w $@
-
-internal/assets/templates/templates_gen.go: $(TEMPLATES_FILES)
-	-rm -f $@
 	go generate internal/assets/templates/templates.go
-	gofmt -s -w $@
-
-internal/assets/public/public_gen.go: $(PUBLIC_FILES)
-	-rm -f $@
 	go generate internal/assets/public/public.go
-	gofmt -s -w $@
 
 less: clean public/css/gogs.min.css
 

+ 6 - 7
README.md

@@ -1,4 +1,4 @@
-# <img src="https://github.com/gogs/gogs/raw/master/public/img/favicon.png" width="45" align="left">Gogs - A painless self-hosted Git service
+# <img src="https://github.com/gogs/gogs/raw/main/public/img/favicon.png" width="45" align="left">Gogs - A painless self-hosted Git service
 
 [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/gogs/gogs/Go?logo=github&style=for-the-badge)](https://github.com/gogs/gogs/actions?query=workflow%3AGo) [![Discord](https://img.shields.io/discord/382595433060499458.svg?style=for-the-badge&logo=discord)](https://discord.gg/9aqdHU7) [![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?style=for-the-badge&logo=sourcegraph)](https://sourcegraph.com/github.com/gogs/gogs)
 
@@ -56,7 +56,7 @@ There are 6 ways to install Gogs:
 - [Install from binary](https://gogs.io/docs/installation/install_from_binary.html)
 - [Install from source](https://gogs.io/docs/installation/install_from_source.html)
 - [Install from packages](https://gogs.io/docs/installation/install_from_packages.html)
-- [Ship with Docker](https://github.com/gogs/gogs/tree/master/docker)
+- [Ship with Docker](https://github.com/gogs/gogs/tree/main/docker)
 - [Install with Vagrant](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
 - [Install with Kubernetes Using Helm Charts](https://github.com/helm/charts/tree/master/incubator/gogs)
 
@@ -72,6 +72,7 @@ There are 6 ways to install Gogs:
 
 ### Tutorials
 
+- [Private Git Web Portal in Raspberry PI With Gogs](https://peppe8o.com/private-git-web-portal-in-raspberry-pi-with-gogs/)
 - [How To Set Up Gogs on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-gogs-on-ubuntu-14-04)
 - [Run your own GitHub-like service with the help of Docker](http://blog.hypriot.com/post/run-your-own-github-like-service-with-docker/)
 - [Dockerized Gogs git server and alpine postgres in 20 minutes or less](http://garthwaite.org/docker-gogs.html)
@@ -88,8 +89,6 @@ There are 6 ways to install Gogs:
 - [Jenkins](https://plugins.jenkins.io/gogs-webhook/) (CI)
 - [Taiga](https://taiga.io/) (Project Management)
 - [Puppet](https://forge.puppet.com/Siteminds/gogs) (IT)
-- [Kanboard](https://github.com/kanboard/plugin-gogs-webhook) (Project Management)
-- [BearyChat](https://bearychat.com/) (Team Communication)
 - [GitPitch](https://gitpitch.com/) (Markdown Presentations)
 - [Synology](https://www.synology.com) (Docker)
 - [Syncloud](https://syncloud.org/) (App Store)
@@ -98,7 +97,7 @@ There are 6 ways to install Gogs:
 
 - Thanks [Egon Elbre](https://twitter.com/egonelbre) for designing the original version of the logo.
 - Thanks [Crowdin](https://crowdin.com/project/gogs) for sponsoring open source translation plan.
-- Thanks [DigitalOcean](https://www.digitalocean.com), [VPSServer](https://www.vpsserver.com/), [Hosted.nl](https://www.hosted.nl/) and [BitLaunch](https://bitlaunch.io) for sponsoring VPS services.
+- Thanks [DigitalOcean](https://www.digitalocean.com), [VPSServer](https://www.vpsserver.com/), [Hosted.nl](https://www.hosted.nl/), [MonoVM](https://monovm.com) and [BitLaunch](https://bitlaunch.io) for sponsoring VPS services.
 - Thanks [KeyCDN](https://www.keycdn.com/) for sponsoring CDN service.
 - Thanks [Buildkite](https://buildkite.com) for sponsoring open source CI/CD plan.
 
@@ -107,6 +106,6 @@ There are 6 ways to install Gogs:
 - See [contributors page](https://github.com/gogs/gogs/graphs/contributors) for top 100 contributors.
 - See [TRANSLATORS](conf/locale/TRANSLATORS) for public list of translators.
 
-## License
+## ⚖️ License
 
-This project is under the MIT License. See the [LICENSE](https://github.com/gogs/gogs/blob/master/LICENSE) file for the full license text.
+This project is under the MIT License. See the [LICENSE](https://github.com/gogs/gogs/blob/main/LICENSE) file for the full license text.

+ 3 - 3
README_ZH.md

@@ -13,7 +13,7 @@ Gogs(`/gɑgz/`)项目旨在打造一个以最简便的方式搭建简单、
 - 想要先睹为快?直接去[在线体验](https://try.gogs.io/gogs/gogs)吧!
 - 使用过程中遇到问题?尝试[故障排查](https://gogs.io/docs/intro/troubleshooting.html)或者前往[用户论坛](https://discuss.gogs.io/)获取帮助
 - 希望帮助多国语言的翻译吗?请查看[本地化文档](https://gogs.io/docs/features/i18n.html)
-- 准备搞点事情?请阅读[开发指南](docs/local_development.md)配置开发环境
+- 准备搞点事情?请阅读[开发指南](docs/dev/local_development.md)配置开发环境
 - 想调用 API 吗?请查看[文档](https://github.com/gogs/docs-api)吧
 
 ## 主要特性
@@ -53,7 +53,7 @@ Gogs(`/gɑgz/`)项目旨在打造一个以最简便的方式搭建简单、
 - [二进制安装](https://gogs.io/docs/installation/install_from_binary.html)
 - [源码安装](https://gogs.io/docs/installation/install_from_source.html)
 - [包管理安装](https://gogs.io/docs/installation/install_from_packages.html)
-- [采用 Docker 部署](https://github.com/gogs/gogs/tree/master/docker)
+- [采用 Docker 部署](https://github.com/gogs/gogs/tree/main/docker)
 - [通过 Vagrant 安装](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
 - [通过基于 Kubernetes 的 Helm Charts](https://github.com/helm/charts/tree/master/incubator/gogs)
 
@@ -100,4 +100,4 @@ Gogs(`/gɑgz/`)项目旨在打造一个以最简便的方式搭建简单、
 
 ## 授权许可
 
-本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogs/gogs/blob/master/LICENSE) 文件中。
+本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogs/gogs/blob/main/LICENSE) 文件中。

+ 2 - 3
SECURITY.md

@@ -6,6 +6,5 @@ Only lastest two minor version releases are supported for patching security fixe
 
 ## Reporting a vulnerability
 
-Please send report privately to [security@gogs.io](mailto:security@gogs.io), and include how would you like to be credited.
-
-Thank you!
+Please create a dummy issue with high-level description of the security vulnerability,
+then report details to [security@gogs.io](mailto:security@gogs.io) privately, thank you!

+ 87 - 0
Taskfile.yml

@@ -0,0 +1,87 @@
+version: '3'
+
+tasks:
+  web:
+    desc: Build the binary and start the web server.
+    deps: [build]
+    cmds:
+      - ./gogs web
+
+  build:
+    desc: Build the binary.
+    cmds:
+      - go build -v
+        -ldflags '
+          -X "{{.PKG_PATH}}.BuildTime={{.BUILD_TIME}}"
+          -X "{{.PKG_PATH}}.BuildCommit={{.BUILD_COMMIT}}"
+        '
+        -tags '{{.TAGS}}'
+        -trimpath -o gogs
+    vars:
+      PKG_PATH: gogs.io/gogs/internal/conf
+      BUILD_TIME:
+        sh: date -u '+%Y-%m-%d %I:%M:%S %Z'
+      BUILD_COMMIT:
+        sh: git rev-parse HEAD
+    sources:
+      - gogs.go
+      - internal/**/*.go
+
+  generate-bindata:
+    desc: Generate bindata for all assets.
+    deps: [clean]
+    cmds:
+      - go generate internal/assets/conf/conf.go
+      - go generate internal/assets/templates/templates.go
+      - go generate internal/assets/public/public.go
+
+  generate-schemadoc:
+    desc: Generate database schema documentation.
+    cmds:
+      - go generate ./internal/db/schemadoc
+
+  generate:
+    desc: Run all go:generate commands.
+    deps: [generate-bindata, generate-schemadoc]
+
+  test:
+    desc: Run all tests.
+    cmds:
+      - go test -cover -race ./...
+
+  clean:
+    desc: Cleans up system meta files for code generation.
+    cmds:
+      - find . -name "*.DS_Store" -type f -delete
+
+  release:
+    desc: Build the binary and pack resources to a ZIP file.
+    deps: [build]
+    cmds:
+      - rm -rf {{.RELEASE_GOGS}}
+      - mkdir -p {{.RELEASE_GOGS}}
+      - cp -r gogs LICENSE README.md README_ZH.md scripts {{.RELEASE_GOGS}}
+      - cd {{.RELEASE_ROOT}} && zip -r gogs.$(NOW).zip "gogs"
+    vars:
+      RELEASE_ROOT: release
+      RELEASE_GOGS: release/gogs
+
+  less:
+    desc: Generate CSS from LESS files.
+    cmds:
+      - lessc --clean-css --source-map "public/less/gogs.less" public/css/gogs.min.css
+
+  fixme:
+    desc: Show all occurrences of "FIXME".
+    cmds:
+      - grep -rnw "FIXME" internal
+
+  todo:
+    desc: Show all occurrences of "TODO".
+    cmds:
+      - grep -rnw "TODO" internal
+
+  legacy:
+    desc: Identify legacy and deprecated lines.
+    cmds:
+      - grep -rnw "\(LEGACY\|Deprecated\)" internal

+ 6 - 2
conf/app.ini

@@ -81,6 +81,8 @@ SSH_LISTEN_HOST = 0.0.0.0
 SSH_LISTEN_PORT = %(SSH_PORT)s
 ; The list of accepted ciphers for connections to builtin SSH server.
 SSH_SERVER_CIPHERS = aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128
+; The list of accepted MACs for connections to builtin SSH server.
+SSH_SERVER_MACS = hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1
 
 ; Define allowed algorithms and their minimum key length (use -1 to disable a type).
 [ssh.minimum_key_sizes]
@@ -460,6 +462,7 @@ MIGRATE = 600
 MIRROR = 300
 CLONE = 300
 PULL = 300
+DIFF = 60
 GC = 60
 
 [mirror]
@@ -518,8 +521,8 @@ BASIC_AUTH_PASSWORD =
 [highlight.mapping]
 
 [i18n]
-LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,gl-ES,uk-UA,en-GB,hu-HU,sk-SK,id-ID,fa-IR,vi-VN,pt-PT
-NAMES = English,简体中文,繁體中文(香港),繁體中文(臺灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,galego,українська,English (United Kingdom),Magyar,Slovenčina,Indonesian,Persian,Vietnamese,Português
+LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,gl-ES,uk-UA,en-GB,hu-HU,sk-SK,id-ID,fa-IR,vi-VN,pt-PT, mn-MN
+NAMES = English,简体中文,繁體中文(香港),繁體中文(臺灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,galego,українська,English (United Kingdom),Magyar,Slovenčina,Indonesian,Persian,Vietnamese,Português,Монгол
 
 ; Used for datetimepicker
 [i18n.datelang]
@@ -553,6 +556,7 @@ id-ID = id
 fa-IR = fa
 vi-VN = vi
 pt-PT = pt
+mn-MN = mn
 
 [other]
 SHOW_FOOTER_BRANDING = false

+ 10 - 10
conf/locale/locale_de-DE.ini

@@ -44,8 +44,8 @@ issues=Issues
 cancel=Abbrechen
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Seite nicht gefunden
+internal_server_error=Interner Serverfehler
 
 [install]
 install=Installation
@@ -263,7 +263,7 @@ following=Folge ich
 follow=Folgen
 unfollow=Nicht mehr folgen
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Benutzername oder Muster %q ist nicht erlaubt.
 
 [settings]
 profile=Profil
@@ -789,8 +789,8 @@ settings.remove_collaborator_success=Mitarbeiter wurde entfernt.
 settings.search_user_placeholder=Benutzer suchen...
 settings.org_not_allowed_to_be_collaborator=Eine Organisation kann nicht als Mitarbeiter hinzugefügt werden.
 settings.hooks_desc=Webhooks erlauben es Ihnen, externe Dienste zu informieren, wenn etwas Bestimmtes in Ihrem Repository passiert. Gogs sendet dann einen POST-Request an alle angegebenen URLs. Erfahren Sie mehr in unserem <a target="_blank" href="%s">Webhooks Guide</a>.
-settings.webhooks.add_new=Add a new webhook:
-settings.webhooks.choose_a_type=Choose a type...
+settings.webhooks.add_new=Einen neuen Webhook hinzufügen:
+settings.webhooks.choose_a_type=Typ auswählen...
 settings.add_webhook=Webhook hinzufügen
 settings.webhook_deletion=Webhook entfernen
 settings.webhook_deletion_desc=Das Löschen dieses Webhooks wird alle zugehörigen Informationen und den Übertragungsverlauf entfernen. Wirklich fortfahren?
@@ -805,8 +805,8 @@ settings.webhook.response=Antwort
 settings.webhook.headers=Kopfzeilen
 settings.webhook.payload=Nutzdaten
 settings.webhook.body=Inhalt
-settings.webhook.err_cannot_parse_payload_url=Cannot parse payload URL: %v
-settings.webhook.err_cannot_use_local_addresses=Non admins are not allowed to use local addresses.
+settings.webhook.err_cannot_parse_payload_url=Payload URL kann nicht analysiert werden: %v
+settings.webhook.err_cannot_use_local_addresses=Nicht-Administratoren dürfen keine lokalen Adressen verwenden.
 settings.githooks_desc=Git-Hooks werden von Git selbst bereitgestellt. Sie können die Dateien der unterstützten Hooks in der Liste unten bearbeiten, um eigene Operationen einzubinden.
 settings.githook_edit_desc=Wenn ein Hook inaktiv ist, wird der Standardinhalt benutzt. Lassen Sie den Inhalt leer, um den Hook zu deaktivieren.
 settings.githook_name=Hook-Name
@@ -1332,9 +1332,9 @@ config.git.clone_timeout=Clone-Timeout
 config.git.pull_timeout=Pull-Timeout
 config.git.gc_timeout=GC-Timeout
 
-config.lfs_config=LFS configuration
-config.lfs.storage=Storage
-config.lfs.objects_path=Objects path
+config.lfs_config=LFS-Konfiguration
+config.lfs.storage=Speicher
+config.lfs.objects_path=Objektpfad
 
 config.log_config=Konfiguration des Loggings
 config.log_file_root_path=Log-Verzeichnis

+ 71 - 5
conf/locale/locale_en-GB.ini

@@ -236,6 +236,7 @@ team_name_been_taken=Team name has already been taken.
 email_been_used=Email address has already been used.
 username_password_incorrect=Username or password is not correct.
 auth_source_mismatch=The authentication source selected is not associated with the user.
+
 enterred_invalid_repo_name=Please make sure that the repository name you have entered is correct.
 enterred_invalid_owner_name=Please make sure that the owner name you have entered is correct.
 enterred_invalid_password=Please make sure the that password you have entered is correct.
@@ -263,7 +264,8 @@ following=Following
 follow=Follow
 unfollow=Unfollow
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Username or pattern %q is not allowed.
+
 
 [settings]
 profile=Profile
@@ -355,6 +357,7 @@ two_factor_then_enter_passcode=Then enter passcode:
 two_factor_verify=Verify
 two_factor_invalid_passcode=The passcode you entered is not valid, please try again!
 two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
+
 two_factor_enable_error=Enable Two-factor authentication failed: %v
 two_factor_enable_success=Two-factor authentication has enabled for your account successfully!
 two_factor_recovery_codes_title=Two-factor Authentication Recovery Codes
@@ -379,6 +382,7 @@ access_token_deletion_desc=Delete this personal access token will remove all rel
 delete_token_success=Personal access token has been removed successfully! Don't forget to update your application as well.
 token_name_exists=Token with same name already exists.
 
+
 orgs.none=You are not a member of any organisations.
 orgs.leave_title=Leave organisation
 orgs.leave_desc=You will lose access to all repositories and teams after you left the organization. Do you want to continue?
@@ -426,11 +430,14 @@ watchers=Watchers
 stargazers=Stargazers
 forks=Forks
 repo_description_helper=Description of repository. Maximum 512 characters length.
+
 repo_description_length=Available characters
 
+
 form.reach_limit_of_creation=The owner has reached maximum creation limit of %d repositories.
 form.name_not_allowed=Repository name or pattern %q is not allowed.
 
+
 need_auth=Need Authorisation
 migrate_type=Migration Type
 migrate_type_helper=This repository will be a <span class="text blue">mirror</span>
@@ -524,6 +531,7 @@ editor.file_already_exists=A file with name '%s' already exists in this reposito
 editor.no_changes_to_show=There are no changes to show.
 editor.fail_to_update_file=Failed to update/create file '%s' with error: %v
 editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
+
 editor.add_subdir=Add subdirectory...
 editor.unable_to_upload_files=Failed to upload files to '%s' with error: %v
 editor.upload_files_to_dir=Upload files to '%s'
@@ -643,6 +651,7 @@ pulls.can_auto_merge_desc=This pull request can be merged automatically.
 pulls.cannot_auto_merge_desc=This pull request can't be merged automatically because there are conflicts.
 pulls.cannot_auto_merge_helper=Please merge manually in order to resolve the conflicts.
 pulls.create_merge_commit=Create a merge commit
+
 pulls.rebase_before_merging=Rebase before merging
 pulls.commit_description=Commit Description
 pulls.merge_pull_request=Merge Pull Request
@@ -750,8 +759,11 @@ settings.tracker_issue_style.numeric=Numeric
 settings.tracker_issue_style.alphanumeric=Alphanumeric
 settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
 settings.pulls_desc=Enable pull requests to accept contributions between repositories and branches
+
 settings.pulls.ignore_whitespace=Ignore changes in whitespace
+
 settings.pulls.allow_rebase_merge=Allow use rebase to merge commits
+
 settings.danger_zone=Danger Zone
 settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
 settings.new_owner_has_same_repo=The new owner already has a repository with same name. Please choose another name.
@@ -773,6 +785,7 @@ settings.delete=Delete This Repository
 settings.delete_desc=Once you delete a repository, there is no going back. Please be certain.
 settings.delete_notices_1=- This operation <strong>CANNOT</strong> be undone.
 settings.delete_notices_2=- This operation will permanently delete everything in this repository, including Git data, issues, comments and collaborator access.
+
 settings.delete_notices_fork_1=- All forks will become independent after deletion.
 settings.deletion_success=Repository has been deleted successfully!
 settings.update_settings_success=Repository options has been updated successfully.
@@ -790,7 +803,9 @@ settings.search_user_placeholder=Search user...
 settings.org_not_allowed_to_be_collaborator=Organisation is not allowed to be added as a collaborator.
 settings.hooks_desc=Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gogs, we will handle the notification to the target host you specify. Learn more in this <a target="_blank" href="%s">Webhooks Guide</a>.
 settings.webhooks.add_new=Add a new webhook:
+
 settings.webhooks.choose_a_type=Choose a type...
+
 settings.add_webhook=Add Webhook
 settings.webhook_deletion=Delete Webhook
 settings.webhook_deletion_desc=Delete this webhook will remove its information and all delivery history. Do you want to continue?
@@ -805,8 +820,9 @@ settings.webhook.response=Response
 settings.webhook.headers=Headers
 settings.webhook.payload=Payload
 settings.webhook.body=Body
-settings.webhook.err_cannot_parse_payload_url=Cannot parse payload URL: %v
-settings.webhook.err_cannot_use_local_addresses=Non admins are not allowed to use local addresses.
+settings.webhook.err_cannot_parse_payload_url=Cannot parse the payload URL: %v
+
+settings.webhook.err_cannot_use_local_addresses=Only admins are allowed to use local addresses.
 settings.githooks_desc=Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to perform custom operations.
 settings.githook_edit_desc=If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.
 settings.githook_name=Hook Name
@@ -868,8 +884,10 @@ settings.deploy_key_deletion=Delete Deploy Key
 settings.deploy_key_deletion_desc=Deleting this deploy key will remove all related accesses for this repository. Do you want to continue?
 settings.deploy_key_deletion_success=Deploy key has been deleted successfully!
 settings.description_desc=Description of repository. Maximum 512 characters length.
+
 settings.description_length=Available characters
 
+
 diff.browse_source=Browse Source
 diff.parent=parent
 diff.commit=commit
@@ -934,8 +952,10 @@ team_desc_helper=What is this team all about?
 team_permission_desc=What permission level should this team have?
 
 form.name_not_allowed=Organization name or pattern %q is not allowed.
+
 form.team_name_not_allowed=Team name or pattern %q is not allowed.
 
+
 settings=Settings
 settings.options=Options
 settings.full_name=Full Name
@@ -1007,18 +1027,25 @@ last_page=Last
 total=Total: %d
 
 dashboard.build_info=Build Information
+
 dashboard.app_ver=Application version
+
 dashboard.git_version=Git version
+
 dashboard.go_version=Go version
+
 dashboard.build_time=Build time
+
 dashboard.build_commit=Build commit
+
 dashboard.statistic=Statistics
 dashboard.operations=Operations
 dashboard.system_status=System Monitor Status
 dashboard.statistic_info=Gogs database has <b>%d</b> users, <b>%d</b> organisations, <b>%d</b> public keys, <b>%d</b> repositories, <b>%d</b> watches, <b>%d</b> stars, <b>%d</b> actions, <b>%d</b> accesses, <b>%d</b> issues, <b>%d</b> comments, <b>%d</b> social accounts, <b>%d</b> follows, <b>%d</b> mirrors, <b>%d</b> releases, <b>%d</b> login sources, <b>%d</b> webhooks, <b>%d</b> milestones, <b>%d</b> labels, <b>%d</b> hook tasks, <b>%d</b> teams, <b>%d</b> update tasks, <b>%d</b> attachments.
 dashboard.operation_name=Operation Name
 dashboard.operation_switch=Switch
-dashboard.select_operation_to_run=Please select operation to run
+dashboard.select_operation_to_run=Please select an operation to run
+
 dashboard.operation_run=Run
 dashboard.clean_unbind_oauth=Clean unbound OAuthes
 dashboard.clean_unbind_oauth_success=All unbind OAuthes have been deleted successfully.
@@ -1125,6 +1152,7 @@ auths.host=Host
 auths.port=Port
 auths.bind_dn=Bind DN
 auths.bind_dn_helper=You can use '%s' as placeholder for username, e.g. DOM\%s
+
 auths.bind_password=Bind Password
 auths.bind_password_helper=Warning: This password is stored in plain text. Do not use a high privileged account.
 auths.user_base=User Search Base
@@ -1154,7 +1182,8 @@ auths.pam_service_name=PAM Service Name
 auths.enable_auto_register=Enable Auto Registration
 auths.edit=Edit Authentication Setting
 auths.activated=This authentication is activated
-auths.default_auth=This authentication is default login source
+auths.default_auth=This authentication is the default login page
+
 auths.new_success=New authentication '%s' has been added successfully.
 auths.update_success=Authentication setting has been updated successfully.
 auths.update=Update Authentication Setting
@@ -1167,25 +1196,41 @@ auths.login_source_exist=Login source '%s' already exists.
 auths.github_api_endpoint=API Endpoint
 
 config.not_set=(not set)
+
 config.server_config=Server Configuration
 config.brand_name=Brand name
+
 config.run_user=Run User
 config.run_mode=Run Mode
 config.server.external_url=External URL
+
 config.server.domain=Domain
+
 config.server.protocol=Protocol
 config.server.http_addr=HTTP address
+
 config.server.http_port=HTTP port
+
 config.server.cert_file=Certificate file
+
 config.server.key_file=Key file
+
 config.server.tls_min_version=Minimum TLS version
+
 config.server.unix_socket_permission=Unix socket permission
+
 config.server.local_root_url=Local root URL
+
 config.server.offline_mode=Offline mode
+
 config.server.disable_router_log=Disable router log
+
 config.server.enable_gzip=Enable Gzip
+
 config.server.app_data_path=Application data path
+
 config.server.load_assets_from_disk=Load assets from disk
+
 config.server.landing_url=Landing URL
 
 config.ssh_config=SSH Configuration
@@ -1245,28 +1290,49 @@ config.security.login_status_cookie_name=Login status cookie
 
 config.email_config=Email configuration
 config.email.enabled=Enabled
+
 config.email.subject_prefix=Subject prefix
+
 config.email.host=Host
+
 config.email.from=From
+
 config.email.user=User
 config.email.disable_helo=Disable HELO
+
 config.email.helo_hostname=HELO hostname
+
 config.email.skip_verify=Skip certificate verify
+
 config.email.use_certificate=Use custom certificate
+
 config.email.cert_file=Certificate file
+
 config.email.key_file=Key file
+
 config.email.use_plain_text=Use plain text
+
 config.email.add_plain_text_alt=Add plain text alternative
+
 config.email.send_test_mail=Send test email
+
 config.email.test_mail_failed=Failed to send test email to '%s': %v
+
 config.email.test_mail_sent=Test email has been sent to '%s'.
 
+
 config.auth_config=Authentication configuration
+
 config.auth.activate_code_lives=Activate code lives
+
 config.auth.reset_password_code_lives=Reset password code lives
+
 config.auth.require_email_confirm=Require email confirmation
+
 config.auth.require_sign_in_view=Require sign in view
+
 config.auth.disable_registration=Disable registration
+
 config.auth.enable_registration_captcha=Enable registration captcha
 config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
 config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration

+ 4 - 1
conf/locale/locale_en-US.ini

@@ -51,7 +51,7 @@ internal_server_error = Internal Server Error
 install = Installation
 title = Install Steps For First-time Run
 docker_helper = If you're running Gogs inside Docker, please read <a target="_blank" href="%s">Guidelines</a> carefully before you change anything in this page!
-requite_db_desc = Gogs requires MySQL, PostgreSQL, SQLite3, MSSQL or TiDB.
+requite_db_desc = Gogs requires MySQL, PostgreSQL, SQLite3 or TiDB (via MySQL protocol).
 db_title = Database Settings
 db_type = Database Type
 host = Host
@@ -399,7 +399,9 @@ owner = Owner
 repo_name = Repository Name
 repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
 visibility = Visibility
+unlisted = Unlisted
 visiblity_helper = This repository is <span class="ui red text">Private</span>
+unlisted_helper = This repository is <span class="ui red text">Unlisted</span>
 visiblity_helper_forced = Site admin has forced all new repositories to be <span class="ui red text">Private</span>
 visiblity_fork_helper = (Change of this value will affect all forks)
 clone_helper = Need help cloning? Visit <a target="_blank" href="%s">Help</a>!
@@ -1202,6 +1204,7 @@ config.ssh.start_builtin_server = Start builtin server
 config.ssh.listen_host = Listen host
 config.ssh.listen_port = Listen port
 config.ssh.server_ciphers = Server ciphers
+config.ssh.server_macs = Server MACs
 
 config.repo_config = Repository configuration
 config.repo.root_path = Root path

+ 6 - 6
conf/locale/locale_es-ES.ini

@@ -1008,9 +1008,9 @@ total=Total: %d
 
 dashboard.build_info=Build Information
 dashboard.app_ver=Application version
-dashboard.git_version=Git version
-dashboard.go_version=Go version
-dashboard.build_time=Build time
+dashboard.git_version=Versión de Git
+dashboard.go_version=Versión de Go
+dashboard.build_time=Tiempo de compilación
 dashboard.build_commit=Build commit
 dashboard.statistic=Estadísticas
 dashboard.operations=Operaciones
@@ -1174,8 +1174,8 @@ config.run_mode=Modo de ejecución
 config.server.external_url=External URL
 config.server.domain=Domain
 config.server.protocol=Protocol
-config.server.http_addr=HTTP address
-config.server.http_port=HTTP port
+config.server.http_addr=Dirección HTTP
+config.server.http_port=Puerto HTTP
 config.server.cert_file=Certificate file
 config.server.key_file=Key file
 config.server.tls_min_version=Minimum TLS version
@@ -1198,7 +1198,7 @@ config.ssh.key_test_path=Key test path
 config.ssh.minimum_key_size_check=Minimum key size check
 config.ssh.minimum_key_sizes=Minimum key sizes
 config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
-config.ssh.start_builtin_server=Start builtin server
+config.ssh.start_builtin_server=Iniciar servidor integrado
 config.ssh.listen_host=Listen host
 config.ssh.listen_port=Listen port
 config.ssh.server_ciphers=Server ciphers

+ 6 - 6
conf/locale/locale_fa-IR.ini

@@ -44,8 +44,8 @@ issues=مسائل
 cancel=لغو
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=صفحه مورد نظر یافت نشد.
+internal_server_error=خطای داخلی سرور
 
 [install]
 install=نصب
@@ -125,7 +125,7 @@ run_user_not_match=کاربری را اجرا کنید که کاربر فعلی
 smtp_host_missing_port=شماره پورت در آدرس میزبان SMTP وارد نشده است.
 invalid_smtp_from=مقدار وارد شده در فرم SMTP معتبر نیست: %v
 save_config_failed=تنظیمات ذخیره نشد: %v
-init_failed=Failed to initialize application: %v
+init_failed=بارگزاری برنامه به مشکل برخورد: %v
 invalid_admin_setting=تنظیمات حساب مدیر نامعتبر است: %v
 install_success=خوش آمدی! ما خوشحالیم که شما Gogs را انتخاب کردید. لذت ببرید و مراقب خودتون باشید.
 invalid_log_root_path=آدرس روت فایل لاگ صحیح نیست: %v
@@ -263,7 +263,7 @@ following=دنبال می کند
 follow=دنبال کردن
 unfollow=لغو دنبال کردن
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=الگوی نام کاربری '%s' مجاز نیست.
 
 [settings]
 profile=پروفایل
@@ -379,7 +379,7 @@ delete_token=حذف
 access_token_deletion=حذف توکن دسترسی شخصی
 access_token_deletion_desc=حذف این توکن دسترسی شخصی ، تمام دسترسی های مرتبط به برنامه را حذف خواهد کرد. آیا ادامه می دهید؟
 delete_token_success=رمز دسترسی شخصی با موفقیت حذف شد! به روز رسانی نرم افزار خود را نیز فراموش نکنید.
-token_name_exists=Token with same name already exists.
+token_name_exists=نشان امنیتی با این نام از قبل وجود دارد
 
 orgs.none=شما عضو هیچ سازمانی نیستید.
 orgs.leave_title=ترک یک سازمان
@@ -431,7 +431,7 @@ repo_description_helper=توضیحات مخرن. حداکثر طول ۵۱۲ کا
 repo_description_length=کاراکترهای موجود
 
 form.reach_limit_of_creation=مخزن های دارنده حساب به حداکثر تعداد مجاز %d رسیده است.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=الگو یا نام مخزن %s مجاز نیست.
 
 need_auth=نیاز به مجوز
 migrate_type=نوع انتقال

+ 86 - 86
conf/locale/locale_fi-FI.ini

@@ -44,45 +44,45 @@ issues=Ongelmat
 cancel=Peruuta
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Sivua ei löydy
+internal_server_error=Sisäinen palvelinvirhe
 
 [install]
 install=Asennus
 title=Asennusvaiheet ottaessa ensi kertaa käyttöön
 docker_helper=Jos käytät Gogsia Dockerin sisällä, ole hyvä ja lue <a target="_blank" href="%s">ohjeet</a> huolellisesti ennen kuin muutat mitään tältä sivulta!
 requite_db_desc=Gogs tarvitsee jonkin seuraavista: MySQL, PostgreSQL, SQLite3, MSSQL tai TiDB.
-db_title=Tietokanta asetukset
-db_type=Tietokanta tyyppi
+db_title=Tietokannan asetukset
+db_type=Tietokannan tyyppi
 host=Isäntä
 user=Käyttäjä
 password=Salasana
 db_name=Tietokannan nimi
 db_helper=Ole hyvä ja käytä INNODB moottoria ja utf8_general_ci merkistöä MySQLssä.
-ssl_mode=SSL tila
+ssl_mode=SSL-tila
 path=Polku
-sqlite_helper=Tiedostopolku SQLite3 tietokantaan. <br>Käytä absoluuttista polkua ajaessasi palveluna.
-err_empty_db_path=SQLite3 tietokantapolku ei voi olla tyhjä.
-no_admin_and_disable_registration=Et voi poistaa käytöstä rekisteröintiä luomatta ylläpito tiliä.
+sqlite_helper=Tiedostopolku SQLite3-tietokantaan. <br>Käytä absoluuttista polkua ajaessasi palveluna.
+err_empty_db_path=SQLite3-tietokantapolku ei voi olla tyhjä.
+no_admin_and_disable_registration=Et voi poistaa käytöstä rekisteröintiä luomatta ylläpitotiliä.
 err_empty_admin_password=Ylläpito salasana ei voi olla tyhjä.
 
 general_title=Sovellus yleiset asetukset
 app_name=Sovelluksen nimi
 app_name_helper=Laita organisaatiosi nimi tähän isolla ja kovaäänisesti!
 repo_path=Repon juuren polku
-repo_path_helper=Kaikki Git etä repot tullaan tallentamaan tähän hakemistoon.
+repo_path_helper=Kaikki Git-etärepot tullaan tallentamaan tähän hakemistoon.
 run_user=Suorita käyttäjänä
 run_user_helper=Käyttäjällä täytyy olla oikeus repositoryn juuripolkuun. Käyttäjällä täytyy myös olla oikeus suorittaa Gogs.
 domain=Verkkotunnus
-domain_helper=Tämä vaikuttaa SSH klooni URLeihin.
+domain_helper=Tämä vaikuttaa SSH-kloonausosoitteisiin.
 ssh_port=SSH-portti
 ssh_port_helper=Portti numero jota SSH palvelimesi käyttää, jätä tyhjäksi poistaaksesi käytöstä SSH toiminnon.
 use_builtin_ssh_server=Käytä sisäänrakennettua SSH-palvelinta
 use_builtin_ssh_server_popup=Käynnistä sisäänrakennettu SSH-palvelin Git-operaatioille, järjestelmän SSH-palvelusta erottautumiseksi.
-http_port=HTTP portti
-http_port_helper=Portti numero jota sovellus tulee kuuntelemaan.
-app_url=Sovellus URL
-app_url_helper=Tämä vaikuttaa HTTP/HTTPS klooni URLeihin ja joihinkin sähköposteihin.
+http_port=HTTP-portti
+http_port_helper=Porttinumero, jota sovellus tulee kuuntelemaan.
+app_url=Sovelluksen osoite
+app_url_helper=Tämä vaikuttaa HTTP/HTTPS-klooniosoitteisiin ja joihinkin sähköposteihin.
 log_root_path=Lokin polku
 log_root_path_helper=Lokien tallennushakemisto.
 enable_console_mode=Ota käyttöön konsoli tila
@@ -92,41 +92,41 @@ optional_title=Valinnaiset asetukset
 email_title=Sähköposti palvelu asetukset
 smtp_host=SMTP isäntä
 smtp_from=Lähettäjä
-smtp_from_helper=Sähköposti lähettäjän osoite, RFC 5322. Se voi olla pelkkä sähköposti osoite, tai "Nimi" <email@example.com> muodossa.
+smtp_from_helper=Sähköpostin lähettäjän osoite, RFC 5322. Se voi olla pelkkä sähköpostiosoite tai "Nimi" <email@example.com> -muodossa.
 mailer_user=Lähettäjän sähköposti
 mailer_password=Lähettäjän salasana
-register_confirm=Ota käyttöön rekisteröinti varmistus
+register_confirm=Ota käyttöön rekisteröintivarmistus
 mail_notify=Ota käyttöön sähköposti ilmoitukset
 server_service_title=Palvelin ja muut palvelu asetukset
-offline_mode=Ota käyttöön Offline tila
-offline_mode_popup=Poista käytöstä CDN myös tuotanto tilassa, kaikki resurssi tiedostot palvellaan paikallisesti.
-disable_gravatar=Poista käytöstä Gravatar palvelu
+offline_mode=Ota käyttöön yhteydetön tila
+offline_mode_popup=Poista käytöstä CDN myös tuotantotilassa, kaikki resurssitiedostot palvellaan paikallisesti.
+disable_gravatar=Poista käytöstä Gravatar-palvelu
 disable_gravatar_popup=Poista käytöstä Gravatar ja mukautetut lähteet, kaikki profiilikuvat on käyttäjien palvelimelle lähettämiä tai oletus.
 federated_avatar_lookup=Käytä ulkopuolista profiilikuvien hakua
 federated_avatar_lookup_popup=Ota ulkopuolinen profiilikuvien haku käyttöön käyttääksesi avoimen lähdekoodin libravatar-palvelua.
 disable_registration=Poista käytöstä itse-rekisteröinti
-disable_registration_popup=Poista käyttäjän itse rekisteröinti, vain ylläpito voi luoda tilejä.
+disable_registration_popup=Poista käyttäjän itserekisteröinti, vain ylläpito voi luoda tilejä.
 enable_captcha=Ota käyttöön Captcha
 enable_captcha_popup=Pakollinen captcha käyttäjän itse rekisteröityessä.
 require_sign_in_view=Ota käyttöön vaadi sisäänkirjautuminen nähdäksesi sivut
-require_sign_in_view_popup=Vain sisään kirjautuneet käyttäjät voivat nähdä sivut, vierailijat tulevat näkemään vain kirjautumis/rekisteröinti sivut.
-admin_setting_desc=Sinun ei tarvitse luoda ylläpito tiliä nyt, ensimmäinen käyttäjä ID=1 saa ylläpito oikeudet automaattisesti.
-admin_title=Ylläpito tili asetukset
+require_sign_in_view_popup=Vain sisäänkirjautuneet käyttäjät voivat nähdä sivut, vierailijat tulevat näkemään vain kirjautumis-/rekisteröintisivut.
+admin_setting_desc=Sinun ei tarvitse luoda ylläpitotiliä nyt, ensimmäinen käyttäjä ID=1 saa ylläpito-oikeudet automaattisesti.
+admin_title=Ylläpitotilin asetukset
 admin_name=Käyttäjätunnus
 admin_password=Salasana
 confirm_password=Varmista salasana
 admin_email=Ylläpito sähköposti
 install_gogs=Asenna Gogs
 test_git_failed=Epäonnistui testata 'git' komentoa: %v
-sqlite3_not_available=Julkaisu versiosi ei tue SQLite3, ole hyvä ja lataa virallinen binääri versio osoitteesta %s, EI gobuild versiota.
+sqlite3_not_available=Julkaisuversiosi ei tue SQLite3:a, ole hyvä ja lataa virallinen binääriversio osoitteesta %s, EI gobuild-versiota.
 invalid_db_setting=Tietokanta asetus ei ole oikea: %v
 invalid_repo_path=Repo juuri polku on virheellinen: %v
 run_user_not_match=Suoritus käyttäjä ei ole nykyinen käyttäjä: %s -> %s
 smtp_host_missing_port=SMTP-isännältä puuttuu portin osoite.
 invalid_smtp_from=SMTP From kenttä ei ole kelvollinen: %v
 save_config_failed=Asetuksien tallennus epäonnistui: %v
-init_failed=Failed to initialize application: %v
-invalid_admin_setting=Ylläpito tili asetus virheellinen: %v
+init_failed=Sovelluksen alustus epäonnistui: %v
+invalid_admin_setting=Ylläpitotilin asetus on virheellinen: %v
 install_success=Tervetuloa! Olemme iloisia että valitsit Gogs, pidä hauskaa ja pidä huolta itsestäsi.
 invalid_log_root_path=Loki juurihakemisto ei kelpaa: %v
 
@@ -136,7 +136,7 @@ password_holder=Salasana
 switch_dashboard_context=Vaihda kojelaudan kontekstia
 my_repos=Reponi
 show_more_repos=Näytä lisää repoja...
-collaborative_repos=Yhteistyö repot
+collaborative_repos=Yhteistyörepot
 my_orgs=Organisaationi
 my_mirrors=Peilini
 view_home=Näytä %s
@@ -151,27 +151,27 @@ search=Hae
 
 [auth]
 create_new_account=Luo uusi tili
-register_hepler_msg=On jo tili? Kirjaudu sisään nyt!
+register_hepler_msg=Onko sinulla jo tili? Kirjaudu sisään nyt!
 social_register_hepler_msg=On jo tili? Liitä nyt!
-disable_register_prompt=Sori, rekisteröinti on poistettu käytöstä. Ole hyvä ja ota yhteyttä sivuston ylläpitoon.
-disable_register_mail=Sori, rekisteröinti sähköpostivarmistukset on poistettu käytöstä.
+disable_register_prompt=Valitettavasti rekisteröinti on poistettu käytöstä. Ole hyvä ja ota yhteyttä sivuston ylläpitoon.
+disable_register_mail=Valitettavasti sähköpostipalvelut ovat poissa käytöstä. Otathan yhteyttä sivuston ylläpitoon.
 auth_source=Todennuslähde
 local=Paikallinen
 remember_me=Muista minut
 forgot_password=Unohtuiko salasana
 forget_password=Unohtuiko salasana?
 sign_up_now=Tarvitsetko tilin? Rekisteröidy nyt.
-confirmation_mail_sent_prompt=Uusi varmistus sähköposti on lähetetty osoitteeseen <b>%s</b>, ole hyvä ja tarkista saapuneet seuraavan %d tunnin sisällä saadaksesi rekisteröintiprosessin valmiiksi.
+confirmation_mail_sent_prompt=Uusi varmistussähköposti on lähetetty osoitteeseen <b>%s</b>, ole hyvä ja tarkista saapuneet seuraavan %d tunnin sisällä saadaksesi rekisteröintiprosessin valmiiksi.
 active_your_account=Aktivoi tilisi
 prohibit_login=Kirjautuminen kielletty
 prohibit_login_desc=Käyttäjätilisi kirjautuminen on estetty. Ota yhteys sivuston ylläpitäjään.
 resent_limit_prompt=Sori, olet jo tilannut aktivointi sähköpostin lähiaikoina. Ole hyvä ja odota 3 minuuttia ja yritä sitten uudelleen.
-has_unconfirmed_mail=Hei %s, sinulla on varmistamaton sähköposti osoite (<b>%s</b>). Jos et ole saanut varmistus sähköpostia tai tarvitset uudelleenlähetyksen, ole hyvä ja klikkaa allaolevaa painiketta.
-resend_mail=Klikkaa tästä uudelleenlähettääksesi aktivointi sähköpostisi
-send_reset_mail=Klikkaa tästä (uudelleen)lähettääksesi salasanan nollaus sähköpostin
+has_unconfirmed_mail=Hei %s, sinulla on varmistamaton sähköpostiosoite (<b>%s</b>). Jos et ole saanut varmistussähköpostia tai tarvitset uudelleenlähetyksen, ole hyvä ja napsauta allaolevaa painiketta.
+resend_mail=Napsauta tästä uudelleenlähettääksesi aktivointisähköpostisi
+send_reset_mail=Napsauta tästä (uudelleen)lähettääksesi salasanan alustussähköpostin
 reset_password=Nollaa salasanasi
 invalid_code=Sori, varmistuskoodisi on vanhentunut tai väärä.
-reset_password_helper=Klikkaa tästä nollataksesi salasanasi
+reset_password_helper=Napsauta tästä nollataksesi salasanasi
 password_too_short=Salasanan pituus ei voi olla vähemmän kuin 6 merkkiä.
 non_local_account=Vain paikallisten käyttäjätilien salasanan vaihto onnistuu Gogsin kautta.
 
@@ -198,11 +198,11 @@ modify=Muokkaa
 [form]
 UserName=Käyttäjätunnus
 RepoName=Repon nimi
-Email=Sähköposti osoite
+Email=Sähköpostiosoite
 Password=Salasana
 Retype=Kirjoita salasana uudelleen
-SSHTitle=SSH avain nimi
-HttpsUrl=HTTPS URL
+SSHTitle=SSH-avaimen nimi
+HttpsUrl=HTTPS-osoite
 PayloadUrl=Payload URL
 TeamName=Tiimin nimi
 AuthName=Luvan nimi
@@ -242,8 +242,8 @@ enterred_invalid_password=Ole hyvä ja varmista että kirjoittamasi salasana on
 user_not_exist=Käyttäjää ei ole olemassa.
 last_org_owner=Viimeisen käyttäjän poistaminen omistaja tiimistä ei ole sallittu, koska organisaatiossa tulee olla ainakin yksi omistaja.
 
-invalid_ssh_key=Sori, emme pystyneet varmistamaan SSH avainta: %s
-unable_verify_ssh_key=Gogs ei voi varmistaa SSH avaintasi, mutta oletamme että se on toimiva, ole hyvä ja tarkista se.
+invalid_ssh_key=Pahoittelut, emme pystyneet varmistamaan SSH-avainta: %s
+unable_verify_ssh_key=Gogs ei voi varmistaa SSH-avaintasi, mutta oletamme että se on toimiva, ole hyvä ja tarkista se.
 auth_failed=Todennus epäonnistui: %v
 
 still_own_repo=Tililläsi on yhä omistajuus ainakin yhteen repoon, sinun täytyy poistaa tai siirtää ne ensin.
@@ -277,7 +277,7 @@ applications=Sovellukset
 delete=Poista tili
 
 public_profile=Julkinen profiili
-profile_desc=Sähköposti osoitteesi on julkinen ja käytetään tiliin liittyviin ilmoituksiin, ja nettipohjaisiin toimintoihin joita on tehty sivujen kautta.
+profile_desc=Sähköpostiosoitteesi on julkinen ja käytetään tiliin liittyviin ilmoituksiin, ja nettipohjaisiin toimintoihin joita on tehty sivujen kautta.
 password_username_disabled=Ei-paikallinen tyyppisten käyttäjien ei sallita vaihtavan käyttäjänimeä.
 full_name=Kokonimi
 website=Nettisivut
@@ -306,23 +306,23 @@ password_incorrect=Nykyinen salasana ei ole oikea.
 change_password_success=Salasanasi on onnistuneesti vaihdettu. Voit nyt kirjautua sisään käyttäen tätä uutta salasanaa.
 password_change_disabled=Ei-paikallinen tyyppisten käyttäjien ei sallita vaihtavan salasanaa.
 
-emails=Sähköposti osoite
-manage_emails=Hallitse sähköposti osoitteita
+emails=Sähköpostiosoite
+manage_emails=Hallitse sähköpostiosoitteita
 email_desc=Ensisijaista sähköpostiosoitettasi käytetään ilmoituksiin ja muihin toimintoihin.
 primary=Ensisijainen
 primary_email=Aseta ensisijaiseksi
 delete_email=Poista
 email_deletion=Sähköpostin poistaminen
-email_deletion_desc=Tämän sähköposti osoitteen poistaminen poistaa siihen liittyvät tiedot tililtäsi. Haluatko jatkaa?
+email_deletion_desc=Tämän sähköpostiosoitteen poistaminen poistaa siihen liittyvät tiedot tililtäsi. Haluatko jatkaa?
 email_deletion_success=Sähköposti on poistettu onnistuneesti!
 add_new_email=Lisää uusi sähköpostiosoite
 add_email=Lisää sähköposti
-add_email_confirmation_sent=Uusi varmistus sähköposti on lähetetty osoitteeseen '%s', ole hyvä ja tarkista saapuneet seuraavan %d tunnin sisällä saadaksesi rekisteröintiprosessin valmiiksi.
+add_email_confirmation_sent=Uusi varmistussähköposti on lähetetty osoitteeseen '%s', ole hyvä ja tarkista saapuneet seuraavan %d tunnin sisällä saadaksesi rekisteröintiprosessin valmiiksi.
 add_email_success=Uusi sähköpostiosoitteesi on lisätty onnistuneesti.
 
 manage_ssh_keys=Hallitse SSH avaimia
 add_key=Lisää avain
-ssh_desc=Tämä on luettelo tiliisi liitetyistä SSH avaimista. Koska nämä avaimet sallivat kenen tahansa niitä käyttävän pääsevän repoihisi, on erittäin tärkeää että tunnistat ne.
+ssh_desc=Tämä on luettelo tiliisi liitetyistä SSH-avaimista. Koska nämä avaimet sallivat kenen tahansa niitä käyttävän pääsevän repoihisi, on erittäin tärkeää että tunnistat ne.
 ssh_helper=<strong>Etkö tiedä miten?</strong>Tarkista Githubin opas <a href="%s">luo oma SSH avain</a> tai ratkaise <a href="%s">yleisiä ongelmia</a> joita voit kohdata SSHta käyttäessä.
 add_new_key=Lisää SSH avain
 ssh_key_been_used=Julkisen avaimen sisältö on käytetty.
@@ -347,7 +347,7 @@ two_factor_off=Pois käytöstä
 two_factor_enable=Ota käyttöön
 two_factor_disable=Poista käytöstä
 two_factor_view_recovery_codes=Katso ja tallenna <a href="%s%s">palautuskoodejasi</a> turvallisessa paikassa. Voit käyttää niitä salasanoina, jos menetän pääsyn todennussovellukseen.
-two_factor_http=HTTP/HTTPS toimintoihin et voi enää käyttää pelkkää käyttäjänimeä ja salasanaa. Luo ja käytä <a href="%[1]s%[2]s">henkilökohtaisia pääsymerkkejä</a> tunnuksinasi, esimerkiksi <code>%[3]s</code>.
+two_factor_http=HTTP/HTTPS-toimintoihin et voi enää käyttää pelkkää käyttäjänimeä ja salasanaa. Luo ja käytä <a href="%[1]s%[2]s">henkilökohtaisia pääsymerkkejä</a> tunnuksinasi, esimerkiksi <code>%[3]s</code>.
 two_factor_enable_title=Ota käyttöön kaksivaiheinen todennus
 two_factor_scan_qr=Käytä todennus sovellustasi lukeaksesi kuvan:
 two_factor_or_enter_secret=Tai kirjoita salaisuus:
@@ -462,10 +462,10 @@ push_exist_repo=Työnnä olemassaoleva repo komentoriviltä
 bare_message=Tässä repossa ei ole mitään sisältöä vielä.
 
 files=Tiedostot
-branch=Branch
+branch=Haara
 tree=Puu
 filter_branch_and_tag=Suodata haara tai tagi
-branches=Branchit
+branches=Haarat
 tags=Tagit
 issues=Ongelmat
 pulls=Pull-pyynnöt
@@ -519,7 +519,7 @@ editor.directory_is_a_file=Annettu nimi '%s' on tiedosto, ei kansio.
 editor.file_is_a_symlink=Tiedosto '%s' on symlinkki jota ei voi muokata web-selaimesta.
 editor.filename_is_a_directory=Kansio nimeltä '%s' on jo olemassa tässä repossa.
 editor.file_editing_no_longer_exists=Tiedostoa '%s' jota olet muokkaamassa ei ole enää olemassa tässä repossa.
-editor.file_changed_while_editing=Tiedoston sisältöä on muutettu aloittamisesi jälkeen. <a target="_blank" href="%s">Klikkaa tästä</a> nähdäksesi mitä on muutettu tai <strong>paina commit uudelleen</strong> ylikirjoittaaksesi muutokset.
+editor.file_changed_while_editing=Tiedoston sisältöä on muutettu aloittamisesi jälkeen. <a target="_blank" href="%s">Napsauta tästä</a> nähdäksesi mitä on muutettu tai <strong>paina commit uudelleen</strong> ylikirjoittaaksesi muutokset.
 editor.file_already_exists=Tiedosto '%s' on jo olemassa tässä repossa.
 editor.no_changes_to_show=Ei muutoksia näytettäväksi.
 editor.fail_to_update_file=Tiedoston '%s' päivitys/luonti epäonnistui virheeseen: %v
@@ -555,7 +555,7 @@ issues.new_label=Uusi tunniste
 issues.new_label_placeholder=Tunnisteen nimi...
 issues.create_label=Luo tunniste
 issues.label_templates.title=Lataa ennaltamääritelty tarrajoukko
-issues.label_templates.info=Tarroja ei ole. Voit luoda uuden klikkaamalla "Uusi tarra" tai käyttää ennaltamääriteltyä tarrajoukkoa alta.
+issues.label_templates.info=Tarroja ei ole. Voit luoda uuden napsauttamalla "Uusi tarra" tai käyttää ennaltamääriteltyä tarrajoukkoa alta.
 issues.label_templates.helper=Valitse tarrajoukko
 issues.label_templates.use=Käytä tätä tarrajoukkoa
 issues.label_templates.fail_to_load_file=Tarramallin lataus epäonnistui tiedostosta '%s': %v
@@ -615,15 +615,15 @@ issues.label_deletion=Tunnisteen poistaminen
 issues.label_deletion_desc=Tämän tunnisteen poistaminen poistaa sen tiedot kaikista siihen liittyvistä ongelmista. Haluatko jatkaa?
 issues.label_deletion_success=Tunniste on poistettu onnistuneesti!
 issues.num_participants=%d osallistujaa
-issues.attachment.open_tab=`Klikkaa nähdäksesi "%s" uudessa välilehdessä`
-issues.attachment.download=`Klikkaa ladataksesi "%s"`
+issues.attachment.open_tab=`Napsauta nähdäksesi "%s" uudessa välilehdessä`
+issues.attachment.download=`Napsauta ladataksesi "%s"`
 
 pulls.new=Uusi pull pyyntö
 pulls.compare_changes=Vertaa muutoksia
 pulls.compare_changes_desc=Vertaa kahta branchia ja tee pull-pyyntö muutoksista.
 pulls.compare_base=base
 pulls.compare_compare=vertaa
-pulls.filter_branch=Suodata branch
+pulls.filter_branch=Suodata haara
 pulls.no_results=Tuloksia ei löytynyt.
 pulls.nothing_to_compare=Ei ole mitään verrattavaa koska base ja head branchit ovat tasoissa.
 pulls.nothing_merge_base=Ei ole mitään verrattavaa, koska kahdella haaralla on täysin erilainen historia.
@@ -704,7 +704,7 @@ settings.branches_bare=Et voi hallita haaroja tyhjässä repossa. Lisää jotain
 settings.default_branch=Oletushaara
 settings.default_branch_desc=Oletushaaraa käytetään "pohjahaarana" commiteille, pull-pyynnöille ja sivustolla toteutetuille muokkauksille.
 settings.update=Päivitä
-settings.update_default_branch_unsupported=Palvelimella oleva Git versio ei tue oletushaaran vaihtamista.
+settings.update_default_branch_unsupported=Palvelimella oleva Git-versio ei tue oletushaaran vaihtamista.
 settings.update_default_branch_success=Repositoryn oletushaara päivitetty!
 settings.protected_branches=Suojatut haarat
 settings.protected_branches_desc=Suojaa haaroja pakotetulta push-operaatiolta, vahinkopoistamisilta ja sallitun listan committereilta.
@@ -723,7 +723,7 @@ settings.protect_whitelist_teams=Tiimit joiden jäsenet voivat pushata tähän h
 settings.protect_whitelist_search_teams=Etsi tiimejä
 settings.update_protect_branch_success=Tämän haaran suojausasetukset on päivitetty!
 settings.hooks=Webkoukut
-settings.githooks=Git koukut
+settings.githooks=Git-koukut
 settings.basic_settings=Perusasetukset
 settings.mirror_settings=Peilauksen asetukset
 settings.sync_mirror=Synkronisoi nyt
@@ -736,15 +736,15 @@ settings.wiki_desc=Ota wiki käyttöön
 settings.use_internal_wiki=Käytä sisäänrakennettua wikiä
 settings.allow_public_wiki_desc=Salli julkinen pääsy wikiin kun repo on yksityinen
 settings.use_external_wiki=Käytä ulkoista wikiä
-settings.external_wiki_url=Ulkoinen Wiki URL
-settings.external_wiki_url_desc=Vierailijat uudelleenohjataan URL-osoitteeseen kun he klikkaavat välilehteä.
+settings.external_wiki_url=Ulkoisen wikin osoite
+settings.external_wiki_url_desc=Vierailijat uudelleenohjataan URL-osoitteeseen kun he napsauttavat välilehteä.
 settings.issues_desc=Ota virheenseuranta käyttöön
 settings.use_internal_issue_tracker=Käytä sisäänrakennettua kevyttä virheenseurantaa
 settings.allow_public_issues_desc=Salli julkinen pääsy ongelmiin kun repo on yksityinen
 settings.use_external_issue_tracker=Käytä ulkoista vikaseurantaa
 settings.external_tracker_url=Ulkoisen virheenseurannan URL
-settings.external_tracker_url_desc=Vierailijat ohjataan URL-osoitteeseen kun he klikkaavat välilehteä.
-settings.tracker_url_format=Ulkoisen vikaseurannan URL muoto
+settings.external_tracker_url_desc=Vierailijat ohjataan URL-osoitteeseen kun he napsauttavat välilehteä.
+settings.tracker_url_format=Ulkoisen vikaseurannan osoitteen muoto
 settings.tracker_issue_style=Ulkoisen virheenseurannan nimeämistyyli:
 settings.tracker_issue_style.numeric=Numeerinen
 settings.tracker_issue_style.alphanumeric=Aakkosnumeerinen
@@ -784,11 +784,11 @@ settings.add_collaborator=Lisää uusi yhteistyökumppani
 settings.add_collaborator_success=Uusi yhteistyökumppani on lisätty.
 settings.delete_collaborator=Poista
 settings.collaborator_deletion=Yhteistyökumppanin poistaminen
-settings.collaborator_deletion_desc=Tällä käyttäjällä ei tule enää olemaan yhteistyö pääsyä tähän repoon poistamisen jälkeen. Haluatko jatkaa?
+settings.collaborator_deletion_desc=Tällä käyttäjällä ei tule enää olemaan yhteistyöpääsyä tähän repoon poistamisen jälkeen. Haluatko jatkaa?
 settings.remove_collaborator_success=Yhteistyökumppani on poistettu.
 settings.search_user_placeholder=Etsi käyttäjä...
 settings.org_not_allowed_to_be_collaborator=Yhteistyökumppaniksi ei voi lisätä organisaatiota.
-settings.hooks_desc=Webkoukut muistuttavat paljon perus HTTP POST tapahtuma laukaisimia. Aina kun jotain tapahtuu Gogsissa, käsittelemme ilmoituksen määrittäämääsi kohteeseen. Lisätietoja <a target="_blank" href="%s">webkoukku oppaassa</a>.
+settings.hooks_desc=Webkoukut muistuttavat paljon perus HTTP POST -tapahtumalaukaisimia. Aina kun jotain tapahtuu Gogsissa, käsittelemme ilmoituksen määrittäämääsi kohteeseen. Lisätietoja <a target="_blank" href="%s">webkoukku-oppaassa</a>.
 settings.webhooks.add_new=Add a new webhook:
 settings.webhooks.choose_a_type=Choose a type...
 settings.add_webhook=Lisää webkoukku
@@ -812,7 +812,7 @@ settings.githook_edit_desc=Jos koukku ei ole käytössä, esitellään esimerkki
 settings.githook_name=Koukun nimi
 settings.githook_content=Koukun sisältö
 settings.update_githook=Päivitys koukku
-settings.add_webhook_desc=Gogs lähettää <code>POST</code> requestin määrittämääsi URLiin, mukaanlukien tapahtuneen eventin. Voit myös määrittää millaisen tiedostomuodon haluat saada koukun lauettua (JSON, x-www-form-urlencoded, XML, jne). Lisätietoa löytyy meidän <a target="_blank" href="%s">koukut oppaasta</a>.
+settings.add_webhook_desc=Gogs lähettää <code>POST</code>-pyynnön määrittämääsi osoitteeseen, sekä tapahtunutta tapahtumaa koskevat lisätiedot. Voit myös määrittää millaisen tiedostomuodon haluat saada koukun lauettua (JSON, x-www-form-urlencoded, XML, jne). Lisätietoa löytyy <a target="_blank" href="%s">koukut-oppaastamme</a>.
 settings.payload_url=Payload URL
 settings.content_type=Sisältötyyppi
 settings.secret=Salaus
@@ -821,7 +821,7 @@ settings.slack_username=Käyttäjätunnus
 settings.slack_icon_url=Kuvakkeen URL
 settings.slack_color=Väri
 settings.event_desc=Milloin pitäisi tämän webkoukun laueta?
-settings.event_push_only=Vain <code>push</code> tilanteessa.
+settings.event_push_only=Vain <code>push</code>-tilanteessa.
 settings.event_send_everything=Tarvitsen <strong>kaiken</strong>.
 settings.event_choose=Haluan valita, mitä tarvitsen.
 settings.event_create=Luo
@@ -848,9 +848,9 @@ settings.update_hook_success=Webkoukku on päivitetty.
 settings.delete_webhook=Poista webkoukku
 settings.recent_deliveries=Viimeisimmät toimitukset
 settings.hook_type=Koukkutyyppi
-settings.add_slack_hook_desc=Lisää <a href="%s">Slack</a> integraatio repoosi.
-settings.add_discord_hook_desc=Lisää <a href="%s">Discord</a> integraatio repositoryysi.
-settings.add_dingtalk_hook_desc=Lisää <a href="%s">Dingtalk</a> integraatio repositoryysi.
+settings.add_slack_hook_desc=Lisää <a href="%s">Slack</a>-integraatio repoosi.
+settings.add_discord_hook_desc=Lisää <a href="%s">Discord</a>-integraatio repositoryysi.
+settings.add_dingtalk_hook_desc=Lisää <a href="%s">Dingtalk</a>-integraatio repositoryysi.
 settings.slack_token=Pääsymerkki
 settings.slack_domain=Verkkotunnus
 settings.slack_channel=Kanava
@@ -908,7 +908,7 @@ release.save_draft=Tallenna luonnos
 release.edit_release=Muokkaa versiota
 release.delete_release=Poista tämä versio
 release.deletion=Version poisto
-release.deletion_desc=Tämän version poistaminen poistaa vastaavan Git tagin. Haluatko jatkaa?
+release.deletion_desc=Tämän julkaisun poistaminen poistaa vastaavan Git-tagin. Haluatko jatkaa?
 release.deletion_success=Versio on poistettu onnistuneesti!
 release.tag_name_already_exist=Versio tällä taginimellä on jo olemassa.
 release.tag_name_invalid=Tagin nimi ei kelpaa
@@ -1008,14 +1008,14 @@ total=Yhteensä: %d
 
 dashboard.build_info=Build Information
 dashboard.app_ver=Application version
-dashboard.git_version=Git version
+dashboard.git_version=Git-versio
 dashboard.go_version=Go version
 dashboard.build_time=Build time
 dashboard.build_commit=Build commit
 dashboard.statistic=Statistiikka
 dashboard.operations=Toiminnot
 dashboard.system_status=Järjestelmänvalvonnan tila
-dashboard.statistic_info=Gogs tietokannassa on <b>%d</b> käyttäjää, <b>%d</b> organisaatiota, <b>%d</b> julkista avainta, <b>%d</b> repoa, <b>%d</b> tarkkailijaa, <b>%d</b> tähteä, <b>%d</b> toimea, <b>%d</b> sisäänkirjautunutta, <b>%d</b> ongelmaa, <b>%d</b> kommenttia, <b>%d</b> sosiaalista tiliä, <b>%d</b> seuraajaa, <b>%d</b> peiliä, <b>%d</b> julkaisua, <b>%d</b> kirjautumis lähdettä, <b>%d</b> webkoukkua, <b>%d</b> merkkipaalua, <b>%d</b> tunnistetta, <b>%d</b> koukku tehtävää, <b>%d</b> tiimiä, <b>%d</b> päivitys tehtävää, <b>%d</b> liitetiedostoa.
+dashboard.statistic_info=Gogs-tietokannassa on <b>%d</b> käyttäjää, <b>%d</b> organisaatiota, <b>%d</b> julkista avainta, <b>%d</b> repoa, <b>%d</b> tarkkailijaa, <b>%d</b> tähteä, <b>%d</b> toimea, <b>%d</b> sisäänkirjautunutta, <b>%d</b> ongelmaa, <b>%d</b> kommenttia, <b>%d</b> sosiaalista tiliä, <b>%d</b> seuraajaa, <b>%d</b> peiliä, <b>%d</b> julkaisua, <b>%d</b> kirjautumislähdettä, <b>%d</b> webkoukkua, <b>%d</b> merkkipaalua, <b>%d</b> tunnistetta, <b>%d</b> koukkutehtävää, <b>%d</b> tiimiä, <b>%d</b> päivitystehtävää, <b>%d</b> liitetiedostoa.
 dashboard.operation_name=Toiminnon nimi
 dashboard.operation_switch=Vaihda
 dashboard.select_operation_to_run=Please select operation to run
@@ -1030,7 +1030,7 @@ dashboard.delete_missing_repos=Poista kaikki repo tietueet jotka menettivät Git
 dashboard.delete_missing_repos_success=Kaikki repo tietueet jotka menettivät Git tiedostoja on poistettu onnistuneesti.
 dashboard.git_gc_repos=Suorita roskienkeruu repoille
 dashboard.git_gc_repos_success=Kaikki repot ovat tehneet roskienkeruun onnistuneesti.
-dashboard.resync_all_sshkeys=Uudelleenkirjoita '.ssh/authorized_keys' tiedosto (varoitus: ei-Gogs avaimet menetetään)
+dashboard.resync_all_sshkeys=Uudelleenkirjoita '.ssh/authorized_keys' -tiedosto (varoitus: ei-Gogs-avaimet menetetään)
 dashboard.resync_all_sshkeys_success=Kaikki julkiset avaimet on uudelleenkirjoitettu onnistuneesti.
 dashboard.resync_all_hooks=Uudelleensynkronoi kaikkien repositoryjen "pre-receive, update ja post-receive" hookit.
 dashboard.resync_all_hooks_success=Kaikkien repositoryjen "pre-receive, update ja post-receive" hookit synkronoitu.
@@ -1171,28 +1171,28 @@ config.server_config=Palvelinasetukset
 config.brand_name=Brand name
 config.run_user=Suorita käyttäjänä
 config.run_mode=Suoritustila
-config.server.external_url=External URL
+config.server.external_url=Ulkoinen osoite
 config.server.domain=Domain
 config.server.protocol=Protocol
-config.server.http_addr=HTTP address
-config.server.http_port=HTTP port
+config.server.http_addr=HTTP-osoite
+config.server.http_port=HTTP-portti
 config.server.cert_file=Certificate file
 config.server.key_file=Key file
 config.server.tls_min_version=Minimum TLS version
 config.server.unix_socket_permission=Unix socket permission
 config.server.local_root_url=Local root URL
-config.server.offline_mode=Offline mode
+config.server.offline_mode=Yhteydetön tila
 config.server.disable_router_log=Disable router log
-config.server.enable_gzip=Enable Gzip
+config.server.enable_gzip=Ota käyttöön Gzip
 config.server.app_data_path=Application data path
 config.server.load_assets_from_disk=Load assets from disk
 config.server.landing_url=Landing URL
 
 config.ssh_config=SSH asetukset
-config.ssh.enabled=Enabled
+config.ssh.enabled=Käytössä
 config.ssh.domain=Exposed domain
 config.ssh.port=Exposed port
-config.ssh.root_path=Root path
+config.ssh.root_path=Juuripolku
 config.ssh.keygen_path=Keygen path
 config.ssh.key_test_path=Key test path
 config.ssh.minimum_key_size_check=Minimum key size check
@@ -1227,8 +1227,8 @@ config.db.type=Type
 config.db.host=Host
 config.db.name=Name
 config.db.user=User
-config.db.ssl_mode=SSL mode
-config.db.ssl_mode_helper=(for "postgres" only)
+config.db.ssl_mode=SSL-tila
+config.db.ssl_mode_helper=(vain "postgres")
 config.db.path=Path
 config.db.path_helper=(for "sqlite3"only)
 config.db.max_open_conns=Maximum open connections
@@ -1258,7 +1258,7 @@ config.email.key_file=Key file
 config.email.use_plain_text=Use plain text
 config.email.add_plain_text_alt=Add plain text alternative
 config.email.send_test_mail=Send test email
-config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_failed=Testisähköpostin lähettäminen vastaanottajalle '%s' epäonnistui: %v
 config.email.test_mail_sent=Test email has been sent to '%s'.
 
 config.auth_config=Authentication configuration
@@ -1279,7 +1279,7 @@ config.session_config=Istunnon asetukset
 config.session.provider=Provider
 config.session.provider_config=Provider config
 config.session.cookie_name=Cookie
-config.session.https_only=HTTPS only
+config.session.https_only=Vain HTTPS
 config.session.gc_interval=GC interval
 config.session.max_life_time=Max life time
 config.session.csrf_cookie_name=CSRF cookie
@@ -1308,8 +1308,8 @@ config.release.attachment.max_files=Attachment files limit
 config.picture_config=Kuva asetukset
 config.picture.avatar_upload_path=User avatar upload path
 config.picture.repo_avatar_upload_path=Repository avatar upload path
-config.picture.gravatar_source=Gravatar source
-config.picture.disable_gravatar=Disable Gravatar
+config.picture.gravatar_source=Gravatar-lähde
+config.picture.disable_gravatar=Poista Gravatar käytöstä
 config.picture.enable_federated_avatar=Enable federated avatars
 
 config.mirror_config=Mirror configuration
@@ -1409,10 +1409,10 @@ months=%d kuukautta %s
 years=%d vuotta %s
 raw_seconds=sekuntia
 raw_minutes=minuuttia
-raw_hours=hours
+raw_hours=tuntia
 
 [dropzone]
-default_message=Pudota tiedostot tähän tai klikkaa lataamista varten.
+default_message=Pudota tiedostot tähän tai napsauta lataamista varten.
 invalid_input_type=Tämäntyyppisiä tiedostoja ei voi ladata.
 file_too_big=Tiedostokoko ({{filesize}} MB) koko ylittää enimmäiskoon ({{maxFilesize}} MB).
 remove_file=Poista tiedosto

+ 35 - 35
conf/locale/locale_fr-FR.ini

@@ -44,8 +44,8 @@ issues=Tickets
 cancel=Annuler
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Page non trouvée
+internal_server_error=Erreur interne du serveur
 
 [install]
 install=Installation
@@ -125,7 +125,7 @@ run_user_not_match=L'utilisateur d'exécution saisi n'est pas l'utilisateur d'ex
 smtp_host_missing_port=Le numéro de port est manquant dans l'adresse de l'Hôte SMTP.
 invalid_smtp_from=Le champ SMTP Provenant de n'est pas valide: %v
 save_config_failed=La sauvegarde de la configuration a échoué : %v
-init_failed=Failed to initialize application: %v
+init_failed=L'initialisation de l'application a échoué.
 invalid_admin_setting=Paramètres du compte administrateur invalides : %v
 install_success=Bienvenue ! Nous sommes heureux que vous ayez choisi Gogs, amusez-vous et prenez soin de vous.
 invalid_log_root_path=L'emplacement racine des fichiers logs est invalide : %v
@@ -790,7 +790,7 @@ settings.search_user_placeholder=Rechercher un utilisateur...
 settings.org_not_allowed_to_be_collaborator=Une organisation n'est pas autorisée à être ajoutée en tant que collaborateur.
 settings.hooks_desc=Les Webhooks sont des déclencheurs de POST HTTP . Lorsque qu'un événement se produit dans Gogs, une notification sera envoyée vers l'hôte cible préalablement spécifié. Apprenez-en davantage dans le <a target="_blank" href="%s">Guide des Webhooks</a>.
 settings.webhooks.add_new=Add a new webhook:
-settings.webhooks.choose_a_type=Choose a type...
+settings.webhooks.choose_a_type=Choisis le type de...
 settings.add_webhook=Ajouter un Webhook
 settings.webhook_deletion=Supprimer le Webhook
 settings.webhook_deletion_desc=Supprimer ce webhook va supprimer ses informations et l'historique de livraison. Voulez-vous continuer ?
@@ -805,7 +805,7 @@ settings.webhook.response=Réponse
 settings.webhook.headers=Entêtes 
 settings.webhook.payload=Payload
 settings.webhook.body=Corps
-settings.webhook.err_cannot_parse_payload_url=Cannot parse payload URL: %v
+settings.webhook.err_cannot_parse_payload_url=Impossible d'analyser l'URL : %v
 settings.webhook.err_cannot_use_local_addresses=Non admins are not allowed to use local addresses.
 settings.githooks_desc=Les Hooks Git sont alimentés par Git lui même. Les Hooks compatibles sont modifiables dans la liste ci-dessous pour effectuer des opérations personnalisées.
 settings.githook_edit_desc=Si un Hook est inactif, un exemple de contenu vous sera proposé. Un contenu laissé vide signifie un Hook inactif.
@@ -934,7 +934,7 @@ team_desc_helper=Présentation de l'équipe
 team_permission_desc=Quel niveau d'accès cette équipe devrait-elle posséder ?
 
 form.name_not_allowed=Organization name or pattern %q is not allowed.
-form.team_name_not_allowed=Team name or pattern %q is not allowed.
+form.team_name_not_allowed=Le nom de l'équipe ou le pattern %q n'est pas autorisé.
 
 settings=Paramètres
 settings.options=Options
@@ -1006,12 +1006,12 @@ first_page=Première
 last_page=Dernière
 total=Total : %d
 
-dashboard.build_info=Build Information
-dashboard.app_ver=Application version
-dashboard.git_version=Git version
-dashboard.go_version=Go version
-dashboard.build_time=Build time
-dashboard.build_commit=Build commit
+dashboard.build_info=Informations sur la construction
+dashboard.app_ver=Version de l'application
+dashboard.git_version=Version de Git
+dashboard.go_version=Version de Go
+dashboard.build_time=Temps de compilation
+dashboard.build_commit=Commit
 dashboard.statistic=Statistiques
 dashboard.operations=Opérations
 dashboard.system_status=État du système
@@ -1172,10 +1172,10 @@ config.brand_name=Brand name
 config.run_user=Utilisateur système
 config.run_mode=Mode d'Éxécution
 config.server.external_url=External URL
-config.server.domain=Domain
-config.server.protocol=Protocol
-config.server.http_addr=HTTP address
-config.server.http_port=HTTP port
+config.server.domain=Domaine
+config.server.protocol=Protocole
+config.server.http_addr=Adresse HTTP
+config.server.http_port=Port HTTP
 config.server.cert_file=Certificate file
 config.server.key_file=Key file
 config.server.tls_min_version=Minimum TLS version
@@ -1189,18 +1189,18 @@ config.server.load_assets_from_disk=Load assets from disk
 config.server.landing_url=Landing URL
 
 config.ssh_config=Configuration SSH
-config.ssh.enabled=Enabled
-config.ssh.domain=Exposed domain
-config.ssh.port=Exposed port
-config.ssh.root_path=Root path
+config.ssh.enabled=Activé
+config.ssh.domain=Domaine exposé
+config.ssh.port=Port exposé
+config.ssh.root_path=Emplacement racine
 config.ssh.keygen_path=Keygen path
 config.ssh.key_test_path=Key test path
 config.ssh.minimum_key_size_check=Minimum key size check
 config.ssh.minimum_key_sizes=Minimum key sizes
 config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
-config.ssh.start_builtin_server=Start builtin server
-config.ssh.listen_host=Listen host
-config.ssh.listen_port=Listen port
+config.ssh.start_builtin_server=Démarrer le serveur intégré
+config.ssh.listen_host=Hôte en écoute
+config.ssh.listen_port=Port d'écoute
 config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Configuration du dépôt
@@ -1225,31 +1225,31 @@ config.repo.upload.max_files=Upload files limit
 config.db_config=Configuration de la Base de Données
 config.db.type=Type
 config.db.host=Host
-config.db.name=Name
-config.db.user=User
-config.db.ssl_mode=SSL mode
-config.db.ssl_mode_helper=(for "postgres" only)
-config.db.path=Path
+config.db.name=Nom
+config.db.user=Utilisateur
+config.db.ssl_mode=Mode SSL
+config.db.ssl_mode_helper=("postgres" uniquement)
+config.db.path=Chemin
 config.db.path_helper=(for "sqlite3"only)
 config.db.max_open_conns=Maximum open connections
 config.db.max_idle_conns=Maximum idle connections
 
 config.security_config=Security configuration
 config.security.login_remember_days=Login remember days
-config.security.cookie_remember_name=Remember cookie
+config.security.cookie_remember_name=Mémoriser le cookie
 config.security.cookie_username=Username cookie
 config.security.cookie_secure=Enable secure cookie
 config.security.reverse_proxy_auth_user=Reverse proxy authentication header
 config.security.enable_login_status_cookie=Enable login status cookie
 config.security.login_status_cookie_name=Login status cookie
 
-config.email_config=Email configuration
-config.email.enabled=Enabled
+config.email_config=Configuration de l’e-mail
+config.email.enabled=Activé
 config.email.subject_prefix=Subject prefix
-config.email.host=Host
-config.email.from=From
-config.email.user=User
-config.email.disable_helo=Disable HELO
+config.email.host=Hôte
+config.email.from=De:
+config.email.user=Utilisateur
+config.email.disable_helo=Désactiver HELO
 config.email.helo_hostname=HELO hostname
 config.email.skip_verify=Skip certificate verify
 config.email.use_certificate=Use custom certificate

+ 29 - 29
conf/locale/locale_it-IT.ini

@@ -44,8 +44,8 @@ issues=Problemi
 cancel=Annulla
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Pagina Non Trovata
+internal_server_error=Errore Interno del Server
 
 [install]
 install=Installazione
@@ -125,7 +125,7 @@ run_user_not_match=Run user non è l'utente corrente:  %s -> %s
 smtp_host_missing_port=All'Host SMTP manca la porta nell'indirizzo.
 invalid_smtp_from=Campo SMTP From non valido: %v
 save_config_failed=Fallito il salvataggio della configurazione: %v
-init_failed=Failed to initialize application: %v
+init_failed=Impossibile inizializzare l'applicazione: %v
 invalid_admin_setting=Impostazioni account Admin non valide: %v
 install_success=Benvenuto! Siamo felici che tu abbia scelto Gogs, buon divertimento.
 invalid_log_root_path=Percorso deilog non valido: %v
@@ -263,7 +263,7 @@ following=Seguiti
 follow=Segui
 unfollow=Non seguire più
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Nome utente o schema %q non consentito.
 
 [settings]
 profile=Profilo
@@ -377,7 +377,7 @@ delete_token=Elimina
 access_token_deletion=Eliminazione Token di accesso personale
 access_token_deletion_desc=Eliminare questo token di accesso personale rimuoverà tutti i relativi accessi di applicazione. Si desidera continuare?
 delete_token_success=Il token di accesso personale è stato eliminato! Non dimenticare di aggiornare anche l'applicazione.
-token_name_exists=Token with same name already exists.
+token_name_exists=Un token con lo stesso nome esiste già.
 
 orgs.none=Non sei membro di alcuna organizzazione.
 orgs.leave_title=Abbandona una organizzazione
@@ -417,7 +417,7 @@ auto_init=Inizializzare questo repository con i file e il modello selezionati
 create_repo=Crea Repository
 default_branch=Ramo (Branch) predefinito
 mirror_prune=Rimuovi
-mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
+mirror_prune_desc=Rimuovi ogni riferimento di monitoraggio remoto che non esiste più sul telecomando
 mirror_interval=Intervallo Mirror (in ore)
 mirror_address=Indirizzo del mirror
 mirror_address_desc=Si prega di includere nell'indirizzo le credenziali utente necessarie.
@@ -425,11 +425,11 @@ mirror_last_synced=Ultimo aggiornamento
 watchers=Osservatori
 stargazers=Fan
 forks=Fork
-repo_description_helper=Description of repository. Maximum 512 characters length.
+repo_description_helper=Descrizione della repository. Lunghezza massima di 512 caratteri.
 repo_description_length=Caratteri disponibili
 
 form.reach_limit_of_creation=Il proprietario ha raggiunto il limite massimo di %d repository creati.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=Nome della repository o schema %q non consentiti.
 
 need_auth=Richiesta di autorizzazione
 migrate_type=Tipo di migrazione
@@ -1183,7 +1183,7 @@ config.server.unix_socket_permission=Unix socket permission
 config.server.local_root_url=Local root URL
 config.server.offline_mode=Offline mode
 config.server.disable_router_log=Disable router log
-config.server.enable_gzip=Enable Gzip
+config.server.enable_gzip=Abilita Gzip
 config.server.app_data_path=Application data path
 config.server.load_assets_from_disk=Load assets from disk
 config.server.landing_url=Landing URL
@@ -1223,14 +1223,14 @@ config.repo.upload.file_max_size=Upload file size limit
 config.repo.upload.max_files=Upload files limit
 
 config.db_config=Configurazione Database
-config.db.type=Type
+config.db.type=Tipo
 config.db.host=Host
-config.db.name=Name
-config.db.user=User
-config.db.ssl_mode=SSL mode
-config.db.ssl_mode_helper=(for "postgres" only)
-config.db.path=Path
-config.db.path_helper=(for "sqlite3"only)
+config.db.name=Nome
+config.db.user=Utente
+config.db.ssl_mode=modalità SSL
+config.db.ssl_mode_helper=(solo per "postgres")
+config.db.path=Percorso
+config.db.path_helper=(solo per "sqlite3")
 config.db.max_open_conns=Maximum open connections
 config.db.max_idle_conns=Maximum idle connections
 
@@ -1247,17 +1247,17 @@ config.email_config=Email configuration
 config.email.enabled=Enabled
 config.email.subject_prefix=Subject prefix
 config.email.host=Host
-config.email.from=From
-config.email.user=User
-config.email.disable_helo=Disable HELO
+config.email.from=Da
+config.email.user=Utente
+config.email.disable_helo=Disattiva HELO
 config.email.helo_hostname=HELO hostname
 config.email.skip_verify=Skip certificate verify
 config.email.use_certificate=Use custom certificate
-config.email.cert_file=Certificate file
+config.email.cert_file=File certificato
 config.email.key_file=Key file
-config.email.use_plain_text=Use plain text
+config.email.use_plain_text=Usa testo semplice
 config.email.add_plain_text_alt=Add plain text alternative
-config.email.send_test_mail=Send test email
+config.email.send_test_mail=Invia email di test
 config.email.test_mail_failed=Failed to send test email to '%s': %v
 config.email.test_mail_sent=Test email has been sent to '%s'.
 
@@ -1279,22 +1279,22 @@ config.session_config=Configurazione Sessione
 config.session.provider=Provider
 config.session.provider_config=Provider config
 config.session.cookie_name=Cookie
-config.session.https_only=HTTPS only
+config.session.https_only=Solo HTTPS
 config.session.gc_interval=GC interval
 config.session.max_life_time=Max life time
-config.session.csrf_cookie_name=CSRF cookie
+config.session.csrf_cookie_name=Cookie CSRF
 
 config.cache_config=Configurazione Cache
-config.cache.adapter=Adapter
-config.cache.interval=GC interval
+config.cache.adapter=Adattatore
+config.cache.interval=Intervallo GC
 config.cache.host=Host
 
 config.http_config=Configurazione HTTP
 config.http.access_control_allow_origin=Access control allow origin
 
 config.attachment_config=Attachment configuration
-config.attachment.enabled=Enabled
-config.attachment.path=Path
+config.attachment.enabled=Attivo
+config.attachment.path=Percorso
 config.attachment.allowed_types=Allowed types
 config.attachment.max_size=Size limit
 config.attachment.max_files=Files limit
@@ -1409,7 +1409,7 @@ months=%d mesi %s
 years=%d anni %s
 raw_seconds=secondi
 raw_minutes=minuti
-raw_hours=hours
+raw_hours=ore
 
 [dropzone]
 default_message=Trascina i file qui o clicca per caricare.

+ 41 - 41
conf/locale/locale_ja-JP.ini

@@ -44,8 +44,8 @@ issues=課題
 cancel=キャンセル
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=ページが見つかりません
+internal_server_error=サーバ内部エラー
 
 [install]
 install=インストール
@@ -934,7 +934,7 @@ team_desc_helper=このチームに関する全ての情報は?
 team_permission_desc=このチームに必要な権限レベルは?
 
 form.name_not_allowed=Organization name or pattern %q is not allowed.
-form.team_name_not_allowed=Team name or pattern %q is not allowed.
+form.team_name_not_allowed=チーム名またはパターン %q は許可されていません。
 
 settings=設定
 settings.options=オプション
@@ -1010,7 +1010,7 @@ dashboard.build_info=ビルド情報
 dashboard.app_ver=アプリケーションのバージョン
 dashboard.git_version=Git バージョン
 dashboard.go_version=Go バージョン
-dashboard.build_time=Build time
+dashboard.build_time=ビルド日時
 dashboard.build_commit=Build commit
 dashboard.statistic=統計
 dashboard.operations=操作
@@ -1018,7 +1018,7 @@ dashboard.system_status=システム モニターのステータス
 dashboard.statistic_info=Gogs データベースは <b>%d</b> 人のユーザー、<b>%d</b> 個の組織、<b>%d</b> 個の公開鍵、<b>%d</b> 個のリポジトリ、<b>%d</b> 個のウォッチ、<b>%d</b> 個のスター、<b>%d</b> 回のアクション、<b>%d</b> 回のアクセス、<b>%d</b> 個の課題、<b>%d</b> 個のコメント、<b>%d</b> 個のソーシャルアカウント、<b>%d</b> 個のフォロー、<b>%d</b> 個のミラー、<b>%d</b> 個のリリース、<b>%d</b> 個のログイン元、<b>%d</b> 個のwebフック、<b>%d</b> 個のマイルストーン、<b>%d</b> 個のラベル、<b>%d</b> 個のフックタスク、<b>%d</b> 個のチーム、<b>%d</b> 更新タスク、<b>%d</b> 個の添付ファイルの情報を保持しています。
 dashboard.operation_name=操作の名前
 dashboard.operation_switch=スイッチ
-dashboard.select_operation_to_run=Please select operation to run
+dashboard.select_operation_to_run=操作を選択してください
 dashboard.operation_run=実行
 dashboard.clean_unbind_oauth=結び付けられていない OAuth をクリーン
 dashboard.clean_unbind_oauth_success=結び付けられていない全ての OAuth を正常に削除しました。
@@ -1180,11 +1180,11 @@ config.server.cert_file=証明書ファイル
 config.server.key_file=キーファイル
 config.server.tls_min_version=最小TLSバージョン
 config.server.unix_socket_permission=Unixソケットの権限
-config.server.local_root_url=Local root URL
+config.server.local_root_url=ローカル ルート URL
 config.server.offline_mode=オフラインモード
 config.server.disable_router_log=ルーターログを無効にする
 config.server.enable_gzip=Gzip を有効化
-config.server.app_data_path=Application data path
+config.server.app_data_path=アプリケーション データ パス
 config.server.load_assets_from_disk=Load assets from disk
 config.server.landing_url=Landing URL
 
@@ -1193,8 +1193,8 @@ config.ssh.enabled=Enabled
 config.ssh.domain=Exposed domain
 config.ssh.port=Exposed port
 config.ssh.root_path=Root path
-config.ssh.keygen_path=Keygen path
-config.ssh.key_test_path=Key test path
+config.ssh.keygen_path=Keygen パス
+config.ssh.key_test_path=鍵テストパス
 config.ssh.minimum_key_size_check=最小キーサイズチェック
 config.ssh.minimum_key_sizes=最小キーサイズ
 config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
@@ -1206,7 +1206,7 @@ config.ssh.server_ciphers=Server ciphers
 config.repo_config=リポジトリの設定
 config.repo.root_path=Root path
 config.repo.script_type=Script type
-config.repo.ansi_chatset=ANSI charset
+config.repo.ansi_chatset=ANSI 文字コード
 config.repo.force_private=非公開にする
 config.repo.max_creation_limit=最大作成数
 config.repo.preferred_licenses=Preferred licenses
@@ -1223,13 +1223,13 @@ config.repo.upload.file_max_size=Upload file size limit
 config.repo.upload.max_files=Upload files limit
 
 config.db_config=データベース設定
-config.db.type=Type
-config.db.host=Host
-config.db.name=Name
-config.db.user=User
+config.db.type=DB種類
+config.db.host=DBホスト
+config.db.name=DB名
+config.db.user=DBユーザー
 config.db.ssl_mode=SSL モード
 config.db.ssl_mode_helper=("postgres"のみ)
-config.db.path=Path
+config.db.path=DBパス
 config.db.path_helper=("sqlite3"のみ)
 config.db.max_open_conns=Maximum open connections
 config.db.max_idle_conns=Maximum idle connections
@@ -1246,16 +1246,16 @@ config.security.login_status_cookie_name=Login status cookie
 config.email_config=Email configuration
 config.email.enabled=Enabled
 config.email.subject_prefix=Subject prefix
-config.email.host=Host
+config.email.host=ホスト
 config.email.from=From
-config.email.user=User
-config.email.disable_helo=Disable HELO
+config.email.user=ユーザー
+config.email.disable_helo=HELOを無効にする
 config.email.helo_hostname=HELO hostname
 config.email.skip_verify=Skip certificate verify
 config.email.use_certificate=Use custom certificate
 config.email.cert_file=Certificate file
 config.email.key_file=Key file
-config.email.use_plain_text=Use plain text
+config.email.use_plain_text=プレーンテキストを使用する
 config.email.add_plain_text_alt=Add plain text alternative
 config.email.send_test_mail=Send test email
 config.email.test_mail_failed=Failed to send test email to '%s': %v
@@ -1266,14 +1266,14 @@ config.auth.activate_code_lives=Activate code lives
 config.auth.reset_password_code_lives=Reset password code lives
 config.auth.require_email_confirm=Require email confirmation
 config.auth.require_sign_in_view=Require sign in view
-config.auth.disable_registration=Disable registration
-config.auth.enable_registration_captcha=Enable registration captcha
-config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
-config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
-config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+config.auth.disable_registration=登録を無効にする
+config.auth.enable_registration_captcha=登録時のCAPTCHAを有効にする
+config.auth.enable_reverse_proxy_authentication=リバースプロキシ認証を有効にする
+config.auth.enable_reverse_proxy_auto_registration=リバースプロキシの自動登録を有効にする
+config.auth.reverse_proxy_authentication_header=リバースプロキシ認証ヘッダー
 
-config.user_config=User configuration
-config.user.enable_email_notify=Enable email notification
+config.user_config=ユーザー設定
+config.user.enable_email_notify=メール通知を有効にする
 
 config.session_config=セッションの設定
 config.session.provider=Provider
@@ -1287,28 +1287,28 @@ config.session.csrf_cookie_name=CSRF cookie
 config.cache_config=キャッシュの設定
 config.cache.adapter=Adapter
 config.cache.interval=GC 間隔
-config.cache.host=Host
+config.cache.host=ホスト
 
 config.http_config=HTTP の設定
 config.http.access_control_allow_origin=Access control allow origin
 
 config.attachment_config=Attachment configuration
 config.attachment.enabled=Enabled
-config.attachment.path=Path
+config.attachment.path=パス
 config.attachment.allowed_types=Allowed types
 config.attachment.max_size=サイズ制限
 config.attachment.max_files=ファイルの制限
 
 config.release_config=リリースの構成
-config.release.attachment.enabled=Attachment enabled
-config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.enabled=添付ファイルが有効になっています
+config.release.attachment.allowed_types=添付ファイルで許可されるタイプ
 config.release.attachment.max_size=添付ファイルのサイズ制限
-config.release.attachment.max_files=Attachment files limit
+config.release.attachment.max_files=添付ファイルのサイズ制限
 
 config.picture_config=画像の設定
 config.picture.avatar_upload_path=User avatar upload path
 config.picture.repo_avatar_upload_path=Repository avatar upload path
-config.picture.gravatar_source=Gravatar source
+config.picture.gravatar_source=Gravatarのソース
 config.picture.disable_gravatar=Gravatarを無効にする
 config.picture.enable_federated_avatar=Enable federated avatars
 
@@ -1317,23 +1317,23 @@ config.mirror.default_interval=Default interval
 
 config.webhook_config=Webhook設定
 config.webhook.types=Types
-config.webhook.deliver_timeout=Deliver timeout
-config.webhook.skip_tls_verify=Skip TLS verify
+config.webhook.deliver_timeout=配信のタイムアウト
+config.webhook.skip_tls_verify=TLS検証をスキップ
 
 config.git_config=Git 設定
-config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.disable_diff_highlight=Diff のシンタックスハイライトを無効にする
 config.git.max_diff_lines=Diff lines limit (for a single file)
-config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_line_characters=Diff の最大文字数(1行あたり)
 config.git.max_diff_files=Diff files limit (for a single diff)
 config.git.gc_args=GC の引数
 config.git.migrate_timeout=Migration timeout
 config.git.mirror_timeout=Mirror fetch timeout
-config.git.clone_timeout=Clone timeout
+config.git.clone_timeout=クローンのタイムアウト
 config.git.pull_timeout=Pull タイムアウト
-config.git.gc_timeout=GC timeout
+config.git.gc_timeout=GC タイムアウト
 
-config.lfs_config=LFS configuration
-config.lfs.storage=Storage
+config.lfs_config=LFS設定
+config.lfs.storage=ストレージ
 config.lfs.objects_path=Objects path
 
 config.log_config=ログの設定
@@ -1409,7 +1409,7 @@ months=%d ヶ月 %s
 years=%d 年 %s
 raw_seconds=秒
 raw_minutes=分
-raw_hours=hours
+raw_hours=時間
 
 [dropzone]
 default_message=ここにファイルをドロップまたはクリックしてアップロードします。

+ 4 - 4
conf/locale/locale_ko-KR.ini

@@ -44,8 +44,8 @@ issues=이슈
 cancel=취소
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=페이지를 찾을 수 없음
+internal_server_error=내부 서버 오류
 
 [install]
 install=설치
@@ -263,7 +263,7 @@ following=팔로우 중
 follow=추적하기
 unfollow=추적해제
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=사용자 이름 또는 패턴 %q 은(는) 허용되지 않습니다.
 
 [settings]
 profile=프로필
@@ -429,7 +429,7 @@ repo_description_helper=저장소 설명.최대 512길이의 문자열이 가능
 repo_description_length=가능한 문자열입니다.
 
 form.reach_limit_of_creation=소유자가 저장소 만들기 최대 제한에 (%d개) 도달했습니다.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=저장소명 또는 패턴 %q 은(는) 허용되지 않습니다.
 
 need_auth=인증 필요
 migrate_type=마이그레이션 유형

+ 1419 - 0
conf/locale/locale_mn-MN.ini

@@ -0,0 +1,1419 @@
+app_desc=Хамгийн хялбар GIT үйлчилгээ
+
+home=Эхлэл
+dashboard=Удирдлага
+explore=Бүгдийг харах
+help=Тусламж
+sign_in=Нэвтрэх
+sign_out=Гарах
+sign_up=Бүртгүүлэх
+register=Бүртгүүлэх
+website=Вэбсайт
+page=Хуудас
+template=Загвар
+language=Хэл
+create_new=Шинээр нэмэх...
+user_profile_and_more=Хэрэглэгчийн профайл болон бусад
+signed_in_as=Нэвтэрсэн хэрэглэгч
+
+username=Нэвтрэх нэр
+email=Имэйл
+password=Нууц үг
+re_type=Дахин бичих
+captcha=Батлах тэмдэгт
+
+repository=Репо
+organization=Байгууллага
+mirror=Хуулбарлах
+new_repo=Шинэ Репо
+new_migrate=Шинэ
+new_mirror=Шинэ хуулбар
+new_fork=Шинэ Репо Салаалах
+new_org=Шинэ Байгууллага
+manage_org=Байгууллага удирдах
+admin_panel=Админ удирдлага
+account_settings=Дансны тохиргоо
+settings=Тохиргоо
+your_profile=Таны профайл
+your_settings=Таны тохиргоо
+
+activities=Үйлдлүүд
+pull_requests=Татаж авах хүсэлтүүд
+issues=Асуудал
+
+cancel=Болих
+
+[status]
+page_not_found=Хуудас олдсонгүй
+internal_server_error=Сервертэй холбогдоход алдаа гарлаа.
+
+[install]
+install=Суулгах
+title=Install Steps For First-time Run
+docker_helper=If you're running Gogs inside Docker, please read <a target="_blank" href="%s">Guidelines</a> carefully before you change anything in this page!
+requite_db_desc=Gogs requires MySQL, PostgreSQL, SQLite3 or TiDB (via MySQL protocol).
+db_title=Database Settings
+db_type=Database Type
+host=Host
+user=User
+password=Password
+db_name=Database Name
+db_helper=Please use INNODB engine with utf8_general_ci charset for MySQL.
+ssl_mode=SSL Mode
+path=Path
+sqlite_helper=The file path of SQLite3 database. <br>Please use absolute path when you start as service.
+err_empty_db_path=SQLite3 database path cannot be empty.
+no_admin_and_disable_registration=You cannot disable registration without creating an admin account.
+err_empty_admin_password=Admin password cannot be empty.
+
+general_title=Application General Settings
+app_name=Application Name
+app_name_helper=Put your organization name here huge and loud!
+repo_path=Repository Root Path
+repo_path_helper=All Git remote repositories will be saved to this directory.
+run_user=Run User
+run_user_helper=The user must have access to Repository Root Path and run Gogs.
+domain=Domain
+domain_helper=This affects SSH clone URLs.
+ssh_port=SSH Port
+ssh_port_helper=Port number which your SSH server is using, leave it empty to disable SSH feature.
+use_builtin_ssh_server=Use Builtin SSH Server
+use_builtin_ssh_server_popup=Start builtin SSH server for Git operations to distinguish from system SSH daemon.
+http_port=HTTP Port
+http_port_helper=Port number which application will listen on.
+app_url=Application URL
+app_url_helper=This affects HTTP/HTTPS clone URL and somewhere in email.
+log_root_path=Log Path
+log_root_path_helper=Directory to write log files to.
+enable_console_mode=Enable Console Mode
+enable_console_mode_popup=In addition to file mode, also print logs to console.
+
+optional_title=Optional Settings
+email_title=Email Service Settings
+smtp_host=SMTP Host
+smtp_from=From
+smtp_from_helper=Mail from address, RFC 5322. It can be just an email address, or the "Name" <email@example.com> format.
+mailer_user=Sender Email
+mailer_password=Sender Password
+register_confirm=Enable Register Confirmation
+mail_notify=Enable Mail Notification
+server_service_title=Server and Other Services Settings
+offline_mode=Enable Offline Mode
+offline_mode_popup=Disable CDN even in production mode, all resource files will be served locally.
+disable_gravatar=Disable Gravatar Service
+disable_gravatar_popup=Disable Gravatar and custom sources, all avatars are uploaded by users or default.
+federated_avatar_lookup=Enable Federated Avatars Lookup
+federated_avatar_lookup_popup=Enable federated avatars lookup to use federated open source service based on libravatar.
+disable_registration=Disable Self-registration
+disable_registration_popup=Disable user self-registration, only admin can create accounts.
+enable_captcha=Enable Captcha
+enable_captcha_popup=Require validate captcha for user self-registration.
+require_sign_in_view=Enable Require Sign In to View Pages
+require_sign_in_view_popup=Only signed in users can view pages, visitors will only be able to see sign in/up pages.
+admin_setting_desc=You don't need to create an admin account right now. The first user in the users table will be automatically granted admin access.
+admin_title=Admin Account Settings
+admin_name=Username
+admin_password=Password
+confirm_password=Confirm Password
+admin_email=Admin Email
+install_gogs=Install Gogs
+test_git_failed=Failed to test 'git' command: %v
+sqlite3_not_available=Your release version does not support SQLite3, please download the official binary version from %s, NOT the gobuild version.
+invalid_db_setting=Database setting is not correct: %v
+invalid_repo_path=Repository root path is invalid: %v
+run_user_not_match=Run user isn't the current user: %s -> %s
+smtp_host_missing_port=SMTP Host port missing from address.
+invalid_smtp_from=SMTP From field is invalid: %v
+save_config_failed=Failed to save configuration: %v
+init_failed=Failed to initialize application: %v
+invalid_admin_setting=Admin account setting is invalid: %v
+install_success=Welcome! We're glad that you chose Gogs, have fun and take care.
+invalid_log_root_path=Log root path is invalid: %v
+
+[home]
+uname_holder=Нэвтрэх нэр эсвэл имэйл
+password_holder=Нууц үг
+switch_dashboard_context=Удирдлагын сайт руу шилжих
+my_repos=Миний Репонууд
+show_more_repos=Бусад Репонуудыг харах...
+collaborative_repos=Дундын Репонууд
+my_orgs=Миний Байгууллага
+my_mirrors=Миний Хуулбарууд
+view_home=Харах %s
+
+issues.in_your_repos=Таны Репо-д
+
+[explore]
+repos=Репонууд
+users=Хэрэглэгчид
+organizations=Байгууллагууд
+search=Хайлт
+
+[auth]
+create_new_account=Шинэ данс үүсгэх
+register_hepler_msg=Та хэрэглэгчийн эрхээ үүсгэсэн бол Нэвтрэх хуудас руу шилжих!
+social_register_hepler_msg=Данс үүсгэсэн бол? Нэвтрэх хуудас руу шилжих!
+disable_register_prompt=Уучлаарай, бүртгэл идэвхгүй байна. Сайтын админтай холбоо барина уу.
+disable_register_mail=Уучлаарай, имэйлийн үйлчилгээ идэвхгүй байна. Сайтын админтай холбоо барина уу.
+auth_source=Баталгаажуулалтын эх сурвалж
+local=Локал
+remember_me=Сануулах
+forgot_password=Нууц үг сэргээх
+forget_password=Нууц үг сэргээх?
+sign_up_now=Данс үүсгэх бол? Одоо бүртгүүлнэ үү.
+confirmation_mail_sent_prompt=Таны <b>%s</b> хаяг руу баталгаажуулах имэйл илгээлээ, та %d цагийн дотор имэйлээ шалгаж баталгаажуулна уу.
+active_your_account=Дансаа идэвхижүүлэх
+prohibit_login=Нэвтрэх эрх түгжигдсэн
+prohibit_login_desc=Таны нэвтрэх эрх түгжигдсэн. Сайтын админтай холбоо барина уу.
+resent_limit_prompt=Уучлаарай, та саяхан данс идэвхжүүлэх хүсэлт илгээсэн байна. 3 минут хүлээгээд дахин оролдоно уу.
+has_unconfirmed_mail=Сайн байна уу %s, таны (<b>%s</b>) имэйл хаяг баталгаажаагүй байна. Хэрэв танд баталгаажуулах имэйл ирээгүй эсвэл шинээр баталгаажуулах имэйл авах шаардлагатай бол доорх товчийг дарна уу.
+resend_mail=Баталгаажуулах имэйлээ дахин илгээх бол энд дарна уу
+send_reset_mail=Нууц үгээ шинэчлэх имэйлийг (дахин) илгээх бол энд дарна уу
+reset_password=Нууц үгээ сэргээх
+invalid_code=Уучлаарай, таны баталгаажуулах кодын хугацаа дууссан эсвэл хүчин төгөлдөр бус байна.
+reset_password_helper=Нууц үгээ шинэчлэх бол энд дарна уу
+password_too_short=Нууц үгийн урт нь дор хаяж 6 тэмдэгт байх ёстой.
+non_local_account=Гадаад хэрэглэгчид нууц үгээ солих боломжгүй.
+
+login_two_factor=2 давхар баталгаажуулалт
+login_two_factor_passcode=Баталгаажуулалтын нууц код
+login_two_factor_enter_recovery_code=2 давхар баталгаажуулалтын дахин сэргээх код оруулах
+login_two_factor_recovery=2 давхар баталгаажуулалтын код сэргээх
+login_two_factor_recovery_code=Сэргээх код
+login_two_factor_enter_passcode=2 давхар баталгаажуулалтын нууц үгээ оруулна уу
+login_two_factor_invalid_recovery_code=Сэргээх код өмнө нь ашиглагдсан эсвэл хүчингүй байна.
+
+[mail]
+activate_account=Бүртгэлээ идэвхжүүлнэ үү
+activate_email=Имэйл хаягаа баталгаажуулна уу
+reset_password=Нууц үгээ дахин сэргээх
+register_success=Бүртгэл амжилттай боллоо, тавтай морилно уу
+register_notify=Манай системд тавтай морилно уу
+
+[modal]
+yes=Тийм
+no=Үгүй
+modify=Засах
+
+[form]
+UserName=Нэвтрэн нэр
+RepoName=Репо нэр
+Email=Имэйл хаяг
+Password=Нууц үг
+Retype=Дахин оруулна уу
+SSHTitle=SSH түлхүүрийн нэр
+HttpsUrl=HTTPS хаяг
+PayloadUrl=Payload хаяг
+TeamName=Багийн нэр
+AuthName=Зөвшөөрлийн нэр
+AdminEmail=Админы имэйл
+
+NewBranchName=Шинэ салаа нэр
+CommitSummary=Коммит мэдээлэл
+CommitMessage=Коммит мессеж
+CommitChoice=Коммит сонголт
+TreeName=Файлын зам
+Content=Агуулга
+
+require_error=` талбарын оруулна уу.`
+alpha_dash_error=` үсэг, тоо эсвэл зураас (-_) агуулсан тэмдэгтүүд оруулна уу.`
+alpha_dash_dot_error=` үсэг, тоо, зураас (-_) эсвэл цэг агуулсан тэмдэгтүүд оруулна уу.`
+alpha_dash_dot_slash_error=` үсэг, тоо, зураас (-_), цэг эсвэл налуу зураас агуулсан тэмдэгтүүд оруулна уу.`
+size_error=` талбар нь %s тэмдэгтийн уртай байна.`
+min_size_error=` талбар нь хамгийн багадаа %s тэмдэгтийн уртай байна.`
+max_size_error=` талбар нь хамгийн ихдээ %s тэмдэгтийн уртай байна.`
+email_error=` буруу имэйл хаяг оруулсан байна.`
+url_error=` буруу URL оруулсан байна.`
+include_error=` талбар '%s' тэмдэгт заавал оруулах ёстой.`
+unknown_error=Үл мэдэгдэх алдаа:
+captcha_incorrect=Батлах тэмдэгт буруу байна.
+password_not_match=Нууц үг болон дахин оруулсан нууц үг тохирохгүй байна.
+
+username_been_taken=Нэвтрэх нэр аль хэдийн бүртгэгдсэн байна. Өөр нэр сонгоно уу.
+repo_name_been_taken=Репо нэр аль хэдийн бүртгэгдсэн байна. Өөр нэр сонгоно уу.
+org_name_been_taken=Байгууллагын нэр аль хэдийн бүртгэгдсэн байна. Өөр нэр сонгоно уу.
+team_name_been_taken=Багийн нэр аль хэдийн бүртгэгдсэн байна. Өөр нэр сонгоно уу.
+email_been_used=Имэйл хаяг аль хэдийн бүртгэгдсэн байна. Өөр нэр сонгоно уу.
+username_password_incorrect=Хэрэглэгчийн нэр эсвэл нууц үг буруу байна.
+auth_source_mismatch=Сонгосон танил нэвтрэлтийн эх сурвалж нь хэрэглэгчтэй холбоогүй болно.
+enterred_invalid_repo_name=Таны оруулсан Репо нэр зөв эсэхийг шалгана уу.
+enterred_invalid_owner_name=Таны оруулсан эзэмшигчийн нэр зөв эсэхийг шалгана уу.
+enterred_invalid_password=Таны оруулсан нууц үг зөв эсэхийг шалгана уу.
+user_not_exist=Оруулсан хэрэглэгч олдохгүй байна.
+last_org_owner=Байгууллага багадаа нэг хэрэглэгчтэй байх ёстой тул сүүлийн хэрэглэгчийг хасах боломжгүй.
+
+invalid_ssh_key=Уучлаарай, таны SSH түлхүүрийг баталгаажуулж чадсангүй: %s
+unable_verify_ssh_key=Сервер таны SSH түлхүүрийг баталгаажуулах боломжгүй байна, гэхдээ энэ түлхүүр хүчин төгөлдөр байх ёстой. Та дахин нягтална уу.
+auth_failed=Баталгаажуулалт амжилтгүй боллоо: %v
+
+still_own_repo=Таны данс аль нэг Репо эзэмшиж байгаа тул та тэдгээрийг устгах эсвэл шилжүүлэх хэрэгтэй.
+still_has_org=Таны данс аль нэг байгууллагын гишүүнчлэлтэй байгаа тул та эхлээд байгууллагаас гарах эсвэл гишүүнчлэлээсээ устгах хэрэгтэй.
+org_still_own_repo=Энэ байгууллага нь аль нэг Репо эзэмшиж байгаа тул та эхлээд устгах эсвэл шилжүүлэх ёстой.
+
+target_branch_not_exist=Сонгосон салаа олдохгүй байна.
+
+[user]
+change_avatar=Өөрийн зургаа солих
+join_on=Бүртгүүлсэн
+repositories=Репонууд
+activity=Олон нийтийн үйл ажиллагаа
+followers=Дагагчид
+starred=Тэмдэглэсэн Репонууд
+following=Дагасан
+follow=Дагах
+unfollow=Дагахаа болих
+
+form.name_not_allowed=%q нэвтрэх нэр эсвэл загвар зөвшөөрөгдөхгүй байна.
+
+[settings]
+profile=Профайл
+password=Нууц үг
+avatar=Зураг
+ssh_keys=SSH түлхүүрүүд
+security=Нууцлал
+repos=Репонууд
+orgs=Байгууллагууд
+applications=Аппликэшнүүл
+delete=Данс устгах
+
+public_profile=Профайл
+profile_desc=Таны имэйл хаяг олон нийтэд нээлттэй тул данстай холбоотой аливаа мэдэгдэл, сайтаар дамжуулан вэбэд суурилсан аливаа үйл ажиллагаанд ашиглагдах болно.
+password_username_disabled=Гадаад хэрэглэгчид Нэвтрэх нэрээ өөрчлөх боломжгүй.
+full_name=Бүтэн нэр
+website=Вэбсайт
+location=Байршил
+update_profile=Профайл өөрчлөх
+update_profile_success=Таны профайл амжилттай өөрчлөгдлөө.
+change_username=Нэвтрэх нэр өөрчлөгдсөн
+change_username_prompt=Энэ өөрчлөлт нь таны данстай холбоотой мэдээллүүд дээр нөлөөлнө.
+continue=Үргэлжлүүлэх
+cancel=Болих
+
+lookup_avatar_by_mail=Имэйл хайгаар зураг хайх
+federated_avatar_lookup=Нээлттэй зураг хайх
+enable_custom_avatar=Өөрийн зурагаа оруулах
+choose_new_avatar=Шинэ зураг сонгох
+update_avatar=Зургийн тохиргоо өөрчлөх
+delete_current_avatar=Одоогийн зураг устгах
+uploaded_avatar_not_a_image=Хуулсан файл зураг биш байна.
+update_avatar_success=Таны зургийн тохиргоо амжилттай өөрчлөгдлөө.
+
+change_password=Нууц үг солих
+old_password=Одоогийн нууц үг
+new_password=Шинэ нууц үг
+retype_new_password=Шинэ нууц үг давтах
+password_incorrect=Одоогийн нууц үгээ буруу оруулсан байна.
+change_password_success=Таны нууц үг амжилттай өөрчлөгдсөн тул нэвтрэхэд ашиглаж болно.
+password_change_disabled=Гадаад хэрэглэгчид нууц үгээ өөрчлөж болохгүй.
+
+emails=Имэйл хаягууд
+manage_emails=Имэйл хаягуудыг удирдах
+email_desc=Таны үндсэн имэйл хаягийг мэдэгдэл болон бусад үйл ажиллагаанд ашиглах болно.
+primary=Үндсэн
+primary_email=Үндсэн болгох
+delete_email=Устгах
+email_deletion=Имэйл устгах
+email_deletion_desc=Энэ имэйл хаягийг устгаснаар холбогдох мэдээллийг таны данснаас устгах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+email_deletion_success=Имэйлийг амжилттай устгалаа!
+add_new_email=Шинэ имэйл хаяг нэмэх
+add_email=Имэйл нэмэх
+add_email_confirmation_sent=Шинэ баталгаажуулах имэйлийг '%s' хаяг руу илгээлээ. Баталгаажуулах процессыг дуусгахын тулд имэйл нээж дараагийн %d цагийн дотор баталгаажуулна уу.
+add_email_success=Таны шинэ имэйл хаяг амжилттай нэмэгдлээ.
+
+manage_ssh_keys=SSH түлхүүрүүдийг удирдах
+add_key=Түлхүүр нэмэх
+ssh_desc=Энэ бол таны данстай холбоотой SSH түлхүүрүүдийн жагсаалт юм. Эдгээр түлхүүрүүд нь эдгээрийг ашиглаж байгаа бүх хүмүүст таны агуулахад нэвтрэх боломжийг олгодог тул та эдгээрийг найдвартай хадгалах нь маш чухал юм.
+ssh_helper=<strong>Яаж үүсгэхээ мэдэхгүй байна уу? </strong> Та SSH түлхүүр үүсгэхтэй холбоотой GitHub-ийн <a href="%s">SSH түлхүүр үүсгэх</a> зааврыг харах эсвэл <a href="%s">нийтлэг гардаг асуудлуудыг</a> шийдэх.
+add_new_key=SSH түлхүүр нэмэх
+ssh_key_been_used=Нийтийн түлхүүрийн утга бүртгэгдсэн байна.
+ssh_key_name_used=Ижил нэртэй нийтийн түлхүүр бүртгэгдсэн байна.
+key_name=Түлхүүрийн нэр
+key_content=Утга
+add_key_success=Шинэ SSH түлхүүр '%s' амжилттай нэмэгдлээ!
+delete_key=Устгах
+ssh_key_deletion=SSH түлхүүр Устгах
+ssh_key_deletion_desc=Энэ SSH түлхүүрийг устгаснаар таны бүртгэлд холбогдох бүх хандалт устах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+ssh_key_deletion_success=SSH түлхүүрийг амжилттай устгалаа!
+add_on=Нэмэгдсэн
+last_used=Сүүлд ашигласан
+no_activity=Ашиглалтын мэдээлэл бүртгэгдээгүй байна.
+key_state_desc=Энэ түлхүүрийг сүүлийн 7 хоногт ашиглагдсан байна
+token_state_desc=Энэхүү токен сүүлийн 7 хоногт ашиглагдсан байна
+
+two_factor=2 давхар танилт
+two_factor_status=Төлөв:
+two_factor_on=Идэвхитэй
+two_factor_off=Идэвхигүй
+two_factor_enable=Идэвхижүүлэх
+two_factor_disable=Идэвхигүй болгох
+two_factor_view_recovery_codes=Та өөрийн <a href="%s%s">сэргээх кодуудаа</a> найдвартай хадгалах хэрэгтэй. Хэрэв та системд нэвтрэх эрхээ алдсан бол тэдгээрийг нууц код болгон ашиглаж болно.
+two_factor_http=HTTP/HTTPS үйлдлийн хувьд та энгийн хэрэглэгчийн нэр нууц үг ашиглах боломжгүй. Та <a href="%[1]s%[2]s">Хувийн хандах токен</a> үүсгэж ашиглана уу. <code>%[3]s</code>.
+two_factor_enable_title=2 давхар танилт идэвхжүүлэх
+two_factor_scan_qr=Өөрийн танилтын аппликэшнээ ашиглаж зургийг скан хийнэ үү:
+two_factor_or_enter_secret=Эсвэл нууц үгээ оруулна уу:
+two_factor_then_enter_passcode=Дараа нь нууц кодоо оруулна уу:
+two_factor_verify=Баталгаажуулах
+two_factor_invalid_passcode=Таны оруулсан нууц код буруу байна, дахин оролдоно уу!
+two_factor_reused_passcode=Таны оруулсан нууц код аль хэдийн ашиглагдсан байна, өөр код оруулна уу!
+two_factor_enable_error=Хоёр давхар баталгаажуулалтыг идэвхжүүлж чадсангүй: %v
+two_factor_enable_success=Хоёр давхар баталгаажуулалтыг амжилттай идэвхижүүллээ!
+two_factor_recovery_codes_title=Хоёр давхар баталгаажуулалтын сэргээх кодууд
+two_factor_recovery_codes_desc=Таныг баталгаажуулах програмд нэвтрэх эрхээ алдах үед сэргээх кодыг ашигладаг. Сэргээх код бүрийг зөвхөн нэг удаа ашиглаж болно, <b>эдгээр кодыг найдвартай хадгална уу</b>.
+two_factor_regenerate_recovery_codes=Сэргээх кодуудыг дахин үүсгэх
+two_factor_regenerate_recovery_codes_error=Сэргээх кодуудыг дахин үүсгэхэд алдаа гарлаа: %v
+two_factor_regenerate_recovery_codes_success=Сэргээх кодуудыг амжилттай үүсгэлээ!
+two_factor_disable_title=Хоёр давхар баталгаажуулалтыг идэвхигүй болгох
+two_factor_disable_desc=Хоёр давхар баталгаажуулалтыг идэвхгүй болгосны дараа таны дансны аюулгүй байдлын түвшин буурах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+two_factor_disable_success=Хоёр давхар баталгаажуулалтыг амжилттай идэвхигүй болголоо!
+
+manage_access_token=Хувийн хандалтын токенуудыг удирдах
+generate_new_token=Шинэ токен үүсгэх
+tokens_desc=Таны үүсгэсэн токенуудыг Gogs API-д нэвтрэхэд ашиглаж болно.
+new_token_desc=Токен бүр таны дансанд бүрэн нэвтрэх боломжтой болно.
+token_name=Токены нэр
+generate_token=Токены үүсгэх
+generate_token_succees=Таны хандалтын токен амжилттай үүслээ! Дараа дахин харах боломжгүй тул яг одоо хуулж аваарай!
+delete_token=Устгах
+access_token_deletion=Хувийн хандалтын токен устгах
+access_token_deletion_desc=Энэхүү хувийн хандалтын токеныг устгаснаар програмын холбогдох бүх хандалтыг устгах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+delete_token_success=Хувийн хандалтын токеныг амжилттай устгалаа! Програмаа шинэчлэхийг бүү мартаарай.
+token_name_exists=Токентой ижил нэр бүртгэгдсэн байна.
+
+orgs.none=Та ямар ч байгууллагын гишүүн биш байна.
+orgs.leave_title=Байгууллагаас гарах
+orgs.leave_desc=Байгууллагаас гарсны дараа та бүх Репо, багуудад хандах эрхээ алдах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+
+repos.leave=Гарах
+repos.leave_title=Репо-с гарах
+repos.leave_desc=Та гарсны дараа Репо руу нэвтрэх эрхээ алдах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+repos.leave_success=Та '%s' Репо-с амжилттай гарлаа!
+
+delete_account=Бүртгэлээ устгах
+delete_prompt=Энэ ажиллагаа нь таны акаунтыг бүр мөсөн устгах бөгөөд <strong> ЭРГЭН СЭРГЭЭХ </strong> боломжгүй болно!
+confirm_delete_account=Устгалтыг баталгаажуулна уу
+delete_account_title=Данс устгах
+delete_account_desc=Энэ акаунтыг бүр мөсөн устгах гэж байна, та үргэлжлүүлэхийг хүсч байна уу?
+
+[repo]
+owner=Эзэмшигч
+repo_name=Репо нэр
+repo_name_helper=Сайн Репо нэр нь ихэвчлэн богино, мартагдашгүй, өвөрмөц түлхүүр үгсээс бүрддэг.
+visibility=Харагдах байдал
+visiblity_helper=Энэ Репо нь <span class="ui red text">Хувийн</span>
+visiblity_helper_forced=Сайтын админ бүх Репо <span class="ui red text">Хувийн</span> байх тохируулга хийсэн байна.
+visiblity_fork_helper=(Энэ утгыг өөрчлөх нь бүх салаалсан хувилбарт нөлөөлнө)
+clone_helper=Хуулж авахад тусламж хэрэгтэй байна уу? <a target="_blank" href="%s">Тусламж </a> цэсэнд зочилно уу!
+fork_repo=Репо салаалах
+fork_from=Аль Репо-с салаалах
+fork_visiblity_helper=Та салаалсан Репо-ын харагдах байдлыг өөрчлөх боломжгүй.
+repo_desc=Тодорхойлолт
+repo_lang=Хэл
+repo_gitignore_helper=.gitignore загварыг сонгох
+license=Лиценз
+license_helper=Лицензийн файлыг сонгоно уу
+readme=Заавар
+readme_helper=Зааврын загварыг сонгоно уу
+auto_init=Энэ Репо-н сонгосон файл, загвараар эхлүүлнэ үү
+create_repo=Репо үүсгэх
+default_branch=Анхны салаа хувилбар
+mirror_prune=Цэвэрлэх
+mirror_prune_desc=Алсаас хянадаг нөөцүүдийг устгах
+mirror_interval=Хуулбарлах интервал (цаг)
+mirror_address=Хуулбарлах хаяг
+mirror_address_desc=Хэрэглэгчийн шаардлагатай мэдээллийг хаягт оруулна уу.
+mirror_last_synced=Сүүлд синк хийсэн
+watchers=Үзэх жагсаалтад нэмсэн хэрэглэгчид
+stargazers=Онцлох жагсаалтад нэмсэн хэрэглэгчид
+forks=Салаанууд
+repo_description_helper=Репо тодорхойлолт. Ихдээ 512 тэмдэгтийн урттай.
+repo_description_length=Боломжтой тэмдэгтүүд
+
+form.reach_limit_of_creation=Эзэмшигч нь Репо үүсгэх %d дээд хязгаарт хүрсэн байна.
+form.name_not_allowed=%q Репо нэр эсвэл загвар зөвшөөрөгдөхгүй байна.
+
+need_auth=Зөвшөөрөл хэрэгтэй
+migrate_type=Шилжүүлэх төрөл
+migrate_type_helper=Энэ Репо нь <span class="text blue">толин хуулбар</span> болно.
+migrate_repo=Репо шилжүүлэх
+migrate.clone_address=Хуулбарлах хаяг
+migrate.clone_address_desc=HTTP/HTTPS/GIT хаяг байж болно.
+migrate.clone_address_desc_import_local=Та мөн Репо-г дотоод серверийн замаар шилжүүлэхийг зөвшөөрдөг.
+migrate.permission_denied=Орон дотоод Репо-г импортлох боломжгүй байна.
+migrate.invalid_local_path=Дотоод зам буруу байна, энэ хаяг дээр үүсээгүй эсвэл дирекдор биш байна.
+migrate.failed=Шилжүүлэлт амжилтгүй боллоо: %v
+
+mirror_from=-ын хуулбар
+forked_from=-с салаалсан
+copy_link=Хуулах
+copy_link_success=Хуулсан!
+copy_link_error=⌘-C эсвэл Ctrl-C дарж хуулна
+copied=Амжилттай хууллаа
+unwatch=Үзэх жагсаалтаас хасах
+watch=Үзэх жагсаалтад нэмэх
+unstar=Онцлох жагсаалтаас хасах
+star=Онцлох жагсаалтад нэмэх
+fork=Салаа
+
+no_desc=Тайлбар байхгүй
+quick_guide=Товч гарын авлага
+clone_this_repo=Энэ Репо-г хуулах
+create_new_repo_command=Шинэ Репо command line-р үүсгэх
+push_exist_repo=Өмнө үүссэн Репо руу command line-р хуулах
+bare_message=Энэ Репо-д одоогоор ямар нэг мэдээлэл алга байна.
+
+files=Файлууд
+branch=Салаа
+tree=Мод
+filter_branch_and_tag=Салаа болон тагаар хайх
+branches=Салаанууд
+tags=Тагууд
+issues=Асуудлууд
+pulls=Хуулах хүсэлтүүд
+labels=Шошгууд
+milestones=Чухал үйл явдлууд
+commits=Коммитууд
+git_branches=Салаанууд
+releases=Хувилбарууд
+file_raw=Анхны өгөгдөл
+file_history=Түүх
+file_view_raw=Анхны өгөгдөл харах
+file_permalink=Байнгын холболт
+file_too_large=Энэ файлыг харуулахад хэтэрхий том байна
+video_not_supported_in_browser=Таны хөтөч HTML5 видео тагыг дэмждэггүй.
+
+branches.overview=Товч мэдээлэл
+branches.active_branches=Идэвхтэй салаанууд
+branches.stale_branches=Хуучирсан салаанууд
+branches.all=Бүх салаанууд
+branches.updated_by=Шинэчлэгдсэн %[1]s by %[2]s
+branches.change_default_branch=Анхны салаа өөрчлөх
+
+editor.new_file=Шинэ файл
+editor.upload_file=Файл хуулах
+editor.edit_file=Файл засах
+editor.preview_changes=Өөрчлөлтийг урьдчилан харах
+editor.cannot_edit_non_text_files=Текстэн бус файлуудыг засах боломжгүй
+editor.edit_this_file=Энэ файлыг засах
+editor.must_be_on_a_branch=Энэ файлд өөрчлөлт оруулах эсвэл санал болгохын тулд та тус салаан дээр байх ёстой
+editor.fork_before_edit=Файлыг засахаасаа өмнө та энэ Репо-г салаалах хэрэгтэй
+editor.delete_this_file=Энэ файлыг устгах
+editor.must_have_write_access=Энэ файлд өөрчлөлт оруулах эсвэл санал болгохын тулд танд бичих хандалттай байх ёстой
+editor.file_delete_success='%s' файлыг амжилттай устгалаа!
+editor.name_your_file=Файлын нэр ...
+editor.filename_help=Директор нэмэхийн тулд, нэрээ бичээд / дарна уу. Директор устгахын тулд, талбарын эхэнд очоод backspace товчийг дарна уу.
+editor.or=эсвэл
+editor.cancel_lower=болих
+editor.commit_changes=Өөрчлөлтийг хадгалах
+editor.add_tmpl='%s/<Файлын нэр>' нэмэх
+editor.add=Нэмэх '%s'
+editor.update=Өөрчлөх '%s'
+editor.delete=Устгах '%s'
+editor.commit_message_desc=Нэмэлт өргөтгөсөн тайлбар нэмэх...
+editor.commit_directly_to_this_branch=<strong class="branch-name">%s</strong> хувилбар луу шууд өөрчлөлтийг хадгалах.
+editor.create_new_branch=Энэ коммитоор <strong>шинэ хувилбар</strong> үүсгэж татаж авах хүсэлт үүсгэх.
+editor.new_branch_name_desc=Шинэ хувилбарын нэр...
+editor.cancel=Болих
+editor.filename_cannot_be_empty=Файлын нэр оруулна уу.
+editor.branch_already_exists='%s' хувилбар тус Репо-д өмнө нь үүссэн байна.
+editor.directory_is_a_file='%s' сан дахь директор биш файл байна.
+editor.file_is_a_symlink='%s' файлыг вэб editor-с өөрчлөх боломжгүй байна.
+editor.filename_is_a_directory='%s' файл нь тус Репо-д өмнө нь үүссэн байна.
+editor.file_editing_no_longer_exists=Таны өөрчлөх гэж буй '%s' файл нь Репо-д олдохгүй байна.
+editor.file_changed_while_editing=Таныг засварлаж эхэлснээс хойш файлын агуулга өөрчлөгдсөн байна. <a target="_blank" href="%s">Энд дарж</a> юу өөрчлөгдсөнийг харах эсвэл тус өөрчлөлтийг дарж <strong>дахин commmit хийж</strong> болно.
+editor.file_already_exists='%s' нэртэй файл нь тус Репо-д өмнө нь үүссэн байна.
+editor.no_changes_to_show=Ямар нэгэн өөрчлөлт ороогүй байна.
+editor.fail_to_update_file='%s' файл үүсгэх/өөрчлөх үед дараах алдаа гарлаа: %v
+editor.fail_to_delete_file='%s' файл устгах үед дараах алдаа гарлаа: %v
+editor.add_subdir=Дэд директор нэмэх...
+editor.unable_to_upload_files='%s' руу файл upload хийх үед дараах алдаа гарлаа: %v
+editor.upload_files_to_dir='%s' руу файл upload хийх
+
+commits.commit_history=Коммит түүх
+commits.commits=Коммитууд
+commits.search=Коммит хайх
+commits.find=Хайх
+commits.author=Эзэн
+commits.message=Мессеж
+commits.date=Огноо
+commits.older=Хуучин
+commits.newer=Шинэ
+
+issues.new=Шинэ асуудал
+issues.new.labels=Шошгууд
+issues.new.no_label=Шошгогүй
+issues.new.clear_labels=Шошгууд цэвэрлэх
+issues.new.milestone=Үе шат
+issues.new.no_milestone=Үе шат заахгүй
+issues.new.clear_milestone=Үе шат цэвэрлэх
+issues.new.open_milestone=Нээлттэй үе шатууд
+issues.new.closed_milestone=Хаагдсан үе шатууд
+issues.new.assignee=Хариуцагч
+issues.new.clear_assignee=Хариуцагч цэвэрлэх
+issues.new.no_assignee=Хариуцагч байхгүй
+issues.create=Шинэ асуудал
+issues.new_label=Шинэ шошго
+issues.new_label_placeholder=Шошго нэр ...
+issues.create_label=Шошго үүсгэх
+issues.label_templates.title=Урьдчилан тодорхойлсон шошгуудын багцыг харах
+issues.label_templates.info=Одоохондоо шошго байхгүй байна. Та дээрх "Шинэ шошго" товчийг дарж үүсгэх эсвэл доор урьдчилан тодорхойлсон багцыг ашиглах боломжтой.
+issues.label_templates.helper=Шошгоны багцыг сонгоно уу
+issues.label_templates.use=Энэхүү шошгоны багцыг ашиглана уу
+issues.label_templates.fail_to_load_file=Шошгоны загварын файлыг ачаалж чадсангүй '%s': %v
+issues.open_tab=%d Нээлттэй
+issues.close_tab=%d Хаалттай
+issues.filter_label=Шошго
+issues.filter_label_no_select=Шошго сонгоогүй байна
+issues.filter_milestone=Үе шат
+issues.filter_milestone_no_select=Үе шат сонгоогүй байна
+issues.filter_assignee=Хариуцагч
+issues.filter_assginee_no_select=Хариуцагч сонгоогүй байна
+issues.filter_type=Төрөл
+issues.filter_type.all_issues=Бүх асуудал
+issues.filter_type.assigned_to_you=Танд оноогдсон
+issues.filter_type.created_by_you=Таны үүсгэсэн
+issues.filter_type.mentioning_you=Таныг дурдсан
+issues.filter_sort=Эрэмбэлэх
+issues.filter_sort.latest=Сүүлд үүссэн нь эхэндээ
+issues.filter_sort.oldest=Түрүүнд үүссэн нь эхэндээ
+issues.filter_sort.recentupdate=Саяхан шинэчлэгдсэн
+issues.filter_sort.leastupdate=Хамгийн сүүлд шинэчлэгдсэн
+issues.filter_sort.mostcomment=Хамгийн олон саналтай
+issues.filter_sort.leastcomment=Хамгийн бага саналтай
+issues.opened_by=нээсэн %[1]s by <a href="%[2]s">%[3]s</a>
+issues.opened_by_fake=нээсэн %[1]s by %[2]s
+issues.previous=Өмнөх
+issues.next=Дараах
+issues.open_title=Нээсэн
+issues.closed_title=Хаасан
+issues.num_comments=%d саналууд
+issues.commented_at=`санал үлдээсэн <a href="#%s">%s</a>`
+issues.delete_comment_confirm=Та энэ саналыг устгахдаа итгэлтэй байна уу?
+issues.no_content=Харуулах агуулга байхгүй байна.
+issues.close_issue=Хаах
+issues.close_comment_issue=Санал бичээд хаах
+issues.reopen_issue=Дахин нээх
+issues.reopen_comment_issue=Санал бичээд дахин нээх
+issues.create_comment=Санал
+issues.closed_at=`хаасан <a id="%[1]s" href="#%[1]s">%[2]s</a>`
+issues.reopened_at=`дахин нээсэн <a id="%[1]s" href="#%[1]s">%[2]s</a>`
+issues.commit_ref_at=`энэ асуудлыг <a id="%[1]s" href="#%[1]s">%[2]s</a> коммитоос иш татсан болно`
+issues.poster=Зурагт хуудас
+issues.collaborator=Хамтрагч
+issues.owner=Эзэмшигч
+issues.sign_in_require_desc=Энэ хэлэлцүүлгэнд нэгдэхийн тулт та <a href="%s">нэвтэрнэ үү</a>.
+issues.edit=Засах
+issues.cancel=Цуцлах
+issues.save=Хадгалах
+issues.label_title=Шошгоны нэр
+issues.label_color=Шошгоны өнгө
+issues.label_count=%d шошго
+issues.label_open_issues=%d нээлттэй асуудлууд
+issues.label_edit=Засах
+issues.label_delete=Устгах
+issues.label_modify=Шошгыг өөрчлөх
+issues.label_deletion=Шошгыг устгах
+issues.label_deletion_desc=Энэ шошгыг устгаснаар холбогдох бүх асуудлаар түүний мэдээллийг устгах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+issues.label_deletion_success=Шошгыг амжилттай устгалаа!
+issues.num_participants=%d Оролцогчид
+issues.attachment.open_tab=`Энд дараад "%s" шинэ таб дээр харах`
+issues.attachment.download=`Энд дараад "%s" татаж авах`
+
+pulls.new=Шинэ татах хүсэлт
+pulls.compare_changes=Өөрчлөлтийг харьцуулах
+pulls.compare_changes_desc=Хоёр хуулбарыг харьцуулж, өөрчлөлт оруулах хүсэлтийг гаргана уу.
+pulls.compare_base=үндэс
+pulls.compare_compare=харьцуулах
+pulls.filter_branch=Салаагаар шүүх
+pulls.no_results=Үр дүн олдсонгүй.
+pulls.nothing_to_compare=Үндэс болон Толгой хуулбарууд ижил тул харьцуулах зүйл алга байна.
+pulls.nothing_merge_base=Хоёр хуулбар огт өөр түүхтэй тул харьцуулах зүйл алга.
+pulls.has_pull_request=`Энэ хоёр зорилтот хуулбарын хооронд татах хүсэлт аль хэдийн ирсэн байна: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
+pulls.create=Татах хүсэлтийг бий болгох
+pulls.title_desc=%[1]d-ийг <code>%[2]s</code>-оос <code>%[3]s</code> руу нэгтгэхийг хүсэлт
+pulls.merged_title_desc=%[1]d-ийг <code>%[2]s</code>-оос <code>%[3]s</code> %[4]s болгон нэгтгэв
+pulls.tab_conversation=Харилцаа
+pulls.tab_commits=Коммитууд
+pulls.tab_files=Өөрчилсөн файлууд
+pulls.reopen_to_merge=Нэгтгэх ажиллагааг гүйцэтгэхийн тулд энэ татах хүсэлтийг дахин нээнэ үү.
+pulls.merged=Нэгтгэсэн
+pulls.has_merged=Энэхүү татах хүсэлтийг амжилттай нэгтгэв!
+pulls.data_broken=Энэхүү татах хүсэлтийн өгөгдөл нь садааны мэдээллийг устгасан тул эвдэрсэн байна.
+pulls.is_checking=Давхцал шалгах ажил үргэлжилж байна, хэдэн хоромын дараа хуудсыг шинэчилнэ үү.
+pulls.can_auto_merge_desc=Энэхүү татах хүсэлтийг автоматаар нэгтгэх боломжтой.
+pulls.cannot_auto_merge_desc=Давхцалтай тул энэ татах хүсэлтийг автоматаар нэгтгэх боломжгүй.
+pulls.cannot_auto_merge_helper=Зөрчлийг арилгахын тулд гараар нэгтгэнэ үү.
+pulls.create_merge_commit=Нэгтгэх хүсэлт үүсгэх
+pulls.rebase_before_merging=Нэгдэхээс өмнө дахин байрлуулах
+pulls.commit_description=Коммитын тайлбар
+pulls.merge_pull_request=Татах хүсэлтийг нэгтгэх
+pulls.open_unmerged_pull_exists=`Тус Репо-с ижил нэгтгэх мэдээлэлтэй нээлттэй татах хүсэлт (#%d) аль хэдийн ирсэн,  нэгтгэхээ хүлээж байгаа тул та дахин нээх үйлдлийг хийж чадахгүй.`
+pulls.delete_branch=Салааг устгах
+pulls.delete_branch_has_new_commits=Нэгтгэсний дараа шинэ өөрчлөлт орсон тул тус салааг устгах боломжгүй байна.
+
+milestones.new=Шинэ үе шат
+milestones.open_tab=%d Нээлттэй
+milestones.close_tab=%d Хаалттай
+milestones.closed=Хаалттай %s
+milestones.no_due_date=Дуусах хугацаагүй
+milestones.open=Нээх
+milestones.close=Хаах
+milestones.new_subheader=Асуудлуудаа цэгцлэх чухал үе шатуудыг бий болго.
+milestones.create=Үе шат үүсгэх
+milestones.title=Гарчиг
+milestones.desc=Тайлбар
+milestones.due_date=Дуусах хугацаа (заавал биш)
+milestones.clear=Цэвэрлэх
+milestones.invalid_due_date_format=Дуусах хугацааг зөв форматтай оруулна уу, 'yyyy-mm-dd' форматтай байх ёстой.
+milestones.create_success='%s' үе шат амжилттай үүслээ!
+milestones.edit=Үе шат засах
+milestones.edit_subheader=Үе шат оруулахдаа тайлбарын тодорхой оруулна уу. Тэгвэл хэрэглэг төөрөлдөхгүй.
+milestones.cancel=Болих
+milestones.modify=Үе шат өөрчлөх
+milestones.edit_success='%s' үе шатыг амжилттай өөрчиллөө!
+milestones.deletion=Үе шат устгах
+milestones.deletion_desc=Үе шатыг устгаснаар холбогдох бүх асуудал дахь мэдээллийг устгах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+milestones.deletion_success=Үе шатыг амжилттай устгалаа!
+
+wiki=Мэдлэгийн сан
+wiki.welcome=Мэдлэгийн санд тавтай морилно уу!
+wiki.welcome_desc=Мэдлэгийн сан бол төслөө хамтдаа баримтжуулж, сайжруулах боломж олгодог талбар юм.
+wiki.create_first_page=Эхний хуудсыг үүсгэх
+wiki.page=Хуудас
+wiki.filter_page=Хуудсыг шүүх
+wiki.new_page=Шинэ хуудас үүсгэх
+wiki.default_commit_message=Энэхүү шинэчлэлтийн талаар тэмдэглэл бичнэ үү (заавал биш).
+wiki.save_page=Хуудас хадгалах
+wiki.last_commit_info=%s энэ хуудсыг %s засварлав
+wiki.edit_page_button=Засах
+wiki.new_page_button=Шинэ хуудас
+wiki.delete_page_button=Хуудсыг устгах
+wiki.delete_page_notice_1=Та <code>"%s"</code> хуудсын утсгах уу. Баталгаажуулна уу!
+wiki.page_already_exists=Ижил нэртэй хуудас аль хэдийн үүссэн байна.
+wiki.pages=Хуудсууд
+wiki.last_updated=Сүүлд өөрчлөгдсөн %s
+
+settings=Тохиргоо
+settings.options=Сонголтууд
+settings.collaboration=Сонголтууд
+settings.collaboration.admin=Админ
+settings.collaboration.write=Бичих
+settings.collaboration.read=Унших
+settings.collaboration.undefined=Тодорхойгүй
+settings.branches=Хуулбарууд
+settings.branches_bare=Та хоосон Репо-г удирдах боломжгүй. Эхлээд ямар нэг мэдээлэл хуулах ёстой.
+settings.default_branch=Репо үндэс
+settings.default_branch_desc=Репо үндэс-г код ажиллуулах, хүсэлт гаргах, онлайн засварлахад зориулсан "суурь" хуулбар гэж үздэг.
+settings.update=Шинэчлэх
+settings.update_default_branch_unsupported=Анхдагч хуулбарыг өөрчлөхийг сервер дээрх Git хувилбар дэмждэггүй.
+settings.update_default_branch_success=Энэ репозиторын анхдагч хуулбар амжилттай шинэчлэгдсэн!
+settings.protected_branches=Хаалттай хуулбарууд
+settings.protected_branches_desc=Хаалттай хуулбар нь санамсаргүйгээр устгах, цагаан жагсаалт оруулахаас хамгаална.
+settings.choose_a_branch=Хуулбар сонгох...
+settings.branch_protection=Хуулбар хамгаалалт
+settings.branch_protection_desc=<b>%s</b> хуулбарыг хамгаалах сонголтыг сонгоно уу.
+settings.protect_this_branch=Энэ хуулбарыг хамгаалах
+settings.protect_this_branch_desc=Энэ хуулбар луу push хийхийг хориглох.
+settings.protect_require_pull_request=Push хийхийн оронд шууд pull хийж авах
+settings.protect_require_pull_request_desc=Энэ хуулбар луу push хийхийг хориглох бол идэвхжүүлнэ үү.
+settings.protect_whitelist_committers=Энэ хуулбар руу push хийх боломжтой хэрэглэгчид
+settings.protect_whitelist_committers_desc=Энэ хуулбар руу шууд push хийх боломжтой хэрэглэгчид. Цагаан жагсаалтад бүртгэгдсэн хэрэглэгчид тус хуулбар луу шууд push хийх боломжтойв
+settings.protect_whitelist_users=Энэ хуулбар руу түлхэх боломжтой хэрэглэгчид
+settings.protect_whitelist_search_users=Хэрэглэгчдийг хайх
+settings.protect_whitelist_teams=Тэдний гишүүд энэ салбар руу түлхэх боломжтой багууд
+settings.protect_whitelist_search_teams=Баг хайх
+settings.update_protect_branch_success=Энэ хуулбарыг хамгаалах сонголтыг амжилттай шинэчиллээ!
+settings.hooks=Webhooks
+settings.githooks=Git Hooks
+settings.basic_settings=Үндсэн тохиргоо
+settings.mirror_settings=Хуулбарын Тохиргоо
+settings.sync_mirror=Одоо нэгтгэе
+settings.mirror_sync_in_progress=Хуулбарыг нэгтгэх ажил хийгдэж байна, түр хүлээгээд хуудсыг дахин шинэчилнэ үү.
+settings.site=Албан ёсны сайт
+settings.update_settings=Тохиргоог шинэчлэх
+settings.change_reponame_prompt=Энэ өөрчлөлт нь холбоосууд репозитортой хэрхэн холбогдоход нөлөөлнө.
+settings.advanced_settings=Нарийвчилсан тохиргоо
+settings.wiki_desc=Мэдлэгийн сангийн системийг идэвхжүүлэх
+settings.use_internal_wiki=Мэдлэгийн сан ашиглах
+settings.allow_public_wiki_desc=Репо нь хувийн байх үед мэдлэгийн сан руу олон нийтийн хандалтыг зөвшөөрөх
+settings.use_external_wiki=Гадаад мэдлэгийн сан ашиглах
+settings.external_wiki_url=Гадаад мэдлэгийн сангийн URL
+settings.external_wiki_url_desc=Зочид таб дээр дарахад URL руу шилжих болно.
+settings.issues_desc=Асуудлыг хянагчийг идэвхжүүлэх
+settings.use_internal_issue_tracker=Хялбар мэдлэгийн сан ашиглах
+settings.allow_public_issues_desc=Репозитор хувийн тохиолдолд олон нийтэд хандах боломжийг олгоно
+settings.use_external_issue_tracker=Гадаад асуудал хянагч ашиглах
+settings.external_tracker_url=Гадаад дугаар хянагч URL
+settings.external_tracker_url_desc=Зочид таб дээр дарахад URL руу дахин чиглүүлэгдэх болно.
+settings.tracker_url_format=Гадаад асуудал хянагч URL формат
+settings.tracker_issue_style=Гадаад дугаар хянагч нэрлэх хэв маяг:
+settings.tracker_issue_style.numeric=Тоо
+settings.tracker_issue_style.alphanumeric=Тоо болон үсэг
+settings.tracker_url_format_desc=Хэрэглэгчийн нэр, репозиторийн нэр, асуудлын индексийг оруулахдаа та <code> {user} {repo} {index} </code> -ийг ашиглаж болно.
+settings.pulls_desc=Репо ба хувилбарын хооронд pull хүсэлтийг идэвхжүүлэх
+settings.pulls.ignore_whitespace=Хоосон зайг алгасах
+settings.pulls.allow_rebase_merge=Буцаан хуулбарлахыг зөвшөөрөх
+settings.danger_zone=Аюултай талбар
+settings.cannot_fork_to_same_owner=Та тус Репо-г анх үүсгэсэн хэрэглэгчид шилжүүлэх боломжгүй.
+settings.new_owner_has_same_repo=Ижил нэртэй Репо байна. Өөр нэр сонгоно уу.
+settings.convert=Энгийн Репо руу хөрвүүлэх
+settings.convert_desc=Та энэ хуулбарыг энгий Репо руу хөрвүүлэх боломжтой. Буцаах боломжгүй.
+settings.convert_notices_1=- Энэ үйлдэл нь энэхүү Репо хуулбарыг энгийн Репо болгон хөрвүүлэх бөгөөд буцаах боломжгүй.
+settings.convert_confirm=Хөрвүүлэлтийг баталгаажуулна уу
+settings.convert_succeed=Репо энгийн Репо руу амжилттай хөрвөлөө.
+settings.transfer=Эзэмшигч шилжүүлэх
+settings.transfer_desc=Энэ нь тус Репо-г өөр эзэмшигч рүү шилжүүлнэ.
+settings.transfer_notices_1=- Хэрэв шинэ эзэмшигч нь хаалттай хэрэглэгч бол та хандах эрхээ алдах болно.
+settings.transfer_notices_2=- Хэрэв шинэ эзэмшигч нь байгууллага байгаад та тус байгууллагын хэрэглэгч бол та нэвтрэх эрхээ хадгалах болно.
+settings.transfer_form_title=Үйл ажиллагаагаа баталгаажуулахын тулд дараахь мэдээллийг оруулна уу:
+settings.wiki_delete=Wiki өгөгдлийг устгах
+settings.wiki_delete_desc=Устгасанаас хойш сэргээх боломжгүй учир болгоомжтой хандана уу.
+settings.wiki_delete_notices_1=- Энэ нь %s-ийн wiki-г устгах ба идэвхгүй болгох болно
+settings.wiki_deletion_success=Репо-ийн вики мэдээллийг амжилттай устгалаа.
+settings.delete=Энэ репо-г устгах
+settings.delete_desc=Устгасанаас хойш сэргээх боломжгүй учир болгоомжтой хандана уу.
+settings.delete_notices_1=- Энэ үйлдлийн <strong>БУЦААХ</strong> боломжгүй.
+settings.delete_notices_2=- Энэ ажиллагаа нь Git-ийн өгөгдөл, асуудал, сэтгэгдэл, хамтран ажиллагсдын хандалт зэрэг энэ репо дахь бүх зүйлийг бүрмөсөн устгах болно.
+settings.delete_notices_fork_1=- Бүх хувилбарууд устгасны дараа бие даасан хувилбар болно.
+settings.deletion_success=Репо-г амжилттай устгалаа!
+settings.update_settings_success=Репо тохиргоонууд амжилттай шинэчлэгдлээ.
+settings.transfer_owner=Шинэ эзэмшигч
+settings.make_transfer=Шилжүүлэх
+settings.transfer_succeed=Репо эзэмшлийг амжилттай шилжүүллээ.
+settings.confirm_delete=Устгалтыг баталгаажуулах
+settings.add_collaborator=Хамтран ажиллагч нэмэх
+settings.add_collaborator_success=Хамтран ажиллагч нэмэгдлээ .
+settings.delete_collaborator=Устгах
+settings.collaborator_deletion=Хамтран ажиллагч устгах
+settings.collaborator_deletion_desc=Энэ хэрэглэгч устгасны дараа энэ агуулахад хамтын ажиллагааны хандалт байхгүй болно. Та үргэлжлүүлэхийг хүсч байна уу?
+settings.remove_collaborator_success=Хамтран ажиллагчийг амжилттай устгала.
+settings.search_user_placeholder=Хэрэглэгч хайх...
+settings.org_not_allowed_to_be_collaborator=Байгууллагыг хамтран ажиллагчаар нэмж оруулахыг хориглоно.
+settings.hooks_desc=Webhooks нь үндсэн HTTP POST үйл явдалтай адилхан байдаг. Gogs-д ямар нэгэн үйлдэл болох үед бид таны зааж өгсөн зорилтот хост руу мэдэгдэх болно.
+settings.webhooks.add_new=Шинэ Webhook нэмэх:
+settings.webhooks.choose_a_type=Төрөл сонгох ...
+settings.add_webhook=Webhook нэмэх
+settings.webhook_deletion=Webhook устгах
+settings.webhook_deletion_desc=Энэ Webhook-г устгаснаар түүний мэдээлэл болон хүргэлтийн түүхийг устгах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+settings.webhook_deletion_success=Webhook-г амжилттай устгалаа
+settings.webhook.test_delivery=Туршилтын хүргэлт
+settings.webhook.test_delivery_desc=Вэбхүүкийн тохиргоог шалгахын тулд хуурамч push хүсэлт илгээмжийг илгээнэ үү
+settings.webhook.test_delivery_success=Туршилтын webhook нь ажлын дараалалд нэмэгдсэн. Тус өөрчлөлтийг хадгалахад багахан хугаацаа орно.
+settings.webhook.redelivery=Дахин илгээх
+settings.webhook.redelivery_success='%s' hook ажил дахин нэмэгдлээ. Тус өөрчлөлтийг хадгалахад багахан хугаацаа орно.
+settings.webhook.request=Хүсэлт
+settings.webhook.response=Хариу
+settings.webhook.headers=Толгой
+settings.webhook.payload=Ачаалах
+settings.webhook.body=Бие
+settings.webhook.err_cannot_parse_payload_url=Тус хаягаас ачааллаж чадсангүй : %v
+settings.webhook.err_cannot_use_local_addresses=Админ биш бол дотоод хаяг ашиглах боломжгүй.
+settings.githooks_desc=Git Hooks -ийг Git тодорхойлдог, та зөвшөөрөгдсөн hooks файлуудыг засвардах боломжтой.
+settings.githook_edit_desc=Хэрэв hook идэвхгүй бол жишээ агуулгыг танилцуулах болно. Агуулгыг утгыыг үлдээвэл энэ hook идэвхгүй болно.
+settings.githook_name=Hook нэр
+settings.githook_content=Hook агуулга
+settings.update_githook=Hook өөрчлөх
+settings.add_webhook_desc=Gogs нь таны оруулсан URL руу <code> POST </code> хүсэлтийг болон болсон үйл явдлын талаарх дэлгэрэнгүй мэдээллийг илгээх болно. Та hook ашигласан тохиолдолд ямар төрлийн өгөгдлийн формат авахыг хүсч байгаагаа зааж өгч болно (JSON, x-www-form-urlencoded, XML гэх мэт). Дэлгэрэнгүй мэдээллийг манай <a target="_blank" href="%s"> Webhooks гарын авлагаас </a> авах боломжтой.
+settings.payload_url=Ачаалах URL
+settings.content_type=Агуулгын төрөл
+settings.secret=Нууцлал
+settings.secret_desc=Нууцлах толгой файл нь SHA256 HMAC <код> X-Gogs-гарын үсэг </code> ашиглана.
+settings.slack_username=Хэрэглэгчийн нэр
+settings.slack_icon_url=Айкон хаяг
+settings.slack_color=Өнгө
+settings.event_desc=Хэзээ энэ webhook ашиглагдах вэ?
+settings.event_push_only=Зөвхөн <code>push</code> хийх
+settings.event_send_everything=Надад <strong>бүгд</strong> хэрэгтэй
+settings.event_choose=Надад хэрэгтэй зүйлээ сонгох
+settings.event_create=Үүсгэх
+settings.event_create_desc=Үүсгэх хувилбар/таг
+settings.event_delete=Устгах
+settings.event_delete_desc=Устгах хувилбар/таг
+settings.event_fork=Хуулбар
+settings.event_fork_desc=Хуулбар репо
+settings.event_push=Push
+settings.event_push_desc=Git push
+settings.event_issues=Асуудлууд
+settings.event_issues_desc=Энэ асуудал нээгдсэн, хаагдсан, дахин нээгдсэн, засварлагдсан, томилогдсон, хуваарилагдаагүй, шошгыг шинэчилсэн, шошгыг цэвэрлэсэн, тэмдэглэсэн.
+settings.event_pull_request=Pull хүсэлт
+settings.event_pull_request_desc=Хүсэлтийг нээх, хаах, дахин нээх, засах, хуваарилах, хуваарилах, шошгыг шинэчлэх, шошгыг цэвэрлэх, тэмдэглэх, demonestones эсвэл синхрончлох.
+settings.event_issue_comment=Тайлбар
+settings.event_issue_comment_desc=Тайлбарыг үүсгэсэн, засварласан эсвэл устгасан.
+settings.event_release=Хувилбар
+settings.event_release_desc=Хувилбар репод амжилттай нийтлэгдлээ.
+settings.active=Идэвхитэй
+settings.active_helper=Hook дэлгэрэнгүй мэдээлэл.
+settings.add_hook_success=Шинэ webhook нэмэгдлээ.
+settings.update_webhook=Webhook өөрчлөх
+settings.update_hook_success=Webhook өөрчлөгдлөө.
+settings.delete_webhook=Webhook устгах
+settings.recent_deliveries=Сүүлийн үеийн хүргэлт
+settings.hook_type=Hook төрөл
+settings.add_slack_hook_desc=<a href="%s">Slack</a> интеграци нэмэх.
+settings.add_discord_hook_desc=<a href="%s">Discord</a> интеграци нэмэх.
+settings.add_dingtalk_hook_desc=<a href="%s">Dingtalk</a> интеграци нэмэх.
+settings.slack_token=Токен
+settings.slack_domain=Домайн
+settings.slack_channel=Суваг
+settings.deploy_keys=Deploy Keys
+settings.deploy_keys_helper=Хэрэв та хувийн нийтийн түлхүүрүүдийг нэмэх гэж байгаа бол үүнийг <a href="%s%s">дансны тохиргоондоо</a> нэмнэ үү.
+settings.add_deploy_key=Deploy Key нэмэх
+settings.deploy_key_desc=Deploy keys зөвхөн унших эрхтэй байна. Эдгээр нь хувийн дансны SSH түлхүүрүүдтэй адил биш юм.
+settings.no_deploy_keys=Та deploy key нэмээгүй байна.
+settings.title=Нэр
+settings.deploy_key_content=Мэдээлэл
+settings.key_been_used=Deploy key мэдээлэл ашиглагдсан байна.
+settings.key_name_used=Ижил нэртэй Deploy key үүссэн байна.
+settings.add_key_success='%s' deploy key амжилттай үүслээ!
+settings.deploy_key_deletion=Deploy Key устгах
+settings.deploy_key_deletion_desc=Энэ Deploy Key устгаснаар хамаарал бүхий Репо-д хандах эрхгүй болно. Үргэлжлүүлэх үү?
+settings.deploy_key_deletion_success=Deploy key-г амжилттай устгалаа!
+settings.description_desc=Репо тайлбар. Ихдээ 512 тэмдэгт.
+settings.description_length=Боломжтой тэмдэгтүүд
+
+diff.browse_source=Эх сурвалжийг харах
+diff.parent=parent
+diff.commit=commit
+diff.data_not_available=Өөрчлөлтийн мэдээлэл алга байна .
+diff.show_diff_stats=Өөрчлөлтийн статистик харах
+diff.show_split_view=Өөрчлөлтийг ялгаж харах
+diff.show_unified_view=Өөрчлөллтийг нэгтгэж харах
+diff.stats_desc=<strong> %d өөрчлөгдсөн </strong> <strong>%d нэмэгдсэн </strong>, <strong>%d устгасан </strong>
+diff.bin=BIN
+diff.view_file=Файл харах
+diff.file_suppressed=Файлын зөрүү хэтэрхий том тул дарагдсан байна
+diff.too_many_files=Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно
+
+release.releases=Хувилбар
+release.new_release=Шинэ хувилбар
+release.draft=Драфт
+release.prerelease=Урьдчилсан хувилбар
+release.edit=засах
+release.ahead=<strong>%d</strong> commit ирсэн байна %s хувилбараас хойш
+release.source_code=Эх код
+release.new_subheader=Бүтээгдэхүүнийг давтан хийх хувилбаруудыг нийтлэх.
+release.edit_subheader=Өөрчлөлтийн дэлгэрэнгүй бүртгэл нь хэрэглэгчдэд сайжруулсан зүйлийг ойлгоход тусална.
+release.tag_name=Шошгоны нэр
+release.target=Сонгох
+release.tag_helper=Одоо байгаа тагийг сонгох, эсвэл нийтлэхдээ шинэ таг үүсгэх.
+release.title=Нэр
+release.content=Агуулга
+release.write=Бичих
+release.preview=Урьдчилан харах
+release.loading=Ачааллаж байна ...
+release.prerelease_desc=Энэ бол урьдчилсан хувилбар
+release.prerelease_helper=Энэ хувилбар нь шууд байрлуулахад бэлэн биш байгааг тэмдэглэх.
+release.cancel=Болих
+release.publish=Хувилбарыг ашиглах
+release.save_draft=Драфт хадгалах
+release.edit_release=Хувилбар засах
+release.delete_release=Энэ хувилбарыг устгэх
+release.deletion=Хувилбар устгах
+release.deletion_desc=Энэ хувилбарыг устгаснаар холбогдох Git таг устах болно. Та үргэлжлүүлэхийг хүсч байна уу?
+release.deletion_success=Хувилбарыг амжилттай устгалаа!
+release.tag_name_already_exist=Энэ шошгоны нэртэй хувилбар аль хэдийнэ гарсан байна.
+release.tag_name_invalid=Тагийн нэр буруу байна.
+release.downloads=Татах
+
+[org]
+org_name_holder=Байгууллагын нэр
+org_full_name_holder=Байгууллагын бүтэн нэр
+org_name_helper=Байгууллагын нэрээ богино, санахад хялбар оруулна уу.
+create_org=Байгууллаг үүсгэх
+repo_updated=Шинэчилсэн
+people=Хүмүүс
+invite_someone=Урилга илгээх
+teams=Багууд
+lower_members=гишүүд
+lower_repositories=репонууд
+create_new_team=Баг үүсгэх
+org_desc=Тайлбар
+team_name=Багийн нэр
+team_desc=Тайлбар
+team_name_helper=Та цаашид энэ нэрийг ашиглана.
+team_desc_helper=Багийн тодорхойлолт?
+team_permission_desc=Багт ямар эрх шаардлагатай вэ?
+
+form.name_not_allowed=Organization name or pattern %q is not allowed.
+form.team_name_not_allowed=Team name or pattern %q is not allowed.
+
+settings=Тохиргоо
+settings.options=Сонголтууд
+settings.full_name=Бүтэн нэр
+settings.website=Вэбсайт
+settings.location=Байршил
+settings.update_settings=Тохиргоог шинэчлэх
+settings.update_setting_success=Байгууллагын тохиргоог амжилттай шинэчиллээ.
+settings.change_orgname_prompt=Энэ өөрчлөлт нь холбоосууд нь байгууллагатай хэрхэн холбогдоход нөлөөлнө.
+settings.update_avatar_success=Байгууллагын аватар тохиргоог амжилттай шинэчиллээ.
+settings.delete=Delete Organization
+settings.delete_account=Байгууллагыг устгах
+settings.delete_prompt=Байгууллага бүрмөсөн устгагдах бөгөөд үүнийг дахин сэргээх <strong> БОЛОМЖГҮЙ </strong>!
+settings.confirm_delete_account=Устгалтыг баталгаажуулах
+settings.delete_org_title=Байгууллагыг устгах
+settings.delete_org_desc=Энэ байгууллага бүрмөсөн устах бол, үргэлжлүүлнэ үү?
+settings.hooks_desc=Энэ байгууллагын харьяалагдах <strong> бүх репо </strong> -д webhooks нэмнэ үү.
+
+members.membership_visibility=Гишүүнчлэлийн харагдах байдал:
+members.public=Нээлттэй
+members.public_helper=хаалттай болгох
+members.private=Хаалттай
+members.private_helper=нээлттэй болгох
+members.member_role=Хэрэглэгчийн эрх:
+members.owner=Эзэмшигч
+members.member=Гишүүн
+members.remove=Устгах
+members.leave=Гарах
+members.invite_desc=%s гишүүн нэмэх :
+members.invite_now=Урих
+
+teams.join=Нэгдэх
+teams.leave=Гарах
+teams.read_access=Унших эрх
+teams.read_access_helper=Тус репо-г үзэх болон хуулах боломжтой болно.
+teams.write_access=Бичих эрх
+teams.write_access_helper=Тус репо-г үзэх болон хуулахаас гадна бичих боломжтой болно.
+teams.admin_access=Админ эрх
+teams.admin_access_helper=Тус репо-г үзэх болон хуулахаас гадна бичих боломжтой. Мөн хамтран ажиллах хэрэглэгч нэмэх эрхтэй болно.
+teams.no_desc=Энэ багт ямар ч тайлбар байхгүй
+teams.settings=Тохиргоо
+teams.owners_permission_desc=Эзэмшигч нь <strong>бүх репо-г</strong> удирдах <strong>админ эрхтэй</strong>.
+teams.members=Багийн гишүүд
+teams.update_settings=Өөрчлөх тохиргоо
+teams.delete_team=Энэ багийг устгах
+teams.add_team_member=Багийн гишүүн нэмэх
+teams.delete_team_title=Багийн устгах
+teams.delete_team_desc=Энэ багийг устгахад тус багийн гишүүд хамаарал бүхий зарим репо руу хандах эрхээ алдаж магадгүй юм. Та үргэлжлүүлэхийг үү?
+teams.delete_team_success=Багийг амжилттай устгалаа.
+teams.read_permission_desc=Энэ багт гишүүнээр элсэх нь <strong> Унших </strong> эрхийг олгоно: гишүүд репозиторыг үзэх, хуулбарлах боломжтой.
+teams.write_permission_desc=Энэ багийн гишүүнчлэл нь <strong> Бичих </strong> эрхийг өгдөг: гишүүд репозиторыг уншиж, бичих боломжтой.
+teams.admin_permission_desc=Энэ багийн гишүүнчлэл нь <strong> Админ </strong> эрх олгоно: гишүүд репозиторыг уншиж, бичих, хэрэглэгч нэмж оруулах боломжтой.
+teams.repositories=Багийн репонууд
+teams.search_repo_placeholder=Репо хайх...
+teams.add_team_repository=Багт репо нэмэх
+teams.remove_repo=Устгах
+teams.add_nonexistent_repo=Таны нэмэх гэж буй репо үүсээгүй байна.
+
+[admin]
+dashboard=Хянах самбар
+users=Хэрэглэгчид
+organizations=Байгууллагууд
+repositories=Репонууд
+authentication=Баталгаажуулалт
+config=Тохиргоо
+notices=Системийн мэдэгдэл
+monitor=Хяналт
+first_page=Эхний
+last_page=Сүүлийн
+total=Нийт: %d
+
+dashboard.build_info=Build мэдээлэл
+dashboard.app_ver=Аппликэшн хувилбар
+dashboard.git_version=Git хувилбар
+dashboard.go_version=Go хувилбар
+dashboard.build_time=Build цаг
+dashboard.build_commit=Build commit
+dashboard.statistic=Статистик
+dashboard.operations=Ажиллагаа
+dashboard.system_status=Системийн төлөв
+dashboard.statistic_info=Gogs өгөгдлийн бааз нь <b>%d</b> хэрэглэгч, <b>%d</b> байгууллага, <b>%d</b> нийтийн түлхүүр, <b>%d</b> репо, <b>%d</b> дагасан, <b>%d</b> тэмдэглэсэн, <b>%d</b> үйлдэл хийгдсэн, <b>%d</b> хандалт авсан, <b>%d</b> асуудал нийтэлсэн, <b>%d</b> саналтай, <b>%d</b> social данс, <b>%d</b> дагагч, <b>%d</b> хуулбар, <b>%d</b> хувилбар, <b>%d</b> нэвтрэх эх сурвалж, <b>%d</b> webhooks, <b>%d</b> чухал үйл явдлууд, <b>%d</b> шошго, <b>%d</b> hook үйл ажиллагаа, <b>%d</b> баг, <b>%d</b> өөрчлөх үйл ажиллагаа, <b>%d</b> хавсралтай байна.
+dashboard.operation_name=Үйлдлийн нэр
+dashboard.operation_switch=Солих
+dashboard.select_operation_to_run=Ажиллуулах үйлдлийг сонгоно уу
+dashboard.operation_run=Run
+dashboard.clean_unbind_oauth=Ашиглаагүй OAuthes цэвэрлэх
+dashboard.clean_unbind_oauth_success=Бүх ашиглаагүй OAuthes-ийг амжилттай устгалаа.
+dashboard.delete_inactivate_accounts=Бүх идэвхгүй дансыг устгах
+dashboard.delete_inactivate_accounts_success=Бүх идэвхгүй данс амжилттай устгалаа.
+dashboard.delete_repo_archives=Бүх репо архив устгах
+dashboard.delete_repo_archives_success=Бүх репо архив данс амжилттай устгалаа.
+dashboard.delete_missing_repos=Git Файлгүй болсон бүх Репо-г устах
+dashboard.delete_missing_repos_success=Git Файлгүй болсон бүх Репо амжилттай устгалаа.
+dashboard.git_gc_repos=Бусад шаардлагагүй мэдээллийг цэвэрлэх
+dashboard.git_gc_repos_success=Шаардлагаггүй мэдэлллүүд амжилттай устлаа
+dashboard.resync_all_sshkeys='.ssh/authorized_keys' файлыг дахин бичих (анхааруулга: Gogs-ийн биш түлхүүрүүд алдагдах болно)
+dashboard.resync_all_sshkeys_success=Бүх нийтийн түлхүүрүүдийг амжилттай дахин бичлээ.
+dashboard.resync_all_hooks=Бүх репо-г дахин шинэчлэх
+dashboard.resync_all_hooks_success=Бүх репо-г  амжилттай дахин бичлээ.
+dashboard.reinit_missing_repos=Git файлуудыг алдсан бүх репозиторыг дахин эхлүүлэх
+dashboard.reinit_missing_repos_success=Git файлуудыг алдсан бүх репозиторыг амжилттай дахин эхлүүллээ.
+
+dashboard.server_uptime=Серверийн ажилласан хугацаа
+dashboard.current_goroutine=Одоогийн
+dashboard.current_memory_usage=Санах ойн одоогийн хэрэглээ
+dashboard.total_memory_allocated=Хуваарилагдсан санах ой
+dashboard.memory_obtained=Авсан санах ой
+dashboard.pointer_lookup_times=Pointer харах хугацаа
+dashboard.memory_allocate_times=Санах ой хуваарилах хугацаа
+dashboard.memory_free_times=Санах ой чөлөөлөх хугацаа
+dashboard.current_heap_usage=Current Heap Usage
+dashboard.heap_memory_obtained=Heap санах ой
+dashboard.heap_memory_idle=Heap санах ой хүлээлгийн горим
+dashboard.heap_memory_in_use=Heap санах ой ашиглаж байгаа
+dashboard.heap_memory_released=Heap санах ой чөлөөлсөн
+dashboard.heap_objects=Heap объект
+dashboard.bootstrap_stack_usage=Bootstrap Stack хэрэглээ
+dashboard.stack_memory_obtained=Stack санах ой
+dashboard.mspan_structures_usage=MSpan бүтцийн хэрэглээ
+dashboard.mspan_structures_obtained=MSpan бүтэц
+dashboard.mcache_structures_usage=MCache бүтцийн хэрэглээ
+dashboard.mcache_structures_obtained=MCache бүтэц
+dashboard.profiling_bucket_hash_table_obtained=Hash Table
+dashboard.gc_metadata_obtained=GC метадата
+dashboard.other_system_allocation_obtained=Бусад хуваарилагдсан
+dashboard.next_gc_recycle=Дараагийн GC Recycle
+dashboard.last_gc_time=Сүүлийн GC Time-с хойш
+dashboard.total_gc_time=Нийт GC цаг
+dashboard.total_gc_pause=Нийт GC зогсолт
+dashboard.last_gc_pause=Сүүлийн GC зогсолт
+dashboard.gc_times=GC цаг
+
+users.user_manage_panel=Хэрэглэгч удирдах
+users.new_account=Хэрэлэгч үүсгэх
+users.name=Нэр
+users.activated=Идэвхитэй
+users.admin=Админ
+users.repos=Репо
+users.created=Үүсгэсэн
+users.send_register_notify=Хэрэглэгчид бүртгэлийн мэдэгдэл илгээх
+users.new_success='%s' шинэ данс амжилттай үүслээ.
+users.edit=Засах
+users.auth_source=Нэвтрэлтийн төрөл
+users.local=Дотоод
+users.auth_login_name=Нэвтрэх нэр
+users.password_helper=Өөрчлөхгүй бол хоосон орхино уу.
+users.update_profile_success=Бүртгэлийн профайл амжилттай шинэчлэгдсэн..
+users.edit_account=Бүртгэлээ засах
+users.max_repo_creation=Репо үүсгэх хамгийн дээд хязгаар
+users.max_repo_creation_desc=(Хязрааргүй бол -1 гэж бичнэ үү)
+users.is_activated=Энэ бүртгэл идэвхжсэн байна
+users.prohibit_login=Энэ дансанд нэвтрэхийг хориглоно
+users.is_admin=Энэ дансанд администраторын зөвшөөрөл байна
+users.allow_git_hook=Энэ дансанд Git hooks үүсгэх зөвшөөрөл байна
+users.allow_import_local=Энэ данс нь дотоод репозиторыг импортлох зөвшөөрөлтэй
+users.update_profile=Бүртгэлийн профайлыг шинэчлэх
+users.delete_account=Энэ дансыг устгах
+users.still_own_repo=Энэ данс дор хаяж нэг репо-г эзэмших эрхтэй хэвээр байгаа тул та эхлээд устгах эсвэл шилжүүлэх хэрэгтэй.
+users.still_has_org=Энэ данс дор хаяж нэг байгууллагын гишүүнчлэлтэй хэвээр байгаа тул та эхлээд байгууллагуудаас гарах эсвэл устгах хэрэгтэй.
+users.deletion_success=Бүртгэлийг амжилттай устгалаа!
+
+orgs.org_manage_panel=Байгууллага удирдах
+orgs.name=Нэр
+orgs.teams=Багууд
+orgs.members=Гишүүд
+
+repos.repo_manage_panel=Репо удирдах
+repos.owner=Эзэмшигч
+repos.name=Нэр
+repos.private=Хувийн
+repos.watches=Үзсэн
+repos.stars=Тэмдэглэсэн
+repos.issues=Шийдвэрлэх асуудал
+repos.size=Хэмжээний
+
+auths.auth_sources=Баталгаажуулалтын эх сурвалжууд
+auths.new=Шинэ эх сурвалж нэмэх
+auths.name=Нэр
+auths.type=Төрөл
+auths.enabled=Идэвхжүүлсэн
+auths.default=Үндсэн
+auths.updated=Шинэчилсэн
+auths.auth_type=Баталгаажуулалтын төрөл
+auths.auth_name=Баталгаажуулалтын нэр
+auths.security_protocol=Нууцлалын протокол
+auths.domain=Домайн
+auths.host=Хост
+auths.port=Порт
+auths.bind_dn=DN-г холбох
+auths.bind_dn_helper=Та '%s'-ийг хэрэглэгчийн нэрэнд зориулж ашиглаж болно, ж.нь. DOM\%s
+auths.bind_password=Нууц үгийг холбох
+auths.bind_password_helper=Анхааруулга: Энэ нууц үг энгийн текстэнд хадгалагддаг.
+auths.user_base=Хэрэглэгчийн хайлтын бааз
+auths.user_dn=Хэрэглэгчийн DN
+auths.attribute_username=Хэрэглэгчийн нэрийн шинж чанар
+auths.attribute_username_placeholder=Хэрэглэгчийн нэр дээр нэвтрэх хэлбэрийн талбарын утгыг ашиглахын тулд хоосон орхино уу.
+auths.attribute_name=Нэр тодорхойлолт
+auths.attribute_surname=Овог тодорхойлолт
+auths.attribute_mail=Имэйл тодорхойлолт
+auths.verify_group_membership=Бүлгийн гишүүнчлэлийг баталгаажуулах
+auths.group_search_base_dn=Бүлгийн DN хайлтын бааз
+auths.group_filter=Бүлгийн шүүлтүүр
+auths.group_attribute_contain_user_list=Хэрэглэгчийн жагсаалтыг агуулсан бүлэг тодорхойлолт
+auths.user_attribute_listed_in_group=Бүлэг доторх хэрэглэгчийн тодорхойлолт
+auths.attributes_in_bind=DN тодорхойлолт
+auths.filter=Хэрэглэгчийн шүүлтүүр
+auths.admin_filter=Админы шүүлтүүр
+auths.ms_ad_sa=Ms Ad SA
+auths.smtp_auth=SMTP тохиргоо
+auths.smtphost=SMTP Хост
+auths.smtpport=SMTP Порт
+auths.allowed_domains=Зөвшөөрөгдсөн домайн
+auths.allowed_domains_helper=Домэйнийг хамааралгүй бол хоосон орхино уу. Олон домэйныг ',' гэсэн таслалаар тусгаарлана.
+auths.enable_tls=TLS шифрлэлтийг идэвхжүүлэх
+auths.skip_tls_verify=TLS баталгаажуулалтыг алгасах
+auths.pam_service_name=PAM үйлчилгээний нэр
+auths.enable_auto_register=Автомат бүртгэлийг идэвхжүүлэх
+auths.edit=Баталгаажуулалтын тохиргоог засах
+auths.activated=Энэ баталгаажуулалт идэвхжсэн байна
+auths.default_auth=Үндсэн танилт нэвтрэлт
+auths.new_success=Шинэ танилт нэвтрэлт '%s' амжилттай нэмэгдэв.
+auths.update_success=Баталгаажуулалтын тохиргоог амжилттай шинэчиллээ.
+auths.update=Баталгаажуулалтын тохиргоог шинэчлэх
+auths.delete=Энэ баталгаажуулалтыг устгах
+auths.delete_auth_title=Баталгаажуулалтыг устгах
+auths.delete_auth_desc=Энэ баталгаажуулалтыг устгах гэж байна, үргэлжлүүлэх үү?
+auths.still_in_used=Энэхүү нэвтрэлт танилтыг зарим хэрэглэгчид ашигладаг хэвээр байгаа тул эхлээд эдгээр хэрэглэгчдийг устгаж эсвэл өөр нэвтрэх хэлбэрт хөрвүүлнэ үү.
+auths.deletion_success=Баталгаажуулалтыг амжилттай устгалаа!
+auths.login_source_exist='% s' танил нэвтрэлтийн төрөл өмнө үүссэн байна.
+auths.github_api_endpoint=API Endpoint
+
+config.not_set=(тохируулаагүй)
+config.server_config=Серверийн тохиргоо
+config.brand_name=Брэндийн нэр
+config.run_user=Ажиллуулах хэрэглэгч
+config.run_mode=Ажиллуулах горим
+config.server.external_url=Гадаад хаяг
+config.server.domain=Домайн
+config.server.protocol=Протокод
+config.server.http_addr=HTTP хаяг
+config.server.http_port=HTTP порт
+config.server.cert_file=Certificate файл
+config.server.key_file=Key файл
+config.server.tls_min_version=TLS хувилбар /багадаа/
+config.server.unix_socket_permission=Unix сокет зөвшөөрөл
+config.server.local_root_url=Дотоод үндсэн URL
+config.server.offline_mode=Офлайн горим
+config.server.disable_router_log=Рүүэрийн бүртгэлийг идэвхгүй болгох
+config.server.enable_gzip=Gzip-ийг идэвхжүүлэх
+config.server.app_data_path=Өгөгдөл хадгалах зам
+config.server.load_assets_from_disk=Нөөц хадгалах зам
+config.server.landing_url=Үндсэн URL
+
+config.ssh_config=SSH тохиргоо
+config.ssh.enabled=Идэвхитэй
+config.ssh.domain=Домэйн
+config.ssh.port=Порт
+config.ssh.root_path=Зам
+config.ssh.keygen_path=Түлхүүрийн зам
+config.ssh.key_test_path=Түлхүүрийн тест зам
+config.ssh.minimum_key_size_check=Түлхүүрийн хамгийн бага хэмжээ шалгах
+config.ssh.minimum_key_sizes=Түлхүүрийн хамгийн бага хэмжээ
+config.ssh.rewrite_authorized_keys_at_start=Дахин чиглүүлэх "authorized_keys"
+config.ssh.start_builtin_server=Дотоод серверийг эхлүүлэх
+config.ssh.listen_host=Сонсох хост
+config.ssh.listen_port=Сонсох порт
+config.ssh.server_ciphers=Серверийн шифр
+
+config.repo_config=Хадгалах сангийн тохиргоо
+config.repo.root_path=Root буюу эх зам
+config.repo.script_type=Скриптийн төрөл
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Албадан нууцлах
+config.repo.max_creation_limit=Хамгийн их үүсгэх хязгаар
+config.repo.preferred_licenses=Бэлтгэсэн лицензүүд
+config.repo.disable_http_git=HTTP Git идэвхигүй болгох
+config.repo.enable_local_path_migration=Дотоод нэгтгэл зөвшөөрөх
+config.repo.enable_raw_file_render_mode=Raw файл горимыг идэвхжүүлэх
+config.repo.commits_fetch_concurrency=Зэрэгцээ commit зөвшөөрөх
+config.repo.editor.line_wrap_extensions=Editor мөр өргөтгөх
+config.repo.editor.previewable_file_modes=Editor удидчилж харах
+config.repo.upload.enabled=Upload идэвхижүүлэх
+config.repo.upload.temp_path=Upload файлын зам
+config.repo.upload.allowed_types=Upload зөвшөөрөгдсөн төрлүүд
+config.repo.upload.file_max_size=Upload файлын хэмжээ ихдээ
+config.repo.upload.max_files=Upload файлын тоо ихдээ
+
+config.db_config=Өгөгдлийн баазын тохиргоо
+config.db.type=Төрөл
+config.db.host=Хост
+config.db.name=Нэр
+config.db.user=Хэрэглэгчийн нэр
+config.db.ssl_mode=SSL
+config.db.ssl_mode_helper=(зөвхөн "postgres"-ийн хувьд)
+config.db.path=Зам
+config.db.path_helper=(зөвхөн "sqlite3"-ийн хувьд)
+config.db.max_open_conns=Нээлттэй холболтын тоо ихдээ
+config.db.max_idle_conns=Идэвхигүй холболтын тоо ихдээ
+
+config.security_config=Аюулгүй байдлын тохиргоо
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Имэйл тохиргоо
+config.email.enabled=Идэвхитэй
+config.email.subject_prefix=Гарчигийн өмнө
+config.email.host=Хост
+config.email.from=Хэнээс
+config.email.user=Хэрэглэгч
+config.email.disable_helo=HELO идэвхигүй
+config.email.helo_hostname=HELO хостын нэр
+config.email.skip_verify=Гэрчилгээ баталгаажуулалтыг алгасах
+config.email.use_certificate=Өөрийн гэрчилгээ ашиглах
+config.email.cert_file=Certificate файл
+config.email.key_file=Key файл
+config.email.use_plain_text=Текст баталгаажуулалт ашиглах
+config.email.add_plain_text_alt=Текстийн өөр хувилбар
+config.email.send_test_mail=Имэйл илгээж турших
+config.email.test_mail_failed=Туршилтын имэйлийг '%s': %v рүү илгээж чадсангүй
+config.email.test_mail_sent=Туршилтын имэйл '%s' рүү илгээгдлээ.
+
+config.auth_config=Authentication тохиргоо
+config.auth.activate_code_lives=Кодын ашиглалтыг идэвхжүүлэх
+config.auth.reset_password_code_lives=Нууц үгийн кодыг шинэчлэх
+config.auth.require_email_confirm=Имэйлээр баталгаажуулахыг шаардана
+config.auth.require_sign_in_view=Нэвтрэхийг шаардана
+config.auth.disable_registration=Бүртгэлийг идэвхгүй болгох
+config.auth.enable_registration_captcha=Бүртгэлийн captcha-г идэвхжүүлэх
+config.auth.enable_reverse_proxy_authentication=Урвуу прокси нэвтрэлт танилтыг идэвхжүүлэх
+config.auth.enable_reverse_proxy_auto_registration=Урвуу прокси автомат бүртгэлийг идэвхжүүлэх
+config.auth.reverse_proxy_authentication_header=Урвуу прокси баталгаажуулах header
+
+config.user_config=Хэрэглэгчийн тохиргоо
+config.user.enable_email_notify=Имэйл тохиргоо
+
+config.session_config=Session тохиргоо
+config.session.provider=Нийлүүлэгч
+config.session.provider_config=Нийлүүлэгчийн тохиргоо
+config.session.cookie_name=Cookie
+config.session.https_only=зөвхөн HTTPS
+config.session.gc_interval=GC хугацаа
+config.session.max_life_time=Хадгалагдах хугацаа хамгийн ихдээ
+config.session.csrf_cookie_name=CSRF cookie
+
+config.cache_config=Cache тохиргоо
+config.cache.adapter=Адаптер
+config.cache.interval=GC хугацаа
+config.cache.host=Хост
+
+config.http_config=HTTP тохиргоо
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Хавсралтын тохиргоо
+config.attachment.enabled=Идэвхитэй
+config.attachment.path=Зам
+config.attachment.allowed_types=Зөвшөөрөгдсөн төрлүүд
+config.attachment.max_size=Хэмжээний хязгаар
+config.attachment.max_files=Файлын хязгаар
+
+config.release_config=Хувилбарын тохиргоо
+config.release.attachment.enabled=Хавсралт идэвхжсэн
+config.release.attachment.allowed_types=Хавсралтын зөвшөөрөгдсөн төрлүүд
+config.release.attachment.max_size=Хавсралтын хэмжээ хязгаар
+config.release.attachment.max_files=Хавсралтын файлын хязгаар
+
+config.picture_config=Зургийн тохиргоо
+config.picture.avatar_upload_path=Хэрэглэгчийн аватар байршуулах зам
+config.picture.repo_avatar_upload_path=Агуулахын аватар байршуулах зам
+config.picture.gravatar_source=Граватар эх сурвалж
+config.picture.disable_gravatar=Граватарыг идэвхгүй болгох
+config.picture.enable_federated_avatar=Холбогдсон аватаруудыг идэвхжүүлэх
+
+config.mirror_config=Хуулбарын тохиргоо
+config.mirror.default_interval=Анхдагч интервал
+
+config.webhook_config=Webhook тохиргоо
+config.webhook.types=Төрлүүд
+config.webhook.deliver_timeout=Дамжуулах хугацаа
+config.webhook.skip_tls_verify=TLS баталгаажуулалтыг алгасах
+
+config.git_config=Git тохиргоо
+config.git.disable_diff_highlight=Ялгааг тодруулж харуулахыг болих
+config.git.max_diff_lines=Ялгаатай мөрийн тоо ихдээ (нэг файлын хувьд)
+config.git.max_diff_line_characters=Ялгаатай тэмдэгтийн тоо (нэг мөрийн хувьд)
+config.git.max_diff_files== Ялгаатай файлын тоо (нэг өөрчлөлтийн хувьд)
+config.git.gc_args=GC аргументууд
+config.git.migrate_timeout=Нэгтгэх хугацаа
+config.git.mirror_timeout=Mirror timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
+
+config.lfs_config=LFS тохиргоо
+config.lfs.storage=Зай
+config.lfs.objects_path=Объектын зам
+
+config.log_config=Лог мэдээллийн тохируулга
+config.log_file_root_path=Лог мэдээллийн зам
+config.log_mode=Горим
+config.log_options=Сонголтууд
+
+monitor.cron=Cron ажлууд
+monitor.name=Нэр
+monitor.schedule=Хуваарь
+monitor.next=Дараах
+monitor.previous=Өмнөх
+monitor.execute_times=Ажилласан
+monitor.process=Ажиллаж байгаа
+monitor.desc=Тайлбар
+monitor.start=Эхлэх цаг
+monitor.execute_time=Ажиллах хугацаа
+
+notices.system_notice_list=Системийн мэдэгдэл
+notices.view_detail_header=Мэдэгдэлийн дэлгэрэнгүйг үзэх
+notices.actions=Үйлдэл
+notices.select_all=Бүгдийг сонгох
+notices.deselect_all=Бүгдийг цуцлах
+notices.inverse_selection=Урвуугаар сонгох
+notices.delete_selected=Сонгогдсоныг устгах
+notices.delete_all=Бүх мэдэгдлийг устгах
+notices.type=Төрөл
+notices.type_1=Репо
+notices.desc=Тайлбар
+notices.op=заавал биш.
+notices.delete_success=Системийн мэдэгдлийг амжилттай устгасан.
+
+[action]
+create_repo=<a href="%s">%s</a> репо-г үүсгэлээ
+rename_repo=<code>%[1]s</code> репо-г <a href="%[2]s">%[3]s</a> болгож өөрчиллөө
+commit_repo=Push хийсэн <a href="%[1]s/src/%[2]s">%[3]s</a> <a href="%[1]s">%[4]s</a>
+compare_commits=Эдгээр %d commit-уудын харьцуулалтыг харах
+transfer_repo=репо-г <code>%s</code> -с <a href="%s">%s</a> рүү шилжүүллээ
+create_issue=`нээлттэй <a href="%s/issues/%s">%s#%[2]s</a>`
+close_issue=`хаалттай  <a href="%s/issues/%s">%s#%[2]s</a>`
+reopen_issue=`дахин нээсэн <a href="%s/issues/%s">%s#%[2]s</a>`
+comment_issue=`сэтгэгдэл үлдээсэн <a href="%s/issues/%s">%s#%[2]s</a>`
+create_pull_request=`pull request үүсгэсэн <a href="%s/pulls/%s">%s#%[2]s</a>`
+close_pull_request=`pull request хаасан <a href="%s/pulls/%s">%s#%[2]s</a>`
+reopen_pull_request=`pull request дахин нээсэн <a href="%s/pulls/%s">%s#%[2]s</a>`
+merge_pull_request=`pull request нэгтгэсэн <a href="%s/pulls/%s">%s#%[2]s</a>`
+create_branch=шинэ хуулбар үүсгэсэн <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
+delete_branch=устгасах хуулбар <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
+push_tag=pushed таг <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a>
+delete_tag=deleted таг <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
+fork_repo=Репо-х <a href="%s">%s</a> хуулбарласан
+mirror_sync_push=<a href="%[1]s/src/%[2]s">%[3]s</a>-с <a href="%[1]s">%[4]s</a>-д нэгтгэсэн
+mirror_sync_create=<a href="%s/src/%s">%[2]s</a>-с <a href="%[1]s">%[3]s</a>-д нэгтгэсэн
+mirror_sync_delete=code>%[2]s</code> -с <a href="%[1]s">%[3]s</a>-д нэгтгэж, устгасан
+
+[tool]
+ago=өмнө
+from_now=одооноос
+now=одоо
+1s=1 секунд %s
+1m=1 минут %s
+1h=1 цаг %s
+1d=1 өдөр %s
+1w=1 долоо хоног %s
+1mon=1 сар %s
+1y=1 жил %s
+seconds=%d секунд %s
+minutes=%d минут %s
+hours=%d цаг %s
+days=%d өдөр %s
+weeks=%d долоо хоног %s
+months=%d сар %s
+years=%d жил %s
+raw_seconds=секунд
+raw_minutes=минут
+raw_hours=цаг
+
+[dropzone]
+default_message=Файлуудаа энд чирж тавина уу эсвэл Файл товчин дээр дарна уу.
+invalid_input_type=Та ийм төрлийн файл байршуулах боломжгүй.
+file_too_big=Файлын хэмжээ ({{filesize}} MB) дээд хязгаар ({{maxFilesize}} MB) -аас хэтэрсэн байна.
+remove_file=Файлыг устгах
+

+ 1 - 1
conf/locale/locale_nl-NL.ini

@@ -44,7 +44,7 @@ issues=Issues
 cancel=Annuleren
 
 [status]
-page_not_found=Page Not Found
+page_not_found=Pagina niet gevonden
 internal_server_error=Internal Server Error
 
 [install]

+ 54 - 54
conf/locale/locale_pl-PL.ini

@@ -44,8 +44,8 @@ issues=Problemy
 cancel=Anuluj
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Strona nie została znaleziona
+internal_server_error=Wewnętrzny błąd serwera
 
 [install]
 install=Instalacja
@@ -263,7 +263,7 @@ following=Obserwowani
 follow=Obserwuj
 unfollow=Przestań obserwować
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Nazwa użytkownika lub wzór %q jest niedozwolony.
 
 [settings]
 profile=Profil
@@ -429,7 +429,7 @@ repo_description_helper=Opis repozytorium. Maksymalnie 512 znaków.
 repo_description_length=Dostępne znaki
 
 form.reach_limit_of_creation=Właściciel osiągnął limit maksymalnej ilości repozytoriów %d.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=Nazwa repozytorium lub wzór %q jest niedozwolony.
 
 need_auth=Wymaga autoryzacji
 migrate_type=Typ migracji
@@ -790,7 +790,7 @@ settings.search_user_placeholder=Szukaj użytkownika...
 settings.org_not_allowed_to_be_collaborator=Organizacji nie można dodać jako współpracownika.
 settings.hooks_desc=Webooki działają tak jak proste wywołania HTTP POST. Jeśli cokolwiek zdarzy się w Gogs, wyślemy powiadomienie do wybranego hosta. Więcej informacji można znaleźć w <a target="_blank" href="%s">przewodniku webhooków</a>.
 settings.webhooks.add_new=Add a new webhook:
-settings.webhooks.choose_a_type=Choose a type...
+settings.webhooks.choose_a_type=Wybierz typ...
 settings.add_webhook=Dodaj webhooka
 settings.webhook_deletion=Usuń webhooka
 settings.webhook_deletion_desc=Usunięcie tego webooka spowoduje usunięcie powiązanych informacji i wpisów w historii. Czy chcesz kontynuować?
@@ -1011,14 +1011,14 @@ dashboard.app_ver=Wersja aplikacji
 dashboard.git_version=Wersja Git
 dashboard.go_version=Wersja Go
 dashboard.build_time=Data kompilacji
-dashboard.build_commit=Build commit
+dashboard.build_commit=Zbuduj commit
 dashboard.statistic=Statystyki
 dashboard.operations=Operacje
 dashboard.system_status=Stan monitora systemu
 dashboard.statistic_info=Baza danych Gogs zawiera <b>%d</b> użytkowników, <b>%d</b> organizacji, <b>%d</b> kluczy publicznych, <b>%d</b> repozytoriów, <b>%d</b> obserwujących, <b>%d</b> polubionych, <b>%d</b> akcji, <b>%d</b> tokenów, <b>%d</b> problemów, <b>%d</b> komenatrzy, <b>%d</b> kont społecznościowych, <b>%d</b> obserwacji, <b>%d</b> mirrorów, <b>%d</b> wydań, <b>%d</b> login sources, <b>%d</b> webhooków, <b>%d</b> kamieni milowych, <b>%d</b> labels, <b>%d</b> zadań hooków, <b>%d</b> zespołów, <b>%d</b> zadań aktualizacji, <b>%d</b> załączników.
 dashboard.operation_name=Nazwa operacji
 dashboard.operation_switch=Przełącz
-dashboard.select_operation_to_run=Please select operation to run
+dashboard.select_operation_to_run=Wybierz operację do uruchomienia
 dashboard.operation_run=Uruchom
 dashboard.clean_unbind_oauth=Usuń niepowiązane wpisy OAuth
 dashboard.clean_unbind_oauth_success=Wszystkie niepowiązane wpisy OAuth zostały pomyślnie usunięte.
@@ -1180,7 +1180,7 @@ config.server.cert_file=Pliki certyfikatu
 config.server.key_file=Plik klucza
 config.server.tls_min_version=Minimalna wersja TLS
 config.server.unix_socket_permission=Unix socket permission
-config.server.local_root_url=Local root URL
+config.server.local_root_url=Lokalny główny adres URL
 config.server.offline_mode=Tryb offline
 config.server.disable_router_log=Wyłącz dziennik routera
 config.server.enable_gzip=Włącz Gzip
@@ -1192,7 +1192,7 @@ config.ssh_config=Konfiguracja SSH
 config.ssh.enabled=Aktywne
 config.ssh.domain=Exposed domain
 config.ssh.port=Exposed port
-config.ssh.root_path=Root path
+config.ssh.root_path=Ścieżka katalogu głównego
 config.ssh.keygen_path=Keygen path
 config.ssh.key_test_path=Key test path
 config.ssh.minimum_key_size_check=Minimum key size check
@@ -1223,65 +1223,65 @@ config.repo.upload.file_max_size=Upload file size limit
 config.repo.upload.max_files=Upload files limit
 
 config.db_config=Konfiguracja bazy danych
-config.db.type=Type
+config.db.type=Typ
 config.db.host=Host
-config.db.name=Name
-config.db.user=User
-config.db.ssl_mode=SSL mode
+config.db.name=Nazwa
+config.db.user=Użytkownik
+config.db.ssl_mode=Tryb SSL
 config.db.ssl_mode_helper=(for "postgres" only)
-config.db.path=Path
+config.db.path=Ścieżka
 config.db.path_helper=(for "sqlite3"only)
 config.db.max_open_conns=Maximum open connections
 config.db.max_idle_conns=Maximum idle connections
 
 config.security_config=Security configuration
 config.security.login_remember_days=Login remember days
-config.security.cookie_remember_name=Remember cookie
+config.security.cookie_remember_name=Pamiętaj pliki cookies
 config.security.cookie_username=Username cookie
 config.security.cookie_secure=Enable secure cookie
 config.security.reverse_proxy_auth_user=Reverse proxy authentication header
 config.security.enable_login_status_cookie=Enable login status cookie
 config.security.login_status_cookie_name=Login status cookie
 
-config.email_config=Email configuration
-config.email.enabled=Enabled
+config.email_config=Konfiguracja E-mail
+config.email.enabled=Włączono
 config.email.subject_prefix=Subject prefix
 config.email.host=Host
-config.email.from=From
-config.email.user=User
-config.email.disable_helo=Disable HELO
+config.email.from=Od
+config.email.user=Użytkownik
+config.email.disable_helo=Wyłącz HELO
 config.email.helo_hostname=HELO hostname
-config.email.skip_verify=Skip certificate verify
+config.email.skip_verify=Pomiń weryfikację certyfikatu
 config.email.use_certificate=Use custom certificate
 config.email.cert_file=Certificate file
-config.email.key_file=Key file
-config.email.use_plain_text=Use plain text
-config.email.add_plain_text_alt=Add plain text alternative
-config.email.send_test_mail=Send test email
-config.email.test_mail_failed=Failed to send test email to '%s': %v
-config.email.test_mail_sent=Test email has been sent to '%s'.
-
-config.auth_config=Authentication configuration
+config.email.key_file=Plik klucza
+config.email.use_plain_text=Użyj zwykłego tekstu
+config.email.add_plain_text_alt=Dodaj prosty tekst alternatywny
+config.email.send_test_mail=Wyślij wiadomość testową
+config.email.test_mail_failed=Nie udało się wysłać wiadomości testowej do '%s': %v
+config.email.test_mail_sent=Wiadomość testowa została wysłana do '%s'.
+
+config.auth_config=Konfiguracja uwierzytelniania
 config.auth.activate_code_lives=Activate code lives
 config.auth.reset_password_code_lives=Reset password code lives
-config.auth.require_email_confirm=Require email confirmation
+config.auth.require_email_confirm=Wymagaj potwierdzenia adresu e-mail
 config.auth.require_sign_in_view=Require sign in view
-config.auth.disable_registration=Disable registration
+config.auth.disable_registration=Wyłącz rejestrację
 config.auth.enable_registration_captcha=Enable registration captcha
 config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
 config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
 config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
 
-config.user_config=User configuration
+config.user_config=Konfiguracja użytkownika
 config.user.enable_email_notify=Enable email notification
 
 config.session_config=Konfiguracja sesji
-config.session.provider=Provider
+config.session.provider=Dostawca
 config.session.provider_config=Provider config
-config.session.cookie_name=Cookie
-config.session.https_only=HTTPS only
-config.session.gc_interval=GC interval
-config.session.max_life_time=Max life time
+config.session.cookie_name=Ciasteczka
+config.session.https_only=Tylko HTTPS
+config.session.gc_interval=Interwał GC
+config.session.max_life_time=Maksymalny czas życia
 config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Konfiguracja cache
@@ -1293,13 +1293,13 @@ config.http_config=Konfiguracja HTTP
 config.http.access_control_allow_origin=Access control allow origin
 
 config.attachment_config=Attachment configuration
-config.attachment.enabled=Enabled
-config.attachment.path=Path
-config.attachment.allowed_types=Allowed types
-config.attachment.max_size=Size limit
-config.attachment.max_files=Files limit
+config.attachment.enabled=Włączono
+config.attachment.path=Ścieżka
+config.attachment.allowed_types=Dozwolone typy
+config.attachment.max_size=Limit rozmiaru
+config.attachment.max_files=Limit plików
 
-config.release_config=Release configuration
+config.release_config=Konfiguracja wydania
 config.release.attachment.enabled=Attachment enabled
 config.release.attachment.allowed_types=Attachment allowed types
 config.release.attachment.max_size=Attachment size limit
@@ -1308,33 +1308,33 @@ config.release.attachment.max_files=Attachment files limit
 config.picture_config=Ustawienia obrazów
 config.picture.avatar_upload_path=User avatar upload path
 config.picture.repo_avatar_upload_path=Repository avatar upload path
-config.picture.gravatar_source=Gravatar source
-config.picture.disable_gravatar=Disable Gravatar
+config.picture.gravatar_source=Źródło Gravatar
+config.picture.disable_gravatar=Wyłącz Gravatar
 config.picture.enable_federated_avatar=Enable federated avatars
 
-config.mirror_config=Mirror configuration
-config.mirror.default_interval=Default interval
+config.mirror_config=Konfiguracja serwera lustrzanego
+config.mirror.default_interval=Domyślny interwał
 
 config.webhook_config=Konfiguracja webhooka
-config.webhook.types=Types
+config.webhook.types=Typy
 config.webhook.deliver_timeout=Deliver timeout
-config.webhook.skip_tls_verify=Skip TLS verify
+config.webhook.skip_tls_verify=Pomiń weryfikację TLS
 
 config.git_config=Konfiguracja Git
 config.git.disable_diff_highlight=Disable diff syntax highlight
 config.git.max_diff_lines=Diff lines limit (for a single file)
 config.git.max_diff_line_characters=Diff characters limit (for a single line)
 config.git.max_diff_files=Diff files limit (for a single diff)
-config.git.gc_args=GC arguments
-config.git.migrate_timeout=Migration timeout
+config.git.gc_args=Argumenty GC
+config.git.migrate_timeout=Limit czasu migracji
 config.git.mirror_timeout=Mirror fetch timeout
 config.git.clone_timeout=Clone timeout
 config.git.pull_timeout=Pull timeout
 config.git.gc_timeout=GC timeout
 
 config.lfs_config=LFS configuration
-config.lfs.storage=Storage
-config.lfs.objects_path=Objects path
+config.lfs.storage=Magazyn
+config.lfs.objects_path=Ścieżka obiektów
 
 config.log_config=Konfiguracja dziennika
 config.log_file_root_path=Ścieżka plików dziennika
@@ -1409,7 +1409,7 @@ months=%d miesięcy %s
 years=%d lat %s
 raw_seconds=sekund
 raw_minutes=minut
-raw_hours=hours
+raw_hours=godziny
 
 [dropzone]
 default_message=Upuść pliki tutaj lub kliknij, aby przesłać.

+ 52 - 52
conf/locale/locale_pt-BR.ini

@@ -44,8 +44,8 @@ issues=Problemas
 cancel=Cancelar
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Página Não Encontrada
+internal_server_error=Erro interno do servidor
 
 [install]
 install=Instalação
@@ -125,7 +125,7 @@ run_user_not_match=O usuário da execução não é o usuário atual: %s -> %s
 smtp_host_missing_port=O endereço do host SMTP não possui porta.
 invalid_smtp_from=O SMTP do campo não é válido: %v
 save_config_failed=Falha ao salvar a configuração: %v
-init_failed=Failed to initialize application: %v
+init_failed=Falha ao inicializar a aplicação: %v
 invalid_admin_setting=Configuração da conta de administrador está inválida: %v
 install_success=Bem-vindo! Estamos contentes que você escolheu o Gogs, divirta-se e tenha cuidado.
 invalid_log_root_path=Pasta raíz do log é inválida: %v
@@ -155,7 +155,7 @@ register_hepler_msg=Já tem uma conta? Entre agora!
 social_register_hepler_msg=Já tem uma conta? Junte-se agora!
 disable_register_prompt=Desculpe, novos registros estão desabilitados. Por favor entre em contato com o administrador do site.
 disable_register_mail=Desculpe, a confirmação de registro por e-mail foi desabilitada.
-auth_source=Authentication Source
+auth_source=Fonte de autenticação
 local=Local
 remember_me=Lembrar de mim
 forgot_password=Esqueci a senha
@@ -235,7 +235,7 @@ org_name_been_taken=Nome da organização já foi tomado.
 team_name_been_taken=Nome da equipe já existe.
 email_been_used=Endereço de e-mail já foi usado.
 username_password_incorrect=Usuário ou senha incorretos.
-auth_source_mismatch=The authentication source selected is not associated with the user.
+auth_source_mismatch=A fonte de autenticação selecionada não está associada ao usuário.
 enterred_invalid_repo_name=Por favor certifique-se que informou o nome do repositório corretamente.
 enterred_invalid_owner_name=Por favor, verifique se o nome do proprietário está correto.
 enterred_invalid_password=Por favor, verifique se a senha que você digitou está correta.
@@ -263,7 +263,7 @@ following=Seguindo
 follow=Seguir
 unfollow=Deixar de seguir
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Nome de usuário ou padrão %q não é permitido.
 
 [settings]
 profile=Perfil
@@ -354,7 +354,7 @@ two_factor_or_enter_secret=Ou informe o segredo:
 two_factor_then_enter_passcode=Em seguida digite a senha:
 two_factor_verify=Verificar
 two_factor_invalid_passcode=A senha inserida é inválida. Tente novamente!
-two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
+two_factor_reused_passcode=A senha fornecida já foi usada, por favor tente outra!
 two_factor_enable_error=Falha ao ativar a autenticação de dois fatores: %v
 two_factor_enable_success=A autenticação de dois fatores foi ativada para a sua conta com sucesso!
 two_factor_recovery_codes_title=Códigos de recup. p/ autenticação de dois fatores
@@ -377,7 +377,7 @@ delete_token=Excluir
 access_token_deletion=Exclusão do token de acesso pessoal
 access_token_deletion_desc=Ao Excluir este token de acesso pessoal será removido todos os acessos do aplicativo. Você deseja continuar?
 delete_token_success=O Token de acesso pessoal foi removido com sucesso! Não se esqueça de atualizar seus aplicativos também.
-token_name_exists=Token with same name already exists.
+token_name_exists=Já existe um token com o mesmo nome.
 
 orgs.none=Você não é participante de nenhuma organização.
 orgs.leave_title=Deixar uma organização
@@ -425,11 +425,11 @@ mirror_last_synced=Última sincronização
 watchers=Observadores
 stargazers=Usuários que estrelaram
 forks=Forks
-repo_description_helper=Description of repository. Maximum 512 characters length.
-repo_description_length=Available characters
+repo_description_helper=Descrição do repositório. Tamanho máximo de 512 caracteres.
+repo_description_length=Caracteres disponíveis
 
 form.reach_limit_of_creation=O proprietário atingiu o limite máximo de criação de repositórios de %d.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=Nome de usuário ou padrão %q não é permitido.
 
 need_auth=Precisa de autorização
 migrate_type=Tipo de migração
@@ -523,7 +523,7 @@ editor.file_changed_while_editing=O conteúdo do arquivo mudou desde que você c
 editor.file_already_exists=Um arquivo com nome '%s' já existe neste repositório.
 editor.no_changes_to_show=Nenhuma alteração a mostrar.
 editor.fail_to_update_file=Houve erro ao criar ou atualizar arquivo '%s': %v
-editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
+editor.fail_to_delete_file=Falha ao excluir arquivo '%s' com erro: %v
 editor.add_subdir=Adicionar o subdiretório...
 editor.unable_to_upload_files=Houve erro ao fazer upload de arquivos para '%s': %v
 editor.upload_files_to_dir=Enviar arquivos para '%s'
@@ -643,8 +643,8 @@ pulls.can_auto_merge_desc=O merge deste Pull Pequest pode ser aplicado automatic
 pulls.cannot_auto_merge_desc=O merge deste Pull Request não pode ser aplicado automaticamente pois há conflitos.
 pulls.cannot_auto_merge_helper=Por favor, aplique o merge manualmente para resolver os conflitos.
 pulls.create_merge_commit=Criar commit de um merge
-pulls.rebase_before_merging=Rebase before merging
-pulls.commit_description=Commit Description
+pulls.rebase_before_merging=Execute rebase antes de fazer merge
+pulls.commit_description=Descrição do Commit
 pulls.merge_pull_request=Solicitação de merge de Pull Request
 pulls.open_unmerged_pull_exists=`Você não pode executar a operação de reabrir porque já existe um Pull request aberto (#%d) do mesmo repositório com as mesmas informações de merge e está esperando pelo merge.`
 pulls.delete_branch=Excluir Branch
@@ -749,7 +749,7 @@ settings.tracker_issue_style=Estilo de nome de issue tracker externo:
 settings.tracker_issue_style.numeric=Numérico
 settings.tracker_issue_style.alphanumeric=Alfanumérico
 settings.tracker_url_format_desc=Você pode usar o espaço reservado <code>{user} {repo} {index}</code> para o nome do usuário, índice de nome e a questão do repositório.
-settings.pulls_desc=Enable pull requests to accept contributions between repositories and branches
+settings.pulls_desc=Habilitar pull requests para aceitar contribuições entre repositórios e branches
 settings.pulls.ignore_whitespace=Ignorar alterações em espaço em branco
 settings.pulls.allow_rebase_merge=Permitir rebase para commits via merge
 settings.danger_zone=Zona de perigo
@@ -789,8 +789,8 @@ settings.remove_collaborator_success=O colaborador foi removido.
 settings.search_user_placeholder=Pesquisar usuário...
 settings.org_not_allowed_to_be_collaborator=Organização não tem permissão para ser adicionada como um colaborador.
 settings.hooks_desc=Hooks da web ou Webhooks permitem serviços externos serem notificados quando certos eventos acontecem no Gogs. Quando acontecem os eventos especificados, enviaremos uma solicitação POST para cada uma das URLs que você fornecer. Saiba mais no nosso <a target="_blank" href="%s"> Guia de Webhooks</a>.
-settings.webhooks.add_new=Add a new webhook:
-settings.webhooks.choose_a_type=Choose a type...
+settings.webhooks.add_new=Adicionar um novo webhook:
+settings.webhooks.choose_a_type=Escolha um tipo...
 settings.add_webhook=Adicionar Webhook
 settings.webhook_deletion=Deletar Webhook
 settings.webhook_deletion_desc=Deletar este Webhook vai remover sua informação e todo o histórico de entrega. Deseja continuar?
@@ -805,8 +805,8 @@ settings.webhook.response=Resposta
 settings.webhook.headers=Cabeçalhos
 settings.webhook.payload=Payload
 settings.webhook.body=Corpo
-settings.webhook.err_cannot_parse_payload_url=Cannot parse payload URL: %v
-settings.webhook.err_cannot_use_local_addresses=Non admins are not allowed to use local addresses.
+settings.webhook.err_cannot_parse_payload_url=Não foi possível analisar a URL da carga: %v
+settings.webhook.err_cannot_use_local_addresses=Não-administradores não tem permissão para usar endereços locais.
 settings.githooks_desc=Hooks do Git são ofertados pelo próprio Git, você pode editar arquivos de hooks suportados na lista abaixo para aplicar operações personalizadas.
 settings.githook_edit_desc=Se o hook não estiver ativo, o conteúdo de exemplo será apresentado. Deixar o conteúdo em branco irá desativar esse hook.
 settings.githook_name=Nome do Hook
@@ -867,8 +867,8 @@ settings.add_key_success=A nova chave de Deploy '%s' foi adicionada com sucesso!
 settings.deploy_key_deletion=Exclusão de chave de Deploy
 settings.deploy_key_deletion_desc=Excluir esta chave de Deploy removerá permissões de acesso a este repositório. Quer mesmo continuar?
 settings.deploy_key_deletion_success=Chave de Deploy excluída com sucesso!
-settings.description_desc=Description of repository. Maximum 512 characters length.
-settings.description_length=Available characters
+settings.description_desc=Descrição do repositório. Tamanho máximo de 512 caracteres.
+settings.description_length=Caracteres disponíveis
 
 diff.browse_source=Ver código fonte
 diff.parent=pai
@@ -933,8 +933,8 @@ team_name_helper=Você usará este nome para mencionar esta equipe em conversas.
 team_desc_helper=Do que trata essa equipe?
 team_permission_desc=Que nível de permissão esta equipe deve ter?
 
-form.name_not_allowed=Organization name or pattern %q is not allowed.
-form.team_name_not_allowed=Team name or pattern %q is not allowed.
+form.name_not_allowed=Nome da organização ou padrão %q não é permitido.
+form.team_name_not_allowed=Nome do time ou padrão %q não é permitido.
 
 settings=Configurações
 settings.options=Opções
@@ -1006,19 +1006,19 @@ first_page=Primeira
 last_page=Última
 total=Total: %d
 
-dashboard.build_info=Build Information
-dashboard.app_ver=Application version
-dashboard.git_version=Git version
-dashboard.go_version=Go version
-dashboard.build_time=Build time
-dashboard.build_commit=Build commit
+dashboard.build_info=Informações da compilação
+dashboard.app_ver=Versão do aplicativo
+dashboard.git_version=Versão do Git
+dashboard.go_version=Versão Go
+dashboard.build_time=Data de compilação
+dashboard.build_commit=Commit da compilação
 dashboard.statistic=Estatística
 dashboard.operations=Operações
 dashboard.system_status=Status do monitor de sistema
 dashboard.statistic_info=O banco de dados do Gogs contém <b>%d</b> usuários, <b>%d</b> organizações, <b>%d</b> chaves públicas, <b>%d</b> repositórios, <b>%d</b> observadores, <b>%d</b> estrelas, <b>%d</b> ações, <b>%d</b> acessos, <b>%d</b> questões, <b>%d</b> comentários, <b>%d</b> contas sociais, <b>%d</b> seguidores, <b>%d</b> espelhos, <b>%d</b> versões, <b>%d</b>  origens de login, <b>%d</b> Hooks da Web, <b>%d</b> milestones, <b>%d</b> labels, <b>%d</b> tarefas hook, <b>%d</b> equipes, <b>%d</b> tarefas de atualização, <b>%d</b> anexos.
 dashboard.operation_name=Nome da operação
 dashboard.operation_switch=Trocar
-dashboard.select_operation_to_run=Please select operation to run
+dashboard.select_operation_to_run=Selecione a operação para executar
 dashboard.operation_run=Executar
 dashboard.clean_unbind_oauth=Limpar OAuthes não acoplados
 dashboard.clean_unbind_oauth_success=Todos OAuthes desvinculados foram excluídos com sucesso.
@@ -1110,12 +1110,12 @@ repos.stars=Favoritos
 repos.issues=Issues
 repos.size=Tamanho
 
-auths.auth_sources=Authentication Sources
+auths.auth_sources=Fontes de autenticação
 auths.new=Adicionar nova fonte
 auths.name=Nome
 auths.type=Tipo
 auths.enabled=Habilitado
-auths.default=Default
+auths.default=Padrão
 auths.updated=Atualizado
 auths.auth_type=Tipo de autenticação
 auths.auth_name=Nome da autenticação
@@ -1135,7 +1135,7 @@ auths.attribute_name=Atributo do Nome
 auths.attribute_surname=Atributo sobrenome
 auths.attribute_mail=Atributo e-mail
 auths.verify_group_membership=Verificar associação a grupo
-auths.group_search_base_dn=Group Search Base DN
+auths.group_search_base_dn=Grupo de Pesquisa DN Base
 auths.group_filter=Filtro de Grupo
 auths.group_attribute_contain_user_list=Atributo do grupo contendo a lista de usuários
 auths.user_attribute_listed_in_group=Atributo do usuário listado no grupo
@@ -1154,7 +1154,7 @@ auths.pam_service_name=Nome de Serviço PAM
 auths.enable_auto_register=Habilitar Registro Automático
 auths.edit=Editar a configuração de autenticação
 auths.activated=Esta autenticação foi ativada
-auths.default_auth=This authentication is default login source
+auths.default_auth=Esta autenticação é uma fonte padrão de login
 auths.new_success=Nova autenticação '%s' foi adicionada com sucesso.
 auths.update_success=A configuração da autenticação foi atualizada com sucesso.
 auths.update=Atualizar a configuração da autenticação
@@ -1164,28 +1164,28 @@ auths.delete_auth_desc=Esta autenticação esta prestes a ser excluída, deseja
 auths.still_in_used=Esta autenticação ainda é usada por alguns usuários. Por favor remova ou converta esses usuários para outro tipo de login primeiro.
 auths.deletion_success=Autenticação excluída com sucesso!
 auths.login_source_exist=A fonte de login '%s" já existe.
-auths.github_api_endpoint=API Endpoint
+auths.github_api_endpoint=Endpoint da API
 
 config.not_set=(não definido)
 config.server_config=Configuração do servidor
-config.brand_name=Brand name
+config.brand_name=Nome da marca
 config.run_user=Usuário de execução
 config.run_mode=Modo de execução
-config.server.external_url=External URL
-config.server.domain=Domain
-config.server.protocol=Protocol
-config.server.http_addr=HTTP address
-config.server.http_port=HTTP port
-config.server.cert_file=Certificate file
-config.server.key_file=Key file
-config.server.tls_min_version=Minimum TLS version
-config.server.unix_socket_permission=Unix socket permission
-config.server.local_root_url=Local root URL
-config.server.offline_mode=Offline mode
-config.server.disable_router_log=Disable router log
-config.server.enable_gzip=Enable Gzip
-config.server.app_data_path=Application data path
-config.server.load_assets_from_disk=Load assets from disk
+config.server.external_url=URL externa
+config.server.domain=Domínio
+config.server.protocol=Protocolo
+config.server.http_addr=Endereço HTTP
+config.server.http_port=Porta HTTP
+config.server.cert_file=Arquivo de certificado
+config.server.key_file=Arquivo chave
+config.server.tls_min_version=Versão mínima de TLS
+config.server.unix_socket_permission=Permissão de soquete Unix
+config.server.local_root_url=URL raiz local
+config.server.offline_mode=Modo offline
+config.server.disable_router_log=Desabilitar log do router
+config.server.enable_gzip=Ativar Gzip
+config.server.app_data_path=Caminho de dados da aplicação
+config.server.load_assets_from_disk=Carregar ativos do disco
 config.server.landing_url=Landing URL
 
 config.ssh_config=Configuração de SSH
@@ -1241,7 +1241,7 @@ config.security.cookie_username=Username cookie
 config.security.cookie_secure=Enable secure cookie
 config.security.reverse_proxy_auth_user=Reverse proxy authentication header
 config.security.enable_login_status_cookie=Enable login status cookie
-config.security.login_status_cookie_name=Login status cookie
+config.security.login_status_cookie_name=Cookie para estado do login
 
 config.email_config=Email configuration
 config.email.enabled=Enabled

+ 2 - 2
conf/locale/locale_pt-PT.ini

@@ -44,8 +44,8 @@ issues=Questões
 cancel=Cancelar
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Página Não Encontrada
+internal_server_error=Erro do servidor interno
 
 [install]
 install=Instalação

+ 42 - 42
conf/locale/locale_ru-RU.ini

@@ -44,8 +44,8 @@ issues=Задачи
 cancel=Отмена
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Страница не найдена
+internal_server_error=Внутренняя ошибка сервера
 
 [install]
 install=Установка
@@ -263,7 +263,7 @@ following=Подписан
 follow=Подписаться
 unfollow=Отписаться
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Имя пользователя «%s» не допускается.
 
 [settings]
 profile=Профиль
@@ -429,7 +429,7 @@ repo_description_helper=Описание репозитория. Максима
 repo_description_length=Доступные символы
 
 form.reach_limit_of_creation=У владельца достигнут максимальный предел в %d создаваемых репозиториев.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=Имя или шаблон репозитория% q недопустимы.
 
 need_auth=Требуется авторизация
 migrate_type=Тип миграции
@@ -789,8 +789,8 @@ settings.remove_collaborator_success=Соавтор был удален.
 settings.search_user_placeholder=Поиск пользователя...
 settings.org_not_allowed_to_be_collaborator=Организации не могут быть добавлены как соавторы.
 settings.hooks_desc=Webhooks позволяют внешним службам получать уведомления при возникновении определенных событий на Gogs. При возникновении указанных событий мы отправим запрос POST на каждый заданный вами URL. Узнать больше можно в нашем <a target="_blank" href="%s">Руководстве по Webhooks</a>.
-settings.webhooks.add_new=Add a new webhook:
-settings.webhooks.choose_a_type=Choose a type...
+settings.webhooks.add_new=Добавьте новый веб-перехватчик:
+settings.webhooks.choose_a_type=Выберите тип...
 settings.add_webhook=Добавить Webhook
 settings.webhook_deletion=Удалить веб-хук
 settings.webhook_deletion_desc=Удаление этого веб-хука приведет к удалению всей, связанной с ним, информации, включая историю. Хотите продолжить?
@@ -805,8 +805,8 @@ settings.webhook.response=Ответ
 settings.webhook.headers=Заголовки
 settings.webhook.payload=Содержимое запроса
 settings.webhook.body=Тело ответа
-settings.webhook.err_cannot_parse_payload_url=Cannot parse payload URL: %v
-settings.webhook.err_cannot_use_local_addresses=Non admins are not allowed to use local addresses.
+settings.webhook.err_cannot_parse_payload_url=Невозможно разобрать URL-адрес полезной нагрузки: %v
+settings.webhook.err_cannot_use_local_addresses=Не администраторам не разрешается использовать локальные адреса.
 settings.githooks_desc=Git-хуки предоставляются Git самим по себе, вы можете изменять файлы поддерживаемых хуков из списка ниже чтобы выполнять внешние операции.
 settings.githook_edit_desc=Если хук не активен, будет подставлен пример содержимого. Пустое значение в этом поле приведет к отключению хука.
 settings.githook_name=Название Hook'a
@@ -933,8 +933,8 @@ team_name_helper=Вы будете использовать это имя для
 team_desc_helper=Что это за команда?
 team_permission_desc=Какой уровень разрешений должен быть у этой команды?
 
-form.name_not_allowed=Organization name or pattern %q is not allowed.
-form.team_name_not_allowed=Team name or pattern %q is not allowed.
+form.name_not_allowed=Имя или шаблон организации% q недопустимы.
+form.team_name_not_allowed=Имя команды или шаблон% q недопустимы.
 
 settings=Настройки
 settings.options=Опции
@@ -1018,7 +1018,7 @@ dashboard.system_status=Статус системного монитора
 dashboard.statistic_info=В базе данных Gogs записано <b>%d</b> пользователей, <b>%d</b> организаций, <b>%d</b> публичных ключей, <b>%d</b> репозиториев, <b>%d</b> подписок на репозитории, <b>%d</b> добавлений в избранное, <b>%d</b> действий, <b>%d</b> доступов, <b>%d</b> задач, <b>%d</b> комментариев, <b>%d</b> социальных учетных записей, <b>%d</b> подписок на пользователей, <b>%d</b> зеркал, <b>%d</b> релизов, <b>%d</b> источников входа, <b>%d</b> веб-хуков, <b>%d</b> этапов, <b>%d</b> меток, <b>%d</b> задач хуков, <b>%d</b> команд, <b>%d</b> задач по обновлению, <b>%d</b> присоединенных файлов.
 dashboard.operation_name=Наименование Операции
 dashboard.operation_switch=Переключить
-dashboard.select_operation_to_run=Please select operation to run
+dashboard.select_operation_to_run=Пожалуйста, выберите операцию для запуска
 dashboard.operation_run=Запуск
 dashboard.clean_unbind_oauth=Удалить не привязанные OAUth
 dashboard.clean_unbind_oauth_success=Не привязанные OAuth аккаунты успешно удалены.
@@ -1179,22 +1179,22 @@ config.server.http_port=Порт HTTP
 config.server.cert_file=Файл сертификата
 config.server.key_file=Файл ключа
 config.server.tls_min_version=Минимальная версия TLS
-config.server.unix_socket_permission=Unix socket permission
-config.server.local_root_url=Local root URL
+config.server.unix_socket_permission=Разрешение сокета Unix
+config.server.local_root_url=Локальный корневой URL
 config.server.offline_mode=Автономный режим
-config.server.disable_router_log=Disable router log
+config.server.disable_router_log=Отключить журнал маршрутизатора
 config.server.enable_gzip=Включить Gzip
-config.server.app_data_path=Application data path
-config.server.load_assets_from_disk=Load assets from disk
+config.server.app_data_path=Путь к данным приложения
+config.server.load_assets_from_disk=Загрузить ассеты с диска
 config.server.landing_url=Landing URL
 
 config.ssh_config=Конфигурация SSH
-config.ssh.enabled=Enabled
-config.ssh.domain=Exposed domain
-config.ssh.port=Exposed port
-config.ssh.root_path=Root path
-config.ssh.keygen_path=Keygen path
-config.ssh.key_test_path=Key test path
+config.ssh.enabled=Включено
+config.ssh.domain=Выделенный домен
+config.ssh.port=Выделенный порт
+config.ssh.root_path=Корневой путь
+config.ssh.keygen_path=Путь к ключу
+config.ssh.key_test_path=Путь к тестовому ключу
 config.ssh.minimum_key_size_check=Проверка минимальной длины ключа
 config.ssh.minimum_key_sizes=Минимальные размеры ключа
 config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
@@ -1205,7 +1205,7 @@ config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Настройка репозитория
 config.repo.root_path=Root path
-config.repo.script_type=Script type
+config.repo.script_type=Тип скрипта
 config.repo.ansi_chatset=ANSI charset
 config.repo.force_private=Force private
 config.repo.max_creation_limit=Max creation limit
@@ -1223,41 +1223,41 @@ config.repo.upload.file_max_size=Upload file size limit
 config.repo.upload.max_files=Upload files limit
 
 config.db_config=Конфигурация базы данных
-config.db.type=Type
-config.db.host=Host
-config.db.name=Name
-config.db.user=User
-config.db.ssl_mode=SSL mode
-config.db.ssl_mode_helper=(for "postgres" only)
-config.db.path=Path
-config.db.path_helper=(for "sqlite3"only)
-config.db.max_open_conns=Maximum open connections
+config.db.type=Тип
+config.db.host=Сервер
+config.db.name=Имя
+config.db.user=Пользователь
+config.db.ssl_mode=Режим SSL
+config.db.ssl_mode_helper=(только для "postgres")
+config.db.path=Путь
+config.db.path_helper=(только для "sqlite3")
+config.db.max_open_conns=Максимальное количество открытых соединений
 config.db.max_idle_conns=Maximum idle connections
 
 config.security_config=Security configuration
 config.security.login_remember_days=Login remember days
 config.security.cookie_remember_name=Remember cookie
-config.security.cookie_username=Username cookie
+config.security.cookie_username=Cookie юзернейма
 config.security.cookie_secure=Enable secure cookie
 config.security.reverse_proxy_auth_user=Reverse proxy authentication header
 config.security.enable_login_status_cookie=Enable login status cookie
 config.security.login_status_cookie_name=Login status cookie
 
-config.email_config=Email configuration
-config.email.enabled=Enabled
-config.email.subject_prefix=Subject prefix
-config.email.host=Host
-config.email.from=From
-config.email.user=User
+config.email_config=E-mail настройки
+config.email.enabled=Включено
+config.email.subject_prefix=Префикс темы
+config.email.host=Сервер
+config.email.from=Из
+config.email.user=Пользователь
 config.email.disable_helo=Disable HELO
-config.email.helo_hostname=HELO hostname
-config.email.skip_verify=Skip certificate verify
+config.email.helo_hostname=ЗДРАВСТВУЙТЕ имя хоста
+config.email.skip_verify=Пропустить проверку сертификата
 config.email.use_certificate=Use custom certificate
 config.email.cert_file=Certificate file
 config.email.key_file=Key file
 config.email.use_plain_text=Use plain text
 config.email.add_plain_text_alt=Add plain text alternative
-config.email.send_test_mail=Send test email
+config.email.send_test_mail=Отправить тестовое письмо
 config.email.test_mail_failed=Failed to send test email to '%s': %v
 config.email.test_mail_sent=Test email has been sent to '%s'.
 

+ 24 - 24
conf/locale/locale_sk-SK.ini

@@ -125,7 +125,7 @@ run_user_not_match=Používateľ pre spustenie sa nezhoduje s aktuálnym použí
 smtp_host_missing_port=V adrese SMTP servera chýba číslo portu.
 invalid_smtp_from=Hodnota položky SMTP Od: je nesprávne zadaná: %v
 save_config_failed=Chyba pri uložení konfigurácie: %v
-init_failed=Failed to initialize application: %v
+init_failed=Nepodarilo sa inicializovať aplikáciu: %v
 invalid_admin_setting=Nastavenie administrátorského účtu je neplatné: %v
 install_success=Vitajte! Sme radi, že ste si vybrali Gogs, bavte sa a dávajte si pozor.
 invalid_log_root_path=Koreňový adresár pre log súbory je neplatný: %v
@@ -1006,12 +1006,12 @@ first_page=Prvý
 last_page=Posledný
 total=Celkom: %d
 
-dashboard.build_info=Build Information
-dashboard.app_ver=Application version
-dashboard.git_version=Git version
-dashboard.go_version=Go version
-dashboard.build_time=Build time
-dashboard.build_commit=Build commit
+dashboard.build_info=Informácie o zostavení
+dashboard.app_ver=Verzia aplikácie
+dashboard.git_version=Git verzia
+dashboard.go_version=Go verzia
+dashboard.build_time=Čas zostavenia
+dashboard.build_commit=Commit zostavenia
 dashboard.statistic=Štatistika
 dashboard.operations=Operácie
 dashboard.system_status=Monitor stavu systému
@@ -1154,7 +1154,7 @@ auths.pam_service_name=Názov služby PAM
 auths.enable_auto_register=Povoliť auto registráciu
 auths.edit=Upraviť nastavenie overovania
 auths.activated=Tento spôsob overovania je aktívny
-auths.default_auth=This authentication is default login source
+auths.default_auth=Toto overenie je východzí zdroj prihlásenia
 auths.new_success=Nový spôsob overovania '%s' bol pridaný.
 auths.update_success=Nastavenie overovania bolo zmenené.
 auths.update=Zmeniť nastavenie overovania
@@ -1164,32 +1164,32 @@ auths.delete_auth_desc=Tento spôsob overovania bude odstránený, chcete pokra
 auths.still_in_used=Tento spôsob overovania je stále používaný niektorými užívateľmi. Prosím, najskôr zmeňte u týchto užívateľov typ overenia na iný.
 auths.deletion_success=Spôsob overovania bol odstránený!
 auths.login_source_exist=Zdroj prihlásenia '%s' už existuje.
-auths.github_api_endpoint=API Endpoint
+auths.github_api_endpoint=Koncový bod API
 
 config.not_set=(nezadané)
 config.server_config=Konfigurácia servera
-config.brand_name=Brand name
+config.brand_name=Názov značky
 config.run_user=Používateľ pre spustenie aplikácie
 config.run_mode=Režim spúšťania
-config.server.external_url=External URL
-config.server.domain=Domain
-config.server.protocol=Protocol
-config.server.http_addr=HTTP address
+config.server.external_url=Externé URL
+config.server.domain=Doména
+config.server.protocol=Protokol
+config.server.http_addr=HTTP adresa
 config.server.http_port=HTTP port
-config.server.cert_file=Certificate file
-config.server.key_file=Key file
-config.server.tls_min_version=Minimum TLS version
-config.server.unix_socket_permission=Unix socket permission
+config.server.cert_file=Súbor certifikátu
+config.server.key_file=Súbor kľúča
+config.server.tls_min_version=Minimálna verzia TLS
+config.server.unix_socket_permission=Oprávnenie Unix socketu
 config.server.local_root_url=Local root URL
 config.server.offline_mode=Offline mode
 config.server.disable_router_log=Disable router log
-config.server.enable_gzip=Enable Gzip
+config.server.enable_gzip=Povoliť Gzip
 config.server.app_data_path=Application data path
 config.server.load_assets_from_disk=Load assets from disk
 config.server.landing_url=Landing URL
 
 config.ssh_config=Nastavenie SSH
-config.ssh.enabled=Enabled
+config.ssh.enabled=Povolené
 config.ssh.domain=Exposed domain
 config.ssh.port=Exposed port
 config.ssh.root_path=Root path
@@ -1211,7 +1211,7 @@ config.repo.force_private=Force private
 config.repo.max_creation_limit=Max creation limit
 config.repo.preferred_licenses=Preferred licenses
 config.repo.disable_http_git=Disable HTTP Git
-config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_local_path_migration=Povoliť migráciu z miestnej cesty
 config.repo.enable_raw_file_render_mode=Enable raw file render mode
 config.repo.commits_fetch_concurrency=Commits fetch concurrency
 config.repo.editor.line_wrap_extensions=Editor line wrap extensions
@@ -1244,7 +1244,7 @@ config.security.enable_login_status_cookie=Enable login status cookie
 config.security.login_status_cookie_name=Login status cookie
 
 config.email_config=Email configuration
-config.email.enabled=Enabled
+config.email.enabled=Povolené
 config.email.subject_prefix=Subject prefix
 config.email.host=Host
 config.email.from=From
@@ -1273,7 +1273,7 @@ config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto reg
 config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
 
 config.user_config=User configuration
-config.user.enable_email_notify=Enable email notification
+config.user.enable_email_notify=Povoliť e-mailové notifikácie
 
 config.session_config=Nastavenie session
 config.session.provider=Provider
@@ -1293,7 +1293,7 @@ config.http_config=HTTP konfigurácia
 config.http.access_control_allow_origin=Access control allow origin
 
 config.attachment_config=Attachment configuration
-config.attachment.enabled=Enabled
+config.attachment.enabled=Povolené
 config.attachment.path=Path
 config.attachment.allowed_types=Allowed types
 config.attachment.max_size=Size limit

+ 10 - 10
conf/locale/locale_sv-SE.ini

@@ -44,8 +44,8 @@ issues=Problem
 cancel=Avbryt
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Sidan hittades inte
+internal_server_error=Internt serverfel
 
 [install]
 install=Installation
@@ -78,7 +78,7 @@ domain_helper=Detta påverkar SSH klonings webbadresser.
 ssh_port=SSH-port
 ssh_port_helper=Portnumret som din SSH-server brukar, lämna tomt för att inaktivera SSH-funktionaliteten.
 use_builtin_ssh_server=Använd inbyggd SSH Server
-use_builtin_ssh_server_popup=Start builtin SSH server for Git operations to distinguish from system SSH daemon.
+use_builtin_ssh_server_popup=Starta inbyggd SSH-server för Git-operationer för att skilja från system-SSH-servern.
 http_port=HTTP Port
 http_port_helper=Portnumret vilket applikationen kommer lyssnar på.
 app_url=Applikationsadressen
@@ -125,7 +125,7 @@ run_user_not_match=Köranvändaren är inte aktuell användare: %s -> %s
 smtp_host_missing_port=SMTP-värden saknar port i adressen.
 invalid_smtp_from=SMTP från fält är inte giltigt: %v
 save_config_failed=Konfigurationssparningen misslyckades: %v
-init_failed=Failed to initialize application: %v
+init_failed=Det gick inte att initiera appen: %v
 invalid_admin_setting=Inställningarna för administratörskontot är felaktiga: %v
 install_success=Välkommen! Vi är glada att du väljer Gogs, ha kul och ta hand om dig.
 invalid_log_root_path=Ogiltig rotsökväg för loggfiler: %v
@@ -155,7 +155,7 @@ register_hepler_msg=Har du redan ett konto? Logga in nu!
 social_register_hepler_msg=Har du redan ett konto? Anslut det nu!
 disable_register_prompt=Tyvärr är användarregistreringen inaktiverad. Vänligen kontakta din administratör.
 disable_register_mail=Tyvärr så är registreringsbekräftelemailutskick inaktiverat.
-auth_source=Authentication Source
+auth_source=Autentiseringskälla
 local=Lokal
 remember_me=Kom ihåg mig
 forgot_password=Glömt lösenord
@@ -235,7 +235,7 @@ org_name_been_taken=Organisationsnamnet har redan används.
 team_name_been_taken=Team namn är redan använt.
 email_been_used=E-postadressen har redan använts.
 username_password_incorrect=Användarnamnet eller lösenordet är inte korrekt.
-auth_source_mismatch=The authentication source selected is not associated with the user.
+auth_source_mismatch=Den autentiseringskälla som valts är inte associerad med användaren.
 enterred_invalid_repo_name=Se till att utvecklingskatalogen som du angav är rätt.
 enterred_invalid_owner_name=Kontrollera att ägarnamnet som du angav är rätt.
 enterred_invalid_password=Se till att den som lösenord du angett är rätt.
@@ -263,7 +263,7 @@ following=Följer
 follow=Följ
 unfollow=Sluta följa
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Användarnamn eller mönster %q är inte tillåtet.
 
 [settings]
 profile=Profil
@@ -347,10 +347,10 @@ two_factor_off=Av
 two_factor_enable=Aktivera
 two_factor_disable=Inaktivera
 two_factor_view_recovery_codes=Visa och spara <a href="%s%s">dina återställningskoder</a> på ett säkert ställe. Du kan använda dem som kod om du förlorar åtkomsten till din autentisering applikation.
-two_factor_http=For HTTP/HTTPS operations, you are no longer able to use plain username and password. Please create and use <a href="%[1]s%[2]s">Personal Access Token</a> as your credential, e.g. <code>%[3]s</code>.
+two_factor_http=För HTTP/HTTPS-operationer kan du inte längre använda vanliga användarnamn och lösenord. Vänligen skapa och använda <a href="%[1]s%[2]s">Personlig åtkomsttoken</a> som ditt användarnamn, t.ex. <code>%[3]s</code>.
 two_factor_enable_title=Avaktivera Tvåfaktorsautentisering
-two_factor_scan_qr=Please use your authentication application to scan the image:
-two_factor_or_enter_secret=Or enter the secret:
+two_factor_scan_qr=Vänligen använd din autentiseringsapp för att skanna bilden:
+two_factor_or_enter_secret=Eller ange hemligheten:
 two_factor_then_enter_passcode=Ange sedan lösenordet:
 two_factor_verify=Verifiera
 two_factor_invalid_passcode=The passcode you entered is not valid, please try again!

+ 64 - 64
conf/locale/locale_tr-TR.ini

@@ -44,8 +44,8 @@ issues=Sorunlar
 cancel=İptal
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Sayfa Bulunamadı
+internal_server_error=İç Sunucu Hatası.
 
 [install]
 install=Kurulum
@@ -263,7 +263,7 @@ following=Takip Edilenler
 follow=Takip Et
 unfollow=Takibi Bırak
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Kullanıcı adı veya %q desenine izin verilmiyor.
 
 [settings]
 profile=Profil
@@ -429,7 +429,7 @@ repo_description_helper=Depo açıklaması. Maksimum 512 karakter uzunluğu.
 repo_description_length=Mevcut karakterler
 
 form.reach_limit_of_creation=Sahip, maksimum %d depo oluşturma limitine ulaşmıştır.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=Depo adı veya %q desenine izin verilmiyor.
 
 need_auth=Yetkilendirme Gereklidir
 migrate_type=Göç Türü
@@ -789,8 +789,8 @@ settings.remove_collaborator_success=Katkıcı silindi.
 settings.search_user_placeholder=Kullanıcı ara...
 settings.org_not_allowed_to_be_collaborator=Organizasyon, bir katkıcı olarak eklenemez.
 settings.hooks_desc=Web istekleri, HTTP POST olay tetikleyicileri gibidirler. Gogs'ta ne zaman bir şey olsa, hedef belirttiğiniz sunuculara bildirim yapabilecek duruma geliriz. Daha fazla bilgiyi <a target="_blank" href="%s">Web İstekleri Kılavuzu</a>'nda bulabilirsiniz.
-settings.webhooks.add_new=Add a new webhook:
-settings.webhooks.choose_a_type=Choose a type...
+settings.webhooks.add_new=Yeni bir web istemci ekle:
+settings.webhooks.choose_a_type=Bir tür seç...
 settings.add_webhook=Web İsteği Ekle
 settings.webhook_deletion=Web İsteğini Sil
 settings.webhook_deletion_desc=Bu web isteğini silerseniz buna bağlı olan tüm bilgiler ve dağıtım geçmişi de silinecektir. Devam etmek istiyor musunuz?
@@ -805,8 +805,8 @@ settings.webhook.response=Cevaplar
 settings.webhook.headers=Başlıklar
 settings.webhook.payload=Yükler
 settings.webhook.body=Gövde
-settings.webhook.err_cannot_parse_payload_url=Cannot parse payload URL: %v
-settings.webhook.err_cannot_use_local_addresses=Non admins are not allowed to use local addresses.
+settings.webhook.err_cannot_parse_payload_url=Yük URL'si ayrıştırılamıyor: %v
+settings.webhook.err_cannot_use_local_addresses=Yönetici olmayanların yerel adresleri kullanmasına izin verilmiyor.
 settings.githooks_desc=Git istekleri, Git'in kendisi tarafından güçlendirilmiştir. Özel işlemleri gerçekleştirmek için aşağıdaki listedeki desteklenen isteklerin dosyalarını düzenleyebilirsiniz.
 settings.githook_edit_desc=İstek aktif değilse örnek içerik sunulacaktır. İçeriği boş bırakmak, isteği devre dışı bırakmayı beraberinde getirecektir.
 settings.githook_name=İstek İsmi
@@ -933,8 +933,8 @@ team_name_helper=Sohbetlerde bu takımdan bahsetmek için bu ismi kullanacaksın
 team_desc_helper=Bu takım ne hakkında?
 team_permission_desc=Bu takım, ne gibi bir izin seviyesine sahiptir?
 
-form.name_not_allowed=Organization name or pattern %q is not allowed.
-form.team_name_not_allowed=Team name or pattern %q is not allowed.
+form.name_not_allowed=Organizasyon adı veya %q desenine izin verilmiyor.
+form.team_name_not_allowed=Takım adı veya %q desenine izin verilmiyor.
 
 settings=Ayarlar
 settings.options=Seçenekler
@@ -1018,7 +1018,7 @@ dashboard.system_status=Sistem İzleme Durumu
 dashboard.statistic_info=Gogs veritabanında <b>%d</b> kullanıcı, <b>%d</b> organizasyon, <b>%d</b> genel anahtar, <b>%d</b> depo, <b>%d</b> izleme, <b>%d</b> yıldız, <b>%d</b> hareket, <b>%d</b> erişim, <b>%d</b> sorun, <b>%d</b> yorum, <b>%d</b> sosyal hesap, <b>%d</b> takip, <b>%d</b> yansı, <b>%d</b> sürüm, <b>%d</b> giriş kaynağı, <b>%d</b> web isteği, <b>%d</b> kilometre taşı, <b>%d</b> etiket, <b>%d</b> istek görevi, <b>%d</b> takım, <b>%d</b> güncellenmiş görev, <b>%d</b> ek var.
 dashboard.operation_name=İşlem Adı
 dashboard.operation_switch=Geç
-dashboard.select_operation_to_run=Please select operation to run
+dashboard.select_operation_to_run=Lütfen çalıştırılacak işlemi seçin
 dashboard.operation_run=Çalıştır
 dashboard.clean_unbind_oauth=Bağlanmamış OAuth'ları Temizle
 dashboard.clean_unbind_oauth_success=Bağlanmamış tüm OAuth'lar başarıyla silindi.
@@ -1214,49 +1214,49 @@ config.repo.disable_http_git=HTTP Git'i devre dışı bırak
 config.repo.enable_local_path_migration=Yerel yol göçünü etkinleştir
 config.repo.enable_raw_file_render_mode=Ham dosya oluşturma modunu etkinleştir
 config.repo.commits_fetch_concurrency=İşlemeler eşzamanlılık getirir
-config.repo.editor.line_wrap_extensions=Editor line wrap extensions
-config.repo.editor.previewable_file_modes=Editor previewable file modes
-config.repo.upload.enabled=Upload enabled
-config.repo.upload.temp_path=Upload temporary path
-config.repo.upload.allowed_types=Upload allowed types
-config.repo.upload.file_max_size=Upload file size limit
-config.repo.upload.max_files=Upload files limit
+config.repo.editor.line_wrap_extensions=Düzenleyici satır kaydırma eklentileri
+config.repo.editor.previewable_file_modes=Düzenleyici önizlenebilir dosya modları
+config.repo.upload.enabled=Yükleme etkinleştirildi
+config.repo.upload.temp_path=Yükleme geçici yolu
+config.repo.upload.allowed_types=Yükleme kabul edilebilir türleri
+config.repo.upload.file_max_size=Yükleme dosya boyutu sınırı
+config.repo.upload.max_files=Yükleme dosya sınırı
 
 config.db_config=Veritabanı Yapılandırması
-config.db.type=Type
-config.db.host=Host
-config.db.name=Name
-config.db.user=User
-config.db.ssl_mode=SSL mode
-config.db.ssl_mode_helper=(for "postgres" only)
-config.db.path=Path
-config.db.path_helper=(for "sqlite3"only)
-config.db.max_open_conns=Maximum open connections
-config.db.max_idle_conns=Maximum idle connections
-
-config.security_config=Security configuration
-config.security.login_remember_days=Login remember days
-config.security.cookie_remember_name=Remember cookie
-config.security.cookie_username=Username cookie
-config.security.cookie_secure=Enable secure cookie
-config.security.reverse_proxy_auth_user=Reverse proxy authentication header
-config.security.enable_login_status_cookie=Enable login status cookie
-config.security.login_status_cookie_name=Login status cookie
-
-config.email_config=Email configuration
-config.email.enabled=Enabled
-config.email.subject_prefix=Subject prefix
-config.email.host=Host
-config.email.from=From
-config.email.user=User
-config.email.disable_helo=Disable HELO
-config.email.helo_hostname=HELO hostname
-config.email.skip_verify=Skip certificate verify
-config.email.use_certificate=Use custom certificate
-config.email.cert_file=Certificate file
-config.email.key_file=Key file
-config.email.use_plain_text=Use plain text
-config.email.add_plain_text_alt=Add plain text alternative
+config.db.type=Tür
+config.db.host=Sunucu
+config.db.name=Ad
+config.db.user=Kullanıcı
+config.db.ssl_mode=SSL modu
+config.db.ssl_mode_helper=(sadece "postgres" için)
+config.db.path=Yol
+config.db.path_helper=(sadece "sqlite3" için)
+config.db.max_open_conns=En fazla açık bağlantı
+config.db.max_idle_conns=En fazla boş bağlantı
+
+config.security_config=Güvenlik yapılandırması
+config.security.login_remember_days=Giriş günlerini hatırla
+config.security.cookie_remember_name=Çerezi hatırla
+config.security.cookie_username=Kullanıcı adı çerezi
+config.security.cookie_secure=Güvenli çerezi etkinleştir
+config.security.reverse_proxy_auth_user=Ters proxy kimlik doğrulama başlığı
+config.security.enable_login_status_cookie=Giriş durumu çerezini etkinleştir
+config.security.login_status_cookie_name=Giriş durumu çerezi
+
+config.email_config=E-Posta yapılandırması
+config.email.enabled=Etkin
+config.email.subject_prefix=Konu öneki
+config.email.host=Sunucu
+config.email.from=Kimden
+config.email.user=Kullanıcı
+config.email.disable_helo=HELO'yu Devre Dışı Bırak
+config.email.helo_hostname=HELO sunucu adı
+config.email.skip_verify=Sertifika doğrulamayı atla
+config.email.use_certificate=Özel sertifika kullan
+config.email.cert_file=Sertifika dosyası
+config.email.key_file=Anahtar dosyası
+config.email.use_plain_text=Düz metin kullan
+config.email.add_plain_text_alt=Düz metin alternatifi ekle
 config.email.send_test_mail=Send test email
 config.email.test_mail_failed=Failed to send test email to '%s': %v
 config.email.test_mail_sent=Test email has been sent to '%s'.
@@ -1324,17 +1324,17 @@ config.git_config=Git Yapılandırması
 config.git.disable_diff_highlight=Disable diff syntax highlight
 config.git.max_diff_lines=Diff lines limit (for a single file)
 config.git.max_diff_line_characters=Diff characters limit (for a single line)
-config.git.max_diff_files=Diff files limit (for a single diff)
-config.git.gc_args=GC arguments
-config.git.migrate_timeout=Migration timeout
-config.git.mirror_timeout=Mirror fetch timeout
-config.git.clone_timeout=Clone timeout
-config.git.pull_timeout=Pull timeout
-config.git.gc_timeout=GC timeout
-
-config.lfs_config=LFS configuration
-config.lfs.storage=Storage
-config.lfs.objects_path=Objects path
+config.git.max_diff_files=Farklı dosya sınırı (tek bir fark için)
+config.git.gc_args=GC değişkenleri
+config.git.migrate_timeout=Göç zaman aşımı
+config.git.mirror_timeout=Yansı getirme zaman aşımı
+config.git.clone_timeout=Klon zaman aşımı
+config.git.pull_timeout=Çekme zaman aşımı
+config.git.gc_timeout=GC zaman aşımı
+
+config.lfs_config=LFS yapılandırması
+config.lfs.storage=Depolama
+config.lfs.objects_path=Nesnelerin yolu
 
 config.log_config=Log Yapılandırması
 config.log_file_root_path=Log Dosyası Kök Yolu
@@ -1409,7 +1409,7 @@ months=%d ay %s
 years=%d yıl %s
 raw_seconds=saniyeler
 raw_minutes=dakikalar
-raw_hours=hours
+raw_hours=saat
 
 [dropzone]
 default_message=Dosyaları yüklemek için sürükleyin veya tıklayın.

+ 100 - 100
conf/locale/locale_uk-UA.ini

@@ -44,8 +44,8 @@ issues=Проблеми
 cancel=Скасувати
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Сторінку не знайдено
+internal_server_error=Внутрішня помилка серверу
 
 [install]
 install=Установка
@@ -125,7 +125,7 @@ run_user_not_match=Користувач, що здійснює запуск, н
 smtp_host_missing_port=В адресі SMTP-хосту не вистачає порту.
 invalid_smtp_from=Невалідне SMTP поле Від: %v
 save_config_failed=Не в змозі зберегти конфігурацію: %v
-init_failed=Failed to initialize application: %v
+init_failed=Не вдалося ініціалізувати додаток: %v
 invalid_admin_setting=Неприпустимі налаштування облікового запису адміністратора: %v
 install_success=Вітаємо! Ми раді, що ви обрали Gogs, отримуйте задоволення і будьте обережні.
 invalid_log_root_path=Шлях до лог файлу хибний: %v
@@ -263,7 +263,7 @@ following=Слідкувати
 follow=Підписатися
 unfollow=Відписатися
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Ім'я користувача чи шаблон %q не допускаються.
 
 [settings]
 profile=Профіль
@@ -429,7 +429,7 @@ repo_description_helper=Опис репозиторію. До 512-ти симв
 repo_description_length=Доступні символи
 
 form.reach_limit_of_creation=Власник досягнув максимальної кількості у %d створених репозиторіїв.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=Назва репозиторію або шаблон %q не допоскаються.
 
 need_auth=Потрібна авторизація
 migrate_type=Тип міграції
@@ -789,8 +789,8 @@ settings.remove_collaborator_success=Співавтора було видале
 settings.search_user_placeholder=Пошук користувача...
 settings.org_not_allowed_to_be_collaborator=Організації не можуть бути додані як співавтори.
 settings.hooks_desc=Web-хуки схожі на HTTP POST тригери подій. Яка б подія не виникла в Gogs, ми можемо обробити повідомлення про неї на сторонньому хості який ви задаєте. Взнайте більше у <a target="_blank" href="%s">Webhooks Guide</a>.
-settings.webhooks.add_new=Add a new webhook:
-settings.webhooks.choose_a_type=Choose a type...
+settings.webhooks.add_new=Додати новий веб-хук:
+settings.webhooks.choose_a_type=Обрати тип...
 settings.add_webhook=Додати Webhook
 settings.webhook_deletion=Видалити Webhook
 settings.webhook_deletion_desc=Видалення цього web-хуку призведе до видалення інформації про нього та усієї історії поставок. Впевнені, що бажаєте продовжити?
@@ -805,8 +805,8 @@ settings.webhook.response=Відповідь
 settings.webhook.headers=Заголовки
 settings.webhook.payload=Зміст
 settings.webhook.body=Тіло
-settings.webhook.err_cannot_parse_payload_url=Cannot parse payload URL: %v
-settings.webhook.err_cannot_use_local_addresses=Non admins are not allowed to use local addresses.
+settings.webhook.err_cannot_parse_payload_url=Неможливо розібрати payload URL: %v
+settings.webhook.err_cannot_use_local_addresses=Не адміністраторам не дозволено використовувати локальні адреси.
 settings.githooks_desc=Git хуки керуються самим Git, ви можете редагувати файли хуків, що підтримуються згідно списку нище, щоб виконувати будь-які операції.
 settings.githook_edit_desc=Якщо хук неактивний, буде представлено зразок вмісту. Порожнє значення у цьому полі призведе до вимкнення хуку.
 settings.githook_name=Ім'я хуку
@@ -933,8 +933,8 @@ team_name_helper=Ви будете використовувати це ім'я 
 team_desc_helper=Що це за команда?
 team_permission_desc=Який рівень дозволів має бути у цієї команди?
 
-form.name_not_allowed=Organization name or pattern %q is not allowed.
-form.team_name_not_allowed=Team name or pattern %q is not allowed.
+form.name_not_allowed=Назва організації чи паттерн %q, не дозволені.
+form.team_name_not_allowed=Назва команди або шаблон %q не допоскаються.
 
 settings=Налаштування
 settings.options=Опції
@@ -1006,19 +1006,19 @@ first_page=Перша
 last_page=Остання
 total=Всього: %d
 
-dashboard.build_info=Build Information
-dashboard.app_ver=Application version
-dashboard.git_version=Git version
-dashboard.go_version=Go version
-dashboard.build_time=Build time
-dashboard.build_commit=Build commit
+dashboard.build_info=Інформація про збірку
+dashboard.app_ver=Версія програми
+dashboard.git_version=Версія Git
+dashboard.go_version=Версія Go
+dashboard.build_time=Дата збірки
+dashboard.build_commit=Створити коміт
 dashboard.statistic=Статистика
 dashboard.operations=Операції
 dashboard.system_status=Статус системного монітору
 dashboard.statistic_info=База даних Gogs має <b>%d</b> користувачів, <b>%d</b> організацій, <b>%d</b> публічних ключів, <b>%d</b> репозиторіїв, <b>%d</b> спостерігачів, <b>%d</b> зірок, <b>%d</b> дій, <b>%d</b> відвідувань, <b>%d</b> обговорень, <b>%d</b> коментарів, <b>%d</b> соціальних облікових записів, <b>%d</b> підписників, <b>%d</b> дзеркал, <b>%d</b> релізів, <b>%d</b> джерел входу, <b>%d</b> webhook-ів, <b>%d</b> етапів, <b>%d</b> міток, <b>%d</b> hook задач, <b>%d</b> команд, <b>%d</b> оновлень завдань, <b>%d</b> вкладень.
 dashboard.operation_name=Назва операції
 dashboard.operation_switch=Перемикнути
-dashboard.select_operation_to_run=Please select operation to run
+dashboard.select_operation_to_run=Будь ласка, виберіть операцію, щоб запустити
 dashboard.operation_run=Запустити
 dashboard.clean_unbind_oauth=Видалити неприв'язані OAuth
 dashboard.clean_unbind_oauth_success=Усі неприв'язані OAuth було знищено.
@@ -1168,87 +1168,87 @@ auths.github_api_endpoint=Адреса API
 
 config.not_set=(не встановлено)
 config.server_config=Конфігурація сервера
-config.brand_name=Brand name
+config.brand_name=Назва бренду
 config.run_user=Запущено користувачем
 config.run_mode=Режим виконання
-config.server.external_url=External URL
-config.server.domain=Domain
-config.server.protocol=Protocol
-config.server.http_addr=HTTP address
-config.server.http_port=HTTP port
-config.server.cert_file=Certificate file
-config.server.key_file=Key file
-config.server.tls_min_version=Minimum TLS version
-config.server.unix_socket_permission=Unix socket permission
-config.server.local_root_url=Local root URL
-config.server.offline_mode=Offline mode
-config.server.disable_router_log=Disable router log
-config.server.enable_gzip=Enable Gzip
-config.server.app_data_path=Application data path
-config.server.load_assets_from_disk=Load assets from disk
+config.server.external_url=Зовнішній URL
+config.server.domain=Домен
+config.server.protocol=Протокол
+config.server.http_addr=Адреса HTTP
+config.server.http_port=Порт HTTP
+config.server.cert_file=Файл сертифікату
+config.server.key_file=Ключовий файл
+config.server.tls_min_version=Мінімальна версія TLS
+config.server.unix_socket_permission=Дозвіл Unix сокету
+config.server.local_root_url=Локальний кореневий URL
+config.server.offline_mode=Автономний режим
+config.server.disable_router_log=Вимкнути журнал маршрутизатора
+config.server.enable_gzip=Увімкнути Gzip
+config.server.app_data_path=Шлях до даних додатку
+config.server.load_assets_from_disk=Завантажити ресурси з диску
 config.server.landing_url=Landing URL
 
 config.ssh_config=Налаштування SSH
-config.ssh.enabled=Enabled
-config.ssh.domain=Exposed domain
-config.ssh.port=Exposed port
-config.ssh.root_path=Root path
-config.ssh.keygen_path=Keygen path
-config.ssh.key_test_path=Key test path
-config.ssh.minimum_key_size_check=Minimum key size check
-config.ssh.minimum_key_sizes=Minimum key sizes
-config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
-config.ssh.start_builtin_server=Start builtin server
-config.ssh.listen_host=Listen host
-config.ssh.listen_port=Listen port
+config.ssh.enabled=Увімкнено
+config.ssh.domain=Виділений домен
+config.ssh.port=Виділений порт
+config.ssh.root_path=Шлях до кореня
+config.ssh.keygen_path=Шлях до генератора ключа
+config.ssh.key_test_path=Шлях до тестового ключа
+config.ssh.minimum_key_size_check=Перевірка мінімального розміру ключа
+config.ssh.minimum_key_sizes=Мінімальні розміри ключів
+config.ssh.rewrite_authorized_keys_at_start=Переписати "authorized_keys" при запуску
+config.ssh.start_builtin_server=Запустити вбудований сервер
+config.ssh.listen_host=Слухати хост
+config.ssh.listen_port=Слухати порт
 config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Налаштування репозиторія
-config.repo.root_path=Root path
-config.repo.script_type=Script type
-config.repo.ansi_chatset=ANSI charset
-config.repo.force_private=Force private
-config.repo.max_creation_limit=Max creation limit
-config.repo.preferred_licenses=Preferred licenses
-config.repo.disable_http_git=Disable HTTP Git
-config.repo.enable_local_path_migration=Enable local path migration
-config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.root_path=Кореневий шлях
+config.repo.script_type=Тип скрипту
+config.repo.ansi_chatset=Набір символів ANSI
+config.repo.force_private=Примусово приватний
+config.repo.max_creation_limit=Ліміт створень
+config.repo.preferred_licenses=Бажані ліцензії
+config.repo.disable_http_git=Вимкнути HTTP Git
+config.repo.enable_local_path_migration=Увімкнути міграцію з локального шляху
+config.repo.enable_raw_file_render_mode=Вмикає режим візуалізації неформатованого файлу
 config.repo.commits_fetch_concurrency=Commits fetch concurrency
 config.repo.editor.line_wrap_extensions=Editor line wrap extensions
 config.repo.editor.previewable_file_modes=Editor previewable file modes
-config.repo.upload.enabled=Upload enabled
-config.repo.upload.temp_path=Upload temporary path
-config.repo.upload.allowed_types=Upload allowed types
-config.repo.upload.file_max_size=Upload file size limit
-config.repo.upload.max_files=Upload files limit
+config.repo.upload.enabled=Вивантаження увімкнено
+config.repo.upload.temp_path=Завантажити тимчасовий шлях
+config.repo.upload.allowed_types=Дозволені типи вивантаження
+config.repo.upload.file_max_size=Ліміт розміру файлу для вивантаження
+config.repo.upload.max_files=Ліміт розміру файлу для вивантаження
 
 config.db_config=Налаштування бази даних
-config.db.type=Type
-config.db.host=Host
-config.db.name=Name
-config.db.user=User
-config.db.ssl_mode=SSL mode
-config.db.ssl_mode_helper=(for "postgres" only)
-config.db.path=Path
-config.db.path_helper=(for "sqlite3"only)
-config.db.max_open_conns=Maximum open connections
-config.db.max_idle_conns=Maximum idle connections
-
-config.security_config=Security configuration
+config.db.type=Тип
+config.db.host=Хост
+config.db.name=Ім'я
+config.db.user=Користувач
+config.db.ssl_mode=Режим SSL
+config.db.ssl_mode_helper=(тільки для "postgres")
+config.db.path=Шлях
+config.db.path_helper=(тільки для "sqlite3")
+config.db.max_open_conns=Максимальна кількість відкритих з'єднань
+config.db.max_idle_conns=Максимальна кількість бездіяльних з'єднань
+
+config.security_config=Налаштування безпеки
 config.security.login_remember_days=Login remember days
-config.security.cookie_remember_name=Remember cookie
+config.security.cookie_remember_name=Запам'ятати куки
 config.security.cookie_username=Username cookie
 config.security.cookie_secure=Enable secure cookie
 config.security.reverse_proxy_auth_user=Reverse proxy authentication header
 config.security.enable_login_status_cookie=Enable login status cookie
 config.security.login_status_cookie_name=Login status cookie
 
-config.email_config=Email configuration
-config.email.enabled=Enabled
+config.email_config=Налаштування пошти
+config.email.enabled=Увімкнено
 config.email.subject_prefix=Subject prefix
-config.email.host=Host
+config.email.host=Хост
 config.email.from=From
-config.email.user=User
+config.email.user=Користувач
 config.email.disable_helo=Disable HELO
 config.email.helo_hostname=HELO hostname
 config.email.skip_verify=Skip certificate verify
@@ -1293,30 +1293,30 @@ config.http_config=Налаштування HTTP
 config.http.access_control_allow_origin=Access control allow origin
 
 config.attachment_config=Attachment configuration
-config.attachment.enabled=Enabled
-config.attachment.path=Path
-config.attachment.allowed_types=Allowed types
-config.attachment.max_size=Size limit
-config.attachment.max_files=Files limit
+config.attachment.enabled=Увімкнено
+config.attachment.path=Шлях
+config.attachment.allowed_types=Дозволені типи
+config.attachment.max_size=Ліміт розміру
+config.attachment.max_files=Ліміт файлів
 
 config.release_config=Release configuration
-config.release.attachment.enabled=Attachment enabled
-config.release.attachment.allowed_types=Attachment allowed types
-config.release.attachment.max_size=Attachment size limit
-config.release.attachment.max_files=Attachment files limit
+config.release.attachment.enabled=Вкладення увімкнено
+config.release.attachment.allowed_types=Дозволені типи вкладень
+config.release.attachment.max_size=Ліміт розміру вкладення
+config.release.attachment.max_files=Ліміт прикріплених файлів
 
 config.picture_config=Налаштування зображень
-config.picture.avatar_upload_path=User avatar upload path
-config.picture.repo_avatar_upload_path=Repository avatar upload path
-config.picture.gravatar_source=Gravatar source
-config.picture.disable_gravatar=Disable Gravatar
-config.picture.enable_federated_avatar=Enable federated avatars
+config.picture.avatar_upload_path=Шлях завантаження аватарок користувачем
+config.picture.repo_avatar_upload_path=Шлях завантаження аватарок в репозиторії
+config.picture.gravatar_source=Джерело граватарів
+config.picture.disable_gravatar=Вимкнути граватари
+config.picture.enable_federated_avatar=Включити федеративні аватарки
 
-config.mirror_config=Mirror configuration
-config.mirror.default_interval=Default interval
+config.mirror_config=Налаштування дзеркала
+config.mirror.default_interval=Інтервал за замовчуванням
 
 config.webhook_config=Налаштування web-хуків
-config.webhook.types=Types
+config.webhook.types=Типи
 config.webhook.deliver_timeout=Deliver timeout
 config.webhook.skip_tls_verify=Skip TLS verify
 
@@ -1325,16 +1325,16 @@ config.git.disable_diff_highlight=Disable diff syntax highlight
 config.git.max_diff_lines=Diff lines limit (for a single file)
 config.git.max_diff_line_characters=Diff characters limit (for a single line)
 config.git.max_diff_files=Diff files limit (for a single diff)
-config.git.gc_args=GC arguments
+config.git.gc_args=Аргументи GC
 config.git.migrate_timeout=Migration timeout
 config.git.mirror_timeout=Mirror fetch timeout
 config.git.clone_timeout=Clone timeout
 config.git.pull_timeout=Pull timeout
-config.git.gc_timeout=GC timeout
+config.git.gc_timeout=Затримка GC
 
-config.lfs_config=LFS configuration
-config.lfs.storage=Storage
-config.lfs.objects_path=Objects path
+config.lfs_config=Налаштування LFS
+config.lfs.storage=Сховище
+config.lfs.objects_path=Шлях об'єктів
 
 config.log_config=Конфігурація журналу
 config.log_file_root_path=Повний шлях до Log-файлу
@@ -1409,7 +1409,7 @@ months=%d місяців %s
 years=%d роки %s
 raw_seconds=секунди
 raw_minutes=хвилини
-raw_hours=hours
+raw_hours=години
 
 [dropzone]
 default_message=Перетягніть файли сюди або натисніть "завантажити".

+ 81 - 81
conf/locale/locale_vi-VN.ini

@@ -44,8 +44,8 @@ issues=Các vấn đề
 cancel=Hủy bỏ
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=Không tìm thấy trang này!
+internal_server_error=Lỗi nội bộ máy chủ.
 
 [install]
 install=Cài đặt
@@ -125,7 +125,7 @@ run_user_not_match=Người dùng đang chạy không phải là người dùng
 smtp_host_missing_port=SMTP host thiếu thông tin cổng ở địa chỉ.
 invalid_smtp_from=Trường SMTP không hợp lệ: %v
 save_config_failed=Lưu cấu hình thất bại: %v
-init_failed=Failed to initialize application: %v
+init_failed=Lỗi khởi tạo ứng dụng: %v
 invalid_admin_setting=Thiết lập tài khoản admin không hợp lệ: %v
 install_success=Chào mừng! Chúng tôi vui mừng vì bạn chọn Gogs, chúc bạn vui.
 invalid_log_root_path=Đường dẫn gốc cho Log không hợp lệ: %v
@@ -235,7 +235,7 @@ org_name_been_taken=Tên tổ chức đã được sử dụng.
 team_name_been_taken=Tên nhóm đã được sử dụng.
 email_been_used=Email đã được sử dụng.
 username_password_incorrect=Tên đăng nhập hoặc mật khẩu không đúng.
-auth_source_mismatch=The authentication source selected is not associated with the user.
+auth_source_mismatch=Nguồn xác thực không liên kết đến người dùng.
 enterred_invalid_repo_name=Hãy chắc chắn tên kho đã nhập chính xác.
 enterred_invalid_owner_name=Please make sure that the owner name you entered is correct.
 enterred_invalid_password=Please make sure the that password you entered is correct.
@@ -263,7 +263,7 @@ following=Đang theo dõi
 follow=Theo dõi
 unfollow=Bỏ theo dõi
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=Tên người dùng %q là không được phép.
 
 [settings]
 profile=Hồ sơ
@@ -354,7 +354,7 @@ two_factor_or_enter_secret=Hoặc nhập mã bí mật:
 two_factor_then_enter_passcode=Sau đó nhập mã:
 two_factor_verify=Xác minh
 two_factor_invalid_passcode=Mật mã mà bạn đã nhập không hợp lệ, hãy thử lại!
-two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
+two_factor_reused_passcode=Mã bạn nhập đã được sử dụng, hãy nhập mã khác
 two_factor_enable_error=Kích hoạt xác thực 2 yếu tố không thành công: %v
 two_factor_enable_success=Xác thực 2 yếu tố đã kích hoạt cho tài khoản của bạn thành công!
 two_factor_recovery_codes_title=Mã khôi phục xác thực 2 yếu tố
@@ -377,7 +377,7 @@ delete_token=Xóa
 access_token_deletion=Xóa mã truy cập cá nhân
 access_token_deletion_desc=Xóa mã quyền truy cập cá nhân sẽ loại bỏ tất cả liên quan đến truy cập của ứng dụng. Bạn có muốn tiếp tục?
 delete_token_success=Mã truy cập cá nhân đã được loại bỏ thành công! Đừng quên để cập nhật ứng dụng của bạn.
-token_name_exists=Token with same name already exists.
+token_name_exists=Token cùng tên đã tồn tại
 
 orgs.none=Bạn không là thành viên của bất kỳ tổ chức nào.
 orgs.leave_title=Rời khỏi tổ chức
@@ -425,11 +425,11 @@ mirror_last_synced=Lần đồng bộ cuối
 watchers=Người theo dõi
 stargazers=Stargazers
 forks=Forks
-repo_description_helper=Description of repository. Maximum 512 characters length.
-repo_description_length=Available characters
+repo_description_helper=Mô tả Reoisitory. Tối đa 512 ký tự
+repo_description_length=Ký tự cho phép
 
 form.reach_limit_of_creation=Chủ sở hữu đã đạt giới hạn tối đa %d kho.
-form.name_not_allowed=Repository name or pattern %q is not allowed.
+form.name_not_allowed=Tên Repository %q là không hợp lệ
 
 need_auth=Cần xác thực Ủy quyền
 migrate_type=Migration Type
@@ -523,7 +523,7 @@ editor.file_changed_while_editing=File content has been changed since you starte
 editor.file_already_exists=Tên tập tin '%s' đã tồn tại trong kho này.
 editor.no_changes_to_show=Không có thay đổi nào.
 editor.fail_to_update_file=Failed to update/create file '%s' with error: %v
-editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
+editor.fail_to_delete_file=Lỗi không xóa được file '%s' : %v
 editor.add_subdir=Thêm thư mục con...
 editor.unable_to_upload_files=Failed to upload files to '%s' with error: %v
 editor.upload_files_to_dir=Tải tập tin đến '%s'
@@ -644,7 +644,7 @@ pulls.cannot_auto_merge_desc=Yêu cầu kéo này không thể được kết h
 pulls.cannot_auto_merge_helper=Xin vui lòng nhập theo cách thủ công để giải quyết các cuộc xung đột.
 pulls.create_merge_commit=Tạo một merge commit
 pulls.rebase_before_merging=Rebase trước khi sáp nhập
-pulls.commit_description=Commit Description
+pulls.commit_description=Mô tả commit
 pulls.merge_pull_request=Merge Pull Request
 pulls.open_unmerged_pull_exists=' Bạn không thể thực hiện thao tác reopen vì đã có một yêu cầu kéo đang mở (#%d) từ kho lưu trữ cùng với cùng một kết hợp thông tin và chờ đợi cho việc sáp nhập.'
 pulls.delete_branch=Xóa nhánh
@@ -789,8 +789,8 @@ settings.remove_collaborator_success=Cộng tác viên đã được gỡ bỏ.
 settings.search_user_placeholder=Tìm kiếm người dùng...
 settings.org_not_allowed_to_be_collaborator=Tổ chức không được phép được thêm vào như là một cộng tác viên.
 settings.hooks_desc=Webhooks nhiều như cơ bản HTTP bài sự kiện gây nên. Bất cứ khi nào một cái gì đó xảy ra tại Gogs, chúng tôi sẽ xử lý thông báo máy chủ mục tiêu mà bạn chỉ định. Tìm hiểu thêm trong này <a target="_blank" href="%s">Webhooks hướng dẫn</a>.
-settings.webhooks.add_new=Add a new webhook:
-settings.webhooks.choose_a_type=Choose a type...
+settings.webhooks.add_new=Thêm webhook mới:
+settings.webhooks.choose_a_type=Chọn kiểu...
 settings.add_webhook=Thêm Webhook
 settings.webhook_deletion=Xóa Webhook
 settings.webhook_deletion_desc=Xóa bỏ điều này webhook sẽ loại bỏ tất cả phân phối lịch sử và thông tin của nó. Bạn có muốn tiếp tục?
@@ -806,7 +806,7 @@ settings.webhook.headers=Tiêu đề
 settings.webhook.payload=Trả phí
 settings.webhook.body=Nội dung
 settings.webhook.err_cannot_parse_payload_url=Cannot parse payload URL: %v
-settings.webhook.err_cannot_use_local_addresses=Non admins are not allowed to use local addresses.
+settings.webhook.err_cannot_use_local_addresses=Quản trị không cho phép sử dụng những địa chỉ nội bộ này.
 settings.githooks_desc=Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to perform custom operations.
 settings.githook_edit_desc=If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.
 settings.githook_name=Tên Hook
@@ -867,8 +867,8 @@ settings.add_key_success=Bộ nhớ heap đã được phát hành!
 settings.deploy_key_deletion=Xóa Khóa triển khai
 settings.deploy_key_deletion_desc=Xóa bỏ điều này triển khai các phím sẽ loại bỏ tất cả liên quan đến truy cập cho các kho lưu trữ này. Bạn có muốn tiếp tục?
 settings.deploy_key_deletion_success=Deploy key has been deleted successfully!
-settings.description_desc=Description of repository. Maximum 512 characters length.
-settings.description_length=Available characters
+settings.description_desc=Mô tả kho. Tối đa 512 ký tự
+settings.description_length=Ký tự cho phép
 
 diff.browse_source=Browse Source
 diff.parent=mục cha
@@ -933,8 +933,8 @@ team_name_helper=Bạn sẽ sử dụng tên này đề cập đến nhóm này
 team_desc_helper=Thông tin về nhóm này là gì?
 team_permission_desc=Cấp độ quyền nhóm này có?
 
-form.name_not_allowed=Organization name or pattern %q is not allowed.
-form.team_name_not_allowed=Team name or pattern %q is not allowed.
+form.name_not_allowed=Tên tổ chức %q là không hợp lệ.
+form.team_name_not_allowed=Tên nhóm %q là không hợp lệ
 
 settings=Các cài đặt
 settings.options=Tuỳ chọn
@@ -1007,9 +1007,9 @@ last_page=Cuối
 total=Tổng: %d
 
 dashboard.build_info=Build Information
-dashboard.app_ver=Application version
-dashboard.git_version=Git version
-dashboard.go_version=Go version
+dashboard.app_ver=Phiên bản phần mềm
+dashboard.git_version=Phiên bản Git
+dashboard.go_version=Phiên bản Go
 dashboard.build_time=Build time
 dashboard.build_commit=Build commit
 dashboard.statistic=Thống kê
@@ -1110,12 +1110,12 @@ repos.stars=Sao
 repos.issues=Các vấn đề
 repos.size=Kích cỡ
 
-auths.auth_sources=Authentication Sources
+auths.auth_sources=Nguồn xác thực
 auths.new=Thêm mới source
 auths.name=Tên
 auths.type=Loại
 auths.enabled=Đã kích hoạt
-auths.default=Default
+auths.default=Mặc định
 auths.updated=Đã cập nhật
 auths.auth_type=Loại xác thực
 auths.auth_name=Tên đăng nhập xác thực
@@ -1168,20 +1168,20 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(chưa đặt)
 config.server_config=Cấu hình server
-config.brand_name=Brand name
+config.brand_name=Tên nhánh
 config.run_user=Người dùng đang chạy
 config.run_mode=Chế độ đang chạy
-config.server.external_url=External URL
+config.server.external_url=URL bên ngoài
 config.server.domain=Domain
-config.server.protocol=Protocol
-config.server.http_addr=HTTP address
-config.server.http_port=HTTP port
-config.server.cert_file=Certificate file
+config.server.protocol=Giao thức
+config.server.http_addr=Địa chỉ HTTP
+config.server.http_port=Cổng HTTP
+config.server.cert_file=Tập tin Chứng thư
 config.server.key_file=Key file
 config.server.tls_min_version=Minimum TLS version
 config.server.unix_socket_permission=Unix socket permission
-config.server.local_root_url=Local root URL
-config.server.offline_mode=Offline mode
+config.server.local_root_url=URL gốc nội bộ
+config.server.offline_mode=Chế độ ngoại tuyến
 config.server.disable_router_log=Disable router log
 config.server.enable_gzip=Enable Gzip
 config.server.app_data_path=Application data path
@@ -1189,7 +1189,7 @@ config.server.load_assets_from_disk=Load assets from disk
 config.server.landing_url=Landing URL
 
 config.ssh_config=Cấu hình SSH
-config.ssh.enabled=Enabled
+config.ssh.enabled=Đã bật
 config.ssh.domain=Exposed domain
 config.ssh.port=Exposed port
 config.ssh.root_path=Root path
@@ -1210,7 +1210,7 @@ config.repo.ansi_chatset=ANSI charset
 config.repo.force_private=Force private
 config.repo.max_creation_limit=Max creation limit
 config.repo.preferred_licenses=Preferred licenses
-config.repo.disable_http_git=Disable HTTP Git
+config.repo.disable_http_git=Vô hiệu hóa HTTP Git
 config.repo.enable_local_path_migration=Enable local path migration
 config.repo.enable_raw_file_render_mode=Enable raw file render mode
 config.repo.commits_fetch_concurrency=Commits fetch concurrency
@@ -1229,8 +1229,8 @@ config.db.name=Name
 config.db.user=User
 config.db.ssl_mode=SSL mode
 config.db.ssl_mode_helper=(for "postgres" only)
-config.db.path=Path
-config.db.path_helper=(for "sqlite3"only)
+config.db.path=Đường dẫn
+config.db.path_helper=(chỉ cho phép "sqlite3")
 config.db.max_open_conns=Maximum open connections
 config.db.max_idle_conns=Maximum idle connections
 
@@ -1243,30 +1243,30 @@ config.security.reverse_proxy_auth_user=Reverse proxy authentication header
 config.security.enable_login_status_cookie=Enable login status cookie
 config.security.login_status_cookie_name=Login status cookie
 
-config.email_config=Email configuration
-config.email.enabled=Enabled
-config.email.subject_prefix=Subject prefix
+config.email_config=Cấu hình Email
+config.email.enabled=Đã bật
+config.email.subject_prefix=Subject Prefix
 config.email.host=Host
-config.email.from=From
+config.email.from=Từ
 config.email.user=User
-config.email.disable_helo=Disable HELO
-config.email.helo_hostname=HELO hostname
-config.email.skip_verify=Skip certificate verify
-config.email.use_certificate=Use custom certificate
-config.email.cert_file=Certificate file
+config.email.disable_helo=Vô hiệu hoá HELO
+config.email.helo_hostname=Tên máy chủ HELO
+config.email.skip_verify=Bỏ qua xác thực chứng thư
+config.email.use_certificate=Sử dụng chứng thư tự tạo
+config.email.cert_file=Tập tin Chứng thư
 config.email.key_file=Key file
-config.email.use_plain_text=Use plain text
-config.email.add_plain_text_alt=Add plain text alternative
-config.email.send_test_mail=Send test email
-config.email.test_mail_failed=Failed to send test email to '%s': %v
-config.email.test_mail_sent=Test email has been sent to '%s'.
+config.email.use_plain_text=Dùng text
+config.email.add_plain_text_alt=Thêm text thay thế
+config.email.send_test_mail=Gửi Kiểm Tra Email
+config.email.test_mail_failed=Gửi email kiểm tra đến '%s':%v thất bại
+config.email.test_mail_sent=Email kiểm tra đã được gửi đến '%s'.
 
-config.auth_config=Authentication configuration
+config.auth_config=Cấu hình xác thực
 config.auth.activate_code_lives=Activate code lives
 config.auth.reset_password_code_lives=Reset password code lives
-config.auth.require_email_confirm=Require email confirmation
-config.auth.require_sign_in_view=Require sign in view
-config.auth.disable_registration=Disable registration
+config.auth.require_email_confirm=Yêu cầu xác nhận email
+config.auth.require_sign_in_view=Yêu cầu đăng nhập để xem
+config.auth.disable_registration=Vô hiệu hóa đăng ký
 config.auth.enable_registration_captcha=Enable registration captcha
 config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
 config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
@@ -1279,7 +1279,7 @@ config.session_config=Cấu hình session
 config.session.provider=Provider
 config.session.provider_config=Provider config
 config.session.cookie_name=Cookie
-config.session.https_only=HTTPS only
+config.session.https_only=Chỉ HTTPS
 config.session.gc_interval=GC interval
 config.session.max_life_time=Max life time
 config.session.csrf_cookie_name=CSRF cookie
@@ -1293,46 +1293,46 @@ config.http_config=Cấu hình HTTP
 config.http.access_control_allow_origin=Access control allow origin
 
 config.attachment_config=Attachment configuration
-config.attachment.enabled=Enabled
-config.attachment.path=Path
+config.attachment.enabled=Đã bật
+config.attachment.path=Đường dẫn
 config.attachment.allowed_types=Allowed types
-config.attachment.max_size=Size limit
-config.attachment.max_files=Files limit
+config.attachment.max_size=Giới hạn kích thước
+config.attachment.max_files=Giới hạn số lượng tệp tin
 
 config.release_config=Release configuration
-config.release.attachment.enabled=Attachment enabled
-config.release.attachment.allowed_types=Attachment allowed types
-config.release.attachment.max_size=Attachment size limit
-config.release.attachment.max_files=Attachment files limit
+config.release.attachment.enabled=Cho phép tệp đính kèm
+config.release.attachment.allowed_types=Loại tệp tin đính kèm
+config.release.attachment.max_size=Giới hạn dung lượng đính kèm
+config.release.attachment.max_files=Giới hạn số lượng tệp đính kèm
 
 config.picture_config=Cấu hình ảnh
-config.picture.avatar_upload_path=User avatar upload path
-config.picture.repo_avatar_upload_path=Repository avatar upload path
-config.picture.gravatar_source=Gravatar source
-config.picture.disable_gravatar=Disable Gravatar
-config.picture.enable_federated_avatar=Enable federated avatars
+config.picture.avatar_upload_path=Đường dẫn tệp Ảnh đại diện
+config.picture.repo_avatar_upload_path=Đường dẫn tệp Ảnh đại diện kho
+config.picture.gravatar_source=Nguồn Gravatar 
+config.picture.disable_gravatar=Vô hiệu hóa Gravatar
+config.picture.enable_federated_avatar=Bật Federated Avatars
 
 config.mirror_config=Mirror configuration
 config.mirror.default_interval=Default interval
 
 config.webhook_config=Cấu hình Webhook
-config.webhook.types=Types
-config.webhook.deliver_timeout=Deliver timeout
-config.webhook.skip_tls_verify=Skip TLS verify
+config.webhook.types=Kiểu
+config.webhook.deliver_timeout=Thời gian chờ phân phối
+config.webhook.skip_tls_verify=Bỏ qua xác thực TLS
 
 config.git_config=Cấu hình Git
 config.git.disable_diff_highlight=Disable diff syntax highlight
 config.git.max_diff_lines=Diff lines limit (for a single file)
 config.git.max_diff_line_characters=Diff characters limit (for a single line)
 config.git.max_diff_files=Diff files limit (for a single diff)
-config.git.gc_args=GC arguments
-config.git.migrate_timeout=Migration timeout
-config.git.mirror_timeout=Mirror fetch timeout
-config.git.clone_timeout=Clone timeout
-config.git.pull_timeout=Pull timeout
+config.git.gc_args=Các tham số GC
+config.git.migrate_timeout=Thời gian chờ Migration
+config.git.mirror_timeout=Thời gian chờ Mirror fetch
+config.git.clone_timeout=Thời gian chờ Clone
+config.git.pull_timeout=Thời gian chờ kéo
 config.git.gc_timeout=GC timeout
 
-config.lfs_config=LFS configuration
+config.lfs_config=Cấu hình LFS
 config.lfs.storage=Storage
 config.lfs.objects_path=Objects path
 
@@ -1385,9 +1385,9 @@ delete_branch=xóa chi nhánh <code>%[2]s</code> tại <a href="%[1]s">%[3]s</a>
 push_tag=đã đẩy thẻ tag <a href="%s/src/%s">%[2]s</a> đến <a href="%[1]s">%[3]s</a>
 delete_tag=đã xóa thẻ tag <code>%[2]s</code> tại <a href="%[1]s">%[3]s</a>
 fork_repo=đã fork một kho lưu trữ đến <a href="%s">%s</a>
-mirror_sync_push=synced commits to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a> from mirror
-mirror_sync_create=synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
-mirror_sync_delete=synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
+mirror_sync_push=đồng bộ commits đến <a href="%[1]s/src/%[2]s">%[3]s</a> tại <a href="%[1]s">%[4]s</a> từ mirror
+mirror_sync_create=đồng bộ tham chiếu mới <a href="%s/src/%s">%[2]s</a> đến <a href="%[1]s">%[3]s</a> từ mirror
+mirror_sync_delete=đồng bộ và xóa tham chiếu <code>%[2]s</code>  tại  <a href="%[1]s">%[3]s</a>  từ mirror
 
 [tool]
 ago=cách đây
@@ -1409,7 +1409,7 @@ months=%d tháng trước %s
 years=%d năm trước %s
 raw_seconds=giây
 raw_minutes=phút
-raw_hours=hours
+raw_hours=giờ
 
 [dropzone]
 default_message=Thả các tập tin ở đây hoặc bấm vào để tải lên.

+ 14 - 14
conf/locale/locale_zh-TW.ini

@@ -44,8 +44,8 @@ issues=問題
 cancel=取消
 
 [status]
-page_not_found=Page Not Found
-internal_server_error=Internal Server Error
+page_not_found=找不到頁面
+internal_server_error=內部伺服器錯誤
 
 [install]
 install=安裝頁面
@@ -125,7 +125,7 @@ run_user_not_match=執行系統用戶非當前用戶:%s -> %s
 smtp_host_missing_port=SMTP 主機缺少位址中的埠。
 invalid_smtp_from=SMTP 寄件者欄位無效﹔%v
 save_config_failed=設定儲存失敗:%v
-init_failed=Failed to initialize application: %v
+init_failed=軟體初始化失敗:%v
 invalid_admin_setting=管理員帳戶設置不正確:%v
 install_success=您好!我們很高興您選擇使用 Gogs,祝您使用愉快,代碼從此無 BUG!
 invalid_log_root_path=日誌根目錄無效: %v
@@ -263,7 +263,7 @@ following=關注中
 follow=關注
 unfollow=取消關注
 
-form.name_not_allowed=User name or pattern %q is not allowed.
+form.name_not_allowed=用戶名不允許 %q 的格式。
 
 [settings]
 profile=個人資訊
@@ -1008,9 +1008,9 @@ total=總計:%d
 
 dashboard.build_info=Build Information
 dashboard.app_ver=Application version
-dashboard.git_version=Git version
-dashboard.go_version=Go version
-dashboard.build_time=Build time
+dashboard.git_version=Git 版本
+dashboard.go_version=Go 版本
+dashboard.build_time=建置時間
 dashboard.build_commit=Build commit
 dashboard.statistic=應用統計數據
 dashboard.operations=管理員操作
@@ -1172,16 +1172,16 @@ config.brand_name=Brand name
 config.run_user=執行用戶
 config.run_mode=執行模式
 config.server.external_url=External URL
-config.server.domain=Domain
-config.server.protocol=Protocol
+config.server.domain=網域
+config.server.protocol=協定
 config.server.http_addr=HTTP address
-config.server.http_port=HTTP port
-config.server.cert_file=Certificate file
+config.server.http_port=HTTP 
+config.server.cert_file=憑證檔案
 config.server.key_file=Key file
 config.server.tls_min_version=Minimum TLS version
 config.server.unix_socket_permission=Unix socket permission
 config.server.local_root_url=Local root URL
-config.server.offline_mode=Offline mode
+config.server.offline_mode=離線模式
 config.server.disable_router_log=Disable router log
 config.server.enable_gzip=Enable Gzip
 config.server.app_data_path=Application data path
@@ -1192,7 +1192,7 @@ config.ssh_config=SSH 配置
 config.ssh.enabled=Enabled
 config.ssh.domain=Exposed domain
 config.ssh.port=Exposed port
-config.ssh.root_path=Root path
+config.ssh.root_path=根路徑
 config.ssh.keygen_path=Keygen path
 config.ssh.key_test_path=Key test path
 config.ssh.minimum_key_size_check=Minimum key size check
@@ -1204,7 +1204,7 @@ config.ssh.listen_port=Listen port
 config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Repository 設定
-config.repo.root_path=Root path
+config.repo.root_path=根路徑
 config.repo.script_type=Script type
 config.repo.ansi_chatset=ANSI charset
 config.repo.force_private=Force private

+ 5 - 5
docker/Dockerfile.aarch64

@@ -7,11 +7,11 @@ RUN apk --no-cache --no-progress add --virtual \
 
 WORKDIR /gogs.io/gogs
 COPY . .
-RUN make build-no-gen TAGS="cert pam"
+RUN make build TAGS="cert pam"
 
 FROM arm64v8/alpine:3.11
-ADD https://github.com/tianon/gosu/releases/download/1.11/gosu-arm64 /usr/sbin/gosu
-RUN chmod +x /usr/sbin/gosu \
+RUN wget https://github.com/tianon/gosu/releases/download/1.11/gosu-arm64 -O /usr/sbin/gosu \
+  && chmod +x /usr/sbin/gosu \
   && echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
   && apk --no-cache --no-progress add \
   bash \
@@ -28,7 +28,7 @@ RUN chmod +x /usr/sbin/gosu \
 
 ENV GOGS_CUSTOM /data/gogs
 
-# Configure LibC Name Service
+# Configure LibC Name Service
 COPY docker/nsswitch.conf /etc/nsswitch.conf
 
 WORKDIR /app/gogs
@@ -37,7 +37,7 @@ COPY --from=binarybuilder /gogs.io/gogs/gogs .
 
 RUN ./docker/finalize.sh
 
-# Configure Docker Container
+# Configure Docker Container
 VOLUME ["/data", "/backup"]
 EXPOSE 22 3000
 ENTRYPOINT ["/app/gogs/docker/start.sh"]

+ 6 - 6
docker/Dockerfile.rpi

@@ -7,11 +7,11 @@ RUN apk --no-cache --no-progress add --virtual \
 
 WORKDIR /gogs.io/gogs
 COPY . .
-RUN make build-no-gen TAGS="cert pam"
+RUN make build TAGS="cert pam"
 
-FROM arm32v7/alpine:3.11
-ADD https://github.com/tianon/gosu/releases/download/1.12/gosu-armhf /usr/sbin/gosu
-RUN chmod +x /usr/sbin/gosu \
+FROM arm32v7/alpine:3.12
+RUN wget https://github.com/tianon/gosu/releases/download/1.12/gosu-armhf -O /usr/sbin/gosu \
+  && chmod +x /usr/sbin/gosu \
   && echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
   && apk --no-cache --no-progress add \
   bash \
@@ -28,7 +28,7 @@ RUN chmod +x /usr/sbin/gosu \
 
 ENV GOGS_CUSTOM /data/gogs
 
-# Configure LibC Name Service
+# Configure LibC Name Service
 COPY docker/nsswitch.conf /etc/nsswitch.conf
 
 WORKDIR /app/gogs
@@ -37,7 +37,7 @@ COPY --from=binarybuilder /gogs.io/gogs/gogs .
 
 RUN ./docker/finalize.sh
 
-# Configure Docker Container
+# Configure Docker Container
 VOLUME ["/data", "/backup"]
 EXPOSE 22 3000
 ENTRYPOINT ["/app/gogs/docker/start.sh"]

+ 1 - 1
docker/README.md

@@ -79,7 +79,7 @@ Most of settings are obvious and easy to understand, but there are some settings
 - **HTTP Port**: Use port you want Gogs to listen on inside Docker container. For example, your Gogs listens on `3000` inside Docker, **and** you expose it by `10080:3000`, but you still use `3000` for this value.
 - **Application URL**: Use combination of **Domain** and **exposed HTTP Port** values (e.g. `http://192.168.99.100:10080/`).
 
-Full documentation of application settings can be found [here](https://github.com/gogs/gogs/blob/master/conf/app.ini).
+Full documentation of application settings can be found [here](https://github.com/gogs/gogs/blob/main/conf/app.ini).
 
 ### Container Options
 

+ 4 - 0
docker/runtime/backup-init.sh

@@ -30,7 +30,9 @@ parse_generate_cron_expression() {
 	CRON_EXPR_DAYS="*"
 	CRON_EXPR_MONTHS="*"
 
+    # shellcheck disable=SC2001
 	TIME_INTERVAL=$(echo "${BACKUP_INTERVAL}" | sed -e 's/[hdM]$//')
+    # shellcheck disable=SC2001
 	TIME_UNIT=$(echo "${BACKUP_INTERVAL}" | sed -e 's/^[0-9]\+//')
 
 	if [ "${TIME_UNIT}" = "h" ]; then
@@ -74,7 +76,9 @@ parse_generate_cron_expression() {
 parse_generate_retention_expression() {
 	FIND_TIME_EXPR='mtime'
 
+	# shellcheck disable=SC2001
 	TIME_INTERVAL=$(echo "${BACKUP_RETENTION}" | sed -e 's/[mhdM]$//')
+	# shellcheck disable=SC2001
 	TIME_UNIT=$(echo "${BACKUP_RETENTION}" | sed -e 's/^[0-9]\+//')
 
 	if [ "${TIME_UNIT}" = "m" ]; then

+ 2 - 1
docker/runtime/backup-rotator.sh

@@ -17,10 +17,11 @@ main() {
 	fi
 
 	if [ ! -d "${BACKUP_PATH}" ]; then
-	  echo "Error: BACKUP_PATH does't exist or is not a directory" 1>&2
+	  echo "Error: BACKUP_PATH doesn't exist or is not a directory" 1>&2
 		exit 1
 	fi
 
+	# shellcheck disable=SC2086
 	find "${BACKUP_PATH}/" -type f -name "gogs-backup-*.zip" -${FIND_EXPRESSION} -print -exec rm "{}" +
 }
 

+ 1 - 1
docker/s6/.s6-svscan/finish

@@ -1,5 +1,5 @@
 #!/bin/sh
 
 # Cleanup SOCAT services and s6 event folder
-rm -rf $(find /app/gogs/docker/s6/ -name 'event')
+rm -rf "$(find /app/gogs/docker/s6/ -name 'event')"
 rm -rf /app/gogs/docker/s6/SOCAT_*

+ 1 - 0
docker/s6/crond/run

@@ -3,6 +3,7 @@
 # The default configuration is also calling all the scripts in /etc/periodic/${period}
 
 if test -f ./setup; then
+    # shellcheck disable=SC2039,SC1091,SC3046
     source ./setup
 fi
 

+ 2 - 1
docker/s6/gogs/run

@@ -1,7 +1,8 @@
 #!/bin/sh
 
 if test -f ./setup; then
+    # shellcheck disable=SC2039,SC1091,SC3046
     source ./setup
 fi
 
-exec gosu $USER /app/gogs/gogs web
+exec gosu "$USER" /app/gogs/gogs web

+ 3 - 3
docker/s6/gogs/setup

@@ -1,16 +1,16 @@
 #!/bin/sh
 
 if ! test -d ~git/.ssh; then
-    gosu $USER mkdir -p ~git/.ssh
+    gosu "$USER" mkdir -p ~git/.ssh
     chmod 700 ~git/.ssh
 fi
 
 if ! test -f ~git/.ssh/environment; then
-    gosu $USER echo "GOGS_CUSTOM=${GOGS_CUSTOM}" > ~git/.ssh/environment
+    gosu "$USER" echo "GOGS_CUSTOM=${GOGS_CUSTOM}" > ~git/.ssh/environment
     chmod 600 ~git/.ssh/environment
 fi
 
-cd /app/gogs
+cd /app/gogs || exit 1
 
 # Link volumed data with app data
 ln -sfn /data/gogs/log  ./log

+ 1 - 0
docker/s6/openssh/run

@@ -1,6 +1,7 @@
 #!/bin/sh
 
 if test -f ./setup; then
+    # shellcheck disable=SC2039,SC1091,SC3046
     source ./setup
 fi
 

+ 2 - 2
docker/s6/openssh/setup

@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Check if host keys are present, else create them
+# Check if host keys are present, else create them
 if ! test -f /data/ssh/ssh_host_rsa_key; then
     ssh-keygen -q -f /data/ssh/ssh_host_rsa_key -N '' -t rsa
 fi
@@ -17,7 +17,7 @@ if ! test -f /data/ssh/ssh_host_ed25519_key; then
     ssh-keygen -q -f /data/ssh/ssh_host_ed25519_key -N '' -t ed25519
 fi
 
-# Set correct right to ssh keys
+# Set correct right to ssh keys
 chown -R root:root /data/ssh/*
 chmod 0700 /data/ssh
 chmod 0600 /data/ssh/*

+ 1 - 0
docker/s6/syslogd/run

@@ -1,6 +1,7 @@
 #!/bin/sh
 
 if test -f ./setup; then
+    # shellcheck disable=SC2039,SC1091,SC3046
     source ./setup
 fi
 

+ 12 - 11
docker/start.sh

@@ -3,17 +3,18 @@
 create_socat_links() {
     # Bind linked docker container to localhost socket using socat
     USED_PORT="3000:22"
-    while read NAME ADDR PORT; do
+    while read -r NAME ADDR PORT; do
         if test -z "$NAME$ADDR$PORT"; then
             continue
         elif echo $USED_PORT | grep -E "(^|:)$PORT($|:)" > /dev/null; then
             echo "init:socat  | Can't bind linked container ${NAME} to localhost, port ${PORT} already in use" 1>&2
         else
             SERV_FOLDER=/app/gogs/docker/s6/SOCAT_${NAME}_${PORT}
-            mkdir -p ${SERV_FOLDER}
+            mkdir -p "${SERV_FOLDER}"
             CMD="socat -ls TCP4-LISTEN:${PORT},fork,reuseaddr TCP4:${ADDR}:${PORT}"
-            echo -e "#!/bin/sh\nexec $CMD" > ${SERV_FOLDER}/run
-            chmod +x ${SERV_FOLDER}/run
+            # shellcheck disable=SC2039,SC3037
+            echo -e "#!/bin/sh\nexec $CMD" > "${SERV_FOLDER}"/run
+            chmod +x "${SERV_FOLDER}"/run
             USED_PORT="${USED_PORT}:${PORT}"
             echo "init:socat  | Linked container ${NAME} will be binded to localhost on port ${PORT}" 1>&2
         fi
@@ -23,20 +24,20 @@ EOT
 }
 
 cleanup() {
-    # Cleanup SOCAT services and s6 event folder
+    # Cleanup SOCAT services and s6 event folder
     # On start and on shutdown in case container has been killed
-    rm -rf $(find /app/gogs/docker/s6/ -name 'event')
+    rm -rf "$(find /app/gogs/docker/s6/ -name 'event')"
     rm -rf /app/gogs/docker/s6/SOCAT_*
 }
 
 create_volume_subfolder() {
     # Modify the owner of /data dir, make $USER(git) user have permission to create sub-dir in /data.
-    chown -R $USER:$USER /data
+    chown -R "$USER:$USER" /data
 
     # Create VOLUME subfolder
     for f in /data/gogs/data /data/gogs/conf /data/gogs/log /data/git /data/ssh; do
         if ! test -d $f; then
-            gosu $USER mkdir -p $f
+            gosu "$USER" mkdir -p $f
         fi
     done
 }
@@ -54,19 +55,19 @@ cleanup
 create_volume_subfolder
 
 LINK=$(echo "$SOCAT_LINK" | tr '[:upper:]' '[:lower:]')
-if [ "$LINK" = "false" -o "$LINK" = "0" ]; then
+if [ "$LINK" = "false" ] || [ "$LINK" = "0" ]; then
     echo "init:socat  | Will not try to create socat links as requested" 1>&2
 else
     create_socat_links
 fi
 
 CROND=$(echo "$RUN_CROND" | tr '[:upper:]' '[:lower:]')
-if [ "$CROND" = "true" -o "$CROND" = "1" ]; then
+if [ "$CROND" = "true" ] || [ "$CROND" = "1" ]; then
     echo "init:crond  | Cron Daemon (crond) will be run as requested by s6" 1>&2
     rm -f /app/gogs/docker/s6/crond/down
     /bin/sh /app/gogs/docker/runtime/backup-init.sh "${PUID}"
 else
-    # Tell s6 not to run the crond service
+    # Tell s6 not to run the crond service
     touch /app/gogs/docker/s6/crond/down
 fi
 

+ 33 - 0
docs/admin/release_strategy.md

@@ -0,0 +1,33 @@
+# Release strategy
+
+## Semantic versioning
+
+Starting 0.12.0, Gogs uses [semantic versioning](https://semver.org/) for publishing releases. For example:
+
+- `0.12.0` is a minor version release.
+- `0.12.1` is the first patch release of `0.12`.
+- `0.12` indicates a series of releases for a minor version and its patch releases.
+
+Each minor release has its own release branch with prefix `release/`, e.g. `release/0.12` is the release branch for minor version 0.12.0 and all its patch releases (`0.12.1`, `0.12.2`, etc.).
+
+## Backwards compatibility
+
+### Before 0.12
+
+If you're running Gogs with any version below 0.12, please upgrade to 0.12 to run necessary migrations.
+
+### After 0.12
+
+We maintain one minor version backwards compatibility, patch releases are disregarded.
+
+For example, you should:
+
+- Upgrade from `0.12.0` to `0.13.0`.
+- Upgrade from `0.12.1` to `0.13.4`.
+- NOT upgrade from `0.12.4` to `0.14.0`.
+
+Therefore, we recommend upgrade one minor version at a time.
+
+### Running source builds
+
+If you're running Gogs with building from source code, we recommend you update at least weekly to be not fall behind and potentially miss migrations.

+ 59 - 0
docs/dev/database_schema.md

@@ -0,0 +1,59 @@
+# Table "access"
+
+```
+  FIELD  | COLUMN  |   POSTGRESQL    |         MYSQL         |     SQLITE3       
+---------+---------+-----------------+-----------------------+-------------------
+  ID     | id      | BIGSERIAL       | BIGINT AUTO_INCREMENT | INTEGER           
+  UserID | user_id | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL  
+  RepoID | repo_id | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL  
+  Mode   | mode    | BIGINT NOT NULL | BIGINT NOT NULL       | INTEGER NOT NULL  
+
+Primary keys: id
+```
+
+# Table "access_token"
+
+```
+     FIELD    |    COLUMN    |     POSTGRESQL     |         MYSQL         |      SQLITE3        
+--------------+--------------+--------------------+-----------------------+---------------------
+  ID          | id           | BIGSERIAL          | BIGINT AUTO_INCREMENT | INTEGER             
+  UserID      | uid          | BIGINT             | BIGINT                | INTEGER             
+  Name        | name         | TEXT               | LONGTEXT              | TEXT                
+  Sha1        | sha1         | VARCHAR(40) UNIQUE | VARCHAR(40) UNIQUE    | VARCHAR(40) UNIQUE  
+  CreatedUnix | created_unix | BIGINT             | BIGINT                | INTEGER             
+  UpdatedUnix | updated_unix | BIGINT             | BIGINT                | INTEGER             
+
+Primary keys: id
+```
+
+# Table "lfs_object"
+
+```
+    FIELD   |   COLUMN   |      POSTGRESQL      |        MYSQL         |      SQLITE3       
+------------+------------+----------------------+----------------------+--------------------
+  RepoID    | repo_id    | BIGINT               | BIGINT               | INTEGER            
+  OID       | oid        | TEXT                 | VARCHAR(191)         | TEXT               
+  Size      | size       | BIGINT NOT NULL      | BIGINT NOT NULL      | INTEGER NOT NULL   
+  Storage   | storage    | TEXT NOT NULL        | LONGTEXT NOT NULL    | TEXT NOT NULL      
+  CreatedAt | created_at | TIMESTAMPTZ NOT NULL | DATETIME(3) NOT NULL | DATETIME NOT NULL  
+
+Primary keys: repo_id, oid
+```
+
+# Table "login_source"
+
+```
+     FIELD    |    COLUMN    |    POSTGRESQL    |         MYSQL         |     SQLITE3       
+--------------+--------------+------------------+-----------------------+-------------------
+  ID          | id           | BIGSERIAL        | BIGINT AUTO_INCREMENT | INTEGER           
+  Type        | type         | BIGINT           | BIGINT                | INTEGER           
+  Name        | name         | TEXT UNIQUE      | VARCHAR(191) UNIQUE   | TEXT UNIQUE       
+  IsActived   | is_actived   | BOOLEAN NOT NULL | BOOLEAN NOT NULL      | NUMERIC NOT NULL  
+  IsDefault   | is_default   | BOOLEAN          | BOOLEAN               | NUMERIC           
+  Config      | cfg          | TEXT             | TEXT                  | TEXT              
+  CreatedUnix | created_unix | BIGINT           | BIGINT                | INTEGER           
+  UpdatedUnix | updated_unix | BIGINT           | BIGINT                | INTEGER           
+
+Primary keys: id
+```
+

+ 17 - 0
docs/dev/import_locale.md

@@ -0,0 +1,17 @@
+# Import locales from Crowdin
+
+1. Download the ZIP archive from [Crowdin](https://crowdin.gogs.io/) and unzip it.
+1. Go to root directory of the repository.
+1. Run the `import` subcommand:
+
+    ```
+    $ ./gogs import locale --source <path to the unzipped directory> --target ./conf/locale
+    Locale files has been successfully imported!
+    ```
+
+1. Run `task generate-bindata` to generate corresponding bindata.
+1. Run `task web` to start the web server, then visit the site in the browser to make sure nothing blows up.
+1. Check out a new branch using `git checkout -b update-locales`.
+1. Stage changes
+1. Run `git commit -m "locale: sync from Crowdin"`.
+1. Push the commit then open up a pull request on GitHub.

+ 10 - 7
docs/dev/local_development.md

@@ -25,7 +25,7 @@ Gogs has the following dependencies:
 - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) (v1.8.3 or higher)
 - [Go](https://golang.org/doc/install) (v1.14 or higher)
 - [Less.js](http://lesscss.org/usage/#command-line-usage-installing)
-- [GNU Make](https://www.gnu.org/software/make/)
+- [Task](https://github.com/go-task/task)
 - Database upon your choice (pick one, we choose PostgreSQL in this document):
     - [PostgreSQL](https://wiki.postgresql.org/wiki/Detailed_installation_guides) (v9.6 or higher)
     - [MySQL](https://dev.mysql.com/downloads/mysql/) with `ENGINE=InnoDB` (v5.7 or higher)
@@ -38,7 +38,7 @@ Gogs has the following dependencies:
 1. Install dependencies:
 
     ```bash
-    brew install go postgresql git go-bindata npm
+    brew install go postgresql git go-bindata npm go-task/tap/go-task
     npm install -g less
     npm install -g less-plugin-clean-css
     ```
@@ -76,8 +76,9 @@ Gogs has the following dependencies:
     ```bash
     sudo apt install -y make git-all postgresql postgresql-contrib golang-go nodejs
     npm install -g less
-    # Watch out, it is not github.com/go-bindata/go-bindata!
+    # Watch out, it is NOT github.com/go-bindata/go-bindata!
     go get -u github.com/kevinburke/go-bindata/...
+    go get go-task/task/cmd/task
     ```
 
 1. Configure startup services:
@@ -130,21 +131,23 @@ Create a `custom/conf/app.ini` file inside the repository and put the following
 
 ```ini
 [database]
-DB_TYPE = postgres
+TYPE = postgres
 HOST = 127.0.0.1:5432
 NAME = gogs
 USER = gogs
-PASSWD = <YOUR PASSWORD HERE>
+PASSWORD = <YOUR PASSWORD HERE>
 SSL_MODE = disable
 ```
 
 ## Step 5: Start the server
 
+The following command will start the web server and automatically recompile and restart the server if any Go files changed:
+
 ```bash
-make web
+task web --watch
 ```
 
-You would have to re-run this command after changing Go files, or any file under `conf/`, `template/` and `public/` directories.
+**NOTE** If you changed any file under `conf/`, `template/` or `public/` directory, be sure to run `task generate` afterwards!
 
 ## Other nice things
 

+ 38 - 0
docs/dev/release/issue_template_minor_version.md

@@ -0,0 +1,38 @@
+## Before release
+
+On develop branch:
+
+- [ ] Close stale issues with the label [status: needs feedback](https://github.com/gogs/gogs/issues?q=is%3Aissue+is%3Aopen+label%3A%22status%3A+needs+feedback%22).
+- [ ] [Sync locales from Crowdin](https://github.com/gogs/gogs/blob/main/docs/dev/import_locale.md).
+- [ ] Update [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) to include entries for the current release.
+- [ ] Cut a new release branch `release/<MAJOR>.<MINOR>`, e.g. `release/0.12`.
+
+## During release
+
+On release branch:
+
+- [ ] Update the [hard-coded version](https://github.com/gogs/gogs/blob/main/gogs.go#L21) to the current release, e.g. `0.12.0+dev` -> `0.12.0`.
+- [ ] Publish a new [GitHub release](https://github.com/gogs/gogs/releases) with entries from [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) for the current release.
+- [ ] Wait for a new [Docker Hub tag](https://hub.docker.com/r/gogs/gogs/tags) for the current release to be created automatically.
+- [ ] Push another Docker image tag as `<MAJOR>.<MINOR>`, e.g. `0.12`.
+- [ ] Compile and pack binaries (all prefixed with `gogs_<MAJOR>.<MINOR>.<PATCH>_`, e.g. `gogs_0.12.0_`):
+	- [ ] macOS: `darwin_amd64.zip`
+	- [ ] Linux: `linux_386.tar.gz`, `linux_386.zip`, `linux_amd64.tar.gz`, `linux_amd64.zip`
+	- [ ] ARM: `linux_armv7.tar.gz`, `linux_armv7.zip`
+	- [ ] Windows: `windows_amd64.zip`, `windows_amd64_mws.zip`
+- [ ] Generate SHA256 checksum for all binaries to the file `checksum_sha256.txt`.
+- [ ] Upload all binaries to:
+	- [ ] GitHub release
+	- [ ] https://dl.gogs.io (also upload `checksum_sha256.txt`)
+- [ ] Build, push and tag a new Docker image for ARM to [Docker Hub](https://hub.docker.com/r/gogs/gogs-rpi).
+
+## After release
+
+On develop branch:
+
+- [ ] Update the repository mirror on [Gitee](https://gitee.com/unknwon/gogs).
+- [ ] Create a new release topic on [Gogs Discussion](https://discuss.gogs.io/c/announcements/5).
+- [ ] Send out release announcement emails via [Mailchimp](https://mailchimp.com/).
+- [ ] Publish a new release article on [OSChina](http://my.oschina.net/Obahua/admin/releases).
+- [ ] Update the [hard-coded version](https://github.com/gogs/gogs/blob/main/gogs.go#L21) to the new develop version, e.g. `0.12.0+dev` -> `0.13.0+dev`.
+- [ ] Run `make legacy` to identify deprecated code that is aimed to be removed in current develop version.

+ 43 - 0
docs/dev/release/issue_template_patch_release.md

@@ -0,0 +1,43 @@
+## Before release
+
+On release branch:
+
+- [ ] Make sure all commits are cherry-picked from the develop branch by checking the patch milestone.
+- [ ] Update [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) to include entries for the current patch release, e.g. `git log v0.12.1...HEAD --pretty=format:'- [ ] %H %s' --reverse`:
+	- [ ] _link to the commit_
+
+## During release
+
+On release branch:
+
+- [ ] Update the [hard-coded version](https://github.com/gogs/gogs/blob/main/gogs.go#L21) to the current release, e.g. `0.12.0` -> `0.12.1`.
+- [ ] Wait for GitHub Actions to complete and no failed jobs.
+- [ ] Publish a new [GitHub release](https://github.com/gogs/gogs/releases) with entries from [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) for the current patch release and all previous releases with same minor version. **Make sure the tag is created on the release branch**.
+- [ ] Update all previous GitHub releases with same minor version with the warning:
+    ```
+    **ℹ️ Heads up! There is a new patch release [0.12.1](https://github.com/gogs/gogs/releases/tag/v0.12.1) available, we recommend directly installing or upgrading to that version.**
+    ```
+- [ ] Wait for a new [Docker Hub tag](https://hub.docker.com/r/gogs/gogs/tags) for the current release to be created automatically.
+- [ ] Update Docker image tag for the minor release `<MAJOR>.<MINOR>`, e.g. `0.12`.
+- [ ] Compile and pack binaries (all prefixed with `gogs_<MAJOR>.<MINOR>.<PATCH>_`, e.g. `gogs_0.12.0_`):
+	- [ ] macOS: `darwin_amd64.zip`
+	- [ ] Linux: `linux_386.tar.gz`, `linux_386.zip`, `linux_amd64.tar.gz`, `linux_amd64.zip`
+	- [ ] ARM: `linux_armv7.tar.gz`, `linux_armv7.zip`, `linux_armv8.tar.gz`, `linux_armv8.zip`
+	- [ ] Windows: `windows_amd64.zip`, `windows_amd64_mws.zip`
+- [ ] Generate SHA256 checksum for all binaries to the file `checksum_sha256.txt`.
+- [ ] Upload all binaries to:
+	- [ ] GitHub release
+	- [ ] https://dl.gogs.io (also upload `checksum_sha256.txt`)
+- [ ] Build, push and tag a new Docker image for ARM to [Docker Hub](https://hub.docker.com/r/gogs/gogs-rpi).
+
+## After release
+
+On develop branch:
+
+- [ ] Post the following message on issues that are included in the patch milestone:
+    ```
+    The <MAJOR>.<MINOR>.<PATCH> has been released.
+    ```
+- [ ] Update the repository mirror on [Gitee](https://gitee.com/unknwon/gogs).
+- [ ] Reply to the release topic for the minor release on [Gogs Discussion](https://discuss.gogs.io/c/announcements/5).
+- [ ] Close the patch milestone.

+ 17 - 0
docs/dev/release/release_new_version.md

@@ -0,0 +1,17 @@
+# Release a new version
+
+## Release a minor version
+
+To release a new minor version, create a new GitHub issue with following attributes:
+
+1. Title: `Release <MAJOR>.<MINOR>.0`
+1. Label: [📸 release](https://github.com/gogs/gogs/labels/%F0%9F%93%B8%20release)
+1. Content: [minor version issue template](issue_template_minor_version.md)
+
+## Make a patch release
+
+To make a patch release, create a new GitHub issue with following attributes:
+
+1. Title: `Release <MAJOR>.<MINOR>.<PATCH>`
+1. Label: [📸 release](https://github.com/gogs/gogs/labels/%F0%9F%93%B8%20release)
+1. Content: [patch release issue template](issue_template_patch_release.md)

+ 22 - 24
go.mod

@@ -3,23 +3,20 @@ module gogs.io/gogs
 go 1.14
 
 require (
-	github.com/Masterminds/semver/v3 v3.1.0
-	github.com/bgentry/speakeasy v0.1.0 // indirect
-	github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e // indirect
-	github.com/editorconfig/editorconfig-core-go/v2 v2.3.2
+	github.com/Masterminds/semver/v3 v3.1.1
+	github.com/editorconfig/editorconfig-core-go/v2 v2.4.1
 	github.com/fatih/color v1.9.0 // indirect
-	github.com/go-macaron/binding v1.1.0
+	github.com/go-macaron/binding v1.1.1
 	github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196
 	github.com/go-macaron/captcha v0.2.0
 	github.com/go-macaron/csrf v0.0.0-20190812063352-946f6d303a4c
 	github.com/go-macaron/gzip v0.0.0-20160222043647-cad1c6580a07
-	github.com/go-macaron/i18n v0.5.0
+	github.com/go-macaron/i18n v0.6.0
 	github.com/go-macaron/session v0.0.0-20190805070824-1a3cdc6f5659
 	github.com/go-macaron/toolbox v0.0.0-20190813233741-94defb8383c6
-	github.com/go-sql-driver/mysql v1.5.0 // indirect
 	github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561
 	github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
-	github.com/gogs/git-module v1.1.2
+	github.com/gogs/git-module v1.1.4
 	github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4
 	github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0
 	github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a
@@ -27,49 +24,50 @@ require (
 	github.com/google/go-querystring v1.0.0 // indirect
 	github.com/issue9/identicon v1.0.1
 	github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43
-	github.com/jinzhu/gorm v1.9.12
 	github.com/json-iterator/go v1.1.10
 	github.com/klauspost/compress v1.8.6 // indirect
 	github.com/klauspost/cpuid v1.2.1 // indirect
-	github.com/lib/pq v1.3.0 // indirect
-	github.com/mattn/go-isatty v0.0.12 // indirect
-	github.com/mattn/go-runewidth v0.0.4 // indirect
 	github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
 	github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 // indirect
 	github.com/microcosm-cc/bluemonday v1.0.4
 	github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9
 	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
 	github.com/niklasfasching/go-org v0.1.9
-	github.com/olekukonko/tablewriter v0.0.1 // indirect
+	github.com/olekukonko/tablewriter v0.0.4
 	github.com/pkg/errors v0.9.1
 	github.com/pquerna/otp v1.2.0
-	github.com/prometheus/client_golang v1.6.0
-	github.com/russross/blackfriday v1.5.2
+	github.com/prometheus/client_golang v1.9.0
+	github.com/russross/blackfriday v1.6.0
 	github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
 	github.com/satori/go.uuid v1.2.0
 	github.com/sergi/go-diff v1.1.0
 	github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
-	github.com/stretchr/testify v1.6.1
-	github.com/t-tiger/gorm-bulk-insert v1.3.0
+	github.com/stretchr/testify v1.7.0
 	github.com/unknwon/cae v1.0.2
 	github.com/unknwon/com v1.0.1
 	github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
 	github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e
-	github.com/urfave/cli v1.22.4
-	golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
-	golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582
-	golang.org/x/text v0.3.3
+	github.com/urfave/cli v1.22.5
+	golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
+	golang.org/x/net v0.0.0-20200625001655-4c5254603344
+	golang.org/x/text v0.3.4
+	gopkg.in/DATA-DOG/go-sqlmock.v2 v2.0.0-20180914054222-c19298f520d0
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
-	gopkg.in/ini.v1 v1.56.0
+	gopkg.in/ini.v1 v1.62.0
 	gopkg.in/ldap.v2 v2.5.1
-	gopkg.in/macaron.v1 v1.3.9
+	gopkg.in/macaron.v1 v1.4.0
+	gorm.io/driver/mysql v1.0.3
+	gorm.io/driver/postgres v1.0.5
+	gorm.io/driver/sqlite v1.1.4
+	gorm.io/driver/sqlserver v1.0.5
+	gorm.io/gorm v1.20.8
 	unknwon.dev/clog/v2 v2.1.2
 	xorm.io/builder v0.3.6
 	xorm.io/core v0.7.2
 	xorm.io/xorm v0.8.0
 )
 
-// +heroku goVersion go1.14
+// +heroku goVersion go1.15
 // +heroku install ./

+ 380 - 67
go.sum

@@ -2,62 +2,96 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk=
-github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
+github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
+github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
 github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
 github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
 github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
 github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA=
 github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
+github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU=
 github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE=
+github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
+github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
+github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
 github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
 github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc=
 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
 github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
-github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
-github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE=
-github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
+github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
-github.com/editorconfig/editorconfig-core-go/v2 v2.3.2 h1:j9GLz0kWF9+1T3IX0MOhhvzLtqhFOvIKLhZFxtY95Qc=
-github.com/editorconfig/editorconfig-core-go/v2 v2.3.2/go.mod h1:+u4rFiKVvlbukHyJM76GYXqQcnHScxvQCuKpMLRtJVw=
+github.com/editorconfig/editorconfig-core-go/v2 v2.4.1 h1:ELDiPZji50x20Wvf9FnP4pb7fE3PV/DNhNd6MRlhgfI=
+github.com/editorconfig/editorconfig-core-go/v2 v2.4.1/go.mod h1:UHV4+gECABtht7ALQkPdc5gzP77D+4WDUOZAfx8ifx8=
 github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
-github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
+github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
+github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
+github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-macaron/binding v1.1.0 h1:A5jpr5UdHr81Hfmb6QUAMTHyvniudOMcgtEg13TJ1ig=
-github.com/go-macaron/binding v1.1.0/go.mod h1:dJU/AtPKG0gUiFra1K5TTGduFGMNxMvfJzV/zmXwyGM=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-macaron/binding v1.1.1 h1:agcYYn3FDj5YQ43CkVRMZ74M2BdqP/X1ut5+hVi8anI=
+github.com/go-macaron/binding v1.1.1/go.mod h1:dJU/AtPKG0gUiFra1K5TTGduFGMNxMvfJzV/zmXwyGM=
 github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196 h1:fqWZxyMLF6RVGmjvsZ9FijiU9UlAjuE6nu9RfNBZ+iE=
 github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196/go.mod h1:O6fSdaYZbGh4clVMGMGO5k2KbMO0Cz8YdBnPrD0I8dM=
 github.com/go-macaron/captcha v0.2.0 h1:d38eYDDF8tdqoM0hJbk+Jb7WQGWlwYNnQwRqLRmSk1Y=
@@ -66,37 +100,44 @@ github.com/go-macaron/csrf v0.0.0-20190812063352-946f6d303a4c h1:kFFz1OpaH3+efG7
 github.com/go-macaron/csrf v0.0.0-20190812063352-946f6d303a4c/go.mod h1:FX53Xq0NNlUj0E5in5J8Dq5nrbdK3ZyDIy6y5VWOiUo=
 github.com/go-macaron/gzip v0.0.0-20160222043647-cad1c6580a07 h1:YSIA98PevNf1NtCa/J6cz7gjzpz99WVAOa9Eg0klKps=
 github.com/go-macaron/gzip v0.0.0-20160222043647-cad1c6580a07/go.mod h1://cJFfDp/70L0oTNAMB+M8Jd0rpuIx/55iARuJ6StwE=
-github.com/go-macaron/i18n v0.5.0 h1:946emShWjaaP65K1xkOH/SGdFhGqGQsQ7JocEVq2fio=
-github.com/go-macaron/i18n v0.5.0/go.mod h1:geFUrUuAX4JocBS1mUlK79QbRAJH/pNM+W8VxPzvVXI=
+github.com/go-macaron/i18n v0.6.0 h1:7WpKDCGYH20pqwKNQgrksZHzKLp+sNA8VTSghElnO6s=
+github.com/go-macaron/i18n v0.6.0/go.mod h1:8XLiwPc4KNvIsHOT0YtSrLvmr9HHjTQMDhAiEhuYCTw=
 github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 h1:NjHlg70DuOkcAMqgt0+XA+NHwtu66MkTVVgR4fFWbcI=
 github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191/go.mod h1:VFI2o2q9kYsC4o7VP1HrEVosiZZTd+MVT3YZx4gqvJw=
 github.com/go-macaron/session v0.0.0-20190805070824-1a3cdc6f5659 h1:YXDFNK98PgKeBd+xM2Babdd6gyABG8H+SSAh5+hr0os=
 github.com/go-macaron/session v0.0.0-20190805070824-1a3cdc6f5659/go.mod h1:tLd0QEudXocQckwcpCq5pCuTCuYc24I0bRJDuRe9OuQ=
 github.com/go-macaron/toolbox v0.0.0-20190813233741-94defb8383c6 h1:x/v1iUWlqXTKVg17ulB0qCgcM2s+eysAbr/dseKLLss=
 github.com/go-macaron/toolbox v0.0.0-20190813233741-94defb8383c6/go.mod h1:YFNJ/JT4yLnpuIXTFef30SZkxGHUczjGZGFaZpPcdn0=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
 github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
+github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
+github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
 github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561 h1:aBzukfDxQlCTVS0NBUjI5YA3iVeaZ9Tb5PxNrrIP1xs=
 github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQdcMdzjbqqXMEnHfq0Or6p8=
 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
-github.com/gogs/git-module v1.1.1 h1:/taoHtOHLorlmQJ7zLBQvJGGgM9LRIoGGH1et4Upzvo=
-github.com/gogs/git-module v1.1.1/go.mod h1:oN37FFStFjdnTJXsSbhIHKJXh2YeDsEcXPATVz/oeuQ=
-github.com/gogs/git-module v1.1.2 h1:30jO+rKEmCDk/O6Mnl7MVrw6rI1qLDByXpkRB+bpYwM=
-github.com/gogs/git-module v1.1.2/go.mod h1:oN37FFStFjdnTJXsSbhIHKJXh2YeDsEcXPATVz/oeuQ=
+github.com/gogs/git-module v1.1.4 h1:Gzg0Rcvd0W4bVVuYb849eR/fTK2qh2/u/vSAGejKglM=
+github.com/gogs/git-module v1.1.4/go.mod h1:oN37FFStFjdnTJXsSbhIHKJXh2YeDsEcXPATVz/oeuQ=
 github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4 h1:C7NryI/RQhsIWwC2bHN601P1wJKeuQ6U/UCOYTn3Cic=
 github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU=
 github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0 h1:K02vod+sn3M1OOkdqi2tPxN2+xESK4qyITVQ3JkGEv4=
 github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0/go.mod h1:Zas3BtO88pk1cwUfEYlvnl/CRwh0ybDxRWSwRjG8I3w=
+github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a h1:8DZwxETOVWIinYxDK+i6L+rMb7eGATGaakD6ZucfHVk=
 github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a/go.mod h1:TUIZ+29jodWQ8Gk6Pvtg4E09aMsc3C/VLZiVYfUhWQU=
 github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
 github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -106,15 +147,20 @@ github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi
 github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
 github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
 github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
 github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
 github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
 github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
@@ -122,65 +168,170 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
 github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
 github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/issue9/assert v1.3.1 h1:L8pRpbnzMIPFJqrMKR/oG03uWrtVeZyYBpI2U2Jx1JE=
 github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
 github.com/issue9/identicon v1.0.1 h1:pCDfjMDM6xWK0Chxo8Lif+ST/nOEtmXgMITgV1YA9Og=
 github.com/issue9/identicon v1.0.1/go.mod h1:UKNVkUFI68RPz/RlLhsAr1aX6bBSaYEWRHVfdjrMUmk=
+github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
+github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
+github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
+github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
+github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
+github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
+github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk=
+github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
+github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
+github.com/jackc/pgconn v1.7.0 h1:pwjzcYyfmz/HQOQlENvG1OcDqauTGaqlVahq934F0/U=
+github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7JMeA=
+github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
+github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
+github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
+github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
+github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.0.5 h1:NUbEWPmCQZbMmYlTjVoNPhc0CfnYyz2bfUAh6A5ZVJM=
+github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
+github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
+github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
+github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
+github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
+github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
+github.com/jackc/pgtype v1.5.0 h1:jzBqRk2HFG2CV4AIwgCI2PwTgm6UUoCAK2ofHHRirtc=
+github.com/jackc/pgtype v1.5.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
+github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
+github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
+github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
+github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
+github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
+github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
+github.com/jackc/pgx/v4 v4.9.0 h1:6STjDqppM2ROy5p1wNDcsC7zJTjSHeuCsguZmXyzx7c=
+github.com/jackc/pgx/v4 v4.9.0/go.mod h1:MNGWmViCgqbZck9ujOOBN63gK9XVGILXWCvKLGKmnms=
+github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
 github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43 h1:jTkyeF7NZ5oIr0ESmcrpiDgAfoidCBF4F5kJhjtaRwE=
 github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
-github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw=
-github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
-github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
 github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
-github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E=
+github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
-github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
 github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/klauspost/compress v1.8.6 h1:970MQcQdxX7hfgc/aqmB4a3grW0ivUVV6i1TLkP8CiE=
 github.com/klauspost/compress v1.8.6/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
 github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
 github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
+github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
 github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
 github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
-github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
+github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
 github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
 github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
 github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
-github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
+github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
-github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
 github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
 github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
@@ -188,10 +339,16 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
 github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
 github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg=
 github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
-github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s=
-github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
 github.com/microcosm-cc/bluemonday v1.0.4 h1:p0L+CTpo/PLFdkoPcJemLXG+fpMD7pYOoDEq1axMbGg=
 github.com/microcosm-cc/bluemonday v1.0.4/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -201,57 +358,103 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
 github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9 h1:ZivaaKmjs9q90zi6I4gTLW6tbVGtlBjellr3hMYaly0=
 github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9/go.mod h1:np1wUFZ6tyoke22qDJZY40URn9Ae51gX7ljIWXN5TJs=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
+github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
 github.com/niklasfasching/go-org v0.1.9 h1:Toz8WMIt+qJb52uYEk1YD/muLuOOmRt1CfkV+bKVMkI=
 github.com/niklasfasching/go-org v0.1.9/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
-github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
-github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
+github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
+github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
 github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
 github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
-github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
+github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
+github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU=
+github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
-github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
+github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM=
+github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
-github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
+github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
-github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
+github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
+github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
+github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
 github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
 github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
+github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
 github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY=
+github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
@@ -259,30 +462,37 @@ github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0
 github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
 github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
 github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
 github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
-github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
 github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho=
-github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
-github.com/t-tiger/gorm-bulk-insert v1.3.0 h1:9k7BaVEhw/3fsvh6GTOBwJ2RXk3asc5xs5m6hwozq20=
-github.com/t-tiger/gorm-bulk-insert v1.3.0/go.mod h1:ruDlk8xDl+8sX4bA7PQuYly9YEb3pbp1eP2LCyeRrFY=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/unknwon/cae v1.0.2 h1:3L8/RCN1ARvD5quyNjU30EdvYkFbxBfnRcIBXugpHlg=
 github.com/unknwon/cae v1.0.2/go.mod h1:HqpmD2fVq9G1oGEXrXzbgIp51uJ29Hshv41n9ljm+AA=
 github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
@@ -292,29 +502,61 @@ github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 h1:sRrkJEHtNoaSvyXMbR
 github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6/go.mod h1:+5rDk6sDGpl3azws3O+f+GpFSyN9GVr0K8cvQLQM2ZQ=
 github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e h1:Qf3QQl/zmEbWDajFEiisbKN83hLY+eq2MhbA0I1/two=
 github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0=
-github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
-github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
+github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
+github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
 github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
 go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
-golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -325,8 +567,9 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA=
-golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -334,60 +577,104 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
-golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs=
+golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
 golang.org/x/tools v0.0.0-20190805222050-c5a2fd39b72a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
+golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
 google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+gopkg.in/DATA-DOG/go-sqlmock.v2 v2.0.0-20180914054222-c19298f520d0 h1:/21c4hNFgj8A1D54vgJZwQlywp64/RUBHzlPdpy5h4s=
+gopkg.in/DATA-DOG/go-sqlmock.v2 v2.0.0-20180914054222-c19298f520d0/go.mod h1:0uueny64T996pN6bez2N3S8HWyPcpyfTPma8Wc1Awx4=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
@@ -395,31 +682,57 @@ gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e h1:wGA78yza6bu/mWcc4QfBuIEH
 gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e/go.mod h1:xsQCaysVCudhrYTfzYWe577fCe7Ceci+6qjO2Rdc0Z4=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
+gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
 gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.56.0 h1:DPMeDvGTM54DXbPkVIZsp19fp/I2K7zwA/itHYHKo8Y=
-gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
+gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ldap.v2 v2.5.1 h1:wiu0okdNfjlBzg6UWvd1Hn8Y+Ux17/u/4nlk4CQr6tU=
 gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
 gopkg.in/macaron.v1 v1.3.4/go.mod h1:/RoHTdC8ALpyJ3+QR36mKjwnT1F1dyYtsGM9Ate6ZFI=
 gopkg.in/macaron.v1 v1.3.5/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
-gopkg.in/macaron.v1 v1.3.9 h1:Dw+DDRYdXgQyEsPlfAfKz+UA5qVUrH3KPD7JhmZ9MFc=
-gopkg.in/macaron.v1 v1.3.9/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
+gopkg.in/macaron.v1 v1.4.0 h1:RJHC09fAnQ8tuGUiZNjG0uyL1BWSdSWd9SpufIcEArQ=
+gopkg.in/macaron.v1 v1.4.0/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
 gopkg.in/redis.v2 v2.3.2 h1:GPVIIB/JnL1wvfULefy3qXmPu1nfNu2d0yA09FHgwfs=
 gopkg.in/redis.v2 v2.3.2/go.mod h1:4wl9PJ/CqzeHk3LVq1hNLHH8krm3+AXEgut4jVc++LU=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/mysql v1.0.3 h1:+JKBYPfn1tygR1/of/Fh2T8iwuVwzt+PEJmKaXzMQXg=
+gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI=
+gorm.io/driver/postgres v1.0.5 h1:raX6ezL/ciUmaYTvOq48jq1GE95aMC0CmxQYbxQ4Ufw=
+gorm.io/driver/postgres v1.0.5/go.mod h1:qrD92UurYzNctBMVCJ8C3VQEjffEuphycXtxOudXNCA=
+gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM=
+gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw=
+gorm.io/driver/sqlserver v1.0.5 h1:n5knSvyaEwufxl0aROEW90pn+aLoV9h+vahYJk1x5l4=
+gorm.io/driver/sqlserver v1.0.5/go.mod h1:WI/bfZ+s9TigYXe3hb3XjNaUP0TqmTdXl11pECyLATs=
+gorm.io/gorm v1.20.2/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
+gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
+gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
+gorm.io/gorm v1.20.8 h1:iToaOdZgjNvlc44NFkxfLa3U9q63qwaxt0FdNCiwOMs=
+gorm.io/gorm v1.20.8/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
 unknwon.dev/clog/v2 v2.1.2 h1:+jwPPp10UtOPunFtviUmXF01Abf6q7p5GEy4jluLl8o=
 unknwon.dev/clog/v2 v2.1.2/go.mod h1:zvUlyibDHI4mykYdWyWje2G9nF/nBzfDOqRo2my4mWc=
 xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8=

+ 1 - 1
gogs.go

@@ -18,7 +18,7 @@ import (
 )
 
 func init() {
-	conf.App.Version = "0.12.3"
+	conf.App.Version = "0.13.0+dev"
 }
 
 func main() {

+ 1 - 1
internal/assets/conf/conf.go

@@ -4,4 +4,4 @@
 
 package conf
 
-//go:generate go-bindata -nomemcopy -pkg=conf -ignore="\\.DS_Store|README.md|TRANSLATORS|auth.d" -prefix=../../../ -debug=false -o=conf_gen.go ../../../conf/...
+//go:generate go-bindata -nomemcopy -nometadata -pkg=conf -ignore="\\.DS_Store|README.md|TRANSLATORS|auth.d" -prefix=../../../ -debug=false -o=conf_gen.go ../../../conf/...

File diff suppressed because it is too large
+ 23 - 22
internal/assets/conf/conf_gen.go


+ 1 - 1
internal/assets/public/public.go

@@ -14,7 +14,7 @@ import (
 	"gogs.io/gogs/internal/assets"
 )
 
-//go:generate go-bindata -nomemcopy -pkg=public -ignore="\\.DS_Store|less" -prefix=../../../public -debug=false -o=public_gen.go ../../../public/...
+//go:generate go-bindata -nomemcopy -nometadata -pkg=public -ignore="\\.DS_Store|less" -prefix=../../../public -debug=false -o=public_gen.go ../../../public/...
 
 /*
 	This file is a modified version of https://github.com/go-bindata/go-bindata/pull/18.

File diff suppressed because it is too large
+ 11 - 11
internal/assets/public/public_gen.go


+ 1 - 1
internal/assets/templates/templates.go

@@ -17,7 +17,7 @@ import (
 	"gogs.io/gogs/internal/osutil"
 )
 
-//go:generate go-bindata -nomemcopy -ignore="\\.DS_Store" -pkg=templates -prefix=../../../templates -debug=false -o=templates_gen.go ../../../templates/...
+//go:generate go-bindata -nomemcopy -nometadata -ignore="\\.DS_Store" -pkg=templates -prefix=../../../templates -debug=false -o=templates_gen.go ../../../templates/...
 
 // fileSystem implements the macaron.TemplateFileSystem interface.
 type fileSystem struct {

File diff suppressed because it is too large
+ 11 - 11
internal/assets/templates/templates_gen.go


+ 69 - 127
internal/auth/auth.go

@@ -5,144 +5,86 @@
 package auth
 
 import (
-	"strings"
+	"fmt"
 
-	"github.com/go-macaron/session"
-	gouuid "github.com/satori/go.uuid"
-	"gopkg.in/macaron.v1"
-	log "unknwon.dev/clog/v2"
+	"gogs.io/gogs/internal/errutil"
+)
 
-	"gogs.io/gogs/internal/conf"
-	"gogs.io/gogs/internal/db"
-	"gogs.io/gogs/internal/tool"
+type Type int
+
+// Note: New type must append to the end of list to maintain backward compatibility.
+const (
+	None   Type = iota
+	Plain       // 1
+	LDAP        // 2
+	SMTP        // 3
+	PAM         // 4
+	DLDAP       // 5
+	GitHub      // 6
 )
 
-func IsAPIPath(url string) bool {
-	return strings.HasPrefix(url, "/api/")
+// Name returns the human-readable name for given authentication type.
+func Name(typ Type) string {
+	return map[Type]string{
+		LDAP:   "LDAP (via BindDN)",
+		DLDAP:  "LDAP (simple auth)", // Via direct bind
+		SMTP:   "SMTP",
+		PAM:    "PAM",
+		GitHub: "GitHub",
+	}[typ]
 }
 
-// SignedInID returns the id of signed in user, along with one bool value which indicates whether user uses token
-// authentication.
-func SignedInID(c *macaron.Context, sess session.Store) (_ int64, isTokenAuth bool) {
-	if !db.HasEngine {
-		return 0, false
-	}
-
-	// Check access token.
-	if IsAPIPath(c.Req.URL.Path) {
-		tokenSHA := c.Query("token")
-		if len(tokenSHA) <= 0 {
-			tokenSHA = c.Query("access_token")
-		}
-		if len(tokenSHA) == 0 {
-			// Well, check with header again.
-			auHead := c.Req.Header.Get("Authorization")
-			if len(auHead) > 0 {
-				auths := strings.Fields(auHead)
-				if len(auths) == 2 && auths[0] == "token" {
-					tokenSHA = auths[1]
-				}
-			}
-		}
-
-		// Let's see if token is valid.
-		if len(tokenSHA) > 0 {
-			t, err := db.AccessTokens.GetBySHA(tokenSHA)
-			if err != nil {
-				if !db.IsErrAccessTokenNotExist(err) {
-					log.Error("GetAccessTokenBySHA: %v", err)
-				}
-				return 0, false
-			}
-			if err = db.AccessTokens.Save(t); err != nil {
-				log.Error("UpdateAccessToken: %v", err)
-			}
-			return t.UserID, true
-		}
-	}
+var _ errutil.NotFound = (*ErrBadCredentials)(nil)
 
-	uid := sess.Get("uid")
-	if uid == nil {
-		return 0, false
-	}
-	if id, ok := uid.(int64); ok {
-		if _, err := db.GetUserByID(id); err != nil {
-			if !db.IsErrUserNotExist(err) {
-				log.Error("Failed to get user by ID: %v", err)
-			}
-			return 0, false
-		}
-		return id, false
-	}
-	return 0, false
+type ErrBadCredentials struct {
+	Args errutil.Args
 }
 
-// SignedInUser returns the user object of signed in user, along with two bool values,
-// which indicate whether user uses HTTP Basic Authentication or token authentication respectively.
-func SignedInUser(ctx *macaron.Context, sess session.Store) (_ *db.User, isBasicAuth bool, isTokenAuth bool) {
-	if !db.HasEngine {
-		return nil, false, false
-	}
-
-	uid, isTokenAuth := SignedInID(ctx, sess)
-
-	if uid <= 0 {
-		if conf.Auth.EnableReverseProxyAuthentication {
-			webAuthUser := ctx.Req.Header.Get(conf.Auth.ReverseProxyAuthenticationHeader)
-			if len(webAuthUser) > 0 {
-				u, err := db.GetUserByName(webAuthUser)
-				if err != nil {
-					if !db.IsErrUserNotExist(err) {
-						log.Error("Failed to get user by name: %v", err)
-						return nil, false, false
-					}
-
-					// Check if enabled auto-registration.
-					if conf.Auth.EnableReverseProxyAutoRegistration {
-						u := &db.User{
-							Name:     webAuthUser,
-							Email:    gouuid.NewV4().String() + "@localhost",
-							Passwd:   webAuthUser,
-							IsActive: true,
-						}
-						if err = db.CreateUser(u); err != nil {
-							// FIXME: should I create a system notice?
-							log.Error("Failed to create user: %v", err)
-							return nil, false, false
-						} else {
-							return u, false, false
-						}
-					}
-				}
-				return u, false, false
-			}
-		}
+func IsErrBadCredentials(err error) bool {
+	_, ok := err.(ErrBadCredentials)
+	return ok
+}
 
-		// Check with basic auth.
-		baHead := ctx.Req.Header.Get("Authorization")
-		if len(baHead) > 0 {
-			auths := strings.Fields(baHead)
-			if len(auths) == 2 && auths[0] == "Basic" {
-				uname, passwd, _ := tool.BasicAuthDecode(auths[1])
+func (err ErrBadCredentials) Error() string {
+	return fmt.Sprintf("bad credentials: %v", err.Args)
+}
 
-				u, err := db.Users.Authenticate(uname, passwd, -1)
-				if err != nil {
-					if !db.IsErrUserNotExist(err) {
-						log.Error("Failed to authenticate user: %v", err)
-					}
-					return nil, false, false
-				}
+func (ErrBadCredentials) NotFound() bool {
+	return true
+}
 
-				return u, true, false
-			}
-		}
-		return nil, false, false
-	}
+// ExternalAccount contains queried information returned by an authenticate provider
+// for an external account.
+type ExternalAccount struct {
+	// REQUIRED: The login to be used for authenticating against the provider.
+	Login string
+	// REQUIRED: The username of the account.
+	Name string
+	// The full name of the account.
+	FullName string
+	// The email address of the account.
+	Email string
+	// The location of the account.
+	Location string
+	// The website of the account.
+	Website string
+	// Whether the user should be prompted as a site admin.
+	Admin bool
+}
 
-	u, err := db.GetUserByID(uid)
-	if err != nil {
-		log.Error("GetUserByID: %v", err)
-		return nil, false, false
-	}
-	return u, false, isTokenAuth
+// Provider defines an authenticate provider which provides ability to authentication against
+// an external identity provider and query external account information.
+type Provider interface {
+	// Authenticate performs authentication against an external identity provider
+	// using given credentials and returns queried information of the external account.
+	Authenticate(login, password string) (*ExternalAccount, error)
+
+	// Config returns the underlying configuration of the authenticate provider.
+	Config() interface{}
+	// HasTLS returns true if the authenticate provider supports TLS.
+	HasTLS() bool
+	// UseTLS returns true if the authenticate provider is configured to use TLS.
+	UseTLS() bool
+	// SkipTLSVerify returns true if the authenticate provider is configured to skip TLS verify.
+	SkipTLSVerify() bool
 }

+ 58 - 0
internal/auth/github/config.go

@@ -0,0 +1,58 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"crypto/tls"
+	"net/http"
+	"strings"
+
+	"github.com/google/go-github/github"
+	"github.com/pkg/errors"
+)
+
+// Config contains configuration for GitHub authentication.
+//
+// ⚠️ WARNING: Change to the field name must preserve the INI key name for backward compatibility.
+type Config struct {
+	// the GitHub service endpoint, e.g. https://api.github.com/.
+	APIEndpoint string
+	SkipVerify  bool
+}
+
+func (c *Config) doAuth(login, password string) (fullname, email, location, website string, err error) {
+	tp := github.BasicAuthTransport{
+		Username: strings.TrimSpace(login),
+		Password: strings.TrimSpace(password),
+		Transport: &http.Transport{
+			TLSClientConfig: &tls.Config{InsecureSkipVerify: c.SkipVerify},
+		},
+	}
+	client, err := github.NewEnterpriseClient(c.APIEndpoint, c.APIEndpoint, tp.Client())
+	if err != nil {
+		return "", "", "", "", errors.Wrap(err, "create new client")
+	}
+	user, _, err := client.Users.Get(context.Background(), "")
+	if err != nil {
+		return "", "", "", "", errors.Wrap(err, "get user info")
+	}
+
+	if user.Name != nil {
+		fullname = *user.Name
+	}
+	if user.Email != nil {
+		email = *user.Email
+	} else {
+		email = login + "+github@local"
+	}
+	if user.Location != nil {
+		location = strings.ToUpper(*user.Location)
+	}
+	if user.HTMLURL != nil {
+		website = strings.ToLower(*user.HTMLURL)
+	}
+	return fullname, email, location, website, nil
+}

+ 0 - 50
internal/auth/github/github.go

@@ -1,50 +0,0 @@
-// Copyright 2018 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package github
-
-import (
-	"context"
-	"crypto/tls"
-	"fmt"
-	"net/http"
-	"strings"
-
-	"github.com/google/go-github/github"
-)
-
-func Authenticate(apiEndpoint, login, passwd string) (name string, email string, website string, location string, _ error) {
-	tp := github.BasicAuthTransport{
-		Username: strings.TrimSpace(login),
-		Password: strings.TrimSpace(passwd),
-		Transport: &http.Transport{
-			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
-		},
-	}
-	client, err := github.NewEnterpriseClient(apiEndpoint, apiEndpoint, tp.Client())
-	if err != nil {
-		return "", "", "", "", fmt.Errorf("create new client: %v", err)
-	}
-	user, _, err := client.Users.Get(context.Background(), "")
-	if err != nil {
-		return "", "", "", "", fmt.Errorf("get user info: %v", err)
-	}
-
-	if user.Name != nil {
-		name = *user.Name
-	}
-	if user.Email != nil {
-		email = *user.Email
-	} else {
-		email = login + "+github@local"
-	}
-	if user.HTMLURL != nil {
-		website = strings.ToLower(*user.HTMLURL)
-	}
-	if user.Location != nil {
-		location = strings.ToUpper(*user.Location)
-	}
-
-	return name, email, website, location, nil
-}

+ 57 - 0
internal/auth/github/provider.go

@@ -0,0 +1,57 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"strings"
+
+	"gogs.io/gogs/internal/auth"
+)
+
+// Provider contains configuration of a PAM authentication provider.
+type Provider struct {
+	config *Config
+}
+
+// NewProvider creates a new PAM authentication provider.
+func NewProvider(cfg *Config) auth.Provider {
+	return &Provider{
+		config: cfg,
+	}
+}
+
+func (p *Provider) Authenticate(login, password string) (*auth.ExternalAccount, error) {
+	fullname, email, website, location, err := p.config.doAuth(login, password)
+	if err != nil {
+		if strings.Contains(err.Error(), "401") {
+			return nil, auth.ErrBadCredentials{Args: map[string]interface{}{"login": login}}
+		}
+		return nil, err
+	}
+	return &auth.ExternalAccount{
+		Login:    login,
+		Name:     login,
+		FullName: fullname,
+		Email:    email,
+		Location: location,
+		Website:  website,
+	}, nil
+}
+
+func (p *Provider) Config() interface{} {
+	return p.config
+}
+
+func (p *Provider) HasTLS() bool {
+	return true
+}
+
+func (p *Provider) UseTLS() bool {
+	return true
+}
+
+func (p *Provider) SkipTLSVerify() bool {
+	return p.config.SkipVerify
+}

+ 76 - 60
internal/auth/ldap/ldap.go → internal/auth/ldap/config.go

@@ -2,8 +2,8 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-// Package ldap provide functions & structure to query a LDAP ldap directory
-// For now, it's mainly tested again an MS Active Directory service, see README.md for more information
+// Package ldap provide functions & structure to query a LDAP ldap directory.
+// For now, it's mainly tested again an MS Active Directory service, see README.md for more information.
 package ldap
 
 import (
@@ -15,19 +15,31 @@ import (
 	log "unknwon.dev/clog/v2"
 )
 
+// SecurityProtocol is the security protocol when the authenticate provider talks to LDAP directory.
 type SecurityProtocol int
 
-// Note: new type must be added at the end of list to maintain compatibility.
+// ⚠️ WARNING: new type must be added at the end of list to maintain compatibility.
 const (
 	SecurityProtocolUnencrypted SecurityProtocol = iota
 	SecurityProtocolLDAPS
 	SecurityProtocolStartTLS
 )
 
-// Basic LDAP authentication service
-type Source struct {
+// SecurityProtocolName returns the human-readable name for given security protocol.
+func SecurityProtocolName(protocol SecurityProtocol) string {
+	return map[SecurityProtocol]string{
+		SecurityProtocolUnencrypted: "Unencrypted",
+		SecurityProtocolLDAPS:       "LDAPS",
+		SecurityProtocolStartTLS:    "StartTLS",
+	}[protocol]
+}
+
+// Config contains configuration for LDAP authentication.
+//
+// ⚠️ WARNING: Change to the field name must preserve the INI key name for backward compatibility.
+type Config struct {
 	Host              string // LDAP host
-	Port              int    // port number
+	Port              int    // Port number
 	SecurityProtocol  SecurityProtocol
 	SkipVerify        bool
 	BindDN            string `ini:"bind_dn,omitempty"` // DN to bind with
@@ -37,18 +49,22 @@ type Source struct {
 	AttributeUsername string // Username attribute
 	AttributeName     string // First name attribute
 	AttributeSurname  string // Surname attribute
-	AttributeMail     string // E-mail attribute
-	AttributesInBind  bool   // fetch attributes in bind context (not user)
+	AttributeMail     string // Email attribute
+	AttributesInBind  bool   // Fetch attributes in bind context (not user)
 	Filter            string // Query filter to validate entry
 	AdminFilter       string // Query filter to check if user is admin
-	GroupEnabled      bool   // if the group checking is enabled
-	GroupDN           string `ini:"group_dn"` // Group Search Base
-	GroupFilter       string // Group Name Filter
+	GroupEnabled      bool   // Whether the group checking is enabled
+	GroupDN           string `ini:"group_dn"` // Group search base
+	GroupFilter       string // Group name filter
 	GroupMemberUID    string `ini:"group_member_uid"` // Group Attribute containing array of UserUID
-	UserUID           string `ini:"user_uid"`         // User Attribute listed in Group
+	UserUID           string `ini:"user_uid"`         // User Attribute listed in group
+}
+
+func (c *Config) SecurityProtocolName() string {
+	return SecurityProtocolName(c.SecurityProtocol)
 }
 
-func (ls *Source) sanitizedUserQuery(username string) (string, bool) {
+func (c *Config) sanitizedUserQuery(username string) (string, bool) {
 	// See http://tools.ietf.org/search/rfc4515
 	badCharacters := "\x00()*\\"
 	if strings.ContainsAny(username, badCharacters) {
@@ -56,10 +72,10 @@ func (ls *Source) sanitizedUserQuery(username string) (string, bool) {
 		return "", false
 	}
 
-	return strings.Replace(ls.Filter, "%s", username, -1), true
+	return strings.Replace(c.Filter, "%s", username, -1), true
 }
 
-func (ls *Source) sanitizedUserDN(username string) (string, bool) {
+func (c *Config) sanitizedUserDN(username string) (string, bool) {
 	// See http://tools.ietf.org/search/rfc4514: "special characters"
 	badCharacters := "\x00()*\\,='\"#+;<>"
 	if strings.ContainsAny(username, badCharacters) || strings.HasPrefix(username, " ") || strings.HasSuffix(username, " ") {
@@ -67,10 +83,10 @@ func (ls *Source) sanitizedUserDN(username string) (string, bool) {
 		return "", false
 	}
 
-	return strings.Replace(ls.UserDN, "%s", username, -1), true
+	return strings.Replace(c.UserDN, "%s", username, -1), true
 }
 
-func (ls *Source) sanitizedGroupFilter(group string) (string, bool) {
+func (c *Config) sanitizedGroupFilter(group string) (string, bool) {
 	// See http://tools.ietf.org/search/rfc4515
 	badCharacters := "\x00*\\"
 	if strings.ContainsAny(group, badCharacters) {
@@ -81,7 +97,7 @@ func (ls *Source) sanitizedGroupFilter(group string) (string, bool) {
 	return group, true
 }
 
-func (ls *Source) sanitizedGroupDN(groupDn string) (string, bool) {
+func (c *Config) sanitizedGroupDN(groupDn string) (string, bool) {
 	// See http://tools.ietf.org/search/rfc4514: "special characters"
 	badCharacters := "\x00()*\\'\"#+;<>"
 	if strings.ContainsAny(groupDn, badCharacters) || strings.HasPrefix(groupDn, " ") || strings.HasSuffix(groupDn, " ") {
@@ -92,12 +108,12 @@ func (ls *Source) sanitizedGroupDN(groupDn string) (string, bool) {
 	return groupDn, true
 }
 
-func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
+func (c *Config) findUserDN(l *ldap.Conn, name string) (string, bool) {
 	log.Trace("Search for LDAP user: %s", name)
-	if len(ls.BindDN) > 0 && len(ls.BindPassword) > 0 {
+	if len(c.BindDN) > 0 && len(c.BindPassword) > 0 {
 		// Replace placeholders with username
-		bindDN := strings.Replace(ls.BindDN, "%s", name, -1)
-		err := l.Bind(bindDN, ls.BindPassword)
+		bindDN := strings.Replace(c.BindDN, "%s", name, -1)
+		err := l.Bind(bindDN, c.BindPassword)
 		if err != nil {
 			log.Trace("LDAP: Failed to bind as BindDN '%s': %v", bindDN, err)
 			return "", false
@@ -108,23 +124,23 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
 	}
 
 	// A search for the user.
-	userFilter, ok := ls.sanitizedUserQuery(name)
+	userFilter, ok := c.sanitizedUserQuery(name)
 	if !ok {
 		return "", false
 	}
 
-	log.Trace("LDAP: Searching for DN using filter '%s' and base '%s'", userFilter, ls.UserBase)
+	log.Trace("LDAP: Searching for DN using filter %q and base %q", userFilter, c.UserBase)
 	search := ldap.NewSearchRequest(
-		ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0,
+		c.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0,
 		false, userFilter, []string{}, nil)
 
 	// Ensure we found a user
 	sr, err := l.Search(search)
 	if err != nil || len(sr.Entries) < 1 {
-		log.Trace("LDAP: Failed search using filter '%s': %v", userFilter, err)
+		log.Trace("LDAP: Failed to search using filter %q: %v", userFilter, err)
 		return "", false
 	} else if len(sr.Entries) > 1 {
-		log.Trace("LDAP: Filter '%s' returned more than one user", userFilter)
+		log.Trace("LDAP: Filter %q returned more than one user", userFilter)
 		return "", false
 	}
 
@@ -137,7 +153,7 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
 	return userDN, true
 }
 
-func dial(ls *Source) (*ldap.Conn, error) {
+func dial(ls *Config) (*ldap.Conn, error) {
 	log.Trace("LDAP: Dialing with security protocol '%v' without verifying: %v", ls.SecurityProtocol, ls.SkipVerify)
 
 	tlsCfg := &tls.Config{
@@ -174,26 +190,26 @@ func bindUser(l *ldap.Conn, userDN, passwd string) error {
 	return err
 }
 
-// searchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter
-func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, string, string, string, bool, bool) {
+// searchEntry searches an LDAP source if an entry (name, passwd) is valid and in the specific filter.
+func (c *Config) searchEntry(name, passwd string, directBind bool) (string, string, string, string, bool, bool) {
 	// See https://tools.ietf.org/search/rfc4513#section-5.1.2
 	if len(passwd) == 0 {
 		log.Trace("authentication failed for '%s' with empty password", name)
 		return "", "", "", "", false, false
 	}
-	l, err := dial(ls)
+	l, err := dial(c)
 	if err != nil {
-		log.Error("LDAP connect failed for '%s': %v", ls.Host, err)
+		log.Error("LDAP connect failed for '%s': %v", c.Host, err)
 		return "", "", "", "", false, false
 	}
 	defer l.Close()
 
 	var userDN string
 	if directBind {
-		log.Trace("LDAP will bind directly via UserDN template: %s", ls.UserDN)
+		log.Trace("LDAP will bind directly via UserDN template: %s", c.UserDN)
 
 		var ok bool
-		userDN, ok = ls.sanitizedUserDN(name)
+		userDN, ok = c.sanitizedUserDN(name)
 		if !ok {
 			return "", "", "", "", false, false
 		}
@@ -201,13 +217,13 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
 		log.Trace("LDAP will use BindDN")
 
 		var found bool
-		userDN, found = ls.findUserDN(l, name)
+		userDN, found = c.findUserDN(l, name)
 		if !found {
 			return "", "", "", "", false, false
 		}
 	}
 
-	if directBind || !ls.AttributesInBind {
+	if directBind || !c.AttributesInBind {
 		// binds user (checking password) before looking-up attributes in user context
 		err = bindUser(l, userDN, passwd)
 		if err != nil {
@@ -215,18 +231,18 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
 		}
 	}
 
-	userFilter, ok := ls.sanitizedUserQuery(name)
+	userFilter, ok := c.sanitizedUserQuery(name)
 	if !ok {
 		return "", "", "", "", false, false
 	}
 
-	log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v' with filter '%s' and base '%s'",
-		ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.UserUID, userFilter, userDN)
+	log.Trace("Fetching attributes %q, %q, %q, %q, %q with user filter %q and user DN %q",
+		c.AttributeUsername, c.AttributeName, c.AttributeSurname, c.AttributeMail, c.UserUID, userFilter, userDN)
+
 	search := ldap.NewSearchRequest(
 		userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter,
-		[]string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.UserUID},
+		[]string{c.AttributeUsername, c.AttributeName, c.AttributeSurname, c.AttributeMail, c.UserUID},
 		nil)
-
 	sr, err := l.Search(search)
 	if err != nil {
 		log.Error("LDAP: User search failed: %v", err)
@@ -241,27 +257,27 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
 		return "", "", "", "", false, false
 	}
 
-	username := sr.Entries[0].GetAttributeValue(ls.AttributeUsername)
-	firstname := sr.Entries[0].GetAttributeValue(ls.AttributeName)
-	surname := sr.Entries[0].GetAttributeValue(ls.AttributeSurname)
-	mail := sr.Entries[0].GetAttributeValue(ls.AttributeMail)
-	uid := sr.Entries[0].GetAttributeValue(ls.UserUID)
+	username := sr.Entries[0].GetAttributeValue(c.AttributeUsername)
+	firstname := sr.Entries[0].GetAttributeValue(c.AttributeName)
+	surname := sr.Entries[0].GetAttributeValue(c.AttributeSurname)
+	mail := sr.Entries[0].GetAttributeValue(c.AttributeMail)
+	uid := sr.Entries[0].GetAttributeValue(c.UserUID)
 
 	// Check group membership
-	if ls.GroupEnabled {
-		groupFilter, ok := ls.sanitizedGroupFilter(ls.GroupFilter)
+	if c.GroupEnabled {
+		groupFilter, ok := c.sanitizedGroupFilter(c.GroupFilter)
 		if !ok {
 			return "", "", "", "", false, false
 		}
-		groupDN, ok := ls.sanitizedGroupDN(ls.GroupDN)
+		groupDN, ok := c.sanitizedGroupDN(c.GroupDN)
 		if !ok {
 			return "", "", "", "", false, false
 		}
 
-		log.Trace("LDAP: Fetching groups '%v' with filter '%s' and base '%s'", ls.GroupMemberUID, groupFilter, groupDN)
+		log.Trace("LDAP: Fetching groups '%v' with filter '%s' and base '%s'", c.GroupMemberUID, groupFilter, groupDN)
 		groupSearch := ldap.NewSearchRequest(
 			groupDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, groupFilter,
-			[]string{ls.GroupMemberUID},
+			[]string{c.GroupMemberUID},
 			nil)
 
 		srg, err := l.Search(groupSearch)
@@ -274,9 +290,9 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
 		}
 
 		isMember := false
-		if ls.UserUID == "dn" {
+		if c.UserUID == "dn" {
 			for _, group := range srg.Entries {
-				for _, member := range group.GetAttributeValues(ls.GroupMemberUID) {
+				for _, member := range group.GetAttributeValues(c.GroupMemberUID) {
 					if member == sr.Entries[0].DN {
 						isMember = true
 					}
@@ -284,7 +300,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
 			}
 		} else {
 			for _, group := range srg.Entries {
-				for _, member := range group.GetAttributeValues(ls.GroupMemberUID) {
+				for _, member := range group.GetAttributeValues(c.GroupMemberUID) {
 					if member == uid {
 						isMember = true
 					}
@@ -293,17 +309,17 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
 		}
 
 		if !isMember {
-			log.Trace("LDAP: Group membership test failed [username: %s, group_member_uid: %s, user_uid: %s", username, ls.GroupMemberUID, uid)
+			log.Trace("LDAP: Group membership test failed [username: %s, group_member_uid: %s, user_uid: %s", username, c.GroupMemberUID, uid)
 			return "", "", "", "", false, false
 		}
 	}
 
 	isAdmin := false
-	if len(ls.AdminFilter) > 0 {
-		log.Trace("Checking admin with filter '%s' and base '%s'", ls.AdminFilter, userDN)
+	if len(c.AdminFilter) > 0 {
+		log.Trace("Checking admin with filter '%s' and base '%s'", c.AdminFilter, userDN)
 		search = ldap.NewSearchRequest(
-			userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ls.AdminFilter,
-			[]string{ls.AttributeName},
+			userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, c.AdminFilter,
+			[]string{c.AttributeName},
 			nil)
 
 		sr, err = l.Search(search)
@@ -316,7 +332,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
 		}
 	}
 
-	if !directBind && ls.AttributesInBind {
+	if !directBind && c.AttributesInBind {
 		// binds user (checking password) after looking-up attributes in BindDN context
 		err = bindUser(l, userDN, passwd)
 		if err != nil {

+ 78 - 0
internal/auth/ldap/provider.go

@@ -0,0 +1,78 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package ldap
+
+import (
+	"fmt"
+
+	"gogs.io/gogs/internal/auth"
+)
+
+// Provider contains configuration of an LDAP authentication provider.
+type Provider struct {
+	directBind bool
+	config     *Config
+}
+
+// NewProvider creates a new LDAP authentication provider.
+func NewProvider(directBind bool, cfg *Config) auth.Provider {
+	return &Provider{
+		directBind: directBind,
+		config:     cfg,
+	}
+}
+
+// Authenticate queries if login/password is valid against the LDAP directory pool,
+// and returns queried information when succeeded.
+func (p *Provider) Authenticate(login, password string) (*auth.ExternalAccount, error) {
+	username, fn, sn, email, isAdmin, succeed := p.config.searchEntry(login, password, p.directBind)
+	if !succeed {
+		return nil, auth.ErrBadCredentials{Args: map[string]interface{}{"login": login}}
+	}
+
+	if len(username) == 0 {
+		username = login
+	}
+	if len(email) == 0 {
+		email = fmt.Sprintf("%s@localhost", username)
+	}
+
+	composeFullName := func(firstname, surname, username string) string {
+		switch {
+		case firstname == "" && surname == "":
+			return username
+		case firstname == "":
+			return surname
+		case surname == "":
+			return firstname
+		default:
+			return firstname + " " + surname
+		}
+	}
+
+	return &auth.ExternalAccount{
+		Login:    login,
+		Name:     username,
+		FullName: composeFullName(fn, sn, username),
+		Email:    email,
+		Admin:    isAdmin,
+	}, nil
+}
+
+func (p *Provider) Config() interface{} {
+	return p.config
+}
+
+func (p *Provider) HasTLS() bool {
+	return p.config.SecurityProtocol > SecurityProtocolUnencrypted
+}
+
+func (p *Provider) UseTLS() bool {
+	return p.config.SecurityProtocol > SecurityProtocolUnencrypted
+}
+
+func (p *Provider) SkipTLSVerify() bool {
+	return p.config.SkipVerify
+}

+ 13 - 0
internal/auth/pam/config.go

@@ -0,0 +1,13 @@
+// Copyright 2014 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package pam
+
+// Config contains configuration for PAM authentication.
+//
+// ⚠️ WARNING: Change to the field name must preserve the INI key name for backward compatibility.
+type Config struct {
+	// The name of the PAM service, e.g. system-auth.
+	ServiceName string
+}

+ 6 - 12
internal/auth/pam/pam.go

@@ -7,29 +7,23 @@
 package pam
 
 import (
-	"errors"
-
 	"github.com/msteinert/pam"
+	"github.com/pkg/errors"
 )
 
-func PAMAuth(serviceName, userName, passwd string) error {
-	t, err := pam.StartFunc(serviceName, userName, func(s pam.Style, msg string) (string, error) {
+func (c *Config) doAuth(login, password string) error {
+	t, err := pam.StartFunc(c.ServiceName, login, func(s pam.Style, msg string) (string, error) {
 		switch s {
 		case pam.PromptEchoOff:
-			return passwd, nil
+			return password, nil
 		case pam.PromptEchoOn, pam.ErrorMsg, pam.TextInfo:
 			return "", nil
 		}
-		return "", errors.New("Unrecognized PAM message style")
+		return "", errors.Errorf("unrecognized PAM message style: %v - %s", s, msg)
 	})
-
 	if err != nil {
 		return err
 	}
 
-	if err = t.Authenticate(0); err != nil {
-		return err
-	}
-
-	return nil
+	return t.Authenticate(0)
 }

+ 2 - 2
internal/auth/pam/pam_stub.go

@@ -7,9 +7,9 @@
 package pam
 
 import (
-	"errors"
+	"github.com/pkg/errors"
 )
 
-func PAMAuth(serviceName, userName, passwd string) error {
+func (c *Config) doAuth(login, password string) error {
 	return errors.New("PAM not supported")
 }

+ 54 - 0
internal/auth/pam/provider.go

@@ -0,0 +1,54 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package pam
+
+import (
+	"strings"
+
+	"gogs.io/gogs/internal/auth"
+)
+
+// Provider contains configuration of a PAM authentication provider.
+type Provider struct {
+	config *Config
+}
+
+// NewProvider creates a new PAM authentication provider.
+func NewProvider(cfg *Config) auth.Provider {
+	return &Provider{
+		config: cfg,
+	}
+}
+
+func (p *Provider) Authenticate(login, password string) (*auth.ExternalAccount, error) {
+	err := p.config.doAuth(login, password)
+	if err != nil {
+		if strings.Contains(err.Error(), "Authentication failure") {
+			return nil, auth.ErrBadCredentials{Args: map[string]interface{}{"login": login}}
+		}
+		return nil, err
+	}
+
+	return &auth.ExternalAccount{
+		Login: login,
+		Name:  login,
+	}, nil
+}
+
+func (p *Provider) Config() interface{} {
+	return p.config
+}
+
+func (p *Provider) HasTLS() bool {
+	return false
+}
+
+func (p *Provider) UseTLS() bool {
+	return false
+}
+
+func (p *Provider) SkipTLSVerify() bool {
+	return false
+}

+ 58 - 0
internal/auth/smtp/config.go

@@ -0,0 +1,58 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package smtp
+
+import (
+	"crypto/tls"
+	"fmt"
+	"net/smtp"
+
+	"github.com/pkg/errors"
+)
+
+// Config contains configuration for SMTP authentication.
+//
+// ⚠️ WARNING: Change to the field name must preserve the INI key name for backward compatibility.
+type Config struct {
+	Auth           string
+	Host           string
+	Port           int
+	AllowedDomains string
+	TLS            bool `ini:"tls"`
+	SkipVerify     bool
+}
+
+func (c *Config) doAuth(auth smtp.Auth) error {
+	client, err := smtp.Dial(fmt.Sprintf("%s:%d", c.Host, c.Port))
+	if err != nil {
+		return err
+	}
+	defer client.Close()
+
+	if err = client.Hello("gogs"); err != nil {
+		return err
+	}
+
+	if c.TLS {
+		if ok, _ := client.Extension("STARTTLS"); ok {
+			if err = client.StartTLS(&tls.Config{
+				InsecureSkipVerify: c.SkipVerify,
+				ServerName:         c.Host,
+			}); err != nil {
+				return err
+			}
+		} else {
+			return errors.New("SMTP server does not support TLS")
+		}
+	}
+
+	if ok, _ := client.Extension("AUTH"); ok {
+		if err = client.Auth(auth); err != nil {
+			return err
+		}
+		return nil
+	}
+	return errors.New("unsupported SMTP authentication method")
+}

+ 132 - 0
internal/auth/smtp/provider.go

@@ -0,0 +1,132 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package smtp
+
+import (
+	"net/smtp"
+	"net/textproto"
+	"strings"
+
+	"github.com/pkg/errors"
+	log "unknwon.dev/clog/v2"
+
+	"gogs.io/gogs/internal/auth"
+)
+
+// Provider contains configuration of an SMTP authentication provider.
+type Provider struct {
+	config *Config
+}
+
+// NewProvider creates a new SMTP authentication provider.
+func NewProvider(cfg *Config) auth.Provider {
+	return &Provider{
+		config: cfg,
+	}
+}
+
+// Authenticate queries if login/password is valid against the SMTP server,
+// and returns queried information when succeeded.
+func (p *Provider) Authenticate(login, password string) (*auth.ExternalAccount, error) {
+	// Verify allowed domains
+	if p.config.AllowedDomains != "" {
+		fields := strings.SplitN(login, "@", 3)
+		if len(fields) != 2 {
+			return nil, auth.ErrBadCredentials{Args: map[string]interface{}{"login": login}}
+		}
+		domain := fields[1]
+
+		isAllowed := false
+		for _, allowed := range strings.Split(p.config.AllowedDomains, ",") {
+			if domain == allowed {
+				isAllowed = true
+				break
+			}
+		}
+
+		if !isAllowed {
+			return nil, auth.ErrBadCredentials{Args: map[string]interface{}{"login": login}}
+		}
+	}
+
+	var smtpAuth smtp.Auth
+	switch p.config.Auth {
+	case Plain:
+		smtpAuth = smtp.PlainAuth("", login, password, p.config.Host)
+	case Login:
+		smtpAuth = &smtpLoginAuth{login, password}
+	default:
+		return nil, errors.Errorf("unsupported SMTP authentication type %q", p.config.Auth)
+	}
+
+	if err := p.config.doAuth(smtpAuth); err != nil {
+		log.Trace("SMTP: Authentication failed: %v", err)
+
+		// Check standard error format first, then fallback to the worse case.
+		tperr, ok := err.(*textproto.Error)
+		if (ok && tperr.Code == 535) ||
+			strings.Contains(err.Error(), "Username and Password not accepted") {
+			return nil, auth.ErrBadCredentials{Args: map[string]interface{}{"login": login}}
+		}
+		return nil, err
+	}
+
+	username := login
+
+	// NOTE: It is not required to have "@" in `login` for a successful SMTP authentication.
+	idx := strings.Index(login, "@")
+	if idx > -1 {
+		username = login[:idx]
+	}
+
+	return &auth.ExternalAccount{
+		Login: login,
+		Name:  username,
+		Email: login,
+	}, nil
+}
+
+func (p *Provider) Config() interface{} {
+	return p.config
+}
+
+func (p *Provider) HasTLS() bool {
+	return true
+}
+
+func (p *Provider) UseTLS() bool {
+	return p.config.TLS
+}
+
+func (p *Provider) SkipTLSVerify() bool {
+	return p.config.SkipVerify
+}
+
+const (
+	Plain = "PLAIN"
+	Login = "LOGIN"
+)
+
+var AuthTypes = []string{Plain, Login}
+
+type smtpLoginAuth struct {
+	username, password string
+}
+
+func (auth *smtpLoginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
+	return "LOGIN", []byte(auth.username), nil
+}
+
+func (auth *smtpLoginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
+	if more {
+		switch string(fromServer) {
+		case "Username:":
+			return []byte(auth.username), nil
+		case "Password:":
+			return []byte(auth.password), nil
+		}
+	}
+	return nil, nil
+}

+ 7 - 6
internal/cmd/serv.go

@@ -210,11 +210,12 @@ func runServ(c *cli.Context) error {
 				fail("Internal error", "Failed to get user by key ID '%d': %v", key.ID, err)
 			}
 
-			mode, err := db.UserAccessMode(user.ID, repo)
-			if err != nil {
-				fail("Internal error", "Failed to check access: %v", err)
-			}
-
+			mode := db.Perms.AccessMode(user.ID, repo.ID,
+				db.AccessModeOptions{
+					OwnerID: repo.OwnerID,
+					Private: repo.IsPrivate,
+				},
+			)
 			if mode < requestMode {
 				clientMessage := _ACCESS_DENIED_MESSAGE
 				if mode >= db.AccessModeRead {
@@ -229,7 +230,7 @@ func runServ(c *cli.Context) error {
 		// Check if the key can access to the repository in case of it is a deploy key (a deploy keys != user key).
 		// A deploy key doesn't represent a signed in user, so in a site with Auth.RequireSignInView enabled,
 		// we should give read access only in repositories where this deploy key is in use. In other cases,
-		// a server or system using an active deploy key can get read access to all repositories on a Gogs instace.
+		// a server or system using an active deploy key can get read access to all repositories on a Gogs instance.
 		if key.IsDeployKey() && conf.Auth.RequireSigninView {
 			checkDeployKey(key, repo)
 		}

+ 3 - 3
internal/conf/computed.go

@@ -53,7 +53,7 @@ var (
 	workDirOnce sync.Once
 )
 
-// WorkDir returns the absolute path of work directory. It reads the value of envrionment
+// WorkDir returns the absolute path of work directory. It reads the value of environment
 // variable GOGS_WORK_DIR. When not set, it uses the directory where the application's
 // binary is located.
 func WorkDir() string {
@@ -75,8 +75,8 @@ var (
 )
 
 // CustomDir returns the absolute path of the custom directory that contains local overrides.
-// It reads the value of envrionment variable GOGS_CUSTOM. When not set, it uses the work
-// directory returned by WorkDir fucntion.
+// It reads the value of environment variable GOGS_CUSTOM. When not set, it uses the work
+// directory returned by WorkDir function.
 func CustomDir() string {
 	customDirOnce.Do(func() {
 		customDir = os.Getenv("GOGS_CUSTOM")

+ 0 - 8
internal/conf/conf.go

@@ -214,10 +214,6 @@ func Init(customConf string) error {
 	if err = File.Section("email").MapTo(&Email); err != nil {
 		return errors.Wrap(err, "mapping [email] section")
 	}
-	// LEGACY [0.13]: In case there are values with old section name.
-	if err = File.Section("mailer").MapTo(&Email); err != nil {
-		return errors.Wrap(err, "mapping [mailer] section")
-	}
 
 	if Email.Enabled {
 		if Email.From == "" {
@@ -238,10 +234,6 @@ func Init(customConf string) error {
 	if err = File.Section("auth").MapTo(&Auth); err != nil {
 		return errors.Wrap(err, "mapping [auth] section")
 	}
-	// LEGACY [0.13]: In case there are values with old section name.
-	if err = File.Section("service").MapTo(&Auth); err != nil {
-		return errors.Wrap(err, "mapping [service] section")
-	}
 
 	// *************************
 	// ----- User settings -----

+ 1 - 1
internal/conf/log.go

@@ -32,7 +32,7 @@ var Log *logConf
 // argument "hookMode" is true, it only initializes the root path for log files.
 // NOTE: Because we always create a console logger as the primary logger at init time,
 // we need to remove it in case the user doesn't configure to use it after the logging
-// service is initalized.
+// service is initialized.
 func initLogConf(cfg *ini.File, hookMode bool) (_ *logConf, hasConsole bool, _ error) {
 	rootPath := cfg.Section("log").Key("ROOT_PATH").MustString(filepath.Join(WorkDir(), "log"))
 	if hookMode {

+ 7 - 97
internal/conf/static.go

@@ -41,9 +41,6 @@ var (
 		BrandName string
 		RunUser   string
 		RunMode   string
-
-		// Deprecated: Use BrandName instead, will be removed in 0.13.
-		AppName string
 	}
 
 	// SSH settings
@@ -62,6 +59,7 @@ var (
 		ListenHost         string   `ini:"SSH_LISTEN_HOST"`
 		ListenPort         int      `ini:"SSH_LISTEN_PORT"`
 		ServerCiphers      []string `ini:"SSH_SERVER_CIPHERS"`
+		ServerMACs         []string `ini:"SSH_SERVER_MACS"`
 	}
 
 	// Repository settings
@@ -103,9 +101,6 @@ var (
 		CookieSecure            bool
 		EnableLoginStatusCookie bool
 		LoginStatusCookieName   string
-
-		// Deprecated: Use Auth.ReverseProxyAuthenticationHeader instead, will be removed in 0.13.
-		ReverseProxyAuthenticationUser string
 	}
 
 	// Email settings
@@ -130,9 +125,6 @@ var (
 
 		// Derived from other static values
 		FromEmail string `ini:"-"` // Parsed email address of From without person's name.
-
-		// Deprecated: Use Password instead, will be removed in 0.13.
-		Passwd string
 	}
 
 	// Authentication settings
@@ -147,17 +139,6 @@ var (
 		EnableReverseProxyAuthentication   bool
 		EnableReverseProxyAutoRegistration bool
 		ReverseProxyAuthenticationHeader   string
-
-		// Deprecated: Use ActivateCodeLives instead, will be removed in 0.13.
-		ActiveCodeLiveMinutes int
-		// Deprecated: Use ResetPasswordCodeLives instead, will be removed in 0.13.
-		ResetPasswdCodeLiveMinutes int
-		// Deprecated: Use RequireEmailConfirmation instead, will be removed in 0.13.
-		RegisterEmailConfirm bool
-		// Deprecated: Use EnableRegistrationCaptcha instead, will be removed in 0.13.
-		EnableCaptcha bool
-		// Deprecated: Use User.EnableEmailNotification instead, will be removed in 0.13.
-		EnableNotifyMail bool
 	}
 
 	// User settings
@@ -174,11 +155,6 @@ var (
 		GCInterval     int64 `ini:"GC_INTERVAL"`
 		MaxLifeTime    int64
 		CSRFCookieName string `ini:"CSRF_COOKIE_NAME"`
-
-		// Deprecated: Use GCInterval instead, will be removed in 0.13.
-		GCIntervalTime int64 `ini:"GC_INTERVAL_TIME"`
-		// Deprecated: Use MaxLifeTime instead, will be removed in 0.13.
-		SessionLifeTime int64
 	}
 
 	// Cache settings
@@ -308,6 +284,7 @@ var (
 			Mirror  int
 			Clone   int
 			Pull    int
+			Diff    int
 			GC      int `ini:"GC"`
 		} `ini:"git.timeout"`
 	}
@@ -382,11 +359,6 @@ type ServerOpts struct {
 	Subpath        string      `ini:"-"` // Subpath found the ExternalURL. Should be empty when not found.
 	SubpathDepth   int         `ini:"-"` // The number of slashes found in the Subpath.
 	UnixSocketMode os.FileMode `ini:"-"` // Parsed file mode of UnixSocketPermission.
-
-	// Deprecated: Use ExternalURL instead, will be removed in 0.13.
-	RootURL string `ini:"ROOT_URL"`
-	// Deprecated: Use LandingURL instead, will be removed in 0.13.
-	LangdingPage string `ini:"LANDING_PAGE"`
 }
 
 // Server settings
@@ -402,11 +374,6 @@ type DatabaseOpts struct {
 	Path         string
 	MaxOpenConns int
 	MaxIdleConns int
-
-	// Deprecated: Use Type instead, will be removed in 0.13.
-	DbType string
-	// Deprecated: Use Password instead, will be removed in 0.13.
-	Passwd string
 }
 
 // Database settings
@@ -440,68 +407,11 @@ var I18n *i18nConf
 
 // handleDeprecated transfers deprecated values to the new ones when set.
 func handleDeprecated() {
-	if App.AppName != "" {
-		App.BrandName = App.AppName
-		App.AppName = ""
-	}
-
-	if Server.RootURL != "" {
-		Server.ExternalURL = Server.RootURL
-		Server.RootURL = ""
-	}
-	if Server.LangdingPage == "explore" {
-		Server.LandingURL = "/explore"
-		Server.LangdingPage = ""
-	}
-
-	if Database.DbType != "" {
-		Database.Type = Database.DbType
-		Database.DbType = ""
-	}
-	if Database.Passwd != "" {
-		Database.Password = Database.Passwd
-		Database.Passwd = ""
-	}
-
-	if Email.Passwd != "" {
-		Email.Password = Email.Passwd
-		Email.Passwd = ""
-	}
-
-	if Auth.ActiveCodeLiveMinutes > 0 {
-		Auth.ActivateCodeLives = Auth.ActiveCodeLiveMinutes
-		Auth.ActiveCodeLiveMinutes = 0
-	}
-	if Auth.ResetPasswdCodeLiveMinutes > 0 {
-		Auth.ResetPasswordCodeLives = Auth.ResetPasswdCodeLiveMinutes
-		Auth.ResetPasswdCodeLiveMinutes = 0
-	}
-	if Auth.RegisterEmailConfirm {
-		Auth.RequireEmailConfirmation = true
-		Auth.RegisterEmailConfirm = false
-	}
-	if Auth.EnableCaptcha {
-		Auth.EnableRegistrationCaptcha = true
-		Auth.EnableCaptcha = false
-	}
-	if Security.ReverseProxyAuthenticationUser != "" {
-		Auth.ReverseProxyAuthenticationHeader = Security.ReverseProxyAuthenticationUser
-		Security.ReverseProxyAuthenticationUser = ""
-	}
-
-	if Auth.EnableNotifyMail {
-		User.EnableEmailNotification = true
-		Auth.EnableNotifyMail = false
-	}
-
-	if Session.GCIntervalTime > 0 {
-		Session.GCInterval = Session.GCIntervalTime
-		Session.GCIntervalTime = 0
-	}
-	if Session.SessionLifeTime > 0 {
-		Session.MaxLifeTime = Session.SessionLifeTime
-		Session.SessionLifeTime = 0
-	}
+	// Add fallback logic here, example:
+	// if App.AppName != "" {
+	// 	App.BrandName = App.AppName
+	// 	App.AppName = ""
+	// }
 }
 
 // HookMode indicates whether program starts as Git server-side hook callback.

+ 4 - 17
internal/conf/testdata/TestInit.golden.ini

@@ -1,7 +1,6 @@
 BRAND_NAME=Testing
 RUN_USER=git
 RUN_MODE=test
-APP_NAME=
 
 [server]
 EXTERNAL_URL=http://localhost:3080/
@@ -20,8 +19,6 @@ ENABLE_GZIP=false
 APP_DATA_PATH=/tmp/data
 LOAD_ASSETS_FROM_DISK=false
 LANDING_URL=/explore
-ROOT_URL=
-LANDING_PAGE=
 DISABLE_SSH=false
 SSH_DOMAIN=localhost
 SSH_PORT=22
@@ -34,6 +31,7 @@ START_SSH_SERVER=false
 SSH_LISTEN_HOST=0.0.0.0
 SSH_LISTEN_PORT=22
 SSH_SERVER_CIPHERS=aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,arcfour256,arcfour128
+SSH_SERVER_MACS=hmac-sha2-256-etm@openssh.com,hmac-sha2-256,hmac-sha1
 
 [repository]
 ROOT=/tmp/gogs-repositories
@@ -68,8 +66,6 @@ SSL_MODE=disable
 PATH=/tmp/gogs.db
 MAX_OPEN_CONNS=30
 MAX_IDLE_CONNS=30
-DB_TYPE=
-PASSWD=
 
 [security]
 INSTALL_LOCK=false
@@ -80,11 +76,10 @@ COOKIE_USERNAME=gogs_awesome
 COOKIE_SECURE=false
 ENABLE_LOGIN_STATUS_COOKIE=false
 LOGIN_STATUS_COOKIE_NAME=login_status
-REVERSE_PROXY_AUTHENTICATION_USER=
 
 [email]
 ENABLED=true
-SUBJECT_PREFIX=[Gogs] 
+SUBJECT_PREFIX="[Testing] "
 HOST=smtp.mailgun.org:587
 FROM=noreply@gogs.localhost
 USER=noreply@gogs.localhost
@@ -97,7 +92,6 @@ CERT_FILE=custom/email/cert.pem
 KEY_FILE=custom/email/key.pem
 USE_PLAIN_TEXT=false
 ADD_PLAIN_TEXT_ALT=false
-PASSWD=
 
 [auth]
 ACTIVATE_CODE_LIVES=10
@@ -109,11 +103,6 @@ ENABLE_REGISTRATION_CAPTCHA=true
 ENABLE_REVERSE_PROXY_AUTHENTICATION=false
 ENABLE_REVERSE_PROXY_AUTO_REGISTRATION=false
 REVERSE_PROXY_AUTHENTICATION_HEADER=X-FORWARDED-FOR
-ACTIVE_CODE_LIVE_MINUTES=0
-RESET_PASSWD_CODE_LIVE_MINUTES=0
-REGISTER_EMAIL_CONFIRM=false
-ENABLE_CAPTCHA=false
-ENABLE_NOTIFY_MAIL=false
 
 [user]
 ENABLE_EMAIL_NOTIFICATION=true
@@ -126,8 +115,6 @@ COOKIE_SECURE=false
 GC_INTERVAL=10
 MAX_LIFE_TIME=10
 CSRF_COOKIE_NAME=_csrf
-GC_INTERVAL_TIME=0
-SESSION_LIFE_TIME=0
 
 [attachment]
 ENABLED=true
@@ -150,6 +137,6 @@ ENABLE_FEDERATED_AVATAR=false
 DEFAULT_INTERVAL=8
 
 [i18n]
-LANGS=en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,gl-ES,uk-UA,en-GB,hu-HU,sk-SK,id-ID,fa-IR,vi-VN,pt-PT
-NAMES=English,简体中文,繁體中文(香港),繁體中文(臺灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,galego,українська,English (United Kingdom),Magyar,Slovenčina,Indonesian,Persian,Vietnamese,Português
+LANGS=en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,gl-ES,uk-UA,en-GB,hu-HU,sk-SK,id-ID,fa-IR,vi-VN,pt-PT,mn-MN
+NAMES=English,简体中文,繁體中文(香港),繁體中文(臺灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,galego,українська,English (United Kingdom),Magyar,Slovenčina,Indonesian,Persian,Vietnamese,Português,Монгол
 

+ 15 - 14
internal/conf/testdata/custom.ini

@@ -1,13 +1,13 @@
-APP_NAME = Testing
+BRAND_NAME = Testing
 RUN_MODE = test
 
 [server]
-ROOT_URL = http://localhost:3080/
+EXTERNAL_URL = http://localhost:3080/
 APP_DATA_PATH = /tmp/data
 SSH_ROOT_PATH = /tmp
 SSH_KEY_TEST_PATH = /tmp/ssh-key-test
 MINIMUM_KEY_SIZE_CHECK = true
-LANDING_PAGE = explore
+LANDING_URL = /explore
 
 [repository]
 ROOT = /tmp/gogs-repositories
@@ -16,27 +16,28 @@ ROOT = /tmp/gogs-repositories
 TEMP_PATH = /tmp/uploads
 
 [database]
-DB_TYPE = sqlite
-PASSWD = 12345678
+TYPE = sqlite
+PASSWORD = 12345678
 PATH = /tmp/gogs.db
 
-[security]
-REVERSE_PROXY_AUTHENTICATION_USER=X-FORWARDED-FOR
-
 [email]
 ENABLED = true
-PASSWD = 87654321
+PASSWORD = 87654321
 
 [auth]
-ACTIVE_CODE_LIVE_MINUTES = 10
-RESET_PASSWD_CODE_LIVE_MINUTES = 10
-REGISTER_EMAIL_CONFIRM = true
+ACTIVATE_CODE_LIVES = 10
+RESET_PASSWORD_CODE_LIVES = 10
+REQUIRE_EMAIL_CONFIRMATION = true
 ENABLE_CAPTCHA = true
 ENABLE_NOTIFY_MAIL = true
+REVERSE_PROXY_AUTHENTICATION_HEADER=X-FORWARDED-FOR
+
+[user]
+ENABLE_EMAIL_NOTIFICATION = true
 
 [session]
-GC_INTERVAL_TIME = 10
-SESSION_LIFE_TIME = 10
+GC_INTERVAL = 10
+MAX_LIFE_TIME = 10
 
 [attachment]
 PATH = /tmp/attachments

+ 139 - 3
internal/context/auth.go

@@ -7,12 +7,18 @@ package context
 import (
 	"net/http"
 	"net/url"
+	"strings"
 
 	"github.com/go-macaron/csrf"
+	"github.com/go-macaron/session"
+	gouuid "github.com/satori/go.uuid"
 	"gopkg.in/macaron.v1"
+	log "unknwon.dev/clog/v2"
 
 	"gogs.io/gogs/internal/auth"
 	"gogs.io/gogs/internal/conf"
+	"gogs.io/gogs/internal/db"
+	"gogs.io/gogs/internal/tool"
 )
 
 type ToggleOptions struct {
@@ -49,7 +55,7 @@ func Toggle(options *ToggleOptions) macaron.Handler {
 			return
 		}
 
-		if !options.SignOutRequired && !options.DisableCSRF && c.Req.Method == "POST" && !auth.IsAPIPath(c.Req.URL.Path) {
+		if !options.SignOutRequired && !options.DisableCSRF && c.Req.Method == "POST" && !isAPIPath(c.Req.URL.Path) {
 			csrf.Validate(c.Context, c.csrf)
 			if c.Written() {
 				return
@@ -59,7 +65,7 @@ func Toggle(options *ToggleOptions) macaron.Handler {
 		if options.SignInRequired {
 			if !c.IsLogged {
 				// Restrict API calls with error message.
-				if auth.IsAPIPath(c.Req.URL.Path) {
+				if isAPIPath(c.Req.URL.Path) {
 					c.JSON(http.StatusForbidden, map[string]string{
 						"message": "Only authenticated user is allowed to call APIs.",
 					})
@@ -77,7 +83,7 @@ func Toggle(options *ToggleOptions) macaron.Handler {
 		}
 
 		// Redirect to log in page if auto-signin info is provided and has not signed in.
-		if !options.SignOutRequired && !c.IsLogged && !auth.IsAPIPath(c.Req.URL.Path) &&
+		if !options.SignOutRequired && !c.IsLogged && !isAPIPath(c.Req.URL.Path) &&
 			len(c.GetCookie(conf.Security.CookieUsername)) > 0 {
 			c.SetCookie("redirect_to", url.QueryEscape(conf.Server.Subpath+c.Req.RequestURI), 0, conf.Server.Subpath)
 			c.RedirectSubpath("/user/login")
@@ -93,3 +99,133 @@ func Toggle(options *ToggleOptions) macaron.Handler {
 		}
 	}
 }
+
+func isAPIPath(url string) bool {
+	return strings.HasPrefix(url, "/api/")
+}
+
+// authenticatedUserID returns the ID of the authenticated user, along with a bool value
+// which indicates whether the user uses token authentication.
+func authenticatedUserID(c *macaron.Context, sess session.Store) (_ int64, isTokenAuth bool) {
+	if !db.HasEngine {
+		return 0, false
+	}
+
+	// Check access token.
+	if isAPIPath(c.Req.URL.Path) {
+		tokenSHA := c.Query("token")
+		if len(tokenSHA) <= 0 {
+			tokenSHA = c.Query("access_token")
+		}
+		if len(tokenSHA) == 0 {
+			// Well, check with header again.
+			auHead := c.Req.Header.Get("Authorization")
+			if len(auHead) > 0 {
+				auths := strings.Fields(auHead)
+				if len(auths) == 2 && auths[0] == "token" {
+					tokenSHA = auths[1]
+				}
+			}
+		}
+
+		// Let's see if token is valid.
+		if len(tokenSHA) > 0 {
+			t, err := db.AccessTokens.GetBySHA(tokenSHA)
+			if err != nil {
+				if !db.IsErrAccessTokenNotExist(err) {
+					log.Error("GetAccessTokenBySHA: %v", err)
+				}
+				return 0, false
+			}
+			if err = db.AccessTokens.Save(t); err != nil {
+				log.Error("UpdateAccessToken: %v", err)
+			}
+			return t.UserID, true
+		}
+	}
+
+	uid := sess.Get("uid")
+	if uid == nil {
+		return 0, false
+	}
+	if id, ok := uid.(int64); ok {
+		if _, err := db.GetUserByID(id); err != nil {
+			if !db.IsErrUserNotExist(err) {
+				log.Error("Failed to get user by ID: %v", err)
+			}
+			return 0, false
+		}
+		return id, false
+	}
+	return 0, false
+}
+
+// authenticatedUser returns the user object of the authenticated user, along with two bool values
+// which indicate whether the user uses HTTP Basic Authentication or token authentication respectively.
+func authenticatedUser(ctx *macaron.Context, sess session.Store) (_ *db.User, isBasicAuth bool, isTokenAuth bool) {
+	if !db.HasEngine {
+		return nil, false, false
+	}
+
+	uid, isTokenAuth := authenticatedUserID(ctx, sess)
+
+	if uid <= 0 {
+		if conf.Auth.EnableReverseProxyAuthentication {
+			webAuthUser := ctx.Req.Header.Get(conf.Auth.ReverseProxyAuthenticationHeader)
+			if len(webAuthUser) > 0 {
+				u, err := db.GetUserByName(webAuthUser)
+				if err != nil {
+					if !db.IsErrUserNotExist(err) {
+						log.Error("Failed to get user by name: %v", err)
+						return nil, false, false
+					}
+
+					// Check if enabled auto-registration.
+					if conf.Auth.EnableReverseProxyAutoRegistration {
+						u := &db.User{
+							Name:     webAuthUser,
+							Email:    gouuid.NewV4().String() + "@localhost",
+							Passwd:   webAuthUser,
+							IsActive: true,
+						}
+						if err = db.CreateUser(u); err != nil {
+							// FIXME: should I create a system notice?
+							log.Error("Failed to create user: %v", err)
+							return nil, false, false
+						} else {
+							return u, false, false
+						}
+					}
+				}
+				return u, false, false
+			}
+		}
+
+		// Check with basic auth.
+		baHead := ctx.Req.Header.Get("Authorization")
+		if len(baHead) > 0 {
+			auths := strings.Fields(baHead)
+			if len(auths) == 2 && auths[0] == "Basic" {
+				uname, passwd, _ := tool.BasicAuthDecode(auths[1])
+
+				u, err := db.Users.Authenticate(uname, passwd, -1)
+				if err != nil {
+					if !auth.IsErrBadCredentials(err) {
+						log.Error("Failed to authenticate user: %v", err)
+					}
+					return nil, false, false
+				}
+
+				return u, true, false
+			}
+		}
+		return nil, false, false
+	}
+
+	u, err := db.GetUserByID(uid)
+	if err != nil {
+		log.Error("GetUserByID: %v", err)
+		return nil, false, false
+	}
+	return u, false, isTokenAuth
+}

+ 3 - 3
internal/context/context.go

@@ -18,7 +18,6 @@ import (
 	"gopkg.in/macaron.v1"
 	log "unknwon.dev/clog/v2"
 
-	"gogs.io/gogs/internal/auth"
 	"gogs.io/gogs/internal/conf"
 	"gogs.io/gogs/internal/db"
 	"gogs.io/gogs/internal/errutil"
@@ -249,13 +248,13 @@ func Contexter() macaron.Handler {
 
 		if len(conf.HTTP.AccessControlAllowOrigin) > 0 {
 			c.Header().Set("Access-Control-Allow-Origin", conf.HTTP.AccessControlAllowOrigin)
-			c.Header().Set("'Access-Control-Allow-Credentials' ", "true")
+			c.Header().Set("Access-Control-Allow-Credentials", "true")
 			c.Header().Set("Access-Control-Max-Age", "3600")
 			c.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")
 		}
 
 		// Get user from session or header when possible
-		c.User, c.IsBasicAuth, c.IsTokenAuth = auth.SignedInUser(c.Context, c.Session)
+		c.User, c.IsBasicAuth, c.IsTokenAuth = authenticatedUser(c.Context, c.Session)
 
 		if c.User != nil {
 			c.IsLogged = true
@@ -290,6 +289,7 @@ func Contexter() macaron.Handler {
 		// 🚨 SECURITY: Prevent MIME type sniffing in some browsers,
 		// see https://github.com/gogs/gogs/issues/5397 for details.
 		c.Header().Set("X-Content-Type-Options", "nosniff")
+		c.Header().Set("X-Frame-Options", "DENY")
 
 		ctx.Map(c)
 	}

+ 16 - 14
internal/context/repo.go

@@ -170,22 +170,24 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 		if c.IsLogged && c.User.IsAdmin {
 			c.Repo.AccessMode = db.AccessModeOwner
 		} else {
-			mode, err := db.UserAccessMode(c.UserID(), c.Repo.Repository)
-			if err != nil {
-				c.Error(err, "get user access mode")
-				return
-			}
-			c.Repo.AccessMode = mode
+			c.Repo.AccessMode = db.Perms.AccessMode(c.UserID(), repo.ID,
+				db.AccessModeOptions{
+					OwnerID: repo.OwnerID,
+					Private: repo.IsPrivate,
+				},
+			)
 		}
 
 		// If the authenticated user has no direct access, see if the repository is a fork
 		// and whether the user has access to the base repository.
-		if c.Repo.AccessMode == db.AccessModeNone && c.Repo.Repository.IsFork {
-			mode, err := db.UserAccessMode(c.UserID(), c.Repo.Repository.BaseRepo)
-			if err != nil {
-				c.Error(err, "get user access mode of base repository")
-				return
-			}
+		if c.Repo.AccessMode == db.AccessModeNone && repo.BaseRepo != nil {
+			mode := db.Perms.AccessMode(c.UserID(), repo.BaseRepo.ID,
+				db.AccessModeOptions{
+					OwnerID: repo.BaseRepo.OwnerID,
+					Private: repo.BaseRepo.IsPrivate,
+				},
+			)
+
 			// Users shouldn't have indirect access level higher than write.
 			if mode > db.AccessModeWrite {
 				mode = db.AccessModeWrite
@@ -278,7 +280,7 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 			return
 		}
 		c.Data["Branches"] = branches
-		c.Data["BrancheCount"] = len(branches)
+		c.Data["BranchCount"] = len(branches)
 
 		// If not branch selected, try default one.
 		// If default branch doesn't exists, fall back to some other branch.
@@ -399,7 +401,7 @@ func RepoRef() macaron.Handler {
 		c.Data["IsViewTag"] = c.Repo.IsViewTag
 		c.Data["IsViewCommit"] = c.Repo.IsViewCommit
 
-		// People who have push access or have fored repository can propose a new pull request.
+		// People who have push access or have forked repository can propose a new pull request.
 		if c.Repo.IsWriter() || (c.IsLogged && c.User.HasForkedRepo(c.Repo.Repository.ID)) {
 			// Pull request is allowed if this is a fork repository
 			// and base repository accepts pull requests.

+ 1 - 1
internal/cron/cron.go

@@ -11,8 +11,8 @@ import (
 
 	"github.com/gogs/cron"
 
-	"gogs.io/gogs/internal/db"
 	"gogs.io/gogs/internal/conf"
+	"gogs.io/gogs/internal/db"
 )
 
 var c = cron.New()

+ 0 - 240
internal/db/access.go

@@ -1,240 +0,0 @@
-// Copyright 2014 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package db
-
-import (
-	"fmt"
-
-	log "unknwon.dev/clog/v2"
-)
-
-type AccessMode int
-
-const (
-	AccessModeNone  AccessMode = iota // 0
-	AccessModeRead                    // 1
-	AccessModeWrite                   // 2
-	AccessModeAdmin                   // 3
-	AccessModeOwner                   // 4
-)
-
-func (mode AccessMode) String() string {
-	switch mode {
-	case AccessModeRead:
-		return "read"
-	case AccessModeWrite:
-		return "write"
-	case AccessModeAdmin:
-		return "admin"
-	case AccessModeOwner:
-		return "owner"
-	default:
-		return "none"
-	}
-}
-
-// ParseAccessMode returns corresponding access mode to given permission string.
-func ParseAccessMode(permission string) AccessMode {
-	switch permission {
-	case "write":
-		return AccessModeWrite
-	case "admin":
-		return AccessModeAdmin
-	default:
-		return AccessModeRead
-	}
-}
-
-// Access represents the highest access level of a user to a repository. The only access type
-// that is not in this table is the real owner of a repository. In case of an organization
-// repository, the members of the owners team are in this table.
-type Access struct {
-	ID     int64
-	UserID int64 `xorm:"UNIQUE(s)"`
-	RepoID int64 `xorm:"UNIQUE(s)"`
-	Mode   AccessMode
-}
-
-func userAccessMode(e Engine, userID int64, repo *Repository) (AccessMode, error) {
-	mode := AccessModeNone
-	// Everyone has read access to public repository
-	if !repo.IsPrivate {
-		mode = AccessModeRead
-	}
-
-	if userID <= 0 {
-		return mode, nil
-	}
-
-	if userID == repo.OwnerID {
-		return AccessModeOwner, nil
-	}
-
-	access := &Access{
-		UserID: userID,
-		RepoID: repo.ID,
-	}
-	if has, err := e.Get(access); !has || err != nil {
-		return mode, err
-	}
-	return access.Mode, nil
-}
-
-// UserAccessMode returns the access mode of given user to the repository.
-func UserAccessMode(userID int64, repo *Repository) (AccessMode, error) {
-	return userAccessMode(x, userID, repo)
-}
-
-func hasAccess(e Engine, userID int64, repo *Repository, testMode AccessMode) (bool, error) {
-	mode, err := userAccessMode(e, userID, repo)
-	return mode >= testMode, err
-}
-
-// HasAccess returns true if someone has the request access level. User can be nil!
-// Deprecated: Use Perms.Authorize instead.
-func HasAccess(userID int64, repo *Repository, testMode AccessMode) (bool, error) {
-	return hasAccess(x, userID, repo, testMode)
-}
-
-// GetRepositoryAccesses finds all repositories with their access mode where a user has access but does not own.
-func (u *User) GetRepositoryAccesses() (map[*Repository]AccessMode, error) {
-	accesses := make([]*Access, 0, 10)
-	if err := x.Find(&accesses, &Access{UserID: u.ID}); err != nil {
-		return nil, err
-	}
-
-	repos := make(map[*Repository]AccessMode, len(accesses))
-	for _, access := range accesses {
-		repo, err := GetRepositoryByID(access.RepoID)
-		if err != nil {
-			if IsErrRepoNotExist(err) {
-				log.Error("Failed to get repository by ID: %v", err)
-				continue
-			}
-			return nil, err
-		}
-		if repo.OwnerID == u.ID {
-			continue
-		}
-		repos[repo] = access.Mode
-	}
-	return repos, nil
-}
-
-// GetAccessibleRepositories finds repositories which the user has access but does not own.
-// If limit is smaller than 1 means returns all found results.
-func (user *User) GetAccessibleRepositories(limit int) (repos []*Repository, _ error) {
-	sess := x.Where("owner_id !=? ", user.ID).Desc("updated_unix")
-	if limit > 0 {
-		sess.Limit(limit)
-		repos = make([]*Repository, 0, limit)
-	} else {
-		repos = make([]*Repository, 0, 10)
-	}
-	return repos, sess.Join("INNER", "access", "access.user_id = ? AND access.repo_id = repository.id", user.ID).Find(&repos)
-}
-
-func maxAccessMode(modes ...AccessMode) AccessMode {
-	max := AccessModeNone
-	for _, mode := range modes {
-		if mode > max {
-			max = mode
-		}
-	}
-	return max
-}
-
-// Deprecated: Use Perms.SetRepoPerms instead.
-func (repo *Repository) refreshAccesses(e Engine, accessMap map[int64]AccessMode) (err error) {
-	newAccesses := make([]Access, 0, len(accessMap))
-	for userID, mode := range accessMap {
-		newAccesses = append(newAccesses, Access{
-			UserID: userID,
-			RepoID: repo.ID,
-			Mode:   mode,
-		})
-	}
-
-	// Delete old accesses and insert new ones for repository.
-	if _, err = e.Delete(&Access{RepoID: repo.ID}); err != nil {
-		return fmt.Errorf("delete old accesses: %v", err)
-	} else if _, err = e.Insert(newAccesses); err != nil {
-		return fmt.Errorf("insert new accesses: %v", err)
-	}
-	return nil
-}
-
-// refreshCollaboratorAccesses retrieves repository collaborations with their access modes.
-func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int64]AccessMode) error {
-	collaborations, err := repo.getCollaborations(e)
-	if err != nil {
-		return fmt.Errorf("getCollaborations: %v", err)
-	}
-	for _, c := range collaborations {
-		accessMap[c.UserID] = c.Mode
-	}
-	return nil
-}
-
-// recalculateTeamAccesses recalculates new accesses for teams of an organization
-// except the team whose ID is given. It is used to assign a team ID when
-// remove repository from that team.
-func (repo *Repository) recalculateTeamAccesses(e Engine, ignTeamID int64) (err error) {
-	accessMap := make(map[int64]AccessMode, 20)
-
-	if err = repo.getOwner(e); err != nil {
-		return err
-	} else if !repo.Owner.IsOrganization() {
-		return fmt.Errorf("owner is not an organization: %d", repo.OwnerID)
-	}
-
-	if err = repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
-		return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
-	}
-
-	if err = repo.Owner.getTeams(e); err != nil {
-		return err
-	}
-
-	for _, t := range repo.Owner.Teams {
-		if t.ID == ignTeamID {
-			continue
-		}
-
-		// Owner team gets owner access, and skip for teams that do not
-		// have relations with repository.
-		if t.IsOwnerTeam() {
-			t.Authorize = AccessModeOwner
-		} else if !t.hasRepository(e, repo.ID) {
-			continue
-		}
-
-		if err = t.getMembers(e); err != nil {
-			return fmt.Errorf("getMembers '%d': %v", t.ID, err)
-		}
-		for _, m := range t.Members {
-			accessMap[m.ID] = maxAccessMode(accessMap[m.ID], t.Authorize)
-		}
-	}
-
-	return repo.refreshAccesses(e, accessMap)
-}
-
-func (repo *Repository) recalculateAccesses(e Engine) error {
-	if repo.Owner.IsOrganization() {
-		return repo.recalculateTeamAccesses(e, 0)
-	}
-
-	accessMap := make(map[int64]AccessMode, 10)
-	if err := repo.refreshCollaboratorAccesses(e, accessMap); err != nil {
-		return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
-	}
-	return repo.refreshAccesses(e, accessMap)
-}
-
-// RecalculateAccesses recalculates all accesses for repository.
-func (repo *Repository) RecalculateAccesses() error {
-	return repo.recalculateAccesses(x)
-}

+ 13 - 11
internal/db/access_tokens.go

@@ -8,8 +8,8 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/jinzhu/gorm"
 	gouuid "github.com/satori/go.uuid"
+	"gorm.io/gorm"
 
 	"gogs.io/gogs/internal/cryptoutil"
 	"gogs.io/gogs/internal/errutil"
@@ -55,24 +55,26 @@ type AccessToken struct {
 }
 
 // NOTE: This is a GORM create hook.
-func (t *AccessToken) BeforeCreate() {
-	if t.CreatedUnix > 0 {
-		return
+func (t *AccessToken) BeforeCreate(tx *gorm.DB) error {
+	if t.CreatedUnix == 0 {
+		t.CreatedUnix = tx.NowFunc().Unix()
 	}
-	t.CreatedUnix = gorm.NowFunc().Unix()
+	return nil
 }
 
 // NOTE: This is a GORM update hook.
-func (t *AccessToken) BeforeUpdate() {
-	t.UpdatedUnix = gorm.NowFunc().Unix()
+func (t *AccessToken) BeforeUpdate(tx *gorm.DB) error {
+	t.UpdatedUnix = tx.NowFunc().Unix()
+	return nil
 }
 
 // NOTE: This is a GORM query hook.
-func (t *AccessToken) AfterFind() {
+func (t *AccessToken) AfterFind(tx *gorm.DB) error {
 	t.Created = time.Unix(t.CreatedUnix, 0).Local()
 	t.Updated = time.Unix(t.UpdatedUnix, 0).Local()
 	t.HasUsed = t.Updated.After(t.Created)
-	t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(gorm.NowFunc())
+	t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(tx.NowFunc())
+	return nil
 }
 
 var _ AccessTokensStore = (*accessTokens)(nil)
@@ -98,7 +100,7 @@ func (db *accessTokens) Create(userID int64, name string) (*AccessToken, error)
 	err := db.Where("uid = ? AND name = ?", userID, name).First(new(AccessToken)).Error
 	if err == nil {
 		return nil, ErrAccessTokenAlreadyExist{args: errutil.Args{"userID": userID, "name": name}}
-	} else if !gorm.IsRecordNotFoundError(err) {
+	} else if err != gorm.ErrRecordNotFound {
 		return nil, err
 	}
 
@@ -137,7 +139,7 @@ func (db *accessTokens) GetBySHA(sha string) (*AccessToken, error) {
 	token := new(AccessToken)
 	err := db.Where("sha1 = ?", sha).First(token).Error
 	if err != nil {
-		if gorm.IsRecordNotFoundError(err) {
+		if err == gorm.ErrRecordNotFound {
 			return nil, ErrAccessTokenNotExist{args: errutil.Args{"sha": sha}}
 		}
 		return nil, err

+ 15 - 6
internal/db/access_tokens_test.go

@@ -8,24 +8,33 @@ import (
 	"testing"
 	"time"
 
-	"github.com/jinzhu/gorm"
 	"github.com/stretchr/testify/assert"
+	"gorm.io/gorm"
 
 	"gogs.io/gogs/internal/errutil"
 )
 
 func TestAccessToken_BeforeCreate(t *testing.T) {
+	now := time.Now()
+	db := &gorm.DB{
+		Config: &gorm.Config{
+			NowFunc: func() time.Time {
+				return now
+			},
+		},
+	}
+
 	t.Run("CreatedUnix has been set", func(t *testing.T) {
 		token := &AccessToken{CreatedUnix: 1}
-		token.BeforeCreate()
+		_ = token.BeforeCreate(db)
 		assert.Equal(t, int64(1), token.CreatedUnix)
 		assert.Equal(t, int64(0), token.UpdatedUnix)
 	})
 
 	t.Run("CreatedUnix has not been set", func(t *testing.T) {
 		token := &AccessToken{}
-		token.BeforeCreate()
-		assert.Equal(t, gorm.NowFunc().Unix(), token.CreatedUnix)
+		_ = token.BeforeCreate(db)
+		assert.Equal(t, db.NowFunc().Unix(), token.CreatedUnix)
 		assert.Equal(t, int64(0), token.UpdatedUnix)
 	})
 }
@@ -80,7 +89,7 @@ func test_accessTokens_Create(t *testing.T, db *accessTokens) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	assert.Equal(t, gorm.NowFunc().Format(time.RFC3339), token.Created.UTC().Format(time.RFC3339))
+	assert.Equal(t, db.NowFunc().Format(time.RFC3339), token.Created.UTC().Format(time.RFC3339))
 
 	// Try create second access token with same name should fail
 	_, err = db.Create(token.UserID, token.Name)
@@ -193,5 +202,5 @@ func test_accessTokens_Save(t *testing.T, db *accessTokens) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	assert.Equal(t, gorm.NowFunc().Format(time.RFC3339), token.Updated.UTC().Format(time.RFC3339))
+	assert.Equal(t, db.NowFunc().Format(time.RFC3339), token.Updated.UTC().Format(time.RFC3339))
 }

+ 7 - 7
internal/db/action.go

@@ -11,7 +11,7 @@ import (
 	"time"
 	"unicode"
 
-	"github.com/json-iterator/go"
+	jsoniter "github.com/json-iterator/go"
 	"github.com/unknwon/com"
 	log "unknwon.dev/clog/v2"
 	"xorm.io/xorm"
@@ -188,7 +188,7 @@ func newRepoAction(e Engine, doer, owner *User, repo *Repository) (err error) {
 		RepoID:       repo.ID,
 		RepoUserName: repo.Owner.Name,
 		RepoName:     repo.Name,
-		IsPrivate:    repo.IsPrivate,
+		IsPrivate:    repo.IsPrivate || repo.IsUnlisted,
 	})
 }
 
@@ -205,7 +205,7 @@ func renameRepoAction(e Engine, actUser *User, oldRepoName string, repo *Reposit
 		RepoID:       repo.ID,
 		RepoUserName: repo.Owner.Name,
 		RepoName:     repo.Name,
-		IsPrivate:    repo.IsPrivate,
+		IsPrivate:    repo.IsPrivate || repo.IsUnlisted,
 		Content:      oldRepoName,
 	}); err != nil {
 		return fmt.Errorf("notify watchers: %v", err)
@@ -512,7 +512,7 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
 		RepoUserName: repo.MustOwner().Name,
 		RepoName:     repo.Name,
 		RefName:      refName,
-		IsPrivate:    repo.IsPrivate,
+		IsPrivate:    repo.IsPrivate || repo.IsUnlisted,
 	}
 
 	apiRepo := repo.APIFormat(nil)
@@ -628,7 +628,7 @@ func transferRepoAction(e Engine, doer, oldOwner *User, repo *Repository) (err e
 		RepoID:       repo.ID,
 		RepoUserName: repo.Owner.Name,
 		RepoName:     repo.Name,
-		IsPrivate:    repo.IsPrivate,
+		IsPrivate:    repo.IsPrivate || repo.IsUnlisted,
 		Content:      path.Join(oldOwner.Name, repo.Name),
 	}); err != nil {
 		return fmt.Errorf("notifyWatchers: %v", err)
@@ -659,7 +659,7 @@ func mergePullRequestAction(e Engine, doer *User, repo *Repository, issue *Issue
 		RepoID:       repo.ID,
 		RepoUserName: repo.Owner.Name,
 		RepoName:     repo.Name,
-		IsPrivate:    repo.IsPrivate,
+		IsPrivate:    repo.IsPrivate || repo.IsUnlisted,
 	})
 }
 
@@ -678,7 +678,7 @@ func mirrorSyncAction(opType ActionType, repo *Repository, refName string, data
 		RepoUserName: repo.MustOwner().Name,
 		RepoName:     repo.Name,
 		RefName:      refName,
-		IsPrivate:    repo.IsPrivate,
+		IsPrivate:    repo.IsPrivate || repo.IsUnlisted,
 	})
 }
 

+ 21 - 10
internal/db/backup.go

@@ -8,10 +8,12 @@ import (
 	"path/filepath"
 	"reflect"
 	"strings"
+	"sync"
 
-	"github.com/jinzhu/gorm"
 	jsoniter "github.com/json-iterator/go"
 	"github.com/pkg/errors"
+	"gorm.io/gorm"
+	"gorm.io/gorm/schema"
 	log "unknwon.dev/clog/v2"
 	"xorm.io/core"
 	"xorm.io/xorm"
@@ -38,7 +40,7 @@ func DumpDatabase(db *gorm.DB, dirPath string, verbose bool) error {
 		return errors.Wrap(err, "dump legacy tables")
 	}
 
-	for _, table := range tables {
+	for _, table := range Tables {
 		tableName := getTableType(table)
 		if verbose {
 			log.Trace("Dumping table %q...", tableName)
@@ -123,7 +125,7 @@ func ImportDatabase(db *gorm.DB, dirPath string, verbose bool) error {
 		return errors.Wrap(err, "import legacy tables")
 	}
 
-	for _, table := range tables {
+	for _, table := range Tables {
 		tableName := strings.TrimPrefix(fmt.Sprintf("%T", table), "*db.")
 		err := func() error {
 			tableFile := filepath.Join(dirPath, tableName+".json")
@@ -153,17 +155,21 @@ func ImportDatabase(db *gorm.DB, dirPath string, verbose bool) error {
 }
 
 func importTable(db *gorm.DB, table interface{}, r io.Reader) error {
-	err := db.DropTableIfExists(table).Error
+	err := db.Migrator().DropTable(table)
 	if err != nil {
 		return errors.Wrap(err, "drop table")
 	}
 
-	err = db.AutoMigrate(table).Error
+	err = db.Migrator().AutoMigrate(table)
 	if err != nil {
 		return errors.Wrap(err, "auto migrate")
 	}
 
-	rawTableName := db.NewScope(table).TableName()
+	s, err := schema.Parse(table, &sync.Map{}, db.NamingStrategy)
+	if err != nil {
+		return errors.Wrap(err, "parse schema")
+	}
+	rawTableName := s.Table
 	skipResetIDSeq := map[string]bool{
 		"lfs_object": true,
 	}
@@ -235,21 +241,26 @@ func importLegacyTables(dirPath string, verbose bool) error {
 				return fmt.Errorf("insert strcut: %v", err)
 			}
 
-			meta := make(map[string]interface{})
+			var meta struct {
+				ID             int64
+				CreatedUnix    int64
+				DeadlineUnix   int64
+				ClosedDateUnix int64
+			}
 			if err = jsoniter.Unmarshal(scanner.Bytes(), &meta); err != nil {
 				log.Error("Failed to unmarshal to map: %v", err)
 			}
 
 			// Reset created_unix back to the date save in archive because Insert method updates its value
 			if isInsertProcessor && !skipInsertProcessors[rawTableName] {
-				if _, err = x.Exec("UPDATE `"+rawTableName+"` SET created_unix=? WHERE id=?", meta["CreatedUnix"], meta["ID"]); err != nil {
-					log.Error("Failed to reset 'created_unix': %v", err)
+				if _, err = x.Exec("UPDATE `"+rawTableName+"` SET created_unix=? WHERE id=?", meta.CreatedUnix, meta.ID); err != nil {
+					log.Error("Failed to reset '%s.created_unix': %v", rawTableName, err)
 				}
 			}
 
 			switch rawTableName {
 			case "milestone":
-				if _, err = x.Exec("UPDATE `"+rawTableName+"` SET deadline_unix=?, closed_date_unix=? WHERE id=?", meta["DeadlineUnix"], meta["ClosedDateUnix"], meta["ID"]); err != nil {
+				if _, err = x.Exec("UPDATE `"+rawTableName+"` SET deadline_unix=?, closed_date_unix=? WHERE id=?", meta.DeadlineUnix, meta.ClosedDateUnix, meta.ID); err != nil {
 					log.Error("Failed to reset 'milestone.deadline_unix', 'milestone.closed_date_unix': %v", err)
 				}
 			}

+ 28 - 12
internal/db/backup_test.go

@@ -11,9 +11,12 @@ import (
 	"testing"
 	"time"
 
-	"github.com/jinzhu/gorm"
 	"github.com/pkg/errors"
+	"gorm.io/gorm"
 
+	"gogs.io/gogs/internal/auth"
+	"gogs.io/gogs/internal/auth/github"
+	"gogs.io/gogs/internal/auth/pam"
 	"gogs.io/gogs/internal/cryptoutil"
 	"gogs.io/gogs/internal/lfsutil"
 	"gogs.io/gogs/internal/testutil"
@@ -26,11 +29,11 @@ func Test_dumpAndImport(t *testing.T) {
 
 	t.Parallel()
 
-	if len(tables) != 3 {
-		t.Fatalf("New table has added (want 3 got %d), please add new tests for the table and update this check", len(tables))
+	if len(Tables) != 4 {
+		t.Fatalf("New table has added (want 4 got %d), please add new tests for the table and update this check", len(Tables))
 	}
 
-	db := initTestDB(t, "dumpAndImport", tables...)
+	db := initTestDB(t, "dumpAndImport", Tables...)
 	setupDBToDump(t, db)
 	dumpTables(t, db)
 	importTables(t, db)
@@ -43,6 +46,19 @@ func setupDBToDump(t *testing.T, db *gorm.DB) {
 	t.Helper()
 
 	vals := []interface{}{
+		&Access{
+			ID:     1,
+			UserID: 1,
+			RepoID: 11,
+			Mode:   AccessModeRead,
+		},
+		&Access{
+			ID:     2,
+			UserID: 2,
+			RepoID: 22,
+			Mode:   AccessModeWrite,
+		},
+
 		&AccessToken{
 			UserID:      1,
 			Name:        "test1",
@@ -79,22 +95,22 @@ func setupDBToDump(t *testing.T, db *gorm.DB) {
 		},
 
 		&LoginSource{
-			Type:      LoginPAM,
+			Type:      auth.PAM,
 			Name:      "My PAM",
 			IsActived: true,
-			Config: &PAMConfig{
+			Provider: pam.NewProvider(&pam.Config{
 				ServiceName: "PAM service",
-			},
+			}),
 			CreatedUnix: 1588568886,
 			UpdatedUnix: 1588572486, // 1 hour later
 		},
 		&LoginSource{
-			Type:      LoginGitHub,
+			Type:      auth.GitHub,
 			Name:      "GitHub.com",
 			IsActived: true,
-			Config: &GitHubConfig{
+			Provider: github.NewProvider(&github.Config{
 				APIEndpoint: "https://api.github.com",
-			},
+			}),
 			CreatedUnix: 1588568886,
 		},
 	}
@@ -109,7 +125,7 @@ func setupDBToDump(t *testing.T, db *gorm.DB) {
 func dumpTables(t *testing.T, db *gorm.DB) {
 	t.Helper()
 
-	for _, table := range tables {
+	for _, table := range Tables {
 		tableName := getTableType(table)
 
 		var buf bytes.Buffer
@@ -126,7 +142,7 @@ func dumpTables(t *testing.T, db *gorm.DB) {
 func importTables(t *testing.T, db *gorm.DB) {
 	t.Helper()
 
-	for _, table := range tables {
+	for _, table := range Tables {
 		tableName := getTableType(table)
 
 		err := func() error {

+ 75 - 43
internal/db/db.go

@@ -6,18 +6,19 @@ package db
 
 import (
 	"fmt"
-	"io"
 	"net/url"
 	"path/filepath"
 	"strings"
 	"time"
 
-	"github.com/jinzhu/gorm"
-	_ "github.com/jinzhu/gorm/dialects/mssql"
-	_ "github.com/jinzhu/gorm/dialects/mysql"
-	_ "github.com/jinzhu/gorm/dialects/postgres"
-	_ "github.com/jinzhu/gorm/dialects/sqlite"
 	"github.com/pkg/errors"
+	"gorm.io/driver/mysql"
+	"gorm.io/driver/postgres"
+	"gorm.io/driver/sqlite"
+	"gorm.io/driver/sqlserver"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+	"gorm.io/gorm/schema"
 	log "unknwon.dev/clog/v2"
 
 	"gogs.io/gogs/internal/conf"
@@ -96,16 +97,7 @@ func parseDSN(opts conf.DatabaseOpts) (dsn string, err error) {
 	return dsn, nil
 }
 
-func openDB(opts conf.DatabaseOpts) (*gorm.DB, error) {
-	dsn, err := parseDSN(opts)
-	if err != nil {
-		return nil, errors.Wrap(err, "parse DSN")
-	}
-
-	return gorm.Open(opts.Type, dsn)
-}
-
-func getLogWriter() (io.Writer, error) {
+func newLogWriter() (logger.Writer, error) {
 	sec := conf.File.Section("log.gorm")
 	w, err := log.NewFileWriter(
 		filepath.Join(conf.Log.RootPath, "gorm.log"),
@@ -119,62 +111,102 @@ func getLogWriter() (io.Writer, error) {
 	if err != nil {
 		return nil, errors.Wrap(err, `create "gorm.log"`)
 	}
-	return w, nil
+	return &dbutil.Logger{Writer: w}, nil
+}
+
+func openDB(opts conf.DatabaseOpts, cfg *gorm.Config) (*gorm.DB, error) {
+	dsn, err := parseDSN(opts)
+	if err != nil {
+		return nil, errors.Wrap(err, "parse DSN")
+	}
+
+	var dialector gorm.Dialector
+	switch opts.Type {
+	case "mysql":
+		dialector = mysql.Open(dsn)
+	case "postgres":
+		dialector = postgres.Open(dsn)
+	case "mssql":
+		dialector = sqlserver.Open(dsn)
+	case "sqlite3":
+		dialector = sqlite.Open(dsn)
+	default:
+		panic("unreachable")
+	}
+
+	return gorm.Open(dialector, cfg)
 }
 
+// Tables is the list of struct-to-table mappings.
+//
 // NOTE: Lines are sorted in alphabetical order, each letter in its own line.
-var tables = []interface{}{
-	new(AccessToken),
+var Tables = []interface{}{
+	new(Access), new(AccessToken),
 	new(LFSObject), new(LoginSource),
 }
 
-func Init(w io.Writer) (*gorm.DB, error) {
-	db, err := openDB(conf.Database)
+func Init(w logger.Writer) (*gorm.DB, error) {
+	level := logger.Info
+	if conf.IsProdMode() {
+		level = logger.Warn
+	}
+
+	// NOTE: AutoMigrate does not respect logger passed in gorm.Config.
+	logger.Default = logger.New(w, logger.Config{
+		SlowThreshold: 100 * time.Millisecond,
+		LogLevel:      level,
+	})
+
+	db, err := openDB(conf.Database, &gorm.Config{
+		NamingStrategy: schema.NamingStrategy{
+			SingularTable: true,
+		},
+		NowFunc: func() time.Time {
+			return time.Now().UTC().Truncate(time.Microsecond)
+		},
+	})
 	if err != nil {
 		return nil, errors.Wrap(err, "open database")
 	}
-	db.SingularTable(true)
-	db.DB().SetMaxOpenConns(conf.Database.MaxOpenConns)
-	db.DB().SetMaxIdleConns(conf.Database.MaxIdleConns)
-	db.DB().SetConnMaxLifetime(time.Minute)
-
-	db.SetLogger(&dbutil.Writer{Writer: w})
-	if !conf.IsProdMode() {
-		db = db.LogMode(true)
+
+	sqlDB, err := db.DB()
+	if err != nil {
+		return nil, errors.Wrap(err, "get underlying *sql.DB")
 	}
+	sqlDB.SetMaxOpenConns(conf.Database.MaxOpenConns)
+	sqlDB.SetMaxIdleConns(conf.Database.MaxIdleConns)
+	sqlDB.SetConnMaxLifetime(time.Minute)
 
 	switch conf.Database.Type {
-	case "mysql":
-		conf.UseMySQL = true
-		db = db.Set("gorm:table_options", "ENGINE=InnoDB")
 	case "postgres":
 		conf.UsePostgreSQL = true
-	case "mssql":
-		conf.UseMSSQL = true
+	case "mysql":
+		conf.UseMySQL = true
+		db = db.Set("gorm:table_options", "ENGINE=InnoDB").Session(&gorm.Session{})
 	case "sqlite3":
 		conf.UseSQLite3 = true
+	case "mssql":
+		conf.UseMSSQL = true
+	default:
+		panic("unreachable")
 	}
 
 	// NOTE: GORM has problem detecting existing columns, see https://github.com/gogs/gogs/issues/6091.
 	// Therefore only use it to create new tables, and do customized migration with future changes.
-	for _, table := range tables {
-		if db.HasTable(table) {
+	for _, table := range Tables {
+		if db.Migrator().HasTable(table) {
 			continue
 		}
 
 		name := strings.TrimPrefix(fmt.Sprintf("%T", table), "*db.")
-		err = db.AutoMigrate(table).Error
+		err = db.Migrator().AutoMigrate(table)
 		if err != nil {
 			return nil, errors.Wrapf(err, "auto migrate %q", name)
 		}
 		log.Trace("Auto migrated %q", name)
 	}
 
-	gorm.NowFunc = func() time.Time {
-		return time.Now().UTC().Truncate(time.Microsecond)
-	}
-
-	sourceFiles, err := loadLoginSourceFiles(filepath.Join(conf.CustomDir(), "conf", "auth.d"))
+	sourceFiles, err := loadLoginSourceFiles(filepath.Join(conf.CustomDir(), "conf", "auth.d"), db.NowFunc)
 	if err != nil {
 		return nil, errors.Wrap(err, "load login source files")
 	}
@@ -188,5 +220,5 @@ func Init(w io.Writer) (*gorm.DB, error) {
 	TwoFactors = &twoFactors{DB: db}
 	Users = &users{DB: db}
 
-	return db, db.DB().Ping()
+	return db, nil
 }

+ 0 - 33
internal/db/errors/login_source.go

@@ -1,33 +0,0 @@
-// Copyright 2017 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package errors
-
-import "fmt"
-
-type LoginSourceNotActivated struct {
-	SourceID int64
-}
-
-func IsLoginSourceNotActivated(err error) bool {
-	_, ok := err.(LoginSourceNotActivated)
-	return ok
-}
-
-func (err LoginSourceNotActivated) Error() string {
-	return fmt.Sprintf("login source is not activated [source_id: %d]", err.SourceID)
-}
-
-type InvalidLoginSourceType struct {
-	Type interface{}
-}
-
-func IsInvalidLoginSourceType(err error) bool {
-	_, ok := err.(InvalidLoginSourceType)
-	return ok
-}
-
-func (err InvalidLoginSourceType) Error() string {
-	return fmt.Sprintf("invalid login source type [type: %v]", err.Type)
-}

+ 5 - 10
internal/db/issue.go

@@ -679,17 +679,12 @@ func newIssue(e *xorm.Session, opts NewIssueOptions) (err error) {
 			return fmt.Errorf("get user by ID: %v", err)
 		}
 
-		// Assume assignee is invalid and drop silently.
-		opts.Issue.AssigneeID = 0
 		if assignee != nil {
-			valid, err := hasAccess(e, assignee.ID, opts.Repo, AccessModeRead)
-			if err != nil {
-				return fmt.Errorf("hasAccess [user_id: %d, repo_id: %d]: %v", assignee.ID, opts.Repo.ID, err)
-			}
-			if valid {
-				opts.Issue.AssigneeID = assignee.ID
-				opts.Issue.Assignee = assignee
-			}
+			opts.Issue.AssigneeID = assignee.ID
+			opts.Issue.Assignee = assignee
+		} else {
+			// The assignee does not exist, drop it
+			opts.Issue.AssigneeID = 0
 		}
 	}
 

Some files were not shown because too many files changed in this diff