Compare commits

...

289 Commits

Author SHA1 Message Date
Unknwon
a38e4a0b02 routers/install.go: able to keep previous custom settings for 2nd time install
- .gopmfile: update all commits
2015-02-13 16:48:23 -05:00
Unknwon
def39d191b conf/locale: update all locales 2015-02-13 15:48:10 -05:00
Unknwon
67a9416ae5 templates/user/auth/signin.tmpl: hide sign up prompt when registration is disabled #884 2015-02-12 12:38:44 -05:00
无闻
0af74b36ad Merge pull request #937 from Stefan-Code/dev
Changes to repo-header-download-drop
2015-02-11 12:27:29 -05:00
Unknwon
d02e45f985 better naming on #891 2015-02-11 12:04:01 -05:00
Stefan-Code
e5d6f4ce56 Changes to repo-header-download-drop, different repo-clone-url input behaviour 2015-02-11 07:28:51 +01:00
Unknwon
485ea6f14f models: make code change for session issue with SQLite3 #739 2015-02-10 23:44:16 -05:00
Unknwon
28580aee63 modules/middleware/auth.go: remove uncheck login for watch a repo #929 2015-02-10 22:53:46 -05:00
Unknwon
6a23252edc able to allow insecure certification of webhook for #891 2015-02-10 21:06:59 -05:00
Unknwon
e407df54f0 update gopmfile and README 2015-02-09 13:32:22 -05:00
Unknwon
bad533a219 models/repo.go: add update hook when migrate for #789 2015-02-09 12:42:53 -05:00
Unknwon
7d3932b9cd templates/ng/base: change year to 2015, fix #928
- conf/locale: update Japanese locale
2015-02-09 11:04:17 -05:00
无闻
b61ef40406 Merge pull request #924 from phsmit/fix_921
Fixes #921
2015-02-09 10:54:24 -05:00
无闻
767bf82eab Merge pull request #923 from phsmit/fix_922
Fix #922
2015-02-09 10:45:41 -05:00
Peter Smit
5cd887dba5 Fixes #921
Fixes #921 and makes the Mention regexp be in line with the others
2015-02-09 12:56:46 +02:00
Peter Smit
b7e26aa5e3 Improve argument parsing for serve command 2015-02-09 12:32:42 +02:00
Peter Smit
aa35be975f Fix #922 2015-02-09 12:27:15 +02:00
无闻
6ed96b7a20 Merge pull request #911 from TonyTsangHK/dev
Link to previous commited source file (diff.view_file button) instead of returning 404 for deleted files.
2015-02-09 00:31:16 -05:00
Unknwon
3cc04682c5 modules/setting: mirror path issue 2015-02-08 22:23:01 -05:00
Unknwon
f15fa9167a cmd: code fix for #905
- routers/admin: add rewrite update hook operation
- conf/locale: update locale file due to ini behavior changes
- cmd/cert_stub.go: remove useless code
- cmd/fix.go: no longer need fix command(at least now)
2015-02-08 21:26:14 -05:00
无闻
cd0ee35b3f Merge pull request #905 from phsmit/conf_on_cli
Add option to provide configuration file on command line
2015-02-08 20:22:02 -05:00
Unknwon
3a44143b81 modules/ans1-ber: fix LDAP UTF8 string decoding for #916 2015-02-08 14:39:54 -05:00
Unknwon
9420eecb87 public/ng/css: code generation for #919 2015-02-08 13:00:22 -05:00
无闻
17a34949eb Merge pull request #919 from Stefan-Code/dev
Updated gogs.css - monospace font for hash
2015-02-08 12:51:58 -05:00
Unknwon
775bd65234 conf/locale: add Spanish locale 2015-02-08 12:39:11 -05:00
Stefan
85f384f271 Updated gogs.css - monospace font for hash
Updated gogs.css to use monospaced font for sha hash label in repository view to make it look nicer because of equal label width.
2015-02-08 17:38:10 +01:00
Unknwon
ba77a3b0b4 routers/repo/http.go: allow HTTP push/pull by token for #845 2015-02-07 15:47:23 -05:00
无闻
19525abfc4 Merge pull request #845 from compressed/token_http
allow http push by token - #842
2015-02-07 15:27:59 -05:00
Unknwon
f989805050 conf/locale: update locales 2015-02-07 11:12:13 -05:00
Unknwon
fc1befcf3c update README notice and CONTRIBUTING.md 2015-02-07 11:09:17 -05:00
Unknwon
2a2596fe61 able to disable SSH for #883 2015-02-07 10:46:57 -05:00
Unknwon
3f2e99962c conf/locale: update French locale 2015-02-06 21:29:15 -05:00
Unknwon
216683004e code fix for #908, and work for #884 2015-02-06 21:16:23 -05:00
无闻
87b90372a7 Merge pull request #908 from nicolai86/feature/hide-signup-button-884
Make Signup button display configurable - #884
2015-02-06 21:03:31 -05:00
Unknwon
5a99e9a37b models/action.go: add action reopen for #462
- models/issue.go: format comment type names
2015-02-06 20:47:21 -05:00
Unknwon
afccd0a3ee models/action.go: mirror fix on #892
- modules/base/markdown.go: fix issue link issue
- routers/repo/view.go: remove useless code
2015-02-06 20:34:49 -05:00
Unknwon
0669897226 modules/base: fix markdown mention regex for #826
- conf/locale: add mew translator profile
2015-02-06 19:15:58 -05:00
无闻
ddddad9792 Merge pull request #826 from deringer/dev
Fix user mention bug when parsing markdown documents
2015-02-06 19:03:35 -05:00
Tony Tsang
fc6d80d619 Link to previous commited source file (diff.view_file button) instead of returning 404 for deleted files. 2015-02-06 17:02:32 +08:00
Raphael Randschau
92036a78d1 Add locales (en/de native, rest -> translate.google.com) 2015-02-05 18:15:00 +01:00
Raphael Randschau
3c65265871 Hide the registration button depending on the setting 2015-02-05 18:15:00 +01:00
Raphael Randschau
79f3281548 Add ShowRegistrationButton configuration option 2015-02-05 18:14:54 +01:00
Unknwon
16018e8323 public/ng/css: code generate for #907 2015-02-05 08:22:59 -05:00
无闻
15d4f32825 Merge pull request #907 from makhov/new-lines-highlighting-format
fix highlighting css for del code
2015-02-05 08:21:01 -05:00
Alexey Makhov
04adc94b26 fix css for same code 2015-02-05 16:02:37 +03:00
Alexey Makhov
2f40f614b5 fix css for del code 2015-02-05 15:56:48 +03:00
无闻
23f3f60dcf Merge pull request #904 from makhov/new-lines-highlighting-format
new lines highlighting format
2015-02-05 07:30:37 -05:00
Peter Smit
1ab09e4f1b Add option to provide configuration file on command line 2015-02-05 12:17:35 +02:00
Alexey Makhov
01cef678a3 new lines highlighting format 2015-02-05 10:49:04 +03:00
无闻
02c5bade0f Merge pull request #892 from EtienneBruines/commit_reference
Referencing issues from commit messages is now possible.
2015-02-04 23:21:20 -05:00
Unknwon
f706102890 models: sanitize user full name when update settings 2015-02-04 20:04:01 -05:00
Unknwon
7140f50637 public/ng/js: script fix on #901 2015-02-04 19:52:31 -05:00
Unknwon
e0329c0eb5 Merge branch 'dev' of github.com:gogits/gogs into dev 2015-02-04 19:14:13 -05:00
Unknwon
4dfffee9fb cmd: update csrf version requirement 2015-02-04 19:14:09 -05:00
无闻
3e307e7862 Merge pull request #901 from makhov/fix-diff-view
fix lines highlighting at diff view
2015-02-04 19:13:40 -05:00
Alexey Makhov
e91b28eb9b little fix 2015-02-04 22:06:40 +03:00
Alexey Makhov
5d4425bbbc add multifile support to diff view highlighting 2015-02-04 21:54:45 +03:00
Alexey Makhov
7f71fe9dae fix diff lines highlighting 2015-02-04 12:41:35 +03:00
Unknwon
5589445557 scripts: remove confuse scripts 2015-02-04 12:36:40 +03:00
Unknwon
98f7f6bef8 scripts: remove confuse scripts 2015-02-03 12:42:34 -05:00
无闻
43bf94e1aa Merge pull request #897 from makhov/makhov/fix-admin-config
fix error at admin/config
2015-02-03 12:21:50 -05:00
Alexey Makhov
a7662f4a39 fix error at admin/config 2015-02-03 17:26:56 +03:00
Unknwon
8e238058b2 public/ng/css: code fix on #895
- templates/user/settings: fix email panel nav highlight
2015-02-03 06:54:29 -05:00
Unknwon
26bccef297 Merge branch 'master' of github.com:gogits/gogs into dev 2015-02-03 06:51:44 -05:00
无闻
e8b62e8957 Merge pull request #895 from makhov/makhov/fix-settings-email-html
fix settings/email html&css
2015-02-03 06:50:57 -05:00
Alexey Makhov
32fb5ea5d0 fix settings/email html&css in less 2015-02-03 11:05:13 +03:00
Alexey Makhov
e43bd15b96 fix settings/email html&css 2015-02-03 10:32:55 +03:00
Unknwon
4de0b19cec models: mirro code fix for #821 2015-02-02 23:42:53 -05:00
无闻
902f19f70b Merge pull request #821 from phsmit/fix_819
Fix #819 by fetching the repository from db before updating
2015-02-02 23:38:04 -05:00
Unknwon
bfce0def25 modules/base: fix README filename checker, fix #877 2015-02-02 23:04:36 -05:00
Etienne Bruines
5c4b85c029 Referencing issues from commit messages is now possible.
Code-wise: the fixing-part of the code now doesn't reference the issue any more, because this is done by the referencing-part of the code, which is called just before.

Fixes #462, #668, #732.
2015-02-02 16:34:07 +01:00
Unknwon
57291d1e2a conf/locale: update Japanese locale 2015-02-02 09:44:51 -05:00
Unknwon
956c59b282 conf/locale: update Japanese locale 2015-02-02 07:33:24 -05:00
Unknwon
0a2068d7fb models: code fix on #818 2015-02-01 17:21:56 -05:00
无闻
cd6376f093 Merge pull request #818 from fzerorubigd/master
add a function to rewrite all public keys on admin request
2015-02-01 16:56:34 -05:00
无闻
d4fc8880eb Merge pull request #889 from mgdelacroix/patch-1
Add Miguel de la Cruz as a translator
2015-02-01 16:48:48 -05:00
Miguel de la Cruz
b8425ccbec Add Miguel de la Cruz as a translator 2015-02-01 22:47:58 +01:00
Unknwon
7ec42465a7 Merge branch 'dev' of github.com:gogits/gogs into dev 2015-02-01 14:40:05 -05:00
Unknwon
89ea3e1acc routers: save partial config when install 2015-02-01 14:39:58 -05:00
无闻
facd491a6d Merge pull request #888 from tstorch/docker_hp_update
correction: updated docker link
2015-02-01 14:38:36 -05:00
Tristan Storch
4c4488213a correction: updated docker link 2015-02-01 20:30:22 +01:00
Unknwon
ac29dc93cd conf/locale: add Japanese support
README: remove duplicated travis badge
2015-02-01 13:36:40 -05:00
Unknwon
27bd2157ed update travis.yml and add badge 2015-02-01 12:44:10 -05:00
Unknwon
b293b6eaa6 cmd: CMD option for port number of gogs web to prevent first time run conflict
- routers: use new binding convention to simplify code
- templates: able to set HTTP port number in install page
2015-02-01 12:41:03 -05:00
Unknwon
3d9cda2d98 public/ng: fix auto-completion #832 2015-02-01 08:46:53 -05:00
Unknwon
faddaff90d templates: fix commit message render issue #828 2015-01-31 15:31:09 -05:00
Unknwon
569fcc30f3 Merge branch 'dev' of github.com:gogits/gogs into dev 2015-01-31 15:28:05 -05:00
Unknwon
32152d2363 routers/repo: set raw page content type to 'text/plain' #828 2015-01-31 15:27:57 -05:00
无闻
69d98e9edd Merge pull request #885 from clinta/dev
Add a freebsd init script.
2015-01-30 23:00:51 -05:00
Clint Armstrong
66a9c0d71d Rename scripts/rc/freebsd/gogs to scripts/init/freebsd/gogs 2015-01-30 22:52:57 -05:00
Clint Armstrong
7e3d66673d Add freebsd rc script 2015-01-30 22:51:38 -05:00
Unknwon
fb9dcfa921 modules/midlleware: little auth code fix, #777 2015-01-30 20:30:42 -05:00
Unknwon
d8394bb2e0 modules/midlleware: little auth code fix 2015-01-30 20:30:07 -05:00
Unknwon
ee6786216a modules/base: clean code with #838 2015-01-30 18:12:30 -05:00
Unknwon
37fcc8daf2 modules/base: add RenderCommitMessage with XSS-safe and special links
- update russian locale
2015-01-30 18:05:20 -05:00
Unknwon
9803f84c88 update link 2015-01-27 16:30:58 -05:00
Unknwon
c0e9481fa6 update locale 2015-01-26 09:13:34 -05:00
Unknwon
c6b87aaf02 Merge branch 'dev' of github.com:gogits/gogs into dev 2015-01-23 00:47:03 +08:00
Unknwon
077d1ae70b update locale 2015-01-23 00:46:48 +08:00
无闻
61608f13a0 Merge pull request #870 from phsmit/migrations
Create db migrations framework
2015-01-22 21:07:11 +08:00
Peter Smit
4ef3245413 Migration code: errors are not to be forgotten 2015-01-22 15:01:45 +02:00
Peter Smit
2a70d6b723 Clean up migrations code 2015-01-22 14:56:50 +02:00
Peter Smit
bb103e8723 Create db migrations framework 2015-01-22 14:52:58 +02:00
无闻
161774d4fb Merge pull request #825 from phsmit/ssh2_keys
Implement #798 Flexible ssh-key input
2015-01-22 19:39:35 +08:00
无闻
edbfbfa66e Merge pull request #822 from phsmit/fix_807
Fix #807 parse the userinfo with the golang tools
2015-01-22 19:31:51 +08:00
无闻
830bc75107 Merge pull request #866 from vitalvas/dev
Fix in url if cache avatar is enabled
2015-01-20 13:38:17 +08:00
Unknwon
8e384ce46c fix #828, may cause unintentional break in other features, but security is no.1 2015-01-20 13:08:49 +08:00
Vitaliy Vasilenko
cf59057ef3 fix if service.ENABLE_CACHE_AVATAR is true 2015-01-20 05:20:33 +02:00
Unknwon
0e286a0ca9 fix locale 2015-01-19 02:51:43 +08:00
Unknwon
bd414a2d1f update gopmfile 2015-01-19 02:05:15 +08:00
Unknwon
be8bdc0393 Merge branch 'master' of github.com:gogits/gogs 2015-01-18 22:26:21 +08:00
Unknwon
9fa287e4f7 update locale 2015-01-18 22:24:20 +08:00
无闻
210306bd64 Merge pull request #865 from clinta/patch-1
Allow start.sh from any working directory
2015-01-18 14:08:12 +08:00
Clint Armstrong
eae08ea8f4 Allow start.sh from any working directory
This change to start.sh allows it to be executed from any working directory and always reference the gogs binary in the parent directory. Very helpful when calling start.sh from an init script.
2015-01-17 16:52:42 -05:00
Unknwon
452cca35e0 Merge branch 'encoding' of github.com:gogits/gogs into dev
Conflicts:
	.gopmfile
2015-01-17 15:29:45 +08:00
Unknwon
7170011f4d update with deps 2015-01-17 15:17:53 +08:00
无闻
f99690a545 Merge pull request #861 from phsmit/change_chardet
Change chardet to gogits
2015-01-17 14:45:48 +08:00
无闻
bdd6aef746 Merge pull request #849 from gittex/translate
Translation update
2015-01-17 14:43:27 +08:00
Peter Smit
e6f97c78ff Change chardet to gogits 2015-01-15 12:40:16 +02:00
Dominik Schulz
50d91f3b6a Make help text for email listing a little more helpful. 2015-01-09 17:55:09 +01:00
Dominik Schulz
7d4cef6008 Add missing translations for email settings page to de_DE. 2015-01-09 17:54:44 +01:00
Christopher Brickley
d0827e5d5e allow http push by token - #842 2015-01-08 09:30:22 -05:00
Unknwon
bb26285a12 fix #827 2015-01-06 17:14:49 +08:00
无闻
9e61ec316e Merge pull request #830 from TonyTsangHK/dev
Add max-width to commit message of repo-files-table
2015-01-05 20:45:06 +08:00
Unknwon
13e35398aa prepare for mirror update release 2015-01-05 20:37:22 +08:00
Tony Tsang
9f4e584122 Add max-width to commit message of repo-files-table 2015-01-05 12:22:20 +08:00
Michael Dyrynda
04d698bfbc add some padding to markdown paragraphs 2015-01-03 22:43:02 +10:30
Michael Dyrynda
c7cbdd34fb Adjust MentionPattern to not match users mid-sentence (or email addresses)
Fix link to user profile, update based on adjusted MentionPattern
2015-01-03 22:03:41 +10:30
Unknwon
d5c6b53571 use new Redis client 2015-01-03 02:54:22 +08:00
Unknwon
f0ca16d78f add cache version require 2015-01-02 23:59:06 +08:00
Peter Smit
6251626de4 Implement #798 Flexible ssh-key input
It is now possible to input ssh keys in a number of formats: openssh, SSH2 or just the base64 encoded key.
2015-01-02 15:38:11 +02:00
无闻
9b0858b1ad Merge pull request #823 from phsmit/fix_799
Fix #799 by adding a tooltip for all dates in all settings/panels
2015-01-02 20:25:48 +08:00
Unknwon
c73e9057ae Optmize git-fsck options and fix #820 2015-01-02 20:14:43 +08:00
Peter Smit
fd70f9ec1b Fix #799 by adding a tooltip for all dates in all settings/panels 2015-01-02 12:41:05 +02:00
Peter Smit
d016eaaa09 Fix #807 parse the userinfo with the golang tools
Note, this is now only fixed with Go version >= 1.4.2, see this bug in Go: 07d86b1f2d
2015-01-02 12:14:11 +02:00
Peter Smit
44fa9147b7 Fix #819 by fetching the repository from db before updating 2015-01-02 11:15:42 +02:00
Unknwon
0b56272c13 fix #805 2015-01-02 13:30:45 +08:00
Unknwon
677b1ec627 fix #808 2015-01-02 12:56:08 +08:00
Unknwon
3ea1443885 work on #784 2015-01-02 12:47:33 +08:00
fzerorubigd
6643647687 add afunction to rewrite all public keys on admin request
refs #763
2015-01-01 02:15:52 +03:30
Unknwon
b6272d1803 fix gopmfile 2014-12-31 21:54:25 +08:00
Unknwon
40de2f78c4 fix gopmfile 2014-12-31 18:41:34 +08:00
Unknwon
aa2148a7a9 fix gopmfile 2014-12-31 18:39:47 +08:00
Unknwon
bd555551ce fix #801 2014-12-31 18:37:29 +08:00
Unknwon
e1c5008238 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-12-31 17:09:07 +08:00
Unknwon
0f1ff9b1ad fix cache dep API broken 2014-12-31 17:08:57 +08:00
无闻
52cc58fd9d Merge pull request #797 from Mikayex/dev
Fix #795
2014-12-29 20:09:50 +08:00
无闻
477bea574a Merge pull request #782 from estetsenko/dev
fix for  #747
2014-12-29 20:08:39 +08:00
无闻
37566f71a9 Merge pull request #787 from andre-hub/dev
flexible the build scripts and add a freebsd build script
2014-12-29 20:07:10 +08:00
无闻
afdb0c7f9d Merge pull request #790 from euank/master
Initialize unset git user.email / user.name correctly; fix Dockerfile
2014-12-29 20:06:27 +08:00
Unknwon
63c1f9a23f fix 500: E-mail already used in user settings page 2014-12-29 20:00:07 +08:00
Thomas Laroche
e948c7c262 Fix #795 2014-12-29 11:55:46 +01:00
Unknwon
81a44e4cd0 fix API changes 2014-12-28 20:40:35 +08:00
euank
f059866a21 Set user.name & user.email in Dockerfile
The previous setting would cause all repo creations to fail, as
described in issue #328.
The previous commit also resolves this issue, but it seems saner to
create the user in the Dockerfile than at runtime.
2014-12-27 19:10:33 -08:00
euank
234a7c19a4 Default values for both user.name and user.email
The previous behavior was to set default values only if user.name was
not set, but to always set it for both. This only sets a value if there
wasn't one; this fixes cases where someone has a user.name but no
user.email (see included Dockerfile) or someone has a user.email but no
user.name (before the email would have been over-written).
2014-12-27 19:07:54 -08:00
André Grötschel
35dd41c3a2 merge flexible the build scripts and add a freebsd build script 2014-12-27 15:28:45 +01:00
André Grötschel
afc659442d flexiable the build scripts and add a freebsd build script 2014-12-27 15:16:05 +01:00
Unknwon
6a6636d451 Merge branch 'master' of github.com:gogits/gogs into dev 2014-12-27 12:38:18 +08:00
无闻
46742a79ca Merge pull request #785 from joshk/patch-1
Use the new build env on Travis
2014-12-27 12:25:08 +08:00
无闻
d61def86e1 Merge pull request #780 from morpheyesh/master
spellcheck
2014-12-27 12:24:21 +08:00
Josh Kalderimis
30c750a5df Use the new build env on Travis
http://docs.travis-ci.com/user/workers/container-based-infrastructure
2014-12-27 01:23:10 +01:00
estetsenko
bae1d65564 bugfix: Unable to assign any issue myself 2014-12-24 20:47:45 +03:00
morpheyesh
995a805a31 spellcheck 2014-12-24 13:20:10 +05:30
fuxiaohei
c0cfd62b90 add label-edit and label-delete logic 2014-12-22 21:26:05 +08:00
无闻
e193005c66 Merge pull request #773 from phsmit/golang_x_text_encoding
Golang x text encoding
2014-12-22 05:30:49 -05:00
Peter Smit
fff8109567 Removing redundant mahonia 2014-12-22 11:29:02 +02:00
Peter Smit
3af757ed77 Replace mahonia with the standard functions in the Golang Sub-repositories 2014-12-22 11:01:52 +02:00
Unknwon
ebbe6177a9 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-12-22 03:44:52 -05:00
Unknwon
97b39ae2e4 fix invite bug(shouldn't include full name to search box) 2014-12-22 03:44:49 -05:00
无闻
0f77ad219c Merge pull request #771 from phsmit/multiple_email_cleanup
Create English locale keys for multiple e-mails feature
2014-12-22 02:43:20 -05:00
Peter Smit
8b31be43c6 Forgot to i18n "Primary" 2014-12-22 09:41:29 +02:00
Peter Smit
21dbcb7c77 Create English locale keys for multiple e-mails feature
Also, change all current 'emails' to 'e-mails'.
Still todo: some CSS for the user/settings/email page, but that is not my specialty
2014-12-22 09:11:30 +02:00
无闻
0d7bb9af46 Merge pull request #769 from gitter-badger/gitter-badge
Add a Gitter chat badge to README.md
2014-12-21 02:58:38 -05:00
The Gitter Badger
86e9ebdcc9 Added Gitter badge 2014-12-21 07:53:06 +00:00
无闻
350e0080e6 Merge pull request #767 from phsmit/fix_email_query
Fix for wrong email query
2014-12-21 02:23:36 -05:00
Peter Smit
66e2016eeb Fix for wrong email query
Changing EmailAdress.OwnerId to EmailAddress.Uid should have accompanied this change
2014-12-21 09:16:56 +02:00
无闻
030b3d751e Merge pull request #766 from phsmit/correct_from
Correct usage of FROM in email creation
2014-12-21 01:55:28 -05:00
Unknwon
79537467da mirror fix and update 2014-12-20 22:51:16 -05:00
无闻
a18decf4cc Merge pull request #755 from phsmit/multiple_emails
Multiple emails
2014-12-20 22:47:05 -05:00
Peter
20b5c23a19 Small fixes to multiple_emails feature 2014-12-20 09:26:51 +02:00
无闻
e6e2cf7855 Merge pull request #764 from phsmit/fix_mailer
Remove standard mailer port lines
2014-12-19 17:20:13 -05:00
Peter
c884ecfea1 Parse the from string to extract the email address 2014-12-19 23:06:03 +02:00
Peter
edbe1de026 Remove unused "User" member of Message Struct and fix bounce address
The User member of a message is not needed anymore.

The from that is send to the server, should always be the "system" from. This is also called the Bounce address http://en.wikipedia.org/wiki/Bounce_address
2014-12-19 22:48:21 +02:00
Peter
2321b4b272 Change from header in email, fixes #765 2014-12-19 22:33:17 +02:00
Peter
007cf33e88 Remove standard mailer port lines
This lines got committed by accident. They do actually nothing, as SplitHostPort will give an error if port is not given.
2014-12-19 22:00:11 +02:00
Unknwon
b231b8c927 update locale and mirror code format 2014-12-19 00:24:17 -05:00
无闻
d01e7b0173 Merge pull request #762 from phsmit/crammd5
Crammd5
2014-12-18 16:49:11 -05:00
无闻
bb267e30b6 Merge pull request #761 from phsmit/mailer_rewritten
Rewrite of SendMail function
2014-12-18 16:37:24 -05:00
Peter
eca42bcb44 Prefer CRAM-MD5 over PLAIN authentication 2014-12-18 14:15:13 +02:00
Peter
5ffeca35e7 Add option to use CRAM-MD5 as authentication method in the mailer 2014-12-18 13:58:48 +02:00
Peter
87be137b88 Rewrite of SendMail function
The SendMail function is rewritten and has the following new functionality:
 - It is optional to skip verification of keys. The config option SKIP_VERIFY is added
 - If the port is 465, or ending on 465, the TLS(/SSL) connection is started first.
2014-12-18 13:34:30 +02:00
Unknwon
0a697517ac work on #754 2014-12-18 03:37:31 -05:00
Unknwon
c4820f119d work on #754 2014-12-18 03:26:09 -05:00
Unknwon
57b3be4016 work on #756 2014-12-17 23:04:05 -05:00
Peter
b033f2f535 Finish method for having multiple emails/user.
All basics are implemented. Missing are the right (localized) strings
and the page markup could have a look at by a frontend guy.
2014-12-17 17:42:54 +02:00
Peter
f34b04cfc0 Template for email activation email 2014-12-17 17:42:31 +02:00
Peter
ec71d538fc Method for activating email addresses through verification email 2014-12-17 17:41:49 +02:00
Peter
6919c80f0b Add function to the model for email address management (add/delete/activate) 2014-12-17 17:40:10 +02:00
Peter Smit
99599c099f Add alternative email addresses to the model
A new struct is created named EmailAddress that contains alternative
email addresses for users. Also the email related methods; IsEmailUsed
and GetUserByEmail are updated.

DeleteUser deletes the extra email addresses and DeleteInactivateUsers
also deletes inactive accounts. This could be factored out, but should
do it for now.
2014-12-17 10:26:19 +02:00
Unknwon
d01f2f3c22 fix #751 2014-12-16 20:47:10 -05:00
Unknwon
1a5aa5e0c0 fix #741 2014-12-16 02:28:57 -05:00
Unknwon
9803c421f5 fix binding api broken 2014-12-15 01:49:59 -05:00
Unknwon
792ec63c8a update locale 2014-12-14 22:47:09 -05:00
Unknwon
c9e0b3b987 prepare for 0.5.9 2014-12-13 20:32:30 -05:00
Unknwon
28766479a7 update gopmfile 2014-12-13 20:26:04 -05:00
Unknwon
9ac940d31d update locales 2014-12-13 20:06:50 -05:00
Unknwon
b553ea45ee modes/repo: incorrect SSH clone URL for #742 2014-12-13 16:46:00 -05:00
Unknwon
ac4a10456e api: able to create repo and fix #726
- POST /user/repos
- POST /org/:org/repos
2014-12-12 20:30:32 -05:00
Unknwon
2f3a7e53cb fix #735 2014-12-12 01:29:36 -05:00
Unknwon
42c7bb7529 mirror code clean 2014-12-11 18:55:09 -05:00
无闻
35140f1cc7 Merge pull request #731 from cryptix/dev
increase minimum version for HTTPS to TLS 1.0 (POODLE, fixes #730)
2014-12-11 18:32:49 -05:00
Henry
4f4392b83e increase minimum version vor HTTPS to TLS 1.0 (POODLE, fixes #730) 2014-12-11 11:14:41 +01:00
codeskyblue
db6c0ebf76 fix git clone error when repo has upper case name 2014-12-11 15:57:32 +08:00
Unknwon
cf7ebfbdc8 mirror fix on release JS 2014-12-10 16:41:49 -05:00
Unknwon
bc8721fb6c Finish new UI for release page 2014-12-10 16:37:54 -05:00
Unknwon
01ba771783 fix #703 2014-12-10 07:00:11 -05:00
Unknwon
9ee80e3e54 fix compile error 2014-12-10 05:10:26 -05:00
无闻
b2c6a6920f Merge pull request #727 from Mageti/master
Correction for #723
2014-12-10 05:03:50 -05:00
Mageti
e321469884 remove unused code in BasicAuthDecode 2014-12-10 11:01:17 +01:00
Mageti
b7ebbb4064 Correction for #723
Correction for #723
Bug was : decode failed if the password contains ```:```
2014-12-10 10:51:51 +01:00
Unknwon
9a1fe801e5 fix #711 2014-12-09 02:18:25 -05:00
Unknwon
6f71632e3e new language 2014-12-07 19:27:49 -05:00
无闻
2844674587 Merge pull request #720 from Alukardd/dev
Allow send mail without authentication if SMTP server allow this
2014-12-07 16:05:55 -05:00
fuxiaohei
0daef29053 add label-create ui elements 2014-12-07 21:29:37 +08:00
Alukardd
21081836ba Allow send mail without authentication if SMTP server allow this 2014-12-07 16:07:48 +03:00
无闻
a2f6e1803b Merge pull request #718 from jbcrail/fix-comment-spelling
Fix spelling errors in comments.
2014-12-06 21:01:00 -05:00
Joseph Crail
39c068400e Fix spelling errors in comments. 2014-12-06 20:22:48 -05:00
Unknwon
47e7175b80 upload locales 2014-12-05 18:27:59 -05:00
Unknwon
0b785ad967 work on #672 2014-12-05 18:08:09 -05:00
Unknwon
069486d169 fix #165 2014-12-05 17:54:57 -05:00
无闻
298ebc58c1 Merge pull request #716 from ErebusBat/master
Fix Gravatar images in web view (like commit listing)
2014-12-05 16:20:34 -05:00
无闻
3fd41d138c Merge pull request #712 from Dennis-Smurf/enhancement-issuelink-in-commit
Added issue link rendering in commit messages
2014-12-05 16:15:43 -05:00
Andrew Burns
35b02997f8 Fix Gravatar images in web view (like commit listing)
Related to #700

In the original bug report it was referencing only the sytem avatar images for setup users (like in the header); however the problem also persists with things like commit history.

This commit fixes the `tool.AvatarLink` function so that it also uses the already existing `avatar.HashEmail` function.

I also refactored the `tool.AvatarLink` method some to make the control flow more apparent and adhere better to DRY (there were multiple calls to the `EncodeMd5` function that the `HashEmail` function call replaced, now there is only one.)
2014-12-05 11:02:59 -07:00
Andrew Burns
adc1ac689e HashEmail function should also remove spaces
According to the [Gravatar API](https://en.gravatar.com/site/implement/hash/) whitespace should also be removed from the email, it was not doing this previously.
2014-12-05 10:58:49 -07:00
dennis-smurf
528c075ad6 Added issue link rendering in commit messages 2014-12-05 11:02:52 +01:00
Unknwon
e577f2fff3 fix #706 and other mirror improve 2014-12-04 23:07:51 -05:00
无闻
daf96dfae1 Merge pull request #709 from TonyTsangHK/dev
Display multi-line commit message on commit diff page.
2014-12-04 22:36:54 -05:00
Tony Tsang
d4a1d9f82a Display multi-line commit message on commit diff page. 2014-12-05 10:53:37 +08:00
无闻
f7f4ea1dcf Merge pull request #708 from ErebusBat/master
Use the avatar.HashEmail function instead of hashing email directly.
2014-12-04 18:33:10 -05:00
fuxiaohei
0af3a5b603 add issue list filter ui 2014-12-04 23:22:16 +08:00
Andrew Burns
00cf3e4dab Use the avatar.HashEmail function instead of hashing email directly. Fixes #700 2014-12-03 16:19:35 -07:00
无闻
cb6be94358 Merge pull request #696 from deiwin/update/user-api-to-include-full-name
add full name to found users' list on the UI
2014-12-02 10:27:24 -05:00
Deiwin Sarjas
54ef1cee1d add full name to found users' list 2014-12-02 16:55:52 +02:00
无闻
b9999427a8 Merge pull request #694 from deiwin/update/user-api-to-include-full-name
update user api search results to include the full name
2014-12-02 07:50:05 -05:00
无闻
ddeb076890 Merge pull request #695 from CBiX/dev
fixed code view line height for firefox
2014-12-02 07:47:13 -05:00
Florian Hülsmann
d06d58e461 fixed code view line height for firefox 2014-12-02 11:31:57 +01:00
Deiwin Sarjas
48bb0fadc2 update user api search results to include the full name
Is fully backwards compatible
Fixes #677
2014-12-02 11:44:03 +02:00
无闻
cd627ba16e Merge pull request #690 from Dennis-Smurf/feature-sha1-markdown-pattern
Addded sha1 pattern in markdown for current repository
2014-12-01 11:35:18 -05:00
dennis-smurf
d0a80e432d Addded sha1 pattern in markdown for current repository 2014-12-01 09:30:35 +01:00
Unknwon
9558999698 mirror fix 2014-11-30 18:35:05 -05:00
Unknwon
5338808600 fix #676 2014-11-30 18:29:16 -05:00
Unknwon
82da024a4d fix #687 2014-11-30 10:55:26 -05:00
Unknwon
5c866fc737 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-11-30 02:26:33 -05:00
Unknwon
d75013a0e8 fix #580 2014-11-30 02:26:29 -05:00
无闻
1591a37ad5 Merge pull request #686 from willglynn/cert_stub_exit_code
Cert command stub should return a non-zero exit code
2014-11-30 01:38:35 -05:00
Will Glynn
3e528f34af Cert command stub should return a non-zero exit code 2014-11-29 21:52:59 -06:00
Unknwon
b6437b5a4c safe check 2014-11-28 21:54:49 -05:00
Unknwon
db4951bc61 mirror fix on oauth2 2014-11-28 21:38:35 -05:00
Unknwon
d6132aaa88 fix oauth2 2014-11-28 21:20:13 -05:00
无闻
9adc8e9d3f Merge pull request #683 from jcracknell/admin-repos-cols
Fix swapped issue/star columns in /admin/repos
2014-11-28 15:28:08 -05:00
无闻
be54b4bf26 Merge pull request #682 from jcracknell/user-links
Fix user links
2014-11-28 15:22:56 -05:00
James Cracknell
64d90a761b Fix swapped issue/star columns in /admin/repos 2014-11-28 12:40:02 -07:00
James Cracknell
4d123d0a93 Fix user links 2014-11-28 11:53:00 -07:00
Unknwon
5dd8308686 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-11-27 21:36:20 -05:00
Unknwon
9c2120eb34 fix #675 2014-11-27 21:36:12 -05:00
无闻
4f8d888e66 Merge pull request #674 from jcracknell/pfx-export
Added comments documenting how to export SSL keys from .pfx
2014-11-27 16:56:55 -05:00
James Cracknell
ca09a0b516 Added comments documenting how to export SSL keys from .pfx 2014-11-27 14:42:06 -07:00
Unknwon
a43164877c fix #664 2014-11-25 23:05:43 -05:00
Unknwon
515641d033 fix #659 2014-11-25 22:48:04 -05:00
Unknwon
54d25c13d7 Fix #543 2014-11-24 18:47:59 -05:00
fuxiaohei
23d53561d1 update milestone page design 2014-11-24 23:13:42 +08:00
Unknwon
0cce61de3a Merge branch 'dev' of github.com:gogits/gogs into dev 2014-11-24 09:54:22 -05:00
Unknwon
5b96e3fcc7 fix #660 2014-11-24 09:54:08 -05:00
fuxiaohei
79dae254cf add milestone page design 2014-11-24 22:33:04 +08:00
无闻
5b32cdd960 Merge pull request #657 from chai2010/dev
Fix #656
2014-11-23 22:15:25 -05:00
chai2010
f9ad8d6903 Fix #656 2014-11-24 10:58:39 +08:00
Unknwon
1b66600bd0 Fix #652 2014-11-23 02:33:47 -05:00
Unknwon
dc53270da9 Fix 653 2014-11-22 10:22:53 -05:00
Unknwon
8ea7ba3afa fix #644 2014-11-21 13:10:00 -05:00
Unknwon
ef275ebf62 more on change avatar 2014-11-21 12:51:36 -05:00
Unknwon
22ab4fa1b0 fix #139 2014-11-21 11:08:24 -05:00
Unknwon
55dfe2c978 custom avatar upload 2014-11-21 10:58:08 -05:00
Unknwon
3c3f7c2a56 Fix #643 2014-11-20 18:03:42 -05:00
Unknwon
0c92da7e9c fix invalid user links in admin panels 2014-11-19 21:19:37 -05:00
无闻
8fac41768c Merge pull request #639 from pkgr/pkgr
Make postinstall work for CentOS/RHEL packages as well.
2014-11-19 17:27:53 -05:00
Cyril Rohr
c418b83678 Make postinstall work for CentOS/RHEL packages as well. 2014-11-19 21:43:12 +00:00
无闻
b53f6357fc Merge pull request #638 from pkgr/pkgr
Fix packages generated on packager.io
2014-11-19 15:51:00 -05:00
Cyril Rohr
11ca3dedfb Fix .pkgr.yml 2014-11-19 19:18:44 +00:00
Cyril Rohr
f77680520f Link custom app.ini to /etc/gogs/ 2014-11-19 19:18:44 +00:00
176 changed files with 7381 additions and 121865 deletions

3
.gitignore vendored
View File

@@ -1,6 +1,7 @@
.DS_Store
*.db
*.log
log/
custom/
data/
.vendor/
@@ -34,4 +35,4 @@ docker/fig.yml
docker/docker/Dockerfile
docker/docker/init_gogs.sh
gogs.sublime-project
gogs.sublime-workspace
gogs.sublime-workspace

View File

@@ -2,31 +2,35 @@
path = github.com/gogits/gogs
[deps]
github.com/beego/memcache = commit:2aea774416
github.com/beego/redigo = commit:856744a0d5
github.com/bradfitz/gomemcache = commit:72a68649ba
github.com/Unknwon/cae = commit:2e70a1351b
github.com/Unknwon/com = commit:2cbcbc6916
github.com/Unknwon/goconfig = commit:0f8d8dc1c0
github.com/Unknwon/i18n = commit:aec5f77857
github.com/Unknwon/macaron = commit:5c8d1b7642
github.com/codegangsta/cli = commit:7381bc4e62
github.com/go-sql-driver/mysql = commit:8111ee3ec3
github.com/go-xorm/core = commit:3e0fa232ab
github.com/go-xorm/xorm = commit:58d33844ce
github.com/gogits/go-gogs-client = commit:3b1d86c3a8
github.com/gogits/oauth2 = commit:99cbec870a
github.com/lib/pq = commit:b021d0ef20
github.com/macaron-contrib/binding = commit:0e23661e7d
github.com/macaron-contrib/cache = commit:0bb9e6c9ef
github.com/macaron-contrib/captcha = commit:3567dc48b8
github.com/macaron-contrib/csrf = commit:422b79675c
github.com/macaron-contrib/i18n = commit:2246f45894
github.com/macaron-contrib/session = commit:f00d48fd4f
github.com/macaron-contrib/toolbox = commit:57127bcc89
github.com/mattn/go-sqlite3 = commit:a80c27ba33
github.com/nfnt/resize = commit:581d15cb53
github.com/russross/blackfriday = commit:05b8cefd6a
github.com/saintfish/chardet = commit:3af4cd4741
github.com/Unknwon/com = commit:188d690b1a
github.com/Unknwon/i18n = commit:1e88666229
github.com/Unknwon/macaron = commit:e089393c3f
github.com/codegangsta/cli = commit:6086d7927e
github.com/go-sql-driver/mysql = commit:27633f0519
github.com/go-xorm/core = commit:16cb27928f
github.com/go-xorm/xorm = commit:f2d3be988e
github.com/gogits/chardet = commit:2404f77725
github.com/gogits/go-gogs-client = commit:92e76d616a
github.com/lib/pq = commit:835d5eb08d
github.com/macaron-contrib/binding = commit:dc739fabc3
github.com/macaron-contrib/cache = commit:b68f6b448f
github.com/macaron-contrib/captcha = commit:066c50c7eb
github.com/macaron-contrib/csrf = commit:98ddf5a710
github.com/macaron-contrib/i18n = commit:eeebd44f64
github.com/macaron-contrib/oauth2 = commit:8f394c3629
github.com/macaron-contrib/session = commit:8e8d938b27
github.com/macaron-contrib/toolbox = commit:acbfe36e16
github.com/mattn/go-sqlite3 = commit:25d045f12a
github.com/microcosm-cc/bluemonday = commit:fcd0f5074e
github.com/nfnt/resize = commit:8f44931448
github.com/russross/blackfriday = commit:77efab57b2
github.com/shurcooL/go = commit:329f57438c
golang.org/x/net =
golang.org/x/text =
gopkg.in/ini.v1 = commit:4febc4104c
gopkg.in/redis.v2 = commit:e617904962
[res]
include = conf|etc|public|scripts|templates

View File

@@ -2,10 +2,7 @@ targets:
ubuntu-14.04:
ubuntu-12.04:
debian-7:
centos6:
build_dependencies:
- mercurial
- bzr
centos-6:
dependencies:
- git
before:

View File

@@ -2,4 +2,14 @@ language: go
go:
- 1.2
- 1.3
- 1.3
- 1.4
- tip
sudo: false
script: go build -v
notifications:
email:
- u@gogs.io

View File

@@ -2,7 +2,7 @@
> This guidelines sheet is forked from [CONTRIBUTING.md](https://github.com/drone/drone/blob/master/CONTRIBUTING.md).
Gogs is not perfect and it has bugs, or incomplete features for rare cases. You're welcome to tell us or contribute some code. This document describles details about how can you contribute to Gogs project.
Gogs is not perfect and it has bugs, or incomplete features for rare cases. You're welcome to tell us or contribute some code. This document describes details about how can you contribute to Gogs project.
## Contribution guidelines
@@ -15,36 +15,30 @@ Depends on the situation, you will:
### Bug Report
If you find or consider something is a bug, please create a issue on [GitHub](https://github.com/gogits/gogs/issues). To reduce unnecessary time wasting of interacting and waiting with team members, please use following form as template in the first place:
If you find or consider something is a bug, please create a issue on [GitHub](https://github.com/gogits/gogs/issues). To reduce unnecessary time wasting of interacting and waiting with team members, please include following information in the first place with a comfortable form for you:
```
- **Bug Description**:
- **Gogs Version**:
- **Git Version**:
- **System Type**:
- **Error Log**:
- **Other information**:
```
- Bug Description
- Gogs Version
- Git Version
- System Type
- Error Log
- Other information
Please take a moment to check that an issue on [GitHub](https://github.com/gogits/gogs/issues) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
#### Bug Report Example
- **Bug Description**: Crash when create repository with license|
- **Gogs Version**: `v0.4.9.0901`
- **Git Version**: `1.9.0`
- **System Type**: `Ubuntu 12.04`
- **Error Log**:
Gogs crashed when create repository with license, using v0.5.13.0207, SQLite3, Git 1.9.0, Ubuntu 12.04.
Error log:
```
2014/09/01 07:21:49 [E] nil pointer
```
- **Other information**: Use SQLite3 as database
### Feature Request
There is no standard form of making a feature request, just try to describle the feature as clear as possible because team members may not have experience with the functionality you're talking about.
There is no standard form of making a feature request, just try to describe the feature as clear as possible because team members may not have experience with the functionality you're talking about.
### Pull Request
@@ -54,7 +48,7 @@ We are always thrilled to receive pull requests, and do our best to process them
If your pull request is not accepted on the first try, don't be discouraged! If there's a problem with the implementation, hopefully you received feedback on what to improve.
We're trying very hard to keep Gogs lean and focused. We don't want it to do everything for everybody. This means that we might decide against incorporating a new feature.
We're trying very hard to keep Gogs lean and focused. We don't want it to do everything for everybody. This means that we might decide against incorporating a new feature. We believe you do like to discuss with us first in [Gitter](https://gitter.im/gogits/gogs).
### Ask For Help
@@ -64,8 +58,17 @@ Before open any new issue, please check your problem on [Troubleshooting](http:/
Please take a moment to check that an issue on [GitHub](https://github.com/gogits/gogs/issues) or card on [Trello](https://trello.com/b/uxAoeLUl/gogs-go-git-service) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
### Discuss your design on the mailing list
## Code of conduct
We recommend discussing your plans [on the mailing list](https://groups.google.com/forum/#!forum/gogits) before starting to code - especially for more ambitious contributions. This gives other contributors a chance to point you in the right direction, give feedback on your design, and maybe point out if someone else is working on the same thing.
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We may close your pull request if not first discussed on the mailing list. We aren't doing this to be jerks. We are doing this to prevent people from spending large amounts of time on changes that may need to be designed or architected in a specific way, or may not align with the vision of the project.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
Instances of abusive, harassing, or otherwise unacceptable behavior can be
reported by emailing contact@gitlab.com
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)

View File

@@ -1,16 +1,20 @@
Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs)
Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs)
=====================
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gogits/gogs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Gogs(Go Git Service) is a painless self-hosted Git Service written in Go.
![Demo](https://gowalker.org/public/gogs_demo.gif)
![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
##### Current version: 0.5.8 Beta
##### Current version: 0.5.13 Beta
### NOTICES
- Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) has been reset in **June 21, 2014** and will reset multiple times after. Please do **NOT** put your important data on the site.
- Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) has been reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
- Demo site [try.gogs.io](https://try.gogs.io) is running under `dev` branch.
- You **MUST** read [CONTRIBUTING.md](CONTRIBUTING.md) before you start filing a issue or making a Pull Request.
- If you think there are vulnerabilities in the project, please talk private to **u@gogs.io**, thanks!
#### Other language version
@@ -24,8 +28,9 @@ The goal of this project is to make the easiest, fastest and most painless way t
- Please see [Documentation](http://gogs.io/docs/intro/) for project design, known issues, and change log.
- See [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team.
- Try it before anything? Do it [online](https://try.gogs.io/Unknown/gogs) or go down to **Installation -> Install from binary** section!
- Try it before anything? Do it [online](https://try.gogs.io/unknwon/gogs) or go down to **Installation -> Install from binary** section!
- Having troubles? Get help from [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md).
- Want to help on localization? Check out [Crowdin](https://crowdin.com/project/gogs)!
## Features
@@ -47,7 +52,7 @@ The goal of this project is to make the easiest, fastest and most painless way t
- Drone CI integration
- Supports MySQL, PostgreSQL and SQLite3
- Social account login(GitHub, Google, QQ, Weibo)
- Multi-language support(English, Simplified Chinese, Traditional Chinese, Germany, French, Dutch, and [more](https://crowdin.com/project/gogs))
- Multi-language support([10 languages](https://crowdin.com/project/gogs))
## System Requirements
@@ -71,14 +76,15 @@ There are 5 ways to install Gogs:
- Router and middleware mechanism of [Macaron](https://github.com/Unknwon/macaron).
- Mail Service, modules design is inspired by [WeTalk](https://github.com/beego/wetalk).
- System Monitor Status is inspired by [GoBlog](https://github.com/fuxiaohei/goblog).
- Usage and modification from [beego](http://beego.me) modules.
- Thanks [lavachen](http://www.lavachen.cn/) and [Rocker](http://weibo.com/rocker1989) for designing Logo.
- Thanks [gobuild.io](http://gobuild.io) for providing binary compile and download service.
- Thanks [Crowdin](https://crowdin.com/project/gogs) for providing open source translation plan.
## Contributors
The [core team](http://gogs.io/team) of this project. See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
- The [core team](http://gogs.io/team) of this project.
- See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
- See [TRANSLATORS](conf/locale/TRANSLATORS) for full list of translators.
## License

View File

@@ -1,11 +1,11 @@
Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs)
Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs)
=====================
Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。
![Demo](https://gowalker.org/public/gogs_demo.gif)
![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
##### 当前版本0.5.8 Beta
##### 当前版本0.5.13 Beta
## 开发目的
@@ -15,8 +15,9 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- 有关项目设计、已知问题和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。
- 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
- 想要先睹为快?通过 [在线体验](https://try.gogs.io/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
- 想要先睹为快?通过 [在线体验](https://try.gogs.io/unknwon/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.md) 页面获取帮助。
- 希望帮助多国语言界面的翻译吗?请立即访问 [Crowdin](https://crowdin.com/project/gogs)
## 功能特性
@@ -38,7 +39,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- Drone CI 持续部署集成
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录GitHub、Google、QQ、微博
- 多语言支持(英文、简体中文、繁体中文、德语、法语、荷兰语以及 [更多]([more](https://crowdin.com/project/gogs))
- 多语言支持([10 种语言]([more](https://crowdin.com/project/gogs))
## 系统要求
@@ -59,8 +60,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
## 特别鸣谢
- [Macaron](https://github.com/Unknwon/macaron) 的路由与中间件机制。
- [beego](http://beego.me) 模块的使用与修改。
- 基于 [Macaron](https://github.com/Unknwon/macaron) 的路由与中间件机制。
- 基于 [WeTalk](https://github.com/beego/wetalk) 修改的邮件服务和模块设计。
- 基于 [GoBlog](https://github.com/fuxiaohei/goblog) 修改的系统监视状态。
- 感谢 [gobuild.io](http://gobuild.io) 提供二进制编译与下载服务。
@@ -69,7 +69,9 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
## 贡献成员
本项目的 [开发团队](http://gogs.io/team)。您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
- 本项目的 [开发团队](http://gogs.io/team)。
- 您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
- 您可以通过查看 [TRANSLATORS](conf/locale/TRANSLATORS) 文件获取完整的翻译人员列表。
## 授权许可

View File

@@ -8,7 +8,7 @@ package cmd
import (
"fmt"
"time"
"os"
"github.com/codegangsta/cli"
)
@@ -19,16 +19,9 @@ var CmdCert = cli.Command{
Description: `Generate a self-signed X.509 certificate for a TLS server.
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
Action: runCert,
Flags: []cli.Flag{
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""},
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""},
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""},
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""},
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""},
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""},
},
}
func runCert(ctx *cli.Context) {
fmt.Println("Command cert not available, please use build tags 'cert' to rebuild.")
os.Exit(1)
}

View File

@@ -25,11 +25,15 @@ var CmdDump = cli.Command{
It can be used for backup and capture Gogs server image to send to maintainer`,
Action: runDump,
Flags: []cli.Flag{
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
cli.BoolFlag{"verbose, v", "show process details", ""},
},
}
func runDump(ctx *cli.Context) {
if ctx.IsSet("config") {
setting.CustomConf = ctx.String("config")
}
setting.NewConfigContext()
models.LoadModelsConfig()
models.SetEngine()
@@ -58,7 +62,7 @@ func runDump(ctx *cli.Context) {
workDir, _ := setting.WorkDir()
z.AddFile("gogs-repo.zip", path.Join(workDir, "gogs-repo.zip"))
z.AddFile("gogs-db.sql", path.Join(workDir, "gogs-db.sql"))
z.AddFile("custom/conf/app.ini", path.Join(workDir, "custom/conf/app.ini"))
z.AddDir("custom", path.Join(workDir, "custom"))
z.AddDir("log", path.Join(workDir, "log"))
// FIXME: SSH key file.
if err = z.Close(); err != nil {

View File

@@ -1,181 +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 cmd
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"runtime"
"strings"
"github.com/codegangsta/cli"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/setting"
)
var CmdFix = cli.Command{
Name: "fix",
Usage: "This command for upgrade from old version",
Action: runFix,
Subcommands: fixCommands,
Flags: []cli.Flag{},
}
func runFix(ctx *cli.Context) {
}
var fixCommands = []cli.Command{
{
Name: "location",
Usage: "Change Gogs app location",
Description: `Command location fixes location change of Gogs
gogs fix location <old Gogs path>
`,
Action: runFixLocation,
},
}
// rewriteAuthorizedKeys replaces old Gogs path to the new one.
func rewriteAuthorizedKeys(sshPath, oldPath, newPath string) error {
fr, err := os.Open(sshPath)
if err != nil {
return err
}
defer fr.Close()
tmpPath := sshPath + ".tmp"
fw, err := os.Create(tmpPath)
if err != nil {
return err
}
defer fw.Close()
oldPath = "command=\"" + oldPath + " serv"
newPath = "command=\"" + newPath + " serv"
buf := bufio.NewReader(fr)
for {
line, errRead := buf.ReadString('\n')
line = strings.TrimSpace(line)
if errRead != nil {
if errRead != io.EOF {
return errRead
}
// Reached end of file, if nothing to read then break,
// otherwise handle the last line.
if len(line) == 0 {
break
}
}
// Still finding the line, copy the line that currently read.
if _, err = fw.WriteString(strings.Replace(line, oldPath, newPath, 1) + "\n"); err != nil {
return err
}
if errRead == io.EOF {
break
}
}
if err = os.Remove(sshPath); err != nil {
return err
}
return os.Rename(tmpPath, sshPath)
}
func rewriteUpdateHook(path, appPath string) error {
if runtime.GOOS == "windows" {
rp := strings.NewReplacer("\\", "/")
appPath = "\"" + rp.Replace(appPath) + "\""
} else {
rp := strings.NewReplacer("\\", "/", " ", "\\ ")
appPath = rp.Replace(appPath)
}
if err := ioutil.WriteFile(path, []byte(fmt.Sprintf(models.TPL_UPDATE_HOOK,
setting.ScriptType, appPath)), os.ModePerm); err != nil {
return err
}
return nil
}
func walkDir(rootPath, recPath, appPath string, depth int) error {
depth++
if depth > 3 {
return nil
} else if depth == 3 {
if err := rewriteUpdateHook(path.Join(rootPath, "hooks/update"), appPath); err != nil {
return err
}
}
dir, err := os.Open(rootPath)
if err != nil {
return err
}
defer dir.Close()
fis, err := dir.Readdir(0)
if err != nil {
return err
}
for _, fi := range fis {
if strings.Contains(fi.Name(), ".DS_Store") {
continue
}
relPath := path.Join(recPath, fi.Name())
curPath := path.Join(rootPath, fi.Name())
if fi.IsDir() {
if err = walkDir(curPath, relPath, appPath, depth); err != nil {
return err
}
}
}
return nil
}
func runFixLocation(ctx *cli.Context) {
if len(ctx.Args()) != 1 {
fmt.Println("Incorrect arguments number, expect 1")
os.Exit(2)
}
execPath, _ := setting.ExecPath()
oldPath := ctx.Args().First()
fmt.Printf("Old location: %s\n", oldPath)
fmt.Println("This command should be executed in the new Gogs path")
fmt.Printf("Do you want to change Gogs app path from old location to:\n")
fmt.Printf("-> %s?\n", execPath)
fmt.Print("Press <enter> to continue, use <Ctrl+c> to exit.")
fmt.Scanln()
// Fix in authorized_keys file.
sshPath := path.Join(models.SshPath, "authorized_keys")
fmt.Printf("Fixing pathes in file: %s\n", sshPath)
if err := rewriteAuthorizedKeys(sshPath, oldPath, execPath); err != nil {
fmt.Println(err)
os.Exit(1)
}
// Fix position in gogs-repositories.
setting.NewConfigContext()
fmt.Printf("Fixing pathes in repositories: %s\n", setting.RepoRootPath)
if err := walkDir(setting.RepoRootPath, "", execPath, 0); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("Fix position finished!")
}

View File

@@ -27,12 +27,20 @@ var CmdServ = cli.Command{
Usage: "This command should only be called by SSH shell",
Description: `Serv provide access auth for repositories`,
Action: runServ,
Flags: []cli.Flag{},
Flags: []cli.Flag{
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
},
}
func setup(logPath string) {
setting.NewConfigContext()
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
if setting.DisableSSH {
println("Gogs: SSH has been disabled")
os.Exit(1)
}
models.LoadModelsConfig()
if models.UseSQLite3 {
@@ -77,9 +85,15 @@ func In(b string, sl map[string]models.AccessType) bool {
}
func runServ(k *cli.Context) {
if k.IsSet("config") {
setting.CustomConf = k.String("config")
}
setup("serv.log")
keys := strings.Split(os.Args[2], "-")
if len(k.Args()) < 1 {
log.GitLogger.Fatal(2, "Not enough arguments")
}
keys := strings.Split(k.Args()[0], "-")
if len(keys) != 2 {
println("Gogs: auth file format error")
log.GitLogger.Fatal(2, "Invalid auth file format: %s", os.Args[2])
@@ -164,7 +178,7 @@ func runServ(k *cli.Context) {
log.GitLogger.Fatal(2, "User %s has no right to read repository %s", user.Name, repoPath)
}
default:
println("Unknown command")
println("Unknown command: " + cmd)
return
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
var CmdUpdate = cli.Command{
@@ -18,10 +19,15 @@ var CmdUpdate = cli.Command{
Usage: "This command should only be called by SSH shell",
Description: `Update get pushed info and insert into database`,
Action: runUpdate,
Flags: []cli.Flag{},
Flags: []cli.Flag{
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
},
}
func runUpdate(c *cli.Context) {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" {
return

View File

@@ -5,6 +5,7 @@
package cmd
import (
"crypto/tls"
"fmt"
"html/template"
"io/ioutil"
@@ -21,8 +22,12 @@ import (
"github.com/macaron-contrib/captcha"
"github.com/macaron-contrib/csrf"
"github.com/macaron-contrib/i18n"
"github.com/macaron-contrib/oauth2"
"github.com/macaron-contrib/session"
"github.com/macaron-contrib/toolbox"
"gopkg.in/ini.v1"
api "github.com/gogits/go-gogs-client"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
@@ -48,7 +53,16 @@ var CmdWeb = cli.Command{
Description: `Gogs web server is the only thing you need to run,
and it takes care of all the other things for you`,
Action: runWeb,
Flags: []cli.Flag{},
Flags: []cli.Flag{
cli.StringFlag{"port, p", "3000", "Temporary port number to prevent conflict", ""},
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
},
}
type VerChecker struct {
ImportPath string
Version func() string
Expected string
}
// checkVersion checks if binary matches the version of templates files.
@@ -63,17 +77,20 @@ func checkVersion() {
}
// Check dependency version.
macaronVer := git.MustParseVersion(strings.Join(strings.Split(macaron.Version(), ".")[:3], "."))
if macaronVer.LessThan(git.MustParseVersion("0.4.2")) {
log.Fatal(4, "Package macaron version is too old, did you forget to update?(github.com/Unknwon/macaron)")
checkers := []VerChecker{
{"github.com/Unknwon/macaron", macaron.Version, "0.5.1"},
{"github.com/macaron-contrib/binding", binding.Version, "0.0.4"},
{"github.com/macaron-contrib/cache", cache.Version, "0.0.7"},
{"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"},
{"github.com/macaron-contrib/i18n", i18n.Version, "0.0.5"},
{"github.com/macaron-contrib/session", session.Version, "0.1.6"},
{"gopkg.in/ini.v1", ini.Version, "1.2.0"},
}
i18nVer := git.MustParseVersion(i18n.Version())
if i18nVer.LessThan(git.MustParseVersion("0.0.2")) {
log.Fatal(4, "Package i18n version is too old, did you forget to update?(github.com/macaron-contrib/i18n)")
}
sessionVer := git.MustParseVersion(session.Version())
if sessionVer.LessThan(git.MustParseVersion("0.0.5")) {
log.Fatal(4, "Package session version is too old, did you forget to update?(github.com/macaron-contrib/session)")
for _, c := range checkers {
ver := strings.Join(strings.Split(c.Version(), ".")[:3], ".")
if git.MustParseVersion(ver).LessThan(git.MustParseVersion(c.Expected)) {
log.Fatal(4, "Package '%s' version is too old(%s -> %s), did you forget to update?", c.ImportPath, ver, c.Expected)
}
}
}
@@ -94,6 +111,13 @@ func newMacaron() *macaron.Macaron {
SkipLogging: !setting.DisableRouterLog,
},
))
m.Use(macaron.Static(
setting.AvatarUploadPath,
macaron.StaticOptions{
Prefix: "avatars",
SkipLogging: !setting.DisableRouterLog,
},
))
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: path.Join(setting.StaticRootPath, "templates"),
Funcs: []template.FuncMap{base.TemplateFuncs},
@@ -108,18 +132,15 @@ func newMacaron() *macaron.Macaron {
Redirect: true,
}))
m.Use(cache.Cacher(cache.Options{
Adapter: setting.CacheAdapter,
Interval: setting.CacheInternal,
Conn: setting.CacheConn,
Adapter: setting.CacheAdapter,
AdapterConfig: setting.CacheConn,
Interval: setting.CacheInternal,
}))
m.Use(captcha.Captchaer(captcha.Options{
SubURL: setting.AppSubUrl,
}))
m.Use(session.Sessioner(session.Options{
Provider: setting.SessionProvider,
Config: *setting.SessionConfig,
}))
m.Use(csrf.Generate(csrf.Options{
m.Use(session.Sessioner(setting.SessionConfig))
m.Use(csrf.Csrfer(csrf.Options{
Secret: setting.SecretKey,
SetCookie: true,
Header: "X-Csrf-Token",
@@ -133,14 +154,25 @@ func newMacaron() *macaron.Macaron {
},
},
}))
// OAuth 2.
if setting.OauthService != nil {
for _, info := range setting.OauthService.OauthInfos {
m.Use(oauth2.NewOAuth2Provider(info.Options, info.AuthUrl, info.TokenUrl))
}
}
m.Use(middleware.Contexter())
return m
}
func runWeb(*cli.Context) {
routers.GlobalInit()
func runWeb(ctx *cli.Context) {
checkVersion()
if ctx.IsSet("config") {
setting.CustomConf = ctx.String("config")
}
routers.GlobalInit()
m := newMacaron()
reqSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true})
@@ -154,8 +186,9 @@ func runWeb(*cli.Context) {
// Routers.
m.Get("/", ignSignIn, routers.Home)
m.Get("/explore", ignSignIn, routers.Explore)
m.Get("/install", bindIgnErr(auth.InstallForm{}), routers.Install)
m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallPost)
m.Combo("/install", routers.InstallInit).
Get(routers.Install).
Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost)
m.Group("", func() {
m.Get("/pulls", user.Pulls)
m.Get("/issues", user.Issues)
@@ -183,14 +216,15 @@ func runWeb(*cli.Context) {
})
// Repositories.
m.Get("/user/repos", middleware.ApiReqToken(), v1.ListMyRepos)
m.Combo("/user/repos", middleware.ApiReqToken()).Get(v1.ListMyRepos).Post(bind(api.CreateRepoOption{}), v1.CreateRepo)
m.Post("/org/:org/repos", middleware.ApiReqToken(), bind(api.CreateRepoOption{}), v1.CreateOrgRepo)
m.Group("/repos", func() {
m.Get("/search", v1.SearchRepos)
m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), v1.Migrate)
m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), v1.MigrateRepo)
m.Group("/:username/:reponame", func() {
m.Combo("/hooks").Get(v1.ListRepoHooks).Post(bind(v1.CreateRepoHookForm{}), v1.CreateRepoHook)
m.Patch("/hooks/:id:int", bind(v1.EditRepoHookForm{}), v1.EditRepoHook)
m.Combo("/hooks").Get(v1.ListRepoHooks).Post(bind(api.CreateHookOption{}), v1.CreateRepoHook)
m.Patch("/hooks/:id:int", bind(api.EditHookOption{}), v1.EditRepoHook)
m.Get("/raw/*", middleware.RepoRef(), v1.GetRepoRawFile)
}, middleware.ApiRepoAssignment(), middleware.ApiReqToken())
})
@@ -205,7 +239,7 @@ func runWeb(*cli.Context) {
m.Group("/user", func() {
m.Get("/login", user.SignIn)
m.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost)
m.Get("/login/:name", user.SocialSignIn)
m.Get("/info/:name", user.SocialSignIn)
m.Get("/sign_up", user.SignUp)
m.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost)
m.Get("/reset_password", user.ResetPasswd)
@@ -214,6 +248,9 @@ func runWeb(*cli.Context) {
m.Group("/user/settings", func() {
m.Get("", user.Settings)
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), user.SettingsAvatar)
m.Get("/email", user.SettingsEmails)
m.Post("/email", bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
m.Get("/password", user.SettingsPassword)
m.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost)
m.Get("/ssh", user.SettingsSSHKeys)
@@ -225,6 +262,7 @@ func runWeb(*cli.Context) {
m.Group("/user", func() {
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
m.Any("/activate", user.Activate)
m.Any("/activate_email", user.ActivateEmail)
m.Get("/email2user", user.Email2User)
m.Get("/forget_password", user.ForgotPasswd)
m.Post("/forget_password", user.ForgotPasswdPost)
@@ -380,14 +418,17 @@ func runWeb(*cli.Context) {
})
m.Post("/comment/:action", repo.Comment)
m.Get("/releases/new", repo.NewRelease)
m.Post("/releases/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
m.Get("/releases/edit/:tagname", repo.EditRelease)
m.Post("/releases/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
m.Group("/releases", func() {
m.Get("/new", repo.NewRelease)
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
m.Get("/edit/:tagname", repo.EditRelease)
m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
}, middleware.RepoRef())
}, reqSignIn, middleware.RepoAssignment(true))
m.Group("/:username/:reponame", func() {
m.Get("/releases", repo.Releases)
m.Get("/releases", middleware.RepoRef(), repo.Releases)
m.Get("/issues", repo.Issues)
m.Get("/issues/:index", repo.ViewIssue)
m.Get("/issues/milestones", repo.Milestones)
@@ -397,6 +438,7 @@ func runWeb(*cli.Context) {
m.Get("/issues2/", repo.Issues2)
m.Get("/pulls2/", repo.PullRequest2)
m.Get("/labels2/", repo.Labels2)
m.Get("/milestone2/", repo.Milestones2)
m.Group("", func() {
m.Get("/src/*", repo.Home)
@@ -425,6 +467,12 @@ func runWeb(*cli.Context) {
// Not found handler.
m.NotFound(routers.NotFound)
// Flag for port number in case first time run conflict.
if ctx.IsSet("port") {
setting.AppUrl = strings.Replace(setting.AppUrl, setting.HttpPort, ctx.String("port"), 1)
setting.HttpPort = ctx.String("port")
}
var err error
listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
@@ -432,7 +480,8 @@ func runWeb(*cli.Context) {
case setting.HTTP:
err = http.ListenAndServe(listenAddr, m)
case setting.HTTPS:
err = http.ListenAndServeTLS(listenAddr, setting.CertFile, setting.KeyFile, m)
server := &http.Server{Addr: listenAddr, TLSConfig: &tls.Config{MinVersion: tls.VersionTLS10}, Handler: m}
err = server.ListenAndServeTLS(setting.CertFile, setting.KeyFile)
case setting.FCGI:
err = fcgi.Serve(nil, m)
default:

View File

@@ -1,3 +1,6 @@
# NEVER EVER MODIFY THIS FILE
# PLEASE MAKE CHANGES ON CORRESPONDING CUSTOM CONFIG FILE
; App name that shows on every page title
APP_NAME = Gogs: Go Git Service
; Change it if you run locally
@@ -15,6 +18,8 @@ DOMAIN = localhost
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
HTTP_ADDR =
HTTP_PORT = 3000
; Disable SSH feature when not available
DISABLE_SSH = false
SSH_PORT = 22
; Disable CDN even in "prod" mode
OFFLINE_MODE = false
@@ -22,6 +27,11 @@ DISABLE_ROUTER_LOG = false
; Generate steps:
; $ cd path/to/gogs/custom/https
; $ ./gogs cert -ca=true -duration=8760h0m0s -host=myhost.example.com
;
; Or from a .pfx file exported from the Windows certificate store (do
; not forget to export the private key):
; $ openssl pkcs12 -in cert.pfx -out cert.pem -nokeys
; $ openssl pkcs12 -in cert.pfx -out key.pem -nocerts -nodes
CERT_FILE = custom/https/cert.pem
KEY_FILE = custom/https/key.pem
; Upper level of template and static file path
@@ -29,6 +39,8 @@ KEY_FILE = custom/https/key.pem
STATIC_ROOT_PATH =
; Application level GZIP support
ENABLE_GZIP = false
; Landing page for non-logged users, can be "home" or "explore"
LANDING_PAGE = home
[database]
; Either "mysql", "postgres" or "sqlite3", it's your choice
@@ -70,12 +82,15 @@ ENABLE_CACHE_AVATAR = false
ENABLE_NOTIFY_MAIL = false
; More detail: https://github.com/gogits/gogs/issues/165
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
ENABLE_REVERSE_PROXY_AUTO_REGISTERATION = false
[webhook]
; Cron task interval in minutes
TASK_INTERVAL = 1
; Deliver timeout in seconds
DELIVER_TIMEOUT = 5
; Allow insecure certification
SKIP_TLS_VERIFY = false
[mailer]
ENABLED = false
@@ -86,8 +101,11 @@ SUBJECT = %(APP_NAME)s
; Mail server
; Gmail: smtp.gmail.com:587
; QQ: smtp.qq.com:25
; Note, if the port ends with "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409. If the server supports STARTTLS it will always be used.
HOST =
; Mail from address
; Do not verify the certificate of the server. Only use this for self-signed certificates
SKIP_VERIFY =
; Mail from address, RFC 5322. This can be just an email address, or the "Name" <email@example.com> format
FROM =
; Mailer user name and password
USER =
@@ -118,13 +136,10 @@ TOKEN_URL = https://accounts.google.com/o/oauth2/token
ENABLED = false
CLIENT_ID =
CLIENT_SECRET =
SCOPES = all
SCOPES = get_user_info
; QQ 互联
; AUTH_URL = https://graph.qq.com/oauth2.0/authorize
; TOKEN_URL = https://graph.qq.com/oauth2.0/token
; Tencent weibo
AUTH_URL = https://open.t.qq.com/cgi-bin/oauth2/authorize
TOKEN_URL = https://open.t.qq.com/cgi-bin/oauth2/access_token
AUTH_URL = https://graph.qq.com/oauth2.0/authorize
TOKEN_URL = https://graph.qq.com/oauth2.0/token
[oauth.weibo]
ENABLED = false
@@ -140,17 +155,17 @@ ADAPTER = memory
; For "memory" only, GC interval in seconds, default is 60
INTERVAL = 60
; For "redis" and "memcache", connection host address
; redis: `:6039`
; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
; memcache: `127.0.0.1:11211`
HOST =
[session]
; Either "memory", "file", "redis" or "mysql", default is "memory"
PROVIDER = file
PROVIDER = memory
; Provider config options
; memory: not have any config yet
; file: session file path, e.g. `data/sessions`
; redis: config like redis server addr, poolSize, password, e.g. `127.0.0.1:6379,100,gogs`
; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
PROVIDER_CONFIG = data/sessions
; Session cookie name
@@ -167,6 +182,7 @@ SESSION_LIFE_TIME = 86400
[picture]
; The place to picture data, either "server" or "qiniu", default is "server"
SERVICE = server
AVATAR_UPLOAD_PATH = data/avatars
; Chinese users can choose "duoshuo"
GRAVATAR_SOURCE = gravatar
DISABLE_GRAVATAR = false
@@ -251,8 +267,20 @@ DRIVER =
CONN =
[git]
MAX_GITDIFF_LINES = 10000
MAX_GIT_DIFF_LINES = 10000
; Arguments for command 'git gc', e.g.: "--aggressive --auto"
; see more on http://git-scm.com/docs/git-gc/1.7.5
GC_ARGS =
; Git health check.
[git.fsck]
ENABLE = true
; Execution interval in hours. Default is 24.
INTERVAL = 24
; Arguments for command 'git fsck', e.g.: "--unreachable --tags"
; see more on http://git-scm.com/docs/git-fsck/1.7.5
ARGS =
[i18n]
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL,lv-LV,ru-RU,ja-JP,es-ES
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本语,Español

10
conf/locale/TRANSLATORS Normal file
View File

@@ -0,0 +1,10 @@
# This file lists all PUBLIC individuals having contributed content to the translation.
# Order of name is meaningless.
Akihiro YAGASAKI <yaggytter@momiage.com>
Christoph Kisfeld <christoph.kisfeld@gmail.com>
Huimin Wang <wanghm2009@hotmail.co.jp>
Thomas Fanninger <gogs.thomas@fanninger.at>
Łukasz Jan Niemier <lukasz@niemier.pl>
Lafriks <lafriks@gmail.com>
Miguel de la Cruz <miguel@mcrx.me>

View File

@@ -59,9 +59,11 @@ run_user=Ausführender Benutzer
run_user_helper=Der Benutzer muss die Zugriffsberechtigung für das Repository Root-Verzeichnis haben und der ausführende Benutzer von Gogs sein.
domain=Domain
domain_helper=Dies hat Auswirkung auf die SSH clone URLs.
http_port=HTTP Port
http_port_helper=Port number which application will listen on.
app_url=Anwendungs-URL
app_url_helper=Dies hat Auswirkung auf die HTTP/HTTPS clone URLs und für die E-Mails.
email_title=E-Mail-Service-Einstellungen (optional)
email_title=E-Mail-Service Einstellungen (optional)
smtp_host=SMTP Host
mailer_user=Sender E-mail
mailer_password=Sender Passwort
@@ -109,7 +111,7 @@ confirmation_mail_sent_prompt=Eine neue Bestätigungs-E-Mail wurde an <b>%s</b>
sign_in_email=Melde dich mit deiner E-Mail-Adresse an
active_your_account=Aktiviere dein Konto
resent_limit_prompt=Es tut uns leid, du sendest zu häufig Aktivierungs-E-Mails. Bitte warte 3 Minuten.
has_unconfirmed_mail=Hallo %s, du hast eine unbestätigte E-Mail-Adresse (<b>%s</b>). Falls du noch keine Bestätigungs-E-Mail erhalten hast oder eine neue senden musst, klicke auf den unteren Button.
has_unconfirmed_mail=Hallo %s, du hast eine unbestätigte E-Mail-Adresse (<b>%s</b>). Wenn du keine Bestätigungs-E-Mail erhalten hast oder eine neue benötigtst, klicke bitte auf den folgenden Button.
resend_mail=Hier klicken, um deine Aktivierungs-E-Mail erneut zu versenden
email_not_associate=Diese E-Mail-Adresse ist mit keinem Konto verknüpft.
send_reset_mail=Hier klicken, um die E-Mail zum Passwort-zurücksetzen erneut zu versenden
@@ -164,7 +166,7 @@ unable_verify_ssh_key=Gogs kann deinen SSH-Schlüssel nicht verifizieren, nimmt
auth_failed=Authentifizierung fehlgeschlagen: %v
still_own_repo=Dein Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
still_has_org=Ihr Konto noch Mitgliedschaft in der Organisation, Sie nach links oder löschen Sie sie zuerst.
still_has_org=Du bist noch Mitglied einer Organisation, bitte lösche zunächst diese Mitgliedschaft.
org_still_own_repo=Diese Organisation besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
still_own_user=Diese Authentifizierung wird noch von einigen Benutzern genutzt. Entferne diese zuvor und lösche erneut.
@@ -173,6 +175,7 @@ target_branch_not_exist=Ziel-Branch existiert nicht
[user]
change_avatar=Ändere dein Profilbild auf gravatar.com
change_custom_avatar=Ändere deinen Avatar in den Einstellungen
join_on=Registriert
repositories=Repositorys
activity=Öffentliche Aktivität
@@ -191,7 +194,7 @@ delete=Konto löschen
uid=Uid
public_profile=Öffentliches Profil
profile_desc=Deine E-Mail-Adresse ist öffentlich und dient dazu, dir Benachrichtigungen bezüglich deines Kontos und deiner Repositorys zu schicken.
profile_desc=Deine E-Mail-Adresse ist öffentlich einsehbar und wird für accountspezifische Benachrichtigungen verwendet, sowie für alle web-basierten Funktionen, die über die Seite gemacht werden.
full_name=Vollständiger Name
website=Webseite
location=Standort
@@ -202,12 +205,30 @@ change_username_desc=Benutzername wurde geändert, möchtest du fortfahren? Dies
continue=Weiter
cancel=Abbrechen
enable_custom_avatar=Aktiviere benuztzerdefinierten Avatar
enable_custom_avatar_helper=Aktiviere dies, um deinen Avatar nicht von Gravatar zu laden
choose_new_avatar=Neuen Avatar auswählen
update_avatar=Avatar-Einstellung aktualisieren
uploaded_avatar_not_a_image=Die hochgeladene Datei ist kein Bild.
no_custom_avatar_available=Kein benutzerdefinierter Avatar verfügbar, Aktivierung ist nicht möglich.
update_avatar_success=Deine Avatar-Einstellung wurde aktualisiert.
change_password=Passwort ändern
old_password=Aktuelles Passwort
new_password=Neues Passwort
password_incorrect=Aktuelles Passwort ist nicht korrekt.
change_password_success=Passwort geändert. Du kannst dich jetzt mit dem neuen Passwort anmelden.
emails=E-Mail-Adressen
manage_emails=E-Mail-Adressen verwalten
email_desc=Deine primäre E-Mail-Adresse wird für Benachrichtigungen und andere Funktionen verwendet.
primary=Primär
primary_email=Als primäre Adresse verwenden
delete_email=Löschen
add_new_email=Neue E-Mail-Adresse hinzufügen
add_email=E-Mail-Adresse hinzufügen
add_email_success=Deine neue E-Mail-Adresse wurde erfolgreich hinzugefügt.
manage_ssh_keys=SSH-Schlüssel verwalten
add_key=SSH-Schlüssel hinzufügen
ssh_desc=Dies ist eine Liste aller SSH-Schlüssel, die mit deinem Konto verknüpft sind. Entferne alle Schlüssel, die du nicht kennst.
@@ -273,7 +294,7 @@ click_to_copy=In Zwischenablage kopieren
copied=Kopiert OK
clone_helper=Du brauchst Hilfe beim Klonen? Hier gibt es <a target="_blank" href="%s">Hilfe</a>!
unwatch=Beobachtung beenden
watch=Beobachtung
watch=Beobachten
unstar=Markierung aufheben
star=Markierung
fork=Abspaltung
@@ -368,10 +389,34 @@ diff.stats_desc=<strong> %d geänderte Dateien</strong> mit <strong>%d neuen Zei
diff.bin=BIN
diff.view_file=Datei anzeigen
release.releases=Releases
release.new_release=Neues Release
release.draft=Entwurf
release.prerelease=Pre-Release
release.stable=Endversion
release.edit=bearbeiten
release.ahead=<strong>%d</strong> Commits zu %s seit diesem Release
release.source_code=Quelltext
release.tag_name=Tag-Name
release.target=Ziel
release.tag_helper=Wähle ein neues Tag oder erstelle ein Tag beim Veröffentlichen.
release.release_title=Release-Titel
release.content_with_md=Inhalt mit <a href="%s">Markdown</a>
release.write=Schreiben
release.preview=Vorschau
release.content_placeholder=Schreibe hier etwas
release.loading=Laden…
release.prerelease_desc=Dies ist eine Pre-Release-Version
release.prerelease_helper=Wir möchten darauf hinweisen, dass dieses Release nicht für den produktiven Einsatz gedacht ist.
release.publish=Release veröffentlichen
release.save_draft=Entwurf speichern
release.edit_release=Release bearbeiten
release.tag_name_already_exist=Ein Release mit diesem Tag existiert bereits.
[org]
org_name_holder=Name der Organisation
org_name_helper=Gute Namen von Organisationen sind kurz und einprägsam.
org_email_helper=Das E-Mail-Konto der Organisation empfängt alle Benachrichtigungen.
org_email_helper=Die E-Mail-Adresse der Organisation erhält alle Benachrichtigungen und Bestätigungs-E-Mails.
create_org=Organisation erstellen
repo_updated=Aktualisiert
people=Personen
@@ -462,11 +507,18 @@ dashboard.operation_name=Name der Operation
dashboard.operation_switch=Switch
dashboard.operation_run=Ausführen
dashboard.clean_unbind_oauth=ungebundene OAuths bereinigen
dashboard.clean_unbind_oauth_success=Alle aufheben OAuthes erfolgreich gelöscht wurden.
dashboard.clean_unbind_oauth_success=Alle ungebundenen OAuth-Tokens wurden gelöscht.
dashboard.delete_inactivate_accounts=inaktive Konten löschen
dashboard.delete_inactivate_accounts_success=Alle inaktive Konten erfolgreich gelöscht wurden.
dashboard.delete_repo_archives=Alle Repositories Archive löschen
dashboard.delete_repo_archives_success=Alle Repositories Archive wurden erfolgreich gelöscht.
dashboard.delete_inactivate_accounts_success=Alle inaktiven Konten wurden erfolgreich gelöscht.
dashboard.delete_repo_archives=Alle Repository-Archive löschen
dashboard.delete_repo_archives_success=Alle Repositoriy-Archive wurden gelöscht.
dashboard.git_gc_repos=Führe Garbage Collection auf Repositories aus
dashboard.git_gc_repos_success=Garbage Collection wurde auf allen Repositories erfolgreich ausgeführt.
dashboard.resync_all_sshkeys=Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success=All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Server-Uptime
dashboard.current_goroutine=Aktuelle Goroutines
dashboard.current_memory_usage=Aktuelle Speichernutzung
@@ -512,11 +564,11 @@ users.update_profile_success=Kontoprofil aktualisiert
users.edit_account=Konto bearbeiten
users.is_activated=Dieses Konto ist aktiviert
users.is_admin=Dieses Konto hat Administratorrechte
users.allow_git_hook=Dieses Konto verfügt über Berechtigungen zum Erstellen von Git hooks
users.allow_git_hook=Dieses Konto ist berechtigt, Git-Hooks zu erstellen
users.update_profile=Kontoprofil aktualisieren
users.delete_account=Dieses Konto löschen
users.still_own_repo=Dieses Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
users.still_has_org=Dieses Konto noch Mitgliedschaft in der Organisation, Sie nach links oder löschen Sie sie zuerst.
users.still_has_org=Dieses Konto ist noch Mitglied einer Organisation, bitte entferne diese Mitgliedschaft zuerst.
orgs.org_manage_panel=Organisationenverwaltung
orgs.name=Name
@@ -586,6 +638,7 @@ config.db_path_helper=(nur für "sqlite3")
config.service_config=Service-Einstellungen
config.register_email_confirm=E-Mail-Bestätigung bei Registrierung
config.disable_register=Registrierung deaktivieren
config.show_registration_button=Show Register Button
config.require_sign_in_view=Ansehen erfordert Registrierung
config.mail_notify=E-Mail-Benachrichtigung
config.enable_cache_avatar=Avatar-Cache aktivieren
@@ -594,6 +647,7 @@ config.reset_password_code_lives=Passwortcode Lebensdauer
config.webhook_config=Webhook-Einstellungen
config.task_interval=Task-Intervall
config.deliver_timeout=Zeitlimit für Zustellung
config.skip_tls_verify=Skip TLS Verify
config.mailer_config=Mailer-Einstellungen
config.mailer_enabled=Aktiviert
config.mailer_name=Name
@@ -641,8 +695,8 @@ notices.delete_success=System-Mitteilung erfolgreich gelöscht.
[action]
create_repo=hat Repository <a href="%s/%s">%s</a> erstellt
commit_repo=hat nach <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a> gepusht
create_issue=hat Issue <a href="%s/%s/issues/%s">%s#%s</a> eröffnet
comment_issue=hat Issue <a href="%s/%s/issues/%s">%s#%s</a> kommentiert
create_issue=`hat Issue <a href="%s/issues/%s">%[1]s#%[2]s</a> eröffnet`
comment_issue=`hat Issue <a href="%s/issues/%s">%[1]s#%[2]s</a> kommentiert`
transfer_repo=hat Repository <code>%s</code> transferiert an <a href="/%s%s">%s</a>
push_tag=hat nach <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a> gepusht
compare_2_commits=Zeige Vergleich dieser 2 Commits
@@ -668,16 +722,3 @@ years=%[2]s %[1]d Jahren
raw_seconds=Sekunden
raw_minutes=Minuten

View File

@@ -59,13 +59,15 @@ 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.
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 e-mail.
email_title = Email Service Settings(Optional)
email_title = E-mail Service Settings (Optional)
smtp_host = SMTP Host
mailer_user = Sender E-mail
mailer_password = Sender Password
notify_title = Notification Settings(Optional)
mailer_password = Sender Password
notify_title = Notification Settings (Optional)
register_confirm = Enable Register Confirmation
mail_notify = Enable Mail Notification
admin_title = Admin Account Settings
@@ -109,7 +111,7 @@ confirmation_mail_sent_prompt = A new confirmation e-mail has been sent to <b>%s
sign_in_email = Sign in to your e-mail
active_your_account = Activate Your Account
resent_limit_prompt = Sorry, you are sending an activation e-mail too frequently. Please wait 3 minutes.
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address(<b>%s</b>). If you haven't received a confirmation e-mail or need to resend a new one, please click on the button below.
has_unconfirmed_mail = Hi %s, you have an unconfirmed e-mail address (<b>%s</b>). If you haven't received a confirmation e-mail or need to resend a new one, please click on the button below.
resend_mail = Click here to resend your activation e-mail
email_not_associate = This e-mail address does not associate to any account.
send_reset_mail = Click here to (re)send your password reset e-mail
@@ -173,6 +175,7 @@ target_branch_not_exist = Target branch does not exist
[user]
change_avatar = Change your avatar at gravatar.com
change_custom_avatar = Change your avatar in settings
join_on = Joined on
repositories = Repositories
activity = Public Activity
@@ -191,7 +194,7 @@ delete = Delete Account
uid = Uid
public_profile = Public Profile
profile_desc = Your Email address is public and will be used for any account related notifications, and any web based operations made via the site.
profile_desc = Your E-mail address is public and will be used for any account related notifications, and any web based operations made via the site.
full_name = Full Name
website = Website
location = Location
@@ -202,12 +205,30 @@ change_username_desc = Username has been changed, do you want to continue? This
continue = Continue
cancel = Cancel
enable_custom_avatar = Enable Custom Avatar
enable_custom_avatar_helper = Enable this to disable fetch from Gravatar
choose_new_avatar = Choose new avatar
update_avatar = Update Avatar Setting
uploaded_avatar_not_a_image = Uploaded file is not a image.
no_custom_avatar_available = No custom avatar available, cannot enable it.
update_avatar_success = Your avatar setting has been updated successfully.
change_password = Change Password
old_password = Current Password
new_password = New Password
password_incorrect = Current password is not correct.
change_password_success = Password is changed successfully. You can now sign in via new password.
emails = E-mail Addresses
manage_emails = Manage e-mail addresses
email_desc = Your primary e-mail address will be used for notifications and other operations.
primary = Primary
primary_email = Set as primary
delete_email = Delete
add_new_email = Add new e-mail address
add_email = Add e-mail
add_email_success = Your new E-mail address was successfully added.
manage_ssh_keys = Manage SSH Keys
add_key = Add Key
ssh_desc = This is a list of SSH keys associated with your account. Remove any keys that you do not recognize.
@@ -259,7 +280,7 @@ license_helper = Select a license file
init_readme = Initialize this repository with a README.md
create_repo = Create Repository
default_branch = Default Branch
mirror_interval = Mirror Interval(hour)
mirror_interval = Mirror Interval (hour)
goget_meta = Go-Get Meta
goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span>
@@ -368,10 +389,34 @@ diff.stats_desc = <strong> %d changed files</strong> with <strong>%d additions</
diff.bin = BIN
diff.view_file = View File
release.releases = Releases
release.new_release = New Release
release.draft = Draft
release.prerelease = Pre-Release
release.stable = Stable
release.edit = edit
release.ahead = <strong>%d</strong> commits to %s since this release
release.source_code = Source Code
release.tag_name = Tag name
release.target = Target
release.tag_helper = Choose an existing tag, or create a new tag on publish.
release.release_title = Release title
release.content_with_md = Content with <a href="%s">Markdown</a>
release.write = Write
release.preview = Preview
release.content_placeholder = Write some content
release.loading = Loading...
release.prerelease_desc = This is a pre-release
release.prerelease_helper = Well point out that this release is identified as non-production ready.
release.publish = Publish Release
release.save_draft = Save Draft
release.edit_release = Edit Release
release.tag_name_already_exist = Release with this tag name has already existed.
[org]
org_name_holder = Organization Name
org_name_helper = Great organization names are short and memorable.
org_email_helper = Organization's Email receives all notifications and confirmations.
org_email_helper = Organization's E-mail receives all notifications and confirmations.
create_org = Create Organization
repo_updated = Updated
people = People
@@ -467,6 +512,13 @@ dashboard.delete_inactivate_accounts = Delete all inactive accounts
dashboard.delete_inactivate_accounts_success = All inactivate accounts have been deleted successfully.
dashboard.delete_repo_archives = Delete all repositories archives
dashboard.delete_repo_archives_success = All repositories archives have been deleted successfully.
dashboard.git_gc_repos = Do garbage collection on repositories
dashboard.git_gc_repos_success = All repositories have done garbage collection successfully.
dashboard.resync_all_sshkeys = Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success = All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks = Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success = All repositories' update hook have been rewritten successfully.
dashboard.server_uptime = Server Uptime
dashboard.current_goroutine = Current Goroutines
dashboard.current_memory_usage = Current Memory Usage
@@ -584,8 +636,9 @@ config.db_ssl_mode_helper = (for "postgres" only)
config.db_path = Path
config.db_path_helper = (for "sqlite3" only)
config.service_config = Service Configuration
config.register_email_confirm = Register Email Confirmation
config.register_email_confirm = Require E-mail Confirmation
config.disable_register = Disable Registration
config.show_registration_button = Show Register Button
config.require_sign_in_view = Require Sign In View
config.mail_notify = Mail Notification
config.enable_cache_avatar = Enable Cache Avatar
@@ -594,6 +647,7 @@ config.reset_password_code_lives = Reset Password Code Lives
config.webhook_config = Webhook Configuration
config.task_interval = Task Interval
config.deliver_timeout = Deliver Timeout
config.skip_tls_verify = Skip TLS Verify
config.mailer_config = Mailer Configuration
config.mailer_enabled = Enabled
config.mailer_name = Name
@@ -641,8 +695,8 @@ notices.delete_success = System notice has been deleted successfully.
[action]
create_repo = created repository <a href="%s/%s">%s</a>
commit_repo = pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a>
create_issue = opened issue <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue = commented on issue <a href="%s/%s/issues/%s">%s#%s</a>
create_issue = `opened issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue = `commented on issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo = transfered repository <code>%s</code> to <a href="/%s%s">%s</a>
push_tag = pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a>
compare_2_commits = View comparison for these 2 commits
@@ -667,16 +721,3 @@ months = %d months %s
years = %d years %s
raw_seconds = seconds
raw_minutes = minutes

724
conf/locale/locale_es-ES.ini Executable file
View File

@@ -0,0 +1,724 @@
app_desc=Un servicio de Git auto alojado y sin complicaciones
home=Incio
dashboard=Panel de control
explore=Explorar
help=Ayuda
sign_in=Iniciar sesión
social_sign_in=Inicio de sesión social: 2° paso <small>cuenta de asociado</small>
sign_out=Cerrar sesión
sign_up=Suscripción
register=Registro
website=Pagina Web
version=Versión
page=Página
template=Plantilla
language=Lenguaje
username=Nombre de usuario
email=Correo electrónico
password=Contraseña
re_type=Ingrese de nuevo
captcha=Captcha
repository=Repositorio
organization=Organización
mirror=Espejo
new_repo=Nuevo repositorio
new_migrate=Nueva Migración
new_fork=Nuevo Fork del Repositorio
new_org=Nueva organización
manage_org=Administrar organizaciones
admin_panel=Panel de administración
account_settings=Configuraciones de la cuenta
settings=Configuraciones
news_feed=entrada de noticias
pull_requests=Solicitudes de retiro
issues=Publicaciones
cancel=Cancelar
[install]
install=Instalación
title=Pasos de la instalación por primera vez
requite_db_desc=Gogs necesita MySQL, PostgreSQL o SQLite3.
db_type=Tipo de base de datos
host=Anfitrión
user=Usuario
password=Contraseña
db_name=Nombre de la base de datos
db_helper=Por favor utilice el motor INNODB con la configuración de caracteres utf8_general_ci para MySQL.
ssl_mode=Modo SSL
path=Ruta
sqlite_helper=Ruta del archivo de la base de datos de SQLite3.
general_title=Configuraciones Generales de Gogs
repo_path=Ruta del repositorio de Raiz (Root)
repo_path_helper=Todos los repositorios remotos de Git se guardarán en este directorio.
run_user=Abrir el usuario
run_user_helper=El usuario necesita tener acceso a la Ruta Raíz del Repositorio y ejecutar Gogs.
domain=Dominio
domain_helper=Esto afecta a las URLs para clonar por SSH.
http_port=Puerto HTTP
http_port_helper=Puerto en el que escuchará la aplicación.
app_url=URL de la aplicación
app_url_helper=Esto afecta a las URLs para clonar por HTTP/HTTPS y a algunos correos electrónicos.
email_title=Configuración del Servicio de Correo (Opcional)
smtp_host=SMTP Host
mailer_user=Remitente del Correo Electrónico
mailer_password=Contraseña del Remitente
notify_title=Configuración de Notificaciones (Opcional)
register_confirm=Habilitar la Confirmación en el Registro
mail_notify=Habilitar las Notificaciones de Correo
admin_title=Configuración de la Cuenta de Administrador
admin_name=Nombre de usuario
admin_password=Contraseña
confirm_password=Confirmar Contraseña
admin_email=Correo electrónico
install_gogs=Instalar Gogs
test_git_failed=Fallo al probar el comando 'git': %v
sqlite3_not_available=Tu versión no soporta SQLite3, por favor descarga el binario oficial desde %s, NO la versión de gobuild.
invalid_db_setting=La configuración de la base de datos no es correcta: %v
invalid_repo_path=La ruta de la raíz del repositorio es inválida: %v
run_user_not_match=El usuario que está ejecutando la aplicación no es el usuario actual: %s -> %s
save_config_failed=Error al guardar la configuración: %v
invalid_admin_setting=La configuración de la cuenta de administración es inválida: %v
install_success=Bienvenido! Estamos encantados de que hayas escogido Gogs, diviértete y cuídate.
[home]
uname_holder=Nombre de usuario o correo electrónico
password_holder=Contraseña
switch_dashboard_context=Cambiar el contexto del Dashboard
my_repos=Mis Repositorios
collaborative_repos=Repositorios Colaborativos
my_orgs=Mis Organizaciones
my_mirrors=Mis Mirrors
[explore]
repos=Repositorios
[auth]
create_new_account=Crear una Nueva Cuenta
register_hepler_msg=¿Ya tienes una cuenta? ¡Inicia sesión!
social_register_hepler_msg=¿Ya tienes una cuenta? ¡Enlázala!
disable_register_prompt=Lo sentimos, el registro está deshabilitado. Por favor, contacta con el administrador del sitio.
disable_register_mail=Lo sentimos. Los correos de Confirmación de Registro están deshabilitados.
remember_me=Recuérdame
forgot_password=He olvidado mi contraseña
forget_password=¿Has olvidado tu contraseña?
sign_up_now=¿Necesitas una cuenta? Regístrate ahora.
confirmation_mail_sent_prompt=Un nuevo correo de confirmación se ha enviado a <b>%s</b>. Por favor, comprueba tu bandeja de entrada en las siguientes %d horas para completar el proceso de registro.
sign_in_email=Inicia sesión con tu correo electrónico
active_your_account=Activa tu cuenta
resent_limit_prompt=Lo sentimos, estás solicitando el reenvío del mail de activación con demasiada frecuencia. Por favor, espera 3 minutos.
has_unconfirmed_mail=Hola %s, tu correo electrónico (<b>%s</b>) no está confirmado. Si no has recibido un correo de confirmación o necesitas que lo enviemos de nuevo, por favor, haz click en el siguiente botón.
resend_mail=Haz click aquí para reenviar tu correo electrónico de activación
email_not_associate=Esta dirección de correo electrónico no esta asociada a cuenta alguna.
send_reset_mail=Haga clic aquí para (re)enviar el correo para el restablecimiento de la contraseña
reset_password=Restablecer su contraseña
invalid_code=Lo sentimos, su código de confirmación ha expirado o no es valido.
reset_password_helper=Haga Clic aquí para restablecer su contraseña
password_too_short=La longitud de la contraseña no puede ser menor a 6.
[form]
UserName=Nombre de usuario
RepoName=Nombre del repositorio
Email=Dirección de correo electrónico
Password=Contraseña
Retype=Vuelva a escribir la contraseña
SSHTitle=Nombre de la Clave de SSH
HttpsUrl=HTTPS URL
PayloadUrl=URL de carga
TeamName=Nombre del equipo
AuthName=Nombre de autorización
AdminEmail=Correo electrónico del administrador
require_error=` no puede estar vacío.`
alpha_dash_error=` los caracteres deben ser Alfanumericos o dash(-_).`
alpha_dash_dot_error=` debe ser un caracter alfanumérivo válido, un guión alto o bajo (-_) o un signo de puntuación.`
min_size_error=` debe contener al menos %s caracteres.`
max_size_error=` debe contener como máximo %s caracteres.`
email_error=` no es una dirección de correo válida.`
url_error=` no es una URL válida.`
unknown_error=Error desconocido:
captcha_incorrect=El captcha no es válido.
password_not_match=La contraseña de confirmación no coincide.
username_been_taken=Ya existe un usuario con este nombre.
repo_name_been_taken=Ya existe un repositorio con este nombre.
org_name_been_taken=Ya existe una organización con este nombre.
team_name_been_taken=Ya existe un equipo con este nombre.
email_been_used=Esta dirección de correo electrónico ya está en uso.
ssh_key_been_used=Este nombre de clave pública ya está en uso.
illegal_username=Tu nombre de usuario contiene caracteres inválidos.
illegal_repo_name=El nombre del repositorio contiene caracteres inválidos.
illegal_org_name=El nombre de la organización contiene caracteres inválidos.
illegal_team_name=El nombre del equipo contiene caracteres inválidos.
username_password_incorrect=Nombre de usuario o contraseña incorrectos.
enterred_invalid_repo_name=Por favor, asegúrate de que has introducido correctamente el nombre del repositorio.
enterred_invalid_owner_name=Por favor, asegúrate de que has introducido correctamente el nombre del propietario.
enterred_invalid_password=Por favor, asegúrate de que has introducido correctamente tu contraseña.
user_not_exist=El usuario indicado no existe.
last_org_owner=El usuario que se intenta eliminar es el último miembro del equipo de propietarios. Debe existir otro propietario.
invalid_ssh_key=Lo sentimos, no somos capaces de verificar tu clave SSH: %s
unable_verify_ssh_key=Gogs no puede velificar tu clave SSH, pero asumimos que es válida. Por favor, asegúrate de que es así.
auth_failed=Error de autenticación: %v
still_own_repo=Tu cuenta es la propietaria de uno o más repositorios, tienes que borrarlos o transferirlos primero.
still_has_org=Tu cuenta es miembro de una o más organizaciones, tienes que abandonarlas o eliminarlas primero.
org_still_own_repo=Esta organización es dueña de uno o más repositorios, tienes que eliminarlos o transferirlos primero.
still_own_user=Esta autenticación está en uso por algunos usuarios, debes moverlos y antes de eliminarla.
target_branch_not_exist=La rama de destino no existe
[user]
change_avatar=Cambia tu avatar en gravatar.com
change_custom_avatar=Cambia tu avatar en la configuración
join_on=Registrado en
repositories=Repositorios
activity=Actividad pública
followers=Seguidores
starred=Destacados
following=Siguiendo
[settings]
profile=Perfil
password=Contraseña
ssh_keys=Claves SSH
social=Redes Sociales
applications=Aplicaciones
orgs=Organizaciones
delete=Eliminar Cuenta
uid=UUID
public_profile=Perfil Público
profile_desc=Tu correo electrónico es público y será usado para todas las notificaciones relacionadas con cualquier cuenta y cualquier operación hecha a través de la web.
full_name=Nombre Completo
website=Página Web
location=Localización
update_profile=Actualizar Perfil
update_profile_success=Tu perfil se ha actualizado correctamente.
change_username=Nombre de usuario modificado
change_username_desc=El nombre de usuario ha sido modificado, ¿quieres continuar? Esta acción afectará a todos los enlaces relacionados con tu cuenta.
continue=Continuar
cancel=Cancelar
enable_custom_avatar=Activar Avatar Personalizado
enable_custom_avatar_helper=Activa esto para desactivar los avatares de Gravatar
choose_new_avatar=Selecciona nuevo avatar
update_avatar=Actualizar Configuración del Avatar
uploaded_avatar_not_a_image=El archivo enviado no es una imagen.
no_custom_avatar_available=No hay ningún avatar personalizado disponible, no se puede habilitar.
update_avatar_success=La configuración de tu avatar se ha actualizado correctamente.
change_password=Cambiar contraseña
old_password=Contraseña actual
new_password=Nueva contraseña
password_incorrect=Contraseña actual incorrecta.
change_password_success=La contraseña se ha modificado correctamente. Ya puedes iniciar sesión con tu nueva contraseña.
emails=Direcciones de correo electrónico
manage_emails=Gestionar direcciones de correo electrónico
email_desc=Tu dirección de correo principal se utilizará para las notificaciones y otras operaciones.
primary=Principal
primary_email=Marcar como principal
delete_email=Eliminar
add_new_email=Añadir nueva dirección de correo electrónico
add_email=Añadir correo electrónico
add_email_success=Tu nuevo correo electrónico se ha añadido correctamente.
manage_ssh_keys=Gestionar Claves SSH
add_key=Añadir Clave
ssh_desc=Esta es la lista de claves SSH asociadas con tu cuenta. Elimina cualquier clave que no reconozcas.
ssh_helper=<strong>¿Necesitas ayuda?</strong>. Consulta nuestra guía para <a href="%s">generar claves SSH</a> o solucionar <a href="%s">problemas comunes de SSH</a>.
add_new_key=Añadir clave SSH
key_name=Nombre de la Clave
key_content=Contenido
add_key_success=¡Se ha añadido una nueva clave SSH!
delete_key=Eliminar
add_on=Añadido en
last_used=Utilizado por última vez en
no_activity=No hay actividad reciente
manage_social=Gestionar Redes Sociales asociadas
social_desc=Esta es una lista de las Redes Sociales asociadas. Elimina cualquier vínculo que no reconozcas.
unbind=Desvincular
unbind_success=La Red Social ha sido desvinculada.
manage_access_token=Gestionar los Tokens de Acceso personales
generate_new_token=Generar nuevo Token
tokens_desc=Tokens generados que pueden ser usados para acceder al API de Gogs.
new_token_desc=Desde ahora, todos los tokens tendrán acceso completo a tu cuenta.
token_name=Nombre del Token
generate_token=Generar Token
generate_token_succees=¡Los nuevos tokens de acceso se han generado correctamente! Asegúrate de copiar tu nuevo token de acceso personal. ¡No podrás verlo de nuevo!
delete_token=Eliminar
delete_token_success=¡Los tokens de acceso personales se han eliminado correctamente! No olvides actualizar las aplicaciones que los usasen.
delete_account=Elimina tu cuenta
delete_prompt=La operación eliminará tu cuenta de forma permanente y ¡<strong>NO</strong> se puede deshacer!
confirm_delete_account=Confirmar Eliminación
delete_account_title=Eliminación de Cuenta
delete_account_desc=Esta cuenta se va a eliminar permanentemente, ¿quieres continuar?
[repo]
owner=Propietario
repo_name=Nombre del Repositorio
repo_name_helper=Los grandes nombres de repositorios son cortos, memorables y <strong>únicos</strong>.
visibility=Visibilidad
visiblity_helper=Este repositorio es <span class="label label-red label-radius">Privado</span>
fork_repo=Hacer Fork del repositorio
fork_from=Crear un Fork desde
fork_visiblity_helper=No es posible cambiar la visibilidad de un Fork
repo_desc=Descripción
repo_lang=Idioma
repo_lang_helper=Selecciona un fichero .gitignore
license=Licencia
license_helper=Selecciona un fichero de licencia
init_readme=Crear este repositorio con un fichero README.md
create_repo=Crear Repositorio
default_branch=Rama por defecto
mirror_interval=Intervalo de mirror(en horas)
goget_meta=Go-Get Meta
goget_meta_helper=Este repositorio será <span class="label label-blue label-radius">Go-Getable</span>
need_auth=Requiere Autorización
migrate_type=Tipo de Migración
migrate_type_helper=Este repositorio será un <span class="label label-blue label-radius">Mirror</span>
migrate_repo=Migrar Repositorio
copy_link=Copiar
click_to_copy=Copiar al portapapeles
copied=Copiado correctamente
clone_helper=¿Necesitas ayuda con el clone? ¡Consulta la <a target="_blank" href="%s">Ayuda</a>!
unwatch=Dejar de vigilar
watch=Vigilar
unstar=Eliminar destacado
star=Destacar
fork=Fork
no_desc=Sin Descripción
quick_guide=Guía Rápida
clone_this_repo=Clonar este repositorio
create_new_repo_command=Crear un nuevo repositorio desde línea de comandos
push_exist_repo=Hacer Push de un repositorio existente desde línea de comandos
branch=Rama
tree=Árbol
branch_and_tags=Ramas y Etiquetas
branches=Ramas
tags=Etiquetas
issues=Incidencias
commits=Commits
releases=Releases
file_raw=Raw
file_history=Histórico
file_view_raw=Ver Raw
commits.commits=Commits
commits.search=Buscar Commits
commits.find=Buscar
commits.author=Autor
commits.message=Mensaje
commits.date=Fecha
commits.older=Anterior
commits.newer=Posterior
settings=Configuración
settings.options=Opciones
settings.collaboration=Colaboración
settings.hooks=Webhooks
settings.githooks=Git Hooks
settings.deploy_keys=Claves de Despliegue
settings.basic_settings=Configuración Básica
settings.danger_zone=Zona de Peligro
settings.site=Sitio Oficial
settings.update_settings=Actualizar Configuración
settings.change_reponame=Nombre del Repositorio Modificado
settings.change_reponame_desc=El nombre del repositorio ha sido modificado, ¿quieres continuar? Esto afectará a todos los enlaces relacionados con este repositorio.
settings.transfer=Transferir la Propiedad
settings.transfer_desc=Transferir este repositorio a otro usuario u organización donde tengas permisos de administración.
settings.new_owner_has_same_repo=El nuevo propietario tiene un repositorio con el mismo nombre.
settings.delete=Eliminar este Repositorio
settings.delete_desc=Una vez has eliminado un repositorio, no hay vuelta atrás. Por favor, asegúrate de que es lo que quieres.
settings.transfer_notices=<p>- Perderás acceso si el nuevo propietario es un usuario individual.</p><p>- Seguirás teniendo acceso si el nuevo propietario es una organización y estás en el grupo de los propietarios.</p>
settings.update_settings_success=Las opciones del repositorio se han actualizado correctamente.
settings.transfer_owner=Nuevo Propietario
settings.make_transfer=Transferir
settings.transfer_succeed=La propiedad del repositorio ha sido transferida exitosamente.
settings.confirm_delete=Confirmar Eliminación
settings.add_collaborator=Añadir Nuevo Colaborador
settings.add_collaborator_success=Se ha añadido el nuevo colaborador.
settings.remove_collaborator_success=Se ha eliminado el colaborador.
settings.user_is_org_member=El usuario es miembro de la organización, no puede ser añadido como colaborador.
settings.add_webhook=Añadir Webhook
settings.hooks_desc=Los Webhooks permiten a servicios externos recibir notificaciones cuando sucedan ciertos eventos en Gogs. Cuando sucedan los eventos especificados, enviaremos una petición POST a cada una de las URLs indicadas. Para obtener más información, consulta nuestra <a target="_blank" href="%s">Guía de Webhooks</a>.
settings.githooks_desc=Los Git Hooks son una funcionalidad del propio Git, puedes editar los ficheros de los hooks soportados en la siguiente lista para aplicar operaciones personalizadas.
settings.githook_edit_desc=Si el hook no está activo, se mostrará contenido de ejemplo. Dejar el contenido vacío deshabilitará este hook.
settings.githook_name=Nombre del Hook
settings.githook_content=Contenido del Hook
settings.update_githook=Actualizar Hook
settings.remove_hook_success=El Webhook ha sido eliminado.
settings.add_webhook_desc=Enviaremos una petición <code>POST</code> a la siguiente URL con los detalles de cualquier evento suscrito. También puedes especificar qué formato de datos te gustaría recibir (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Puedes encontrar más información en la <a target="_blank" href="%s">Guía de Webhooks</a>.
settings.payload_url=URL de Payload
settings.content_type=Tipo de Contenido
settings.secret=Secreto
settings.event_desc=¿Qué eventos te gustaría que desencadenasen este webhook?
settings.event_push_only=Solo el evento <code>push</code>.
settings.active=Activo
settings.active_helper=Enviaremos detalles del evento cuando este hook se dispare.
settings.add_hook_success=Se ha añadido un nuevo webhook.
settings.update_webhook=Actualizar Webhook
settings.update_hook_success=Se ha actualizado el Webhook.
settings.delete_webhook=Borrar Webhook
settings.recent_deliveries=Envíos Recientes
settings.hook_type=Tipo de Hook
settings.add_slack_hook_desc=Añade integración con <a href="%s">Slack</a> a tu repositorio.
settings.slack_token=Token
settings.slack_domain=Dominio
settings.slack_channel=Canal
diff.browse_source=Explorar el Código
diff.parent=padre
diff.commit=commit
diff.data_not_available=Los datos del Diff no están disponibles.
diff.show_diff_stats=Mostrar Estadísticas de Diff
diff.stats_desc=Se han <strong>modificado %d ficheros</strong> con <strong>%d adiciones</strong> y <strong>%d borrados</strong>
diff.bin=BIN
diff.view_file=Ver Fichero
release.releases=Releases
release.new_release=Nueva Release
release.draft=Borrador
release.prerelease=Pre-Release
release.stable=Estable
release.edit=editar
release.ahead=<strong>%d</strong> commits en %s desde esta release
release.source_code=Código Fuente
release.tag_name=Nombre de la etiqueta
release.target=Destino
release.tag_helper=Escoge una etiqueta o crea una nueva al publicar.
release.release_title=Título de la Release
release.content_with_md=Contenido con formato <a href="%s">Markdown</a>
release.write=Escribir
release.preview=Vista Previa
release.content_placeholder=Escribe algo de contenido
release.loading=Cargando...
release.prerelease_desc=Esta es una pre-release
release.prerelease_helper=Esta release está marcada como no apta para producción.
release.publish=Publicar Release
release.save_draft=Guardar Borrador
release.edit_release=Editar Release
release.tag_name_already_exist=Ya existe una Release con esta etiqueta.
[org]
org_name_holder=Nombre de la Organización
org_name_helper=Los grandes nombres de organizaciones son cortos y memorables.
org_email_helper=Los correos electrónicos de las organizaciones reciben todas las notificaciones y confirmaciones.
create_org=Crear Organización
repo_updated=Actualizado
people=Personas
invite_someone=Invitar a alguien
teams=Equipos
lower_members=miembros
lower_repositories=repositorios
create_new_team=Crear un Nuevo Equipo
org_desc=Descripción
team_name=Nombre del Equipo
team_desc=Descripción
team_name_helper=Utiliza este nombre para mencionar a este equipo en las conversaciones.
team_desc_helper=¿En qué consiste este equipo?
team_permission_desc=¿Qué nivel de permisos debería tener este equipo?
settings=Configuración
settings.options=Opciones
settings.full_name=Nombre Completo
settings.website=Sitio Web
settings.location=Localización
settings.update_settings=Actualizar Configuración
settings.change_orgname=Nombre de la Organización Modificado
settings.change_orgname_desc=El nombre de la organización ha sido modificado, ¿quieres continuar? Esta acción afectará a todos los enlaces relacionados con esta organización.
settings.update_setting_success=La configuración de la Organización se ha actualizado correctamente.
settings.delete=Eliminar Organización
settings.delete_account=Eliminar esta Organización
settings.delete_prompt=Esta operación eliminará esta organización de manera permanente, y ¡<strong>NO PUEDE</strong> deshacerse!
settings.confirm_delete_account=Confirmar Eliminación
settings.delete_org_title=Eliminación de la Organización
settings.delete_org_desc=Esta organización se va a eliminar permanentemente, ¿quieres continuar?
settings.hooks_desc=Añadir webhooks que serán ejecutados para <strong>todos los repositorios</strong> de esta organización.
members.public=Público
members.public_helper=convertir en privado
members.private=Privado
members.private_helper=convertir en público
members.owner=Propietario
members.member=Miembro
members.conceal=Ocultar
members.remove=Eliminar
members.leave=Abandonar
members.invite_desc=Comienza a teclear un nombre de usuario para invitar a un nuevo miembro a %s:
members.invite_now=Invitar
teams.join=Unirse
teams.leave=Abandonar
teams.read_access=Acceso de Lectura
teams.read_access_helper=Este equipo podrá ver y clonar sus repositorios.
teams.write_access=Acceso de Escritura
teams.write_access_helper=Este equipo podrá leer sus repositorios, así como hacer push en ellos.
teams.admin_access=Acceso de Administrador
teams.admin_access_helper=Este equipo podrá hacer push/pull en sus repositorios, así como añadir colaboradores a ellos.
teams.no_desc=Este equipo no tiene descripción
teams.settings=Configuración
teams.owners_permission_desc=Los propietarios tienen acceso completo a <strong>todos los repositorios</strong> y tienen <strong>derechos de administración</strong> en la organización.
teams.members=Miembros del Equipo
teams.update_settings=Actualizar Configuración
teams.delete_team=Borrar este Equipo
teams.add_team_member=Añadir Miembro al Equipo
teams.delete_team_title=Eliminar Equipo
teams.delete_team_desc=Este equipo va a ser eliminado, ¿seguro que quieres continuar? Los miembros de este equipo pueden perder acceso a algunos repositorios.
teams.delete_team_success=El Equipo se ha eliminado correctamente.
teams.read_permission_desc=Este equipo tiene permisos de <strong>Lectura</strong>: sus miembros pueden ver y clonar los repositorios del equipo.
teams.write_permission_desc=Este equipo tiene permisos de <strong>Escritura</strong>: sus miembros pueden leer y hacer push a los repositorios del equipo.
teams.admin_permission_desc=Este equipo tiene permisos de <strong>Administración</strong>: sus miembros pueden leer, hacer push y añadir colaboradores a los repositorios del equipo.
teams.repositories=Repositorios del Equipo
teams.add_team_repository=Añadir Repositorio al Equipo
teams.remove_repo=Eliminar
teams.add_nonexistent_repo=El repositorio que estás intentando añadir no existe, por favor, créalo primero.
[admin]
dashboard=Dashboard
users=Usuarios
organizations=Organizaciones
repositories=Repositorios
authentication=Autenticaciones
config=Configuración
notices=Avisos del Sistema
monitor=Monitorización
prev=Anterior
next=Siguiente
dashboard.statistic=Estadísticas
dashboard.operations=Operaciones
dashboard.system_status=Estado del Monitor del Sistema
dashboard.statistic_info=La base de datos de Gogs contiene <b>%d</b> usuarios, <b>%d</b> organizaciones, <b>%d</b> claves públicas, <b>%d</b> repositorios, <b>%d</b> vigilados, <b>%d</b> destacados, <b>%d</b> acciones, <b>%d</b> accesos, <b>%d</b> incidencias, <b>%d</b> comentarios, <b>%d</b> cuentas de redes sociales, <b>%d</b> seguidores, <b>%d</b> mirrors, <b>%d</b> releases, <b>%d</b> fuentes de login, <b>%d</b> webhooks, <b>%d</b> milestones, <b>%d</b> etiquetas, <b>%d</b> hooks, <b>%d</b> equipos, <b>%d</b> tareas actualizadas, <b>%d</b> adjuntos.
dashboard.operation_name=Nombre de la Operación
dashboard.operation_switch=Interruptor
dashboard.operation_run=Ejecutar
dashboard.clean_unbind_oauth=Limpiar solicitudes de OAuth sin confirmar
dashboard.clean_unbind_oauth_success=Las solicitudes de OAuth sin confirmar se han eliminado correctamente.
dashboard.delete_inactivate_accounts=Eliminar todas las cuentas inactivas
dashboard.delete_inactivate_accounts_success=Todas las cuentas inactivas se han eliminado correctamente.
dashboard.delete_repo_archives=Eliminar todos los archivos de repositorios
dashboard.delete_repo_archives_success=Todos los archivos de repositorios se han eliminado correctamente.
dashboard.git_gc_repos=Ejecutar la recolección de basura en los repositorios
dashboard.git_gc_repos_success=Todos los repositorios han ejecutado correctamente el recolector de basuras.
dashboard.resync_all_sshkeys=Reescribir el fichero '.ssh/authorized_key'(atención: se perderán las claves que no pertenezcan a Gogs)
dashboard.resync_all_sshkeys_success=Todas las claves públicas se han reescrito correctamente.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Uptime del Servidor
dashboard.current_goroutine=Gorutinas Actuales
dashboard.current_memory_usage=Uso de Memoria Actual
dashboard.total_memory_allocated=Total de Memoria Reservada
dashboard.memory_obtained=Memoria Obtenida
dashboard.pointer_lookup_times=Tiempos de Búsqueda de Punteros
dashboard.memory_allocate_times=Tiempos de Reserva de Memoria
dashboard.memory_free_times=Tiempos de Liberado de Memoria
dashboard.current_heap_usage=Uso de Heap Actual
dashboard.heap_memory_obtained=Memoria de Heap Obtenida
dashboard.heap_memory_idle=Memoria de Heap Inactiva
dashboard.heap_memory_in_use=Memoria de Heap en Uso
dashboard.heap_memory_released=Memoria de Heap Liberada
dashboard.heap_objects=Objetos en el Heap
dashboard.bootstrap_stack_usage=Uso de la Pila de Bootstrap
dashboard.stack_memory_obtained=Memoria de Pila Obtenida
dashboard.mspan_structures_usage=Uso de Estructuras MSpan
dashboard.mspan_structures_obtained=Estructuras MSpan Obtenidas
dashboard.mcache_structures_usage=Uso de estructuras MCache
dashboard.mcache_structures_obtained=Estructuras MCache Obtenidas
dashboard.profiling_bucket_hash_table_obtained=Profiling Bucket Hash Table Obtenido
dashboard.gc_metadata_obtained=Metadatos del Recolector de Basuras Obtenidos
dashboard.other_system_allocation_obtained=Otros Recursos del Sistema Asignados
dashboard.next_gc_recycle=Siguiente Reciclado del Recolector de Basuras
dashboard.last_gc_time=Tiempo desde el Último GC
dashboard.total_gc_time=Pausa Total por GC
dashboard.total_gc_pause=Pausa Total por GC
dashboard.last_gc_pause=Última Pausa por GC
dashboard.gc_times=GC Times
users.user_manage_panel=User Manage Panel
users.new_account=Create New Account
users.name=Name
users.activated=Activated
users.admin=Admin
users.repos=Repos
users.created=Created
users.edit=Edit
users.auth_source=Authorization Source
users.local=Local
users.auth_login_name=Authorization Login Name
users.update_profile_success=Account profile has been updated successfully.
users.edit_account=Editar Cuenta
users.is_activated=Esta cuenta está activada
users.is_admin=This account has administrator permissions
users.allow_git_hook=This account has permissions to create Git hooks
users.update_profile=Update Account Profile
users.delete_account=Delete This Account
users.still_own_repo=This account still have ownership of repository, you have to delete or transfer them first.
users.still_has_org=This account still have membership of organization, you have to left or delete them first.
orgs.org_manage_panel=Organization Manage Panel
orgs.name=Name
orgs.teams=Teams
orgs.members=Members
repos.repo_manage_panel=Repository Manage Panel
repos.owner=Owner
repos.name=Name
repos.private=Private
repos.watches=Watches
repos.stars=Stars
repos.issues=Issues
auths.auth_manage_panel=Authorization Manage Panel
auths.new=Add New Authorization Source
auths.name=Name
auths.type=Type
auths.enabled=Enabled
auths.updated=Updated
auths.auth_type=Authorization Type
auths.auth_name=Authorization Name
auths.domain=Domain
auths.host=Host
auths.port=Port
auths.base_dn=Base DN
auths.attributes=Search Attributes
auths.filter=Search Filter
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=SMTP Authorization Type
auths.smtphost=SMTP Host
auths.smtpport=SMTP Port
auths.enable_tls=Enable TLS Encryption
auths.enable_auto_register=Enable Auto Registration
auths.tips=Consejos
auths.edit=Editar la Configuración de Autorización
auths.activated=Esta autenticación ha sido activada
auths.update_success=La Configuración de Autorización ha sido actualizada correctamente.
auths.update=Actualizar la Configuración de Autorización
auths.delete=Eliminar esta Autorización
auths.delete_auth_title=Eliminación de Autorización
auths.delete_auth_desc=Se va a eliminar esta autorización, ¿quieres continuar?
config.server_config=Configuración del Servidor
config.app_name=Nombre de la Aplicación
config.app_ver=Versión de la Aplicación
config.app_url=URL de la Aplicación
config.domain=Dominio
config.offline_mode=Modo Sin Conexión
config.disable_router_log=Deshabilitar Log del Router
config.run_user=Usuario de Ejecución
config.run_mode=Modo de Ejecución
config.repo_root_path=Ruta del Repositorio
config.static_file_root_path=Ruta de los Ficheros Estáticos
config.log_file_root_path=Ruta de los Ficheros de Log
config.script_type=Tipo de Script
config.reverse_auth_user=Reverse Authentication User
config.db_config=Configuración de la Base de Datos
config.db_type=Tipo
config.db_host=Host
config.db_name=Nombre
config.db_user=Usuario
config.db_ssl_mode=Modo SSL
config.db_ssl_mode_helper=(solo para "postgres")
config.db_path=Ruta
config.db_path_helper=(solo para "sqlite3")
config.service_config=Configuración del Servicio
config.register_email_confirm=Solicitar Confirmación por Correo Electrónico
config.disable_register=Deshabilitar el Registro
config.show_registration_button=Mostrar Botón de Registro
config.require_sign_in_view=Solicitar la Vista de Inicio de Sesión
config.mail_notify=Notificación por Correo Electrónico
config.enable_cache_avatar=Activar la Caché de Avatar
config.active_code_lives=Active Code Lives
config.reset_password_code_lives=Reset Password Code Lives
config.webhook_config=Webhook Configuration
config.task_interval=Task Interval
config.deliver_timeout=Deliver Timeout
config.skip_tls_verify=Skip TLS Verify
config.mailer_config=Mailer Configuration
config.mailer_enabled=Enabled
config.mailer_name=Name
config.mailer_host=Host
config.mailer_user=User
config.oauth_config=OAuth Configuration
config.oauth_enabled=Enabled
config.cache_config=Cache Configuration
config.cache_adapter=Cache Adapter
config.cache_interval=Cache Interval
config.cache_conn=Cache Connection
config.session_config=Session Configuration
config.session_provider=Session Provider
config.provider_config=Provider Config
config.cookie_name=Cookie Name
config.enable_set_cookie=Enable Set Cookie
config.gc_interval_time=GC Interval Time
config.session_life_time=Session Life Time
config.https_only=HTTPS Only
config.cookie_life_time=Cookie Life Time
config.picture_config=Picture Configuration
config.picture_service=Picture Service
config.disable_gravatar=Disable Gravatar
config.log_config=Log Configuration
config.log_mode=Log Mode
monitor.cron=Cron Tasks
monitor.name=Name
monitor.schedule=Schedule
monitor.next=Next Time
monitor.previous=Previous Time
monitor.execute_times=Execute Times
monitor.process=Running Processes
monitor.desc=Description
monitor.start=Start Time
monitor.execute_time=Execution Time
notices.system_notice_list=System Notices
notices.type=Type
notices.type_1=Repository
notices.desc=Description
notices.op=Op.
notices.delete_success=System notice has been deleted successfully.
[action]
create_repo=created repository <a href="%s/%s">%s</a>
commit_repo=pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a>
create_issue=`opened issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`commented on issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=transfered repository <code>%s</code> to <a href="/%s%s">%s</a>
push_tag=pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a>
compare_2_commits=View comparison for these 2 commits
[tool]
ago=ago
from_now=from now
now=now
1s=1 second %s
1m=1 minute %s
1h=1 hour %s
1d=1 day %s
1w=1 week %s
1mon=1 month %s
1y=1 year %s
seconds=%d seconds %s
minutes=%d minutes %s
hours=%d hours %s
days=%d days %s
weeks=%d weeks %s
months=%d months %s
years=%d years %s
raw_seconds=seconds
raw_minutes=minutes

View File

@@ -26,7 +26,7 @@ organization=Organisation
mirror=Miroir
new_repo=Nouveau Référentiel
new_migrate=Nouvelle Migration
new_fork=Nouveau référentiel de fourche
new_fork=Nouveau Référentiel d'Embranchement
new_org=Nouvelle Organisation
manage_org=Gérer les Organisations
admin_panel=Administration
@@ -59,6 +59,8 @@ run_user=Entrer un Utilisateur
run_user_helper=L'utilisateur doit avoir accès à la Racine du Référentiel et éxécuter Gogs.
domain=Domaine
domain_helper=Cela affecte les doublons d'URL SSH.
http_port=HTTP Port
http_port_helper=Port number which application will listen on.
app_url=URL de l'Application
app_url_helper=Cela affecte les doublons d'URL HTTP/HTTPS et le contenu d'e-mail.
email_title=Paramètres du Service de Messagerie (Facultatif)
@@ -109,7 +111,7 @@ confirmation_mail_sent_prompt=Un nouveau mail de confirmation à été envoyé
sign_in_email=Connexion avec l'E-mail
active_your_account=Activer votre Compte
resent_limit_prompt=Désolé, vos tentatives d'activation sont trop fréquentes. Veuillez réessayer dans 3 minutes.
has_unconfirmed_mail=Bonjour %s, votre adresse e-mail n'a pas été confirmée (<b>%s</b>). Si vous n'avez reçu aucun mail de confirmation ou souhaitez renouveler l'envoi, appuyez sur le bouton ci-dessous.
has_unconfirmed_mail=Bonjour %s, votre adresse courriel (<b>%s</b>) n'a pas été confirmée. Si vous n'avez reçu aucun courriel de confirmation ou souhaitez renouveler l'envoi, appuyez sur le bouton ci-dessous.
resend_mail=Appuyez ici pour renvoyer un mail de confirmation
email_not_associate=Cette adresse e-mail n'est associée à aucun compte.
send_reset_mail=Appuyez ici pour (r)envoyer le mail de réinitialisation du mot de passe
@@ -173,6 +175,7 @@ target_branch_not_exist=Branche cible n'existe pas
[user]
change_avatar=Changez d'avatar via gravatar.com
change_custom_avatar=Changer de vignette dans les réglages
join_on=Adhéré le
repositories=Référentiels
activity=Activités publiques
@@ -202,12 +205,30 @@ change_username_desc=Nom d'utilisateur modifié. Cela affecte tous les liens rel
continue=Continuer
cancel=Annuler
enable_custom_avatar=Permettre vignette personnalisée
enable_custom_avatar_helper=Cette option désactive l'affichage via Gravatar
choose_new_avatar=Choisir nouvelle vignette
update_avatar=Réglage de mise à jour de vignette
uploaded_avatar_not_a_image=Le fichier téléchargé n'est pas une image.
no_custom_avatar_available=Aucun avatar personnalisé disponible, activation impossible.
update_avatar_success=La mise à jour de votre vignette a réussi.
change_password=Modifier le Mot de Passe
old_password=Mot de Passe actuel
new_password=Nouveau Mot de Passe
password_incorrect=Mot de passe actuel incorrect.
change_password_success=Mot de passe modifié avec succès. Vous pouvez à présent vous connecter avec le nouveau mot de passe.
emails=Adresses E-mail
manage_emails=Gérer les adresses e-mail
email_desc=Votre adresse e-mail principale sera utilisée pour les notifications et d'autres opérations.
primary=Principale
primary_email=Définir comme principale
delete_email=Supprimer
add_new_email=Ajouter une nouvelle adresse courriel
add_email=Ajouter un courriel
add_email_success=Votre courriel a été ajouté avec succès.
manage_ssh_keys=Gérer les clés SSH
add_key=Ajouter une Clé
ssh_desc=Ceci est une liste des clés SSH associées à votre compte. Supprimez celles que vous ne reconnaissez pas.
@@ -248,9 +269,9 @@ repo_name=Nom du Référentiel
repo_name_helper=Idéalement, le nom d'un Référentiel devrait être court, mémorable et <strong>unique</strong>.
visibility=Visibilité
visiblity_helper=Ce Référentiel est <span class="label label-red label-radius">Privé</span>
fork_repo=Référentiel de la fourche
fork_from=Fourche de
fork_visiblity_helper=Référentiel Aristide ne peut pas changer sa visiblité
fork_repo=Référentiel d'Embranchement
fork_from=Embranchement de
fork_visiblity_helper=Un Référentiel d'embranchement ne peut pas changer sa visiblité
repo_desc=Description
repo_lang=Langue
repo_lang_helper=Sélectionner un fichier .gitignore
@@ -368,10 +389,34 @@ diff.stats_desc=<strong> %d fichiers modifiés</strong> avec <strong>%d ajouts</
diff.bin=BIN
diff.view_file=Voir le fichier
release.releases=Versions
release.new_release=Nouvelle version
release.draft=Brouillon
release.prerelease=Pré-publication
release.stable=Stable
release.edit=Éditer
release.ahead=<strong>%d</strong> commissions à %s depuis cette publication
release.source_code=Code Source
release.tag_name=Nom du tag
release.target=Cible 
release.tag_helper=Choisissez un tag existant ou créez-en un nouveau à publier.
release.release_title=Titre de la publication
release.content_with_md=Contenu avec <a href="%s">Démarque(s)</a>
release.write=Écrire
release.preview=Prévisualiser
release.content_placeholder=Rédiger du contenu
release.loading=Chargement…
release.prerelease_desc=Il s'agit d'une version préliminaire
release.prerelease_helper=Nous soulignerons que cette version est considérée comme non prête pour la production.
release.publish=Publier
release.save_draft=Sauvegarder le Brouillon
release.edit_release=Éditer la publication
release.tag_name_already_exist=Une publication avec ce nom de tag a déjà existée.
[org]
org_name_holder=Nom d'organisation
org_name_helper=Idéalement, un nom d'organisation devrait être court et mémorable.
org_email_helper=L'e-mail de l'organisation recevra toutes les notifications et confirmations.
org_email_helper=Le courriel de l'organisation recevra toutes les notifications et confirmations.
create_org=Créer une organisation
repo_updated=Mis à jour
people=Contacts
@@ -467,6 +512,13 @@ dashboard.delete_inactivate_accounts=Supprimer tous les comptes inactifs
dashboard.delete_inactivate_accounts_success=Inactivent tous les comptes ont été supprimés avec succès.
dashboard.delete_repo_archives=Supprimer toutes les archives de référentiels
dashboard.delete_repo_archives_success=Toutes les archives de référentiels ont été supprimés avec succès.
dashboard.git_gc_repos=Collecter les déchets des référentiels
dashboard.git_gc_repos_success=Tous les référentiels ont effectué la collecte avec succès.
dashboard.resync_all_sshkeys=Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success=All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Durée de Marche Serveur
dashboard.current_goroutine=Goroutines actuelles
dashboard.current_memory_usage=Utilisation Mémoire actuelle
@@ -584,8 +636,9 @@ config.db_ssl_mode_helper=("postgres" uniquement)
config.db_path=Emplacement
config.db_path_helper=("sqlite3" uniquement)
config.service_config=Configuration du Service
config.register_email_confirm=E-mail de Confirmation d'Enregistrement
config.register_email_confirm=Nécessite une confirmation par courriel
config.disable_register=Désactiver l'Enregistrement
config.show_registration_button=Show Register Button
config.require_sign_in_view=Connexion Obligatoire pour Visualiser
config.mail_notify=Mailer les Notifications
config.enable_cache_avatar=Activer le Cache d'Avatar
@@ -594,6 +647,7 @@ config.reset_password_code_lives=Réinitialiser le Mot De Passe des Limites de C
config.webhook_config=Configuration Webhook
config.task_interval=Intervalles de Tâches
config.deliver_timeout=Expiration d'Envoi
config.skip_tls_verify=Skip TLS Verify
config.mailer_config=Configuration du Maileur
config.mailer_enabled=Activé
config.mailer_name=Nom
@@ -641,8 +695,8 @@ notices.delete_success=Note système supprimée avec succès.
[action]
create_repo=a crée le Référentiel <a href="%s/%s">%s</a>
commit_repo=a soumis à <a href="%s/%s/src/%s">%s</a> chez <a href="%s/%s">%s</a>
create_issue=a ouvert un problème <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue=a commenté le problème <a href="%s/%s/issues/%s">%s#%s</a>
create_issue=`a ouvert un problème <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`a commenté le problème <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=a transféré le Référentiel <code>%s</code> à <a href="/%s%s">%s</a>
push_tag=a tagé <a href="%s/%s/src/%s">%s</a> à <a href="%s/%s">%s</a>
compare_2_commits=Comparer ces 2 commissions
@@ -668,16 +722,3 @@ years=%d ans %s
raw_seconds=secondes
raw_minutes=minutes

724
conf/locale/locale_ja-JP.ini Executable file
View File

@@ -0,0 +1,724 @@
app_desc=Go言語で実装したセルフホストGitサーバ
home=ホーム
dashboard=ダッシュボード
explore=エスクプローラ
help=ヘルプ
sign_in=サインイン
social_sign_in=SNSでサインイン: ステップ2 <small>アカウント連携</small>
sign_out=サインアウト
sign_up=サインアップ
register=登録
website=WEBサイト
version=バージョン
page=ページ
template=テンプレート
language=言語
username=ユーザ名
email=E-mail
password=パスワード
re_type=再入力
captcha=キャプチャ
repository=リポジトリ
organization=組織
mirror=ミラー
new_repo=新しいリポジトリ
new_migrate=新しい移行
new_fork=新しいフォークのリポジトリ
new_org=新しい組織
manage_org=組織を管理
admin_panel=管理者パネル
account_settings=アカウント設定
settings=設定
news_feed=ニュースのフィード
pull_requests=プルリクエスト
issues=課題
cancel=キャンセル
[install]
install=インストール
title=初回実行のインストール手順
requite_db_desc=Gogs には、MySQL や PostgreSQL 、SQLite3 が必要です。
db_type=データベースの種類
host=ホスト
user=ユーザ
password=パスワード
db_name=データベース名
db_helper=Mysql INNODB エンジン utf8_general_ci の文字セットを使用してください。
ssl_mode=SSL モード
path=パス
sqlite_helper=SQLite3 データベースのファイル パス
general_title=Gogs の全般設定
repo_path=リポジトリのルートパス
repo_path_helper=すべての Git リモート リポジトリはこのディレクトリに保存されます。
run_user=実行ユーザ
run_user_helper=ユーザーはリポジトリ ルートパスへのアクセス、及びGogs を実行する権限を所有する必要があります。
domain=ドメイン
domain_helper=これはSSHクローンURLに影響する。
http_port=HTTP ポート
http_port_helper=アプリケーションが待ち受けするポート番号。
app_url=アプリケーションの URL
app_url_helper=この設定は、HTTP / HTTPSのクローンURLおよび、一部のメールボックスへのリンクに影響を与えます。
email_title=E-mailサービス設定(Optional)
smtp_host=SMTP ホスト
mailer_user=送信者の電子メール
mailer_password=送信者のパスワード
notify_title=通知 Settings(Optional)
register_confirm=登録の確認を有効にする
mail_notify=メール通知を有効にする
admin_title=管理者アカウントの設定
admin_name=ユーザ名
admin_password=パスワード
confirm_password=パスワード確認
admin_email=E-mail
install_gogs=Gogs をインストール
test_git_failed='Git' コマンドテストに失敗: %v
sqlite3_not_available=このリリース バージョンは SQLite3 をサポートしていません。gobuild バージョンではない、公式のバイナリ バージョンを %s からダウンロードしてください。
invalid_db_setting=データベースの設定が正しくありません: %v
invalid_repo_path=リポジトリのルート パスが無効です: %v
run_user_not_match=実行ユーザーは、現在のユーザーではない: %s-> %s
save_config_failed=構成の保存に失敗した: %v
invalid_admin_setting=管理者アカウントの設定が無効です: %v
install_success=ようこそ!我々はあなたが Gogs を選んでくれて嬉しいです!楽しみましょう!
[home]
uname_holder=ユーザー名またはEメール
password_holder=パスワード
switch_dashboard_context=ダッシュ ボードのコンテキストを切替
my_repos=私のリポジトリ
collaborative_repos=共同リポジトリ
my_orgs=私の組織
my_mirrors=私のミラー
[explore]
repos=リポジトリ
[auth]
create_new_account=新規アカウントを作成
register_hepler_msg=すでにアカウントをお持ちですか?今すぐログイン
social_register_hepler_msg=すでにアカウントをお持ちですか?今すぐバインド
disable_register_prompt=申し訳ありませんが、登録が無効になっています。サイト管理者に問い合わせてください。
disable_register_mail=申し訳ありませんが、登録メールの確認機能が無効になっています。
remember_me=ログイン状態を保持する
forgot_password=パスワードを忘れた
forget_password=パスワードを忘れた?
sign_up_now=アカウントが必要ですか?今すぐサインアップ
confirmation_mail_sent_prompt=新しい確認メールを <b>%s</b> に送りました。登録を完了させるために、%d時間以内にあなたのメールボックスを確認してください。
sign_in_email=E-mailでサイイン
active_your_account=アカウントをアクティブ
resent_limit_prompt=申し訳ありませんが、アクティベーションメールは頻繁に送信しています。3 分お待ちください。
has_unconfirmed_mail=こんにちは %s さん、あなたの電子メール アドレス (<b>%s</b>) は未確認です。もし確認メールをまだ確認できていないか、改めて再送信する場合は、下のボタンをクリックしてください。
resend_mail=アクティベーションメールを再送信するにはここをクリック
email_not_associate=この電子メール アドレスは、アカウントには関連付けられません。
send_reset_mail=パスワードリセットのメールを再送するにはここをクリック
reset_password=パスワードリセット
invalid_code=申し訳ありませんが、確認用コードが期限切れまたは無効です。
reset_password_helper=パスワードをリセットするにはここをクリック
password_too_short=6文字未満のパスワードは設定できません。
[form]
UserName=ユーザ名
RepoName=リポジトリ名
Email=Eメールアドレス
Password=パスワード
Retype=パスワードを再入力
SSHTitle=SSH キーの名前
HttpsUrl=HTTPS URL
PayloadUrl=ペイロードの URL
TeamName=チーム名
AuthName=承認名
AdminEmail=管理者の電子メール
require_error=空にできません
alpha_dash_error=アルファベット、数字、ハイフン"-"、アンダースコア"_"のいずれかの必要があります
alpha_dash_dot_error=' アルファベット、数値、ダッシュ(-)、アンダースコア(_) 、ドット(.)のいずれかを入力する必要があります。 '
min_size_error=' 少なくとも %s 文字の必要があります '
max_size_error=' %s 文字以下の必要があります '
email_error=' は有効な電子メール アドレスではない '
url_error=' は有効な URL はありません。 '
unknown_error=不明なエラー:
captcha_incorrect=Captcha が一致しませんでした。
password_not_match=パスワードと確認用パスワードが一致同していません。
username_been_taken=ユーザー名は既に使用されています。
repo_name_been_taken=リポジトリ名は既に使用されています。
org_name_been_taken=組織名は既に使用されています。
team_name_been_taken=チーム名は既に使用されています。
email_been_used=電子メール アドレスは既に使用されています。
ssh_key_been_used=パブリック キー名が使用されています。
illegal_username=あなたのユーザ名に無効な文字が含まれます。
illegal_repo_name=リポジトリ名には無効な文字が含まれています。
illegal_org_name=組織名に無効な文字が含まれています。
illegal_team_name=チーム名に無効な文字が含まれています。
username_password_incorrect=ユーザー名またはパスワードが正しくありません。
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=GogsはあなたのSSH keyを確認できません。しかし、我々は有効とみなしますので、自分自身で確認してください。
auth_failed=認証に失敗しました: %v
still_own_repo=アカウント所有のリポジトリがあり、リポジトリの削除または所有者の移譲が必要です。
still_has_org=アカウントはまだ組織のメンバーであり、組織から退出するか削除する必要があります。
org_still_own_repo=この組織はまだリポジトリの所有しています、リポジトリを削除または転送する必要があります。
still_own_user=この認証はまだ一部のユーザーによって使用されています。一部のユーザを移動させてから、もう一度削除してください。
target_branch_not_exist=ターゲットブランチが存在しない
[user]
change_avatar=gravatar.com で自分のアバターを変更
change_custom_avatar=設定で自分のアバターを変更
join_on=参加しました
repositories=リポジトリ
activity=パブリック・アクティビティ
followers=フォロワー
starred=スター
following=フォロー
[settings]
profile=プロフィール
password=パスワード
ssh_keys=SSH キー
social=SNSアカウント
applications=アプリケーション
orgs=組織
delete=アカウントを削除
uid=Uid
public_profile=パブリック プロフィール
profile_desc=あなたのメールアドレスは公開され、任意のアカウント関連の通知に使用されます。また、Webベースの操作はサイトを介して行います。
full_name=フルネーム
website=WEBサイト
location=ロケーション
update_profile=プロファイル更新
update_profile_success=あなたのプロフィールが更新されました。
change_username=ユーザー名が変更されました
change_username_desc=ユーザー名が変更されている、継続したいですか?これはあなたのアカウントに関連するすべてのリンクに影響を与える。
continue=続行
cancel=キャンセル
enable_custom_avatar=カスタムのアバターを有効にする
enable_custom_avatar_helper=Gravatarからのフェッチを無効にするのを、有効にします
choose_new_avatar=新しいアバターを選択
update_avatar=アバターの設定を更新
uploaded_avatar_not_a_image=アップロードされたファイルは画像ではない。
no_custom_avatar_available=利用可能なカスタム アバターがないため、有効にできません。
update_avatar_success=あなたのアバターの設定が更新されました。
change_password=パスワードを変更
old_password=現在のパスワード
new_password=新しいパスワード
password_incorrect=現在のパスワードが正しくありません。
change_password_success=パスワードが正常に変更されました。今すぐ新しいパスワード経由でサインインすることができます。
emails=E-mail アドレス
manage_emails=E-mail アドレスを管理
email_desc=あなたのプライマリメールアドレスは、通知やその他の操作に使用されます。
primary=プライマリー
primary_email=プライマリに設定
delete_email=削除
add_new_email=新しいe-mailアドレスを追加
add_email=電子メールを追加します。
add_email_success=新しいe-mail アドレスが追加されました。
manage_ssh_keys=SSH キーを管理
add_key=キーを追加
ssh_desc=これはあなたのアカウントに関連付けられている SSH キーの一覧です。あなたが認識していないキーを削除します。
ssh_helper=<strong>ヘルプが必要ですか?</strong> 我々のガイドをご覧ください。 <a href="%s"> SSH キーを生成</a> <a href="%s"> SSH の一般的な問題</a>
add_new_key=SSH キーを追加
key_name=キーの名前
key_content=コンテンツ
add_key_success=新しい SSH キーが追加されました
delete_key=削除
add_on=追加された
last_used=最終使用日
no_activity=最近の活動なし
manage_social=関連付けられているSNSアカウントを管理
social_desc=これは関連付けられたソーシャルアカウントのリストです。あなたが認識していない結び付けを削除します。
unbind=バインド解除
unbind_success=SNSアカウントがバインドされていない。
manage_access_token=個人のアクセス トークンを管理
generate_new_token=新しいトークンを生成
tokens_desc=生成したトークンを利用して Gogs の API にアクセスすることができます。
new_token_desc=今のところ、全てのトークンはあなたのアカウントにフルアクセスできます。
token_name=トークン名
generate_token=トークンを生成
generate_token_succees=新しいアクセス トークンは正常に生成されました !今すぐあなたの新しいアクセス トークンをコピーしておいてください。二度と見ることはできませんので確認してください!
delete_token=削除
delete_token_success=個人のアクセス トークンは正常に削除されました!同時にあなたのアプリケーションを更新することを忘れないでください。
delete_account=アカウントを削除
delete_prompt=この操作はあなたのアカウントを完全に削除し、復旧<strong>できない</strong>
confirm_delete_account=削除の確認
delete_account_title=アカウントの削除
delete_account_desc=このアカウントは永久に削除しようとしている、継続しますか?
[repo]
owner=オーナー
repo_name=リポジトリ名
repo_name_helper=偉大なリポジトリ名は短い。思い出に残り、そして<strong>一意</strong>だ。
visibility=ビジビリティ
visiblity_helper=このリポジトリは <span class="label label-red label-radius"> プライベート</span> です。
fork_repo=フォークのリポジトリ
fork_from=フォーク元
fork_visiblity_helper=フォークされたリポジトリは可視状態を変更できません
repo_desc=説明
repo_lang=言語
repo_lang_helper=.gitignore ファイルを選択
license=ライセンス
license_helper=ライセンス ファイルを選択
init_readme=README.md 付きでリポジトリを初期化
create_repo=リポジトリを作成
default_branch=デフォルトのブランチ
mirror_interval=ミラー 間隔(時)
goget_meta=Go-Get メタ
goget_meta_helper=このリポジトリは <span class="label label-blue label-radius"> Go-Getable </span> になります
need_auth=認証が必要
migrate_type=マイグレーションの種類
migrate_type_helper=このリポジトリは <span class="label label-blue label-radius"> ミラー</span> になります
migrate_repo=リポジトリを移行
copy_link=コピー
click_to_copy=クリップボードにコピー
copied=コピー成功
clone_helper=クローニングのヘルプが必要ですか?<a target="_blank"href="%s"> ヘルプ</a> を参照してください!
unwatch=Unwatch
watch=Watch
unstar=Unstar
star=Star
fork=Fork
no_desc=説明なし
quick_guide=クイック ガイド
clone_this_repo=このリポジトリのクローンを作成
create_new_repo_command=コマンドラインで新しいリポジトリを作成します。
push_exist_repo=コマンド ・ ラインから既存のリポジトリをプッシュ
branch=ブランチ
tree=ツリー
branch_and_tags=ブランチ& タグ
branches=ブランチ
tags=タグ
issues=課題
commits=コミット
releases=リリース
file_raw=生データ
file_history=履歴
file_view_raw=生データを見る
commits.commits=コミット
commits.search=コミットの検索
commits.find=検索
commits.author=作者
commits.message=メッセージ
commits.date=日付
commits.older=古い
commits.newer=新しい
settings=設定
settings.options=オプション
settings.collaboration=コラボレーション
settings.hooks=Webhooks
settings.githooks=Git のフック
settings.deploy_keys=デプロイキー
settings.basic_settings=基本設定
settings.danger_zone=危険地帯
settings.site=公式サイト
settings.update_settings=設定の更新
settings.change_reponame=リポジトリ名が変更されました
settings.change_reponame_desc=リポジトリの名前が変更されています、継続しますか?このリポジトリ関連すべてのリンクに影響を与えます。
settings.transfer=オーナー移転
settings.transfer_desc=リポジトリをあなたが管理者権限を持っている別のユーザーまた組織に移譲します。
settings.new_owner_has_same_repo=新しいオーナーは、既に同じ名前のリポジトリを持っています。
settings.delete=このリポジトリを削除
settings.delete_desc=リポジトリを削除すると元に戻せません。確実に確認してください。
settings.transfer_notices=<p>-新オーナーは個人ユーザの場合、あなたはにアクセスできなくなります。</p><p>-新オーナーは組織であり、かつあなたが組織のオーナーに所属する場合、あなたはアクセス権を維持します。</p>
settings.update_settings_success=リポジトリ オプションが更新されました。
settings.transfer_owner=新しいオーナー
settings.make_transfer=転送
settings.transfer_succeed=リポジトリの所有権は正常に転送されました。
settings.confirm_delete=削除の確認
settings.add_collaborator=新しい共同編集者を追加
settings.add_collaborator_success=新しい共同編集者が追加されました。
settings.remove_collaborator_success=共同編集者が削除されました。
settings.user_is_org_member=ユーザーは組織の一員なので、共同編集者として追加することはできません。
settings.add_webhook=Webhook を追加
settings.hooks_desc=Webhooksは、Gogsで特定のイベントの発生時に指定された外部サービスに通知を許可します。イベントが発生すると、それぞれ指定されたUrlに、POSTリクエストが送られます。詳細はこちらのの <a target="_blank"href="%s"> Webhooks ガイド</a>をご覧ください。
settings.githooks_desc=Git のフックは Git 自体によって提供されています。以下のリストのファイルを編集して、サポートされているフックのカスタム操作を適用することができます。
settings.githook_edit_desc=もしフックがアクティブではない場合は、サンプルコンテンツが表示されます。コンテンツを空白にするにはこのフックを無効にします。
settings.githook_name=フックの名前
settings.githook_content=コンテンツをフック
settings.update_githook=フックを更新
settings.remove_hook_success=Webhookが削除されました。
settings.add_webhook_desc=私たちは、指定されたURLに購読されたイベントの詳細を <code>POST</code>リクエストとして送信します。あなたは、異なるデータ受信モード(JSONまたは, <code>x-www-form-urlencoded</code>, <em>その他</em>) を設定することができます。詳細については、<a target="_blank" href="%s">Webhookガイド</a>を参照してください。
settings.payload_url=ペイロードの URL
settings.content_type=コンテンツ タイプ
settings.secret=秘密
settings.event_desc=どのイベントをこのWEBフックのトリガーにしますか
settings.event_push_only=<code>push</code> イベントのみ
settings.active=アクティブ
settings.active_helper=このフックのトリガーが引かれた時に、イベントの詳細を配信します。
settings.add_hook_success=新しい webhook が追加されました。
settings.update_webhook=Webhookを更新
settings.update_hook_success=Webhook を更新しました。
settings.delete_webhook=Webhook を削除
settings.recent_deliveries=最近のデリバリー
settings.hook_type=フックタイプ
settings.add_slack_hook_desc=<a href="%s"> Slack</a> インテグレーションをリポジトリに追加します。
settings.slack_token=トークン
settings.slack_domain=ドメイン
settings.slack_channel=チャンネル
diff.browse_source=ソースを参照
diff.parent=
diff.commit=コミット
diff.data_not_available=差分データは利用できません。
diff.show_diff_stats=差分情報を表示
diff.stats_desc=共有<strong>%d 個のファイルを変更した</strong>、<strong>%d 個の追加</strong> と <strong>%d 個の削除</strong>を含む
diff.bin=BIN
diff.view_file=ファイルの表示
release.releases=リリース
release.new_release=新しいリリース
release.draft=ドラフト
release.prerelease=プレリリース
release.stable=安定
release.edit=編集
release.ahead=このリリース以降 %s へ <strong>%d</strong> コミット
release.source_code=ソース コード
release.tag_name=タグ名
release.target=ターゲット
release.tag_helper=既存のタグを選択するか、新しいタグを作成し発行します。
release.release_title=リリース タイトル
release.content_with_md=<a href="%s"> Markdown</a> コンテンツ
release.write=書込み
release.preview=プレビュー
release.content_placeholder=コンテンツを書く
release.loading=読み込み中…
release.prerelease_desc=これはリリース前のものです
release.prerelease_helper=このリリースは非プロダクション利用として識別します。
release.publish=リリースを発行
release.save_draft=下書きを保存
release.edit_release=リリースを編集
release.tag_name_already_exist=このタグ名には既にリリースが存在します。
[org]
org_name_holder=組織名
org_name_helper=偉大な組織の名は短く覚えやすいです。
org_email_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=このチームに必要な権限レベルは?
settings=設定
settings.options=オプション
settings.full_name=フルネーム
settings.website=WEBサイト
settings.location=ロケーション
settings.update_settings=設定の更新
settings.change_orgname=組織名が変更されました
settings.change_orgname_desc=組織名が変更されています、継続しますか?これはすべての関連リンクに影響を与えます。
settings.update_setting_success=組織の設定が更新されました。
settings.delete=組織を削除
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> に対してトリガーされる webhook を追加します。
members.public=パブリック
members.public_helper=プライベートにする
members.private=プライベート
members.private_helper=公開する
members.owner=オーナー
members.member=メンバー
members.conceal=隠す
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.add_team_repository=チームのリポジトリを追加
teams.remove_repo=削除(Remove)
teams.add_nonexistent_repo=追加しようとしているリポジトリは存在しません。まずはじめに作成してください。
[admin]
dashboard=ダッシュボード
users=ユーザ
organizations=組織
repositories=リポジトリ
authentication=認証
config=コンフィギュレーション
notices=システム通知
monitor=モニタリング
prev=前へ
next=次へ
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> フックタスク, <b>%d</b> チーム, <b>%d</b> アップデートタスク, <b>%d</b> 添付ファイル の情報を持っています。
dashboard.operation_name=操作の名前
dashboard.operation_switch=スイッチ
dashboard.operation_run=実行
dashboard.clean_unbind_oauth=結び付けられていない OAuth をクリーン
dashboard.clean_unbind_oauth_success=結び付けられていない全ての OAuth を正常に削除しました。
dashboard.delete_inactivate_accounts=非アクティブのアカウントをすべて削除
dashboard.delete_inactivate_accounts_success=すべての非アクティブアカウントは正常に削除されました。
dashboard.delete_repo_archives=リポジトリのすべてのアーカイブを削除
dashboard.delete_repo_archives_success=リポジトリのすべてのアーカイブが正常に削除されました。
dashboard.git_gc_repos=リポジトリでのガベージコレクションを実行します。
dashboard.git_gc_repos_success=すべてのリポジトリは正常にガベージ コレクションを行いました。
dashboard.resync_all_sshkeys='.ssh/ autorized_key' ファイルを再生成します。警告Gogsキー以外は失われます
dashboard.resync_all_sshkeys_success=すべての公開鍵が正常に書き換えられました。
dashboard.resync_all_update_hooks=リポジトリの update フックをすべて再更新する(カスタムの設定パスが変更されたときに必要)
dashboard.resync_all_update_hooks_success=リポジトリの update フックがすべて正常に再更新されました。
dashboard.server_uptime=サーバーの稼働時間
dashboard.current_goroutine=現在のGoroutine
dashboard.current_memory_usage=現在のメモリ使用量
dashboard.total_memory_allocated=割り当てられたメモリの合計
dashboard.memory_obtained=配分されたメモリ量
dashboard.pointer_lookup_times=ポインタ参照回数
dashboard.memory_allocate_times=メモリ割当回数
dashboard.memory_free_times=メモリ解放回数
dashboard.current_heap_usage=現在のヒープ使用量
dashboard.heap_memory_obtained=配分されたヒープ メモリ量
dashboard.heap_memory_idle=アイドルのヒープ メモリ量
dashboard.heap_memory_in_use=使用中のヒープ メモリ
dashboard.heap_memory_released=ヒープ メモリが解放されました
dashboard.heap_objects=ヒープ オブジェクト
dashboard.bootstrap_stack_usage=ブートストラップスタック使用量
dashboard.stack_memory_obtained=配分されたスタック メモリ量
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=ハッシュテーブル分析に割り当てられたメモリ
dashboard.gc_metadata_obtained=GCメタデータ取得
dashboard.other_system_allocation_obtained=他のシステムに割り当てられたメモリ
dashboard.next_gc_recycle=次回のGCリサイクル
dashboard.last_gc_time=前回GCからの時間
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.edit=編集
users.auth_source=認証元
users.local=ローカル
users.auth_login_name=認証ログイン名
users.update_profile_success=アカウントのプロファイルが更新されました。
users.edit_account=アカウントの編集
users.is_activated=アカウントがアクティブされました
users.is_admin=このアカウントには管理者の権限を持つ
users.allow_git_hook=このアカウントには Git のフックを作成する権限を持つ
users.update_profile=アカウント ・ プロファイルを更新
users.delete_account=このアカウントを削除
users.still_own_repo=アカウント所有のリポジトリがあり、リポジトリの削除または所有者の移譲が必要です。
users.still_has_org=アカウントはまだ組織のメンバーであり、組織から退出するか削除する必要があります。
orgs.org_manage_panel=組織の管理パネル
orgs.name=名前
orgs.teams=チーム
orgs.members=メンバー
repos.repo_manage_panel=リポジトリの管理パネル
repos.owner=オーナー
repos.name=名前
repos.private=プライベート
repos.watches=Watches
repos.stars=Stars
repos.issues=課題
auths.auth_manage_panel=承認の管理パネル
auths.new=新しい認証元を追加
auths.name=名前
auths.type=タイプ
auths.enabled=Enabled
auths.updated=Updated
auths.auth_type=認証の種類
auths.auth_name=認証名
auths.domain=ドメイン
auths.host=ホスト
auths.port=ポート
auths.base_dn=ベースのドメイン名
auths.attributes=属性検索
auths.filter=検索フィルター
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=SMTP 認証の種類
auths.smtphost=SMTP ホスト
auths.smtpport=SMTP ポート
auths.enable_tls=TLS 暗号化を有効にする
auths.enable_auto_register=自動登録を有効にする
auths.tips=ヒント
auths.edit=認証設定を編集
auths.activated=認証がアクティブされました
auths.update_success=認証の設定が正常に更新されました。
auths.update=認証設定の更新
auths.delete=この権限を削除
auths.delete_auth_title=認証の削除
auths.delete_auth_desc=認証を削除します、継続しますか?
config.server_config=サーバーの構成
config.app_name=アプリケーション名
config.app_ver=アプリケーションのバージョン
config.app_url=アプリケーションの URL
config.domain=ドメイン
config.offline_mode=オフラインモード
config.disable_router_log=ルーターのログを無効にする
config.run_user=実行ユーザ
config.run_mode=実行モード
config.repo_root_path=リポジトリのルートパス
config.static_file_root_path=静的ファイルのルートパス
config.log_file_root_path=ログ ファイルのルート パス
config.script_type=スクリプトの種類
config.reverse_auth_user=リバース認証ユーザ
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.service_config=サービスの構成
config.register_email_confirm=電子メールの確認を必要
config.disable_register=登録を無効にする
config.show_registration_button=登録ボタンを表示します。
config.require_sign_in_view=サインインを要求
config.mail_notify=メール通知
config.enable_cache_avatar=アバターのキャッシュを有効にします。
config.active_code_lives=コードリンクの有効期限をアクティブ
config.reset_password_code_lives=パスワードリンクの有効期限をリセット
config.webhook_config=Webhook設定
config.task_interval=タスクの間隔
config.deliver_timeout=送信タイムアウト
config.skip_tls_verify=TLSの確認を省略
config.mailer_config=メーラーの構成
config.mailer_enabled=有効にした
config.mailer_name=名前
config.mailer_host=ホスト
config.mailer_user=ユーザ
config.oauth_config=OAuth 構成
config.oauth_enabled=Enabled
config.cache_config=キャッシュの構成
config.cache_adapter=キャッシュ アダプター
config.cache_interval=キャッシュ間隔
config.cache_conn=キャッシュ接続
config.session_config=セッションの構成
config.session_provider=セッション プロバイダー
config.provider_config=プロバイダーの構成
config.cookie_name=クッキー名
config.enable_set_cookie=クッキーの設定を有効にする
config.gc_interval_time=GC 間隔
config.session_life_time=セッションのライフタイム
config.https_only=HTTPS のみ
config.cookie_life_time=クッキーのライフタイム
config.picture_config=画像構成
config.picture_service=画像サービス
config.disable_gravatar=グラバターを無効にする
config.log_config=ログの構成
config.log_mode=ログ モード
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.type=タイプ
notices.type_1=リポジトリ
notices.desc=説明
notices.op=Op。
notices.delete_success=システム通知が正常に削除されました。
[action]
create_repo=リポジトリ <a href="%s/%s"> %s</a>を作成しました
commit_repo=<a href="%s/%s">%s</a>を<a href="%s/%s/src/%s">%s</a>にプッシュしました
create_issue=`問題 <a href="%s/issues/%s">%[1]s#%[2]s</a> を開きました`
comment_issue=`問題 <a href="%s/issues/%s">%[1]s#%[2]s</a> のコメント`
transfer_repo=リポジトリ <code>%s</code> を <a href="/%s%s">%s</a> へ転送しました
push_tag=<a href="%s/%s">%s</a> に タグ <a href="%s/%s/src/%s">%s</a> をプッシュしました
compare_2_commits=これら 2 のコミットの比較を閲覧する
[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=

724
conf/locale/locale_lv-LV.ini Executable file
View File

@@ -0,0 +1,724 @@
app_desc=Viegli uzstādāms Git serviss, kas rakstīts valodā Go
home=Sākums
dashboard=Infopanelis
explore=Izpētīt
help=Palīdzība
sign_in=Pierakstīties
social_sign_in=Sociālā pieteikšanās: 2. solis <small>piesaistīt kontu</small>
sign_out=Izrakstīties
sign_up=Pieteikties
register=Reģistrēties
website=Mājas lapa
version=Versija
page=Lapa
template=Sagatave
language=Valoda
username=Lietotājvārds
email=E-pasts
password=Parole
re_type=Parole atkārtoti
captcha=Pārbaudes kods
repository=Repozitorijs
organization=Organizācija
mirror=Spogulis
new_repo=Jauns repozitorijs
new_migrate=Jauna migrācija
new_fork=Jauns atdalītais repozitorijs
new_org=Jauna organizācija
manage_org=Pārvaldīt organizācijas
admin_panel=Admin panelis
account_settings=Konta iestatījumi
settings=Iestatījumi
news_feed=Jaunumu plūsma
pull_requests=Izmaiņu pieprasījumi
issues=Problēmas
cancel=Atcelt
[install]
install=Instalācija
title=Instalācijas soļi pirmo reizi palaižot
requite_db_desc=Gogs ir nepieciešama MySQL, PostgreSQL vai SQLite3 datu bāze.
db_type=Datu bāzes veids
host=Resursdators
user=Lietotājs
password=Parole
db_name=Datu bāzes nosaukums
db_helper=Nepieciešams izmantot MySQL INNODB dzini ar rakstzīmju kopu utf8_general_ci.
ssl_mode=SSL režīms
path=Ceļš
sqlite_helper=SQLite 3 datu bāzes faila atrašanās vieta.
general_title=Gogs vispārīgie iestatījumi
repo_path=Repozitoriju glabāšanas vieta
repo_path_helper=Visi Git attālinātie repozitoriji tiks glabāti šajā direktorijā.
run_user=Izpildes lietotājs
run_user_helper=Lietotājam ir jābūt rakstīšanas tiesībām repozitorija saknes direktorijai un Gogs jābūt palaistam zem šī lietotāja.
domain=Domēns
domain_helper=Tas ietekmē SSH klonēšanas URL.
http_port=HTTP ports
http_port_helper=Porta numurs pēc kura lietojumprogrammai būs iespējams pieslēgties.
app_url=Lietotnes URL
app_url_helper=Tas ietekmē HTTP/HTTPS klonēšanas URL un e-pasta saturā izsūtītās saites.
email_title=E-pasta pakalpojuma iestatījumi (neobligāti)
smtp_host=SMTP resursdators
mailer_user=Sūtītāja e-pasta adrese
mailer_password=Sūtītāja parole
notify_title=Paziņojumu iestatījumi (neobligāti)
register_confirm=Iespējot reģistrēšanās apstiprināšanu
mail_notify=Iespējot e-pasta paziņojumus
admin_title=Admin konta iestatījumi
admin_name=Lietotājvārds
admin_password=Parole
confirm_password=Apstipriniet paroli
admin_email=E-pasts
install_gogs=Instalēt Gogs
test_git_failed=Kļūda pārbaudot 'git' komandu: %v
sqlite3_not_available=Jūsu versija neatbalsta SQLite3, lūdzu lejupielādējiet oficiālo bināro versiju no %s, NEVIS gobuild versiju.
invalid_db_setting=Datu bāzes iestatījums nav pareizs: %v
invalid_repo_path=Repozitorija atrašanās vieta ir nekorekta: %v
run_user_not_match=Izpildes lietotājs nav pašreizējais lietotājs: %s -> %s
save_config_failed=Neizdevās saglabāt konfigurāciju: %v
invalid_admin_setting=Nekorekts admin konta iestatījums: %v
install_success=Laipni lūdzam! Mēs priecājamies, ka Jūs izvēlaties Gogs, patīkamu lietošanu!
[home]
uname_holder=Lietotājvārds vai e-pasts
password_holder=Parole
switch_dashboard_context=Mainīt infopaneļa kontekstu
my_repos=Mani repozitoriji
collaborative_repos=Sadarbības repozitoriji
my_orgs=Manas organizācijas
my_mirrors=Mani spoguļi
[explore]
repos=Repozitoriji
[auth]
create_new_account=Izveidot jaunu kontu
register_hepler_msg=Jau ir konts? Pieraksties tagad!
social_register_hepler_msg=Jau ir konts? Sasaisti tagad!
disable_register_prompt=Atvainojiet, reģistrācija ir atspējota. Lūdzu, sazinieties ar vietnes administratoru.
disable_register_mail=Atvainojiet, reģistrācijas e-pasta apstiprināšana ir atspējota.
remember_me=Atcerēties mani
forgot_password=Aizmirsu paroli
forget_password=Aizmirsi paroli?
sign_up_now=Nepieciešams konts? Reģistrējies tagad.
confirmation_mail_sent_prompt=Jauns apstiprināšanas e-pasts ir nosūtīts uz <b>%s</b>, lūdzu, pārbaudies savu e-pasta kontu tuvāko %d stundu laikā, lai pabeigtu reģistrācijas procesu.
sign_in_email=Atvērt savu e-pasta kontu
active_your_account=Aktivizēt savu kontu
resent_limit_prompt=Atvainojiet, Jūs sūtījāt aktivizācijas e-pastu pārāk bieži. Lūdzu, gaidiet 3 minūtes.
has_unconfirmed_mail=Sveiki %s, Jums ir neapstiprināta e-pasta adrese (<b>%s</b>). Ja neesat saņēmis apstiprināšanas e-pastu vai Jums ir nepieciešams nosūtīt jaunu, lūdzu, nospiediet pogu, kas atrodas zemāk.
resend_mail=Nospiediet šeit, lai vēlreiz nosūtītu aktivizācijas e-pastu
email_not_associate=Šī e-pasta adrese nav saistīta ar Jūsu kontu.
send_reset_mail=Spiediet šeit, lai nosūtītu paroles maiņas vēstuli uz Jūsu e-pastu
reset_password=Atjaunot savu paroli
invalid_code=Atvainojiet, Jūsu apstiprināšanas kodam ir beidzies derīguma termiņš vai arī tas ir nepareizs.
reset_password_helper=Nospiediet šeit, lai atjaunotu paroli
password_too_short=Paroles garums nedrīkst būt mazāks par 6.
[form]
UserName=Lietotājvārds
RepoName=Repozitorija nosaukums
Email=E-pasta adrese
Password=Parole
Retype=Parole atkārtoti
SSHTitle=SSH atslēgas nosaukums
HttpsUrl=HTTPS URL
PayloadUrl=Vērtuma URL
TeamName=Komandas nosaukums
AuthName=Autorizācijas nosaukums
AdminEmail=Admin e-pasta adrese
require_error=` nedrīkst būt tukšs.`
alpha_dash_error=` drīkst saturēt tikai latīņu alfabēta burtus, ciparus vai domuzīmes (-_).`
alpha_dash_dot_error=` drīkst saturēt tikai latīņu alfabēta burtus, ciparus, domuzīmes (-_) vai punktu.`
min_size_error=` jabūt vismaz %s simbolu garumā.`
max_size_error=` jabūt ne mazāk kā %s simbolu garumā.`
email_error=` nav derīga e-pasta adrese.`
url_error=` nav korekts URL.`
unknown_error=Nezināma kļūda:
captcha_incorrect=Pārbaudes kods nesakrīt ar attēlā redzamo.
password_not_match=Parole un atkārtoti ievadītā parole nav vienādas.
username_been_taken=Lietotājvārds ir jau aizņemts.
repo_name_been_taken=Repozitorija vārds ir jau aizņemts.
org_name_been_taken=Organizācijas nosaukums ir jau aizņemts.
team_name_been_taken=Komandas nosaukums ir jau aizņemts.
email_been_used=E-pasta adrese jau tiek izmantota.
ssh_key_been_used=Publiskās atslēgas nosaukums jau tiek izmantos.
illegal_username=Jūsu lietotājvārds satur neatļautas rakstzīmes.
illegal_repo_name=Krātuves nosaukums satur neatļautas rakstzīmes.
illegal_org_name=Organizācijas nosaukums satur neatļautas rakstzīmes.
illegal_team_name=Grupas nosaukums satur neatļautas rakstzīmes.
username_password_incorrect=Lietotājvārds vai parole nav pareiza.
enterred_invalid_repo_name=Lūdzu, pārliecinieties, vai ievadītā repozitorija nosaukums ir pareizs.
enterred_invalid_owner_name=Lūdzu, pārliecinieties, vai ievadītā īpašnieka vārds ir pareizs.
enterred_invalid_password=Lūdzu pārliecinieties, vai Jūsu ievadītā parole ir pareiza.
user_not_exist=Šāds lietotājs neeksistē.
last_org_owner=Nav iespējams noņemt vienīgo komandas īpašnieku. Pirms tam ir nepieciešams norādīt jauno īpašnieku.
invalid_ssh_key=Atvainojiet, nav iespējams pārbaudīt Jūsu SSH atslēgu: %s
unable_verify_ssh_key=Nav iespējams pārbaudīt jūsu SSH atslēgu, bet tiks pieņemts, ka tā ir derīga, lūdzu, pārliecinieties par to pats.
auth_failed=Autentifikācija neizdevās: %v
still_own_repo=Jūsu esat vismaz viena repozitorija īpašnieks, tos sākumā ir nepieciešams izdzēst vai nomainīt to īpašnieku.
still_has_org=Jūsu esat vismaz vienas organizācijas biedrs, sākumā nepieciešams pamest vai izdzēst šo organizāciju.
org_still_own_repo=Šī organizācija ir vismaz viena repozitorija īpašnieks, tos sākumā ir nepieciešams izdzēst vai nomainīt to īpašnieku.
still_own_user=Šo autentifikāciju joprojām izmanto vismaz viens lietotājs, nepieciešams šiem lietotājiem nomainīt autentifikācijas veidu vai tos izdzēst.
target_branch_not_exist=Mērķa atzars neeksistē
[user]
change_avatar=Mainīt savu profila attēlu vietnē gravatar.com
change_custom_avatar=Mainīt savu profila attēlu iestatījumos
join_on=Pievienojās
repositories=Repozitoriji
activity=Publiskā aktivitāte
followers=Sekotāji
starred=Atzīmēti ar zvaigznīti
following=Seko
[settings]
profile=Profils
password=Parole
ssh_keys=SSH atslēgas
social=Sociālie konti
applications=Lietotnes
orgs=Organizācijas
delete=Dzēst kontu
uid=Lietotāja ID
public_profile=Publiskais profils
profile_desc=Jūsu e-pasta adrese ir publiska un tiks izmantota, lai nosūtītju Jums paziņojumus, kas saistīti ar Jūsu kontu vai darbībām veiktām caur šo mājas lapu.
full_name=Pilns vārds
website=Mājas lapa
location=Atrašanās vieta
update_profile=Mainīt profilu
update_profile_success=Jūsu profila dati ir veiksmīgi saglabāti.
change_username=Lietotāja vārds mainīts
change_username_desc=Lietotājvārds tiks mainīts, vai vēlaties turpināt? Tas ietekmēs visas saites, kas attiecas uz Jūsu kontu.
continue=Turpināt
cancel=Atcelt
enable_custom_avatar=Iespējot maināmu profila attēlu
enable_custom_avatar_helper=Iespējojiet šo, lai atslēgtu profilu attēlu ņemšanu no gravatar.com
choose_new_avatar=Izvēlēties jaunu profila attēlu
update_avatar=Saglabāt profila bildi
uploaded_avatar_not_a_image=Augšupielādētais fails nav attēls.
no_custom_avatar_available=Nav iespējams mainīt profila bildi.
update_avatar_success=Jūsu profila bilde tika veiksmīgi saglabāta.
change_password=Mainīt paroli
old_password=Pašreizējā parole
new_password=Jauna parole
password_incorrect=Ievadīta nepareiza pašreizējā parole.
change_password_success=Parole tika veiksmīgi nomainīta. Tagad jūs varat pieraksītites, izmantojot jauno paroli.
emails=E-pasta adreses
manage_emails=Pārvaldīt e-pasta adreses
email_desc=Primārā e-pasta adrese tiks izmantota sūtot notifikācijas un citām dabībām.
primary=Primārā
primary_email=Iestatīt kā primāro
delete_email=Dzēst
add_new_email=Pievienot jaunu e-pasta adresi
add_email=Pievienot e-pastu
add_email_success=Jūsu jaunā e-pasta adrese tika veiksmīgi pievienota.
manage_ssh_keys=Pārvaldīt SSH atslēgas
add_key=Pievienot atslēgu
ssh_desc=Šis ir saraksts ar Jūsu kontam piesaistītajām SSH atslēgām. Dzēsiet visas, kuras Jūs neatpazīstat.
ssh_helper=<strong>Vajadzīga palīdzība?</strong> Apskatieties pamācību kā <a href="%s">ģenerēt SSH atslēgas</a> vai kā novērst <a href="%s">biežāk sastopamās SSH problēmas</a>.
add_new_key=Pievienot SSH atslēgu
key_name=Atslēgas nosaukums
key_content=Saturs
add_key_success=Pievienota jauna SSH atslēga!
delete_key=Dzēst
add_on=Pievienota
last_used=Pēdējo reizi izmantota
no_activity=Nav nesenas aktivitātes
manage_social=Pārvaldīt piesaistītos sociālos kontus
social_desc=Šeit tiek attēloti visi sociālie konti, kas ir piesaistīti Jūsu kontam. Dzēsiet visus, kurus Jūs neatpazīstat.
unbind=Atsaistīt
unbind_success=Sociālais konts tika atsaistīts.
manage_access_token=Pārvaldīt personīgos piekļuves talonus
generate_new_token=Ģenerēt jaunu talonu
tokens_desc=Talons tika uzģēnerēts, tagad varat to izmantot, lai piekļūtu Gogs API.
new_token_desc=Pašlaik visiem taloniem ir pilna piekļuve Jūsu kontam.
token_name=Talona nosaukums
generate_token=Ģenerēt talonu
generate_token_succees=Jauns piekļuves talons tika veiksmīgi uzģenerēts! Pārliecinieties, ka esat to nokopējis, jo to Jums vairāk nebūs iespēja izdarīt!
delete_token=Dzēst
delete_token_success=Jūsu personīgās piekļuves talons tika veiksmīgi izdzēsts! Neazimistiet veikt nepieciešamos labojumus savās lietojumprogrammās, kas to izmantoja.
delete_account=Dzēst savu kontu
delete_prompt=Šī darbība pilnībā izdzēsīs Jūsu kontu, kā arī tā ir <strong>NEATGRIEZENISKA</strong>!
confirm_delete_account=Apstiprināt dzēšanu
delete_account_title=Konta dzēšana
delete_account_desc=Šis konts tiks neatgriezeniski dzēsts, vai vēlaties turpināt?
[repo]
owner=Īpašnieks
repo_name=Repozitorija nosaukums
repo_name_helper=Labi repzotoriju nosaukumi ir īsi, tādi kurus viegli atcerēties un <strong>unikāli</strong>.
visibility=Redzamība
visiblity_helper=Šis repozitorijs ir <span class="label label-red label-radius">Privāts</span>
fork_repo=Atdalīt repozitoriju
fork_from=Atdalīt no
fork_visiblity_helper=Atdalītam repozitorijam nav iespējams nomainīt tā redzamību
repo_desc=Apraksts
repo_lang=Valoda
repo_lang_helper=Izvēlieties .gitignore failu
license=Licence
license_helper=Izvēlieties licences failu
init_readme=Inicializēt šo repozitoriju ar README.md failu
create_repo=Izveidot repozitoriju
default_branch=Noklusējuma atzars
mirror_interval=Spoguļošanas intervāls (stundās)
goget_meta=Go-Get metadati
goget_meta_helper=Šis repozitorijs saturēs <span class="label label-blue label-radius">Go-Get</span> metadatus
need_auth=Nepieciešama autorizācija
migrate_type=Migrācijas veids
migrate_type_helper=Šis repozitorijs būs <span class="label label-blue label-radius">Spoguļots</span>
migrate_repo=Migrēt repozitoriju
copy_link=Kopēt
click_to_copy=Kopēt uz starpliktuvi
copied=Kopēšana notikusi veiksmīgi
clone_helper=Nepieciešama palīdzība kā veikt klonēšana? Apmeklējiet <a target="_blank" href="%s">Palīdzība</a> lapu!
unwatch=Nevērot
watch=Vērot
unstar=Noņemt zvaigznīti
star=Pievienot zvaigznīti
fork=Atdalīts
no_desc=Nav apraksta
quick_guide=Īsa pamācība
clone_this_repo=Klonēt šo repozitoriju
create_new_repo_command=Izveidot jaunu repozitoriju komandrindā
push_exist_repo=Nosūtīt izmaiņas no komandrindas eksistējošam repozitorijam
branch=Atzars
tree=Koks
branch_and_tags=Atzari un tagi
branches=Atzari
tags=Tagi
issues=Problēmas
commits=Revīzijas
releases=Laidieni
file_raw=Neapstrādāts
file_history=Vēsture
file_view_raw=Rādīt neapstrādātu
commits.commits=Revīzijas
commits.search=Meklēt revīzijas
commits.find=Meklēt
commits.author=Autors
commits.message=Ziņojums
commits.date=Datums
commits.older=Vecāki
commits.newer=Jaunāki
settings=Iestatījumi
settings.options=Opcijas
settings.collaboration=Sadarbība
settings.hooks=Tīmekļa āķi
settings.githooks=Git āķi
settings.deploy_keys=Izvietot atslēgas
settings.basic_settings=Pamatiestatījumi
settings.danger_zone=Bīstamā zona
settings.site=Oficiālā mājas lapa
settings.update_settings=Mainīt iestatījumus
settings.change_reponame=Mainīts repozitorija nosaukums
settings.change_reponame_desc=Repozitorija nosaukums tiks mainīts, vai vēlaties turpināt? Tas ietekmēs visas saites, kas saistītas ar šo repozitoriju.
settings.transfer=Mainīt īpašnieku
settings.transfer_desc=Mainīt šī repozitorija īpašnieku uz citu lietotāju vai organizāciju, kurai Jums ir administratora tiesībs.
settings.new_owner_has_same_repo=Jaunajam īpašniekam jau ir repozitorijs ar šādu nosaukumu.
settings.delete=Dzēst šo repozitoriju
settings.delete_desc=Dzēšot repozitoriju, tā datus vairs nebūs iespējams atgūt. Pirms dzēšanas pārliecinieites vai patiešām vēlaties to darīt.
settings.transfer_notices=<p>- Jūs zaudēsiet piekļuvi repozitorijam, ja jaunais īpašnieks ir individuāls lietotājs.</p><p>- Jūs saglabāsiet piekļuvi repzitorijam, ja jaunais īpašneiks ir organizācija un Jūs esat viens no tās īpašniekiem.</p>
settings.update_settings_success=Repozitorija opcijas ir veiksmīgi saglabātas.
settings.transfer_owner=Jaunais īpašnieks
settings.make_transfer=Mainīt
settings.transfer_succeed=Repozitorija īpašnieks ir veiksmīgi nomainīts.
settings.confirm_delete=Apstiprināt dzēšanu
settings.add_collaborator=Pievienot jaunu līdzstrādnieku
settings.add_collaborator_success=Jauns līdzstrādnieks ir pievienots.
settings.remove_collaborator_success=Līdzstrādnieks tika noņemts.
settings.user_is_org_member=Lietotājs ir organizācijas biedrs, kas nevar tikt pievienots kā līdzstrādnieks.
settings.add_webhook=Pievienot tīmekļa āķi
settings.hooks_desc=Tīmekļa āķi ļauj paziņot ārējiem servisiem par noteiktiem notikomiem, kas notiek Git servisā. Kad iestāsies kāds notikums, katram ārējā servisa URL tiks nosūtīts POST pieprasījums. Lai uzzinātu sīkāk skatieties <a target="_blank" href="%s">Tīmekļa āķu rokasgrāmatā</a>.
settings.githooks_desc=Git āķus apstrādā pats Git. Jūs varat labot atbalsīto āku failus sarakstā zemāk, lai veiktu pielāgotas darbības.
settings.githook_edit_desc=Ja āķis nav aktīvs, tiks attēlots piemērs kā to izmantot. Atstājot āķa saturu tukšu, tas tiks atspējots.
settings.githook_name=Āķa nosaukums
settings.githook_content=Āķa saturs
settings.update_githook=Labot āķi
settings.remove_hook_success=Tīmekļa āķis tika noņemts.
settings.add_webhook_desc=Uz norādīto URL tiks nosūtīts <code>POST</code> pieprasījums ar notikuma datiem. Jūs varat norādīt arī datu formātu, kādā datus vēlaties saņemt (JSON, <code>x-www-form-urlencoded</code> <em>utt.</em>). Detalizētāku informāciju ir iespējams uzzināt <a target="_blank" href="%s">Tīmekļa āķu rokasgrāmatā</a>.
settings.payload_url=Vērtuma URL
settings.content_type=Satura tips
settings.secret=Noslēpums
settings.event_desc=Kādu notikumu rezultātā tiktu izsaukts tīmekļā āķis?
settings.event_push_only=Tikai izmaiņu nosūtīšanas notikumiem.
settings.active=Aktīvs
settings.active_helper=Tiks nosūtīti notikuma dati, kad nostrādās šis āķis.
settings.add_hook_success=Jauns tīmekļa āķis tika veiksmīgi pievienots.
settings.update_webhook=Mainīt tīmekļa āķi
settings.update_hook_success=Tīmekļa āķist tika veiksmīgi saglabāts.
settings.delete_webhook=Dzēst tīmekļa āķi
settings.recent_deliveries=Pēdējās piegādes
settings.hook_type=Āķa veids
settings.add_slack_hook_desc=PIevienot <a href="%s">Slack</a> integrāciju Jūsu repozitorijā.
settings.slack_token=Talons
settings.slack_domain=Domēns
settings.slack_channel=Kanāls
diff.browse_source=Pārlūkot izejas kodu
diff.parent=vecāks
diff.commit=revīzija
diff.data_not_available=Salīdzināšanas dati nav pieejami.
diff.show_diff_stats=Rādīt salīdzināšanas statistiku
diff.stats_desc=<strong>%d mainītis faili</strong> ar <strong>%d papildinājumiem</strong> un <strong>%d dzēšanām</strong>
diff.bin=BIN
diff.view_file=Parādīt failu
release.releases=Laidieni
release.new_release=Jauns laidiens
release.draft=Melnraksts
release.prerelease=Pirmsizlaides versija
release.stable=Stabila
release.edit=labot
release.ahead=<strong>%d</strong> revīzijas atzarā %s kopš šī laidiena
release.source_code=Izejas kods
release.tag_name=Taga nosaukums
release.target=Mērķis
release.tag_helper=Publicējot, izvēlieties esošu vai izveidojiet jaunu tagu.
release.release_title=Laidiena virsraksts
release.content_with_md=Saturs ar <a href="%s">Markdown</a>
release.write=Rakstīt
release.preview=Priekšskatītījums
release.content_placeholder=Uzrakstiet kādu aprakstu
release.loading=Notiek ielāde...
release.prerelease_desc=Šī ir pirmslaidiena versija
release.prerelease_helper=Tiks norādīts, ka šis laidiens nav gatavs lietošanai produkcijas režīmā.
release.publish=Publicēt laidienu
release.save_draft=Saglabāt melnrakstu
release.edit_release=Labot laidienu
release.tag_name_already_exist=Laidiens ar šādu taga nosaukumu jau eksistē.
[org]
org_name_holder=Organizācijas nosaukums
org_name_helper=Labi organizāciju nosaukumi ir īsi un tādi, kurus viegli atcerēties.
org_email_helper=Uz organizācijas e-pastu tiks sūtītas visas notifikācias un apstiprinājumi.
create_org=Izveidot organizāciju
repo_updated=Atjaunināts
people=Personas
invite_someone=Uzaicināt kādu
teams=Komandas
lower_members=dalībnieki
lower_repositories=repozitoriji
create_new_team=Izveidot jaunu komandu
org_desc=Apraksts
team_name=Komandas nosaukums
team_desc=Apraksts
team_name_helper=Šo nosaukumu varēs izmantot, lai pieminētu komandu sarunās.
team_desc_helper=Komandas apraksts
team_permission_desc=Kādām tiesībām šai komandai būtu jābūt?
settings=Iestatījumi
settings.options=Opcijas
settings.full_name=Pilns vārds, uzvārds
settings.website=Mājas lapa
settings.location=Atrašanās vieta
settings.update_settings=Mainīt iestatījumus
settings.change_orgname=Mainīts organizācijas nosaukums
settings.change_orgname_desc=Organizācijas nosaukums tiks mainīts, vai vēlaties turpinat? Tas ietekmēs saites, kas attiecas uz šo organizāciju.
settings.update_setting_success=Organizācijas iestatījumi tika veiksmīgi saglabāti.
settings.delete=Dzēst organizāciju
settings.delete_account=Dzēst šo organizāciju
settings.delete_prompt=Šī darbība pilnībā dzēsīs šo organizāciju, kā arī tā ir <strong>NEATGRIEZENISKA</strong>!
settings.confirm_delete_account=Apstiprināt dzēšanu
settings.delete_org_title=Organizācijas dzēšana
settings.delete_org_desc=Šī organizācija tiks pilnībā izdzēsta, vai vēlaties turpināt?
settings.hooks_desc=Pievienot tīmekļa āķus, kas nostrādās <strong>visiem repozitorijiem</strong> šajā organizācijā.
members.public=Publisks
members.public_helper=padarīt privātu
members.private=Privāts
members.private_helper=padarīt publisku
members.owner=Īpašnieks
members.member=Biedri
members.conceal=Noslēpt
members.remove=Noņemt
members.leave=Atstāt
members.invite_desc=Sāciet rakstīt lietotājvārdu, lai uzaicinātu jaunu biedru organizācijā %s:
members.invite_now=Uzaicināt tagad
teams.join=Pievienoties
teams.leave=Atstāt
teams.read_access=Lasīšanas piekļuve
teams.read_access_helper=Komanda varēs skatīties un klonēt šīs organizācijas repozitorijus.
teams.write_access=Rakstīšanas piekļuve
teams.write_access_helper=Komanda varēs skatīties un klonēt, kā arī nosūtīt izmaiņas šīs organizācijas repozitorijiem.
teams.admin_access=Administratora piekļuve
teams.admin_access_helper=Šī komanda varēs veikt push/pull komandas tās repozitorijiem, kā arī tiem pievienot citus līdzstrādniekus.
teams.no_desc=Komandai nav apraksta
teams.settings=Iestatījumi
teams.owners_permission_desc=Īpašniekiem ir pilna piekļuve <strong>visiem repozitorijiem</strong> un ir organizācijas <strong>administratora tiesības</strong>.
teams.members=Komandas biedri
teams.update_settings=Saglabāt iestatījumus
teams.delete_team=Dzēst komandu
teams.add_team_member=Pievienot komandas biedru
teams.delete_team_title=Komandas dzēšana
teams.delete_team_desc=Komanda tiks dzēsta, vai vēlaties turpināt? Komandas biedri var zaudēt piekļuvi dažiem vai pat visiem repozitorijiem.
teams.delete_team_success=Komanda tika veiksmīgi izdzēsta.
teams.read_permission_desc=Šai komandai ir <strong>lasīšanas</strong> tiesības: dalībnieki var skatīties un klonēt komandas repozitorijus.
teams.write_permission_desc=Šai komandai ir <strong>rakstīšanas</strong> tiesības: dalībnieki var lasīt un nosūtīt izmaiņas repozitorijiem.
teams.admin_permission_desc=Šai komandai ir <strong>administratora</strong> tiesības: dalībnieki var lasīt, rakstīt un pievienot citus dalībniekus komandas repozitorijiem.
teams.repositories=Komandas repozitoriji
teams.add_team_repository=Pievienot komandas repozitoriju
teams.remove_repo=Noņemt
teams.add_nonexistent_repo=Repozitorijs, kuram Jūs mēģinat pievienot neeksistē, sākumā izveidojiet to.
[admin]
dashboard=Infopanelis
users=Lietotāji
organizations=Organizācijas
repositories=Repozitoriji
authentication=Autentifikācijas
config=Konfigurācija
notices=Sistēmas paziņojumi
monitor=Uzraudzība
prev=Iepr.
next=Tālāk
dashboard.statistic=Statistika
dashboard.operations=Darbības
dashboard.system_status=Sistēmas uzraudzības statuss
dashboard.statistic_info=Gogs datu bāze satur <b>%d</b> lietotājus, <b>%d</b> organizācijas, <b>%d</b> publiskās atslēgas, <b>%d</b> repozitorijus, <b>%d</b> vērošanas, <b>%d</b> atzīmētas zvaigznītes, <b>%d</b> darbības, <b>%d</b> piekļuves, <b>%d</b> problēmas, <b>%d</b> komentārus, <b>%d</b> sociālos kontus, <b>%d</b> sekošanas, <b>%d</b> spoguļošanas, <b>%d</b> izlaides, <b>%d</b> login sources, <b>%d</b> tīmekļa āķus, <b>%d</b> starpposmus, <b>%d</b> etiķetes, <b>%d</b> āķu uzdevumus, <b>%d</b> komandas, <b>%d</b> labotus uzdevumus, <b>%d</b> pielikumus.
dashboard.operation_name=Darbības nosaukums
dashboard.operation_switch=Pārslēgt
dashboard.operation_run=Palaist
dashboard.clean_unbind_oauth=Notīrīt nesaistītās OAuth biļetes
dashboard.clean_unbind_oauth_success=Visas nesaistītās OAuth biļetes tika veiksmīgi izdzēstas.
dashboard.delete_inactivate_accounts=Dzēst visus neaktīvos kontus
dashboard.delete_inactivate_accounts_success=Visi neaktīvie kotni tika veiksmīgi izdzēsti.
dashboard.delete_repo_archives=Dzēst visu repozitoriju arhīvus
dashboard.delete_repo_archives_success=Visu repozitoriju arhīvi tika veiksmīgi izdzēsti.
dashboard.git_gc_repos=Veikt repozitoriju datu sakārtošānu (git gc)
dashboard.git_gc_repos_success=Datu sakārtošana visiem repozitorijiem veiksmīgi pabeigta.
dashboard.resync_all_sshkeys=Pārrakstīt '.ssh/authorized_key' failu (brīdinājums: ne-Git atslēgas tiks pazaudētas)
dashboard.resync_all_sshkeys_success=Visas publiskās atslēgas tika veiksmīgi pārrakstītas.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Servera darbības laiks
dashboard.current_goroutine=Izmantotās Gorutīnas
dashboard.current_memory_usage=Pašreiz izmantotā atmiņa
dashboard.total_memory_allocated=Kopējā piešķirtā atmiņa
dashboard.memory_obtained=Iegūtā atmiņa
dashboard.pointer_lookup_times=Rādītāju meklēšanas reizes
dashboard.memory_allocate_times=Atmiņas piešķiršanas reizes
dashboard.memory_free_times=Atmiņas atbrīvošanas reizes
dashboard.current_heap_usage=Pašreizējā kaudzes izmantošana
dashboard.heap_memory_obtained=Iegūtā kaudzes atmiņa
dashboard.heap_memory_idle=Neizmantotā kaudzes atmiņa
dashboard.heap_memory_in_use=Izmantotā kaudzes atmiņa
dashboard.heap_memory_released=Atbrīvotā kaudzes atmiņa
dashboard.heap_objects=Kaudzes atmiņas objekti
dashboard.bootstrap_stack_usage=Izmantotais sāknēšanas steka lielums
dashboard.stack_memory_obtained=Iegūtā steka atmiņa
dashboard.mspan_structures_usage=Izmantotās MSpan struktūras
dashboard.mspan_structures_obtained=Iegūtās MSpan struktūras
dashboard.mcache_structures_usage=Izmantotās MCache struktūras
dashboard.mcache_structures_obtained=Iegūtās MCache struktūras
dashboard.profiling_bucket_hash_table_obtained=Iegūtā profilēšanas kausa jaucējtabula
dashboard.gc_metadata_obtained=Iegūtie GC metadati
dashboard.other_system_allocation_obtained=Iegūtās citas sistēmas sadales
dashboard.next_gc_recycle=Nākošā GC atkritne
dashboard.last_gc_time=Laiks kopš pēdējās GC
dashboard.total_gc_time=Kopējais GC izpildes laiks
dashboard.total_gc_pause=Kopējais GC izpildes laiks
dashboard.last_gc_pause=Pedējās GC izpildes laiks
dashboard.gc_times=GC reizes
users.user_manage_panel=Lietotāju pārvaldības panelis
users.new_account=Izveidot jaunu kontu
users.name=Vārds
users.activated=Aktivizēts
users.admin=Administrators
users.repos=Repozitoriji
users.created=Izveidots
users.edit=Labot
users.auth_source=Autorizācijas avots
users.local=Iebūvētā
users.auth_login_name=Autorizāciju, pietiekšanās vārds
users.update_profile_success=Konta profils tika veiksmīgi saglabāts.
users.edit_account=Labot kontu
users.is_activated=Konts ir aktivizēts
users.is_admin=Šim kontam ir administratora piekļuves tiesības
users.allow_git_hook=Šim kontam ir tiesības pievienot/labot Git āķus
users.update_profile=Mainīt konta profilu
users.delete_account=Dzēst šo kontu
users.still_own_repo=Šis konts ir vismaz viena repozitorija īpašnieks, tos sākumā ir nepieciešams izdzēst vai nomainīt to īpašnieku.
users.still_has_org=Šis konts ir vismaz vienas organizācijas biedrs, sākumā nepieciešams pamest vai izdzēst šo organizāciju.
orgs.org_manage_panel=Organizāciju pārvaldības panelis
orgs.name=Nosaukums
orgs.teams=Komandas
orgs.members=Dalībnieki
repos.repo_manage_panel=Repozitoriju pārvaldības panelis
repos.owner=Īpašnieks
repos.name=Vārds
repos.private=Privāts
repos.watches=Vērošana
repos.stars=Atzīmētās zvaigznītes
repos.issues=Problēmas
auths.auth_manage_panel=Autorizāciju pārvaldības panelis
auths.new=Pievienot jaunu autorizācijas veidu
auths.name=Nosaukums
auths.type=Veids
auths.enabled=Iespējota
auths.updated=Atjaunināta
auths.auth_type=Autorizācijas veids
auths.auth_name=Autorizācijas nosaukums
auths.domain=Domēns
auths.host=Resursdators
auths.port=Ports
auths.base_dn=Pamata DN
auths.attributes=Meklēšanas atribūti
auths.filter=Meklēšanas filtrs
auths.ms_ad_sa=MS Ad SA
auths.smtp_auth=SMTP autorizācijas veids
auths.smtphost=SMTP resursdators
auths.smtpport=SMTP ports
auths.enable_tls=Iespējot TLS šifrēšanu
auths.enable_auto_register=Iespējot automātisko reģistrāciju
auths.tips=Padomi
auths.edit=Labot autorizācijas iestatījumus
auths.activated=Autentifikācija ir aktivizēta
auths.update_success=Autorizācijas iestatījumi tika veiksmīgi saglabāti.
auths.update=Mainīt autorizācijas iestatījumus
auths.delete=Dzēst šo autorizāciju
auths.delete_auth_title=Autorizācijas dzēšana
auths.delete_auth_desc=Šī autorizācija tiks dzēsta, vai vēlaties turpināt?
config.server_config=Servera konfigurācija
config.app_name=Lietotnes nosaukums
config.app_ver=Lietotnes versija
config.app_url=Lietotnes URL
config.domain=Domēns
config.offline_mode=Bezsaistes režīms
config.disable_router_log=Atspējot maršrutētāja žurnalizēšanu
config.run_user=Izpildes lietotājs
config.run_mode=Izpildes režīms
config.repo_root_path=Repozitoriju glabāšanas vieta
config.static_file_root_path=Statisko failu atrašanās vieta
config.log_file_root_path=Žurnalizēšanas failu glabāšanas vieta
config.script_type=Skripta veids
config.reverse_auth_user=Reversā lietotāja autentifikācija
config.db_config=Datu bāzes konfigurācija
config.db_type=Veids
config.db_host=Resursdators
config.db_name=Nosaukums
config.db_user=Lietotājs
config.db_ssl_mode=SSL režīms
config.db_ssl_mode_helper=(tikai PostgreSQL datu bāzei)
config.db_path=Ceļš
config.db_path_helper=(tikai Sqlite3 datu bāzei)
config.service_config=Pakalpojuma konfigurācija
config.register_email_confirm=Pieprasīt e-pasta apstiprināšanu
config.disable_register=Atspējot jaunu lietotāju reģistrāciju
config.show_registration_button=Rādīt reģistrēšanās pogu
config.require_sign_in_view=Nepieciešama autorizācija
config.mail_notify=Pasta paziņojumi
config.enable_cache_avatar=Glabāt profila attēlus kešatmiņā
config.active_code_lives=Aktīvā koda ilgums
config.reset_password_code_lives=Paroles atiestatīšanas koda ilgums
config.webhook_config=Tīkla āķu konfigurācija
config.task_interval=Uzdevuma intervāls
config.deliver_timeout=Piegādes noildze
config.skip_tls_verify=Skip TLS Verify
config.mailer_config=Sūtītāja konfigurācija
config.mailer_enabled=Iespējots
config.mailer_name=Nosaukums
config.mailer_host=Resursdators
config.mailer_user=Lietotājs
config.oauth_config=OAuth konfigurācija
config.oauth_enabled=Iespējota
config.cache_config=Kešatmiņas konfigurācija
config.cache_adapter=Kešatmiņas adapteris
config.cache_interval=Kešatmiņas intervāls
config.cache_conn=Kešatmiņas pieslēguma parametri
config.session_config=Sesijas konfigurācja
config.session_provider=Sesijas nodrošinātājs
config.provider_config=Pakalpojumu sniedzēja konfigurācija
config.cookie_name=Sīkdatnes nosaukums
config.enable_set_cookie=Ļaut izmantot sīkdatnes
config.gc_interval_time=GC laika intervāls
config.session_life_time=Sesijas ilgums
config.https_only=Tikai HTTPS
config.cookie_life_time=Sīkdatņu glabāšanas ilgums
config.picture_config=Attēlu konfigurācija
config.picture_service=Lokāli attēli
config.disable_gravatar=Atspējot Gravatar
config.log_config=Žurnalizēšanas konfigurācija
config.log_mode=Žurnalizēšanas veids
monitor.cron=Cron uzdevumi
monitor.name=Nosaukums
monitor.schedule=Grafiks
monitor.next=Nākošās izpildes laiks
monitor.previous=Pēdējās izpildes laiks
monitor.execute_times=Izpilžu skaits
monitor.process=Darbojošies procesi
monitor.desc=Apraksts
monitor.start=Sākuma laiks
monitor.execute_time=Izpildes laiks
notices.system_notice_list=Sistēmas paziņojumi
notices.type=Veids
notices.type_1=Repozitorijs
notices.desc=Apraksts
notices.op=Op.
notices.delete_success=Sistēmas paziņojums tika veiksmīgi izdzēsts.
[action]
create_repo=izveidoja repozitoriju <a href="%s/%s">%s</a>
commit_repo=veica izmaiņu nosūtīšanu atzaram <a href="%s/%s/src/%s">%s</a> repozitorijā <a href="%s/%s">%s</a>
create_issue=`reģistrēja problēmu <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`pievienoja komentāru problēmai <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=mainīja repozitorija <code>%s</code> īpašnieku uz <a href="/%s%s">%s</a>
push_tag=pievienoja tagu <a href="%s/%s/src/%s">%s</a> repozitorijam <a href="%s/%s">%s</a>
compare_2_commits=Veikt salīdzināšanu starp šīm 2 revīzijām
[tool]
ago=atpakaļ
from_now=no šī brīža
now=tagad
1s=1 sekundi %s
1m=1 minūti %s
1h=1 stundu %s
1d=1 dienu %s
1w=1 nedēļu %s
1mon=1 mēnesi %s
1y=1 gadu %s
seconds=%d sekundes %s
minutes=%d minūtes %s
hours=%d stundas %s
days=%d dienas %s
weeks=%d nedēļas %s
months=%d mēneši %s
years=%d gadi %s
raw_seconds=sekundes
raw_minutes=minūtes

View File

@@ -59,9 +59,11 @@ run_user=Uitvoerende gebruikersnaam
run_user_helper=Deze gebruiker moet toegang hebben tot de git repositorie directorie en moet Gogs kunnen starten
domain=Domein
domain_helper=Dit heeft invloed op de SSH kloon URLs
http_port=HTTP-poort
http_port_helper=Poortnummer waar het programma naar luistert.
app_url=Applicatie URL
app_url_helper=Dit heeft invloed op de HTTP/HTTPS kloon urls en de urls die in de email worden gebruikt
email_title=Email service instellingen (Optioneel)
email_title=E-mail service instellingen (Optioneel)
smtp_host=SMTP host
mailer_user=Afzender e-mail / gebruikersnaam
mailer_password=Wachtwoord
@@ -109,7 +111,7 @@ confirmation_mail_sent_prompt=Een bevestigingsemail is gestuurd naar <b>%s</b>,
sign_in_email=Meld u aan met uw e-mailadres
active_your_account=Activeer uw account
resent_limit_prompt=Sorry, u heeft te snel na elkaar een aanvraag gedaan voor een activatie mail. Wacht drie minuten voor uw volgende aanvraag.
has_unconfirmed_mail=Beste %s, u heeft een onbevestigde e-mailadres (<b>%s</b>). Als u nog geen bevestiging per e-mail heeft ontvangen, of u een nieuwe aanvraag wilt doen, klik dan op de onderstaande knop.
has_unconfirmed_mail=Beste %s, u heeft een onbevestigd e-mailadres (<b>%s</b>). Als u nog geen bevestiging heeft ontvangen, of u een nieuwe aanvraag wilt doen, klik dan op de onderstaande knop.
resend_mail=Klik hier om uw activatie mail nog een keer te verzenden
email_not_associate=Dit e-mailadres is niet gekoppeld aan een account.
send_reset_mail=Klik hier om uw wachtwoord reset mail (nogmaals) te versturen
@@ -173,6 +175,7 @@ target_branch_not_exist=Doel branch bestaat niet
[user]
change_avatar=Verander uw avatar op Gravatar.com
change_custom_avatar=Wijzig uw avatar in de instellingen
join_on=Aangemeld op
repositories=repositories
activity=Openbare activiteit
@@ -191,7 +194,7 @@ delete=Verwijder account
uid=uid
public_profile=Openbaar profiel
profile_desc=Uw e-mailadres is openbaar zichtbaar en zal gebruikt worden gebruikt voor alle account gerlateerde berichtgevingen en web bewerking gemaakt via de website.
profile_desc=Uw e-mailadres is openbaar en zal gebruikt worden voor alle account gerelateerde berichtgevingen en bewerkingingen die via de website worden gedaan.
full_name=Volledige naam
website=Website
location=Locatie
@@ -202,12 +205,30 @@ change_username_desc=Gebruikersnaam is gewijzigd. Wilt u doorgaan? Dit zal gevol
continue=Doorgaan
cancel=Annuleren
enable_custom_avatar=Aangepaste avatar inschakelen
enable_custom_avatar_helper=Avatar niet ophalen van Gravatar
choose_new_avatar=Kies een nieuwe avatar
update_avatar=Avatar instelling bijwerken
uploaded_avatar_not_a_image=Geüpload bestand is geen afbeelding.
no_custom_avatar_available=Geen aangepaste avatar beschikbaar, kan niet worden ingeschakeld.
update_avatar_success=Instellingen voor avatar succesvol bijgewerkt.
change_password=Verander wachtwoord
old_password=Huidige wachtwoord
new_password=Nieuw wachtwoord
password_incorrect=Huidig wachtwoord is niet correct.
change_password_success=Wachtwoord is succesvol gewijzigd. U kunt nu met uw nieuwe wachtwoord inloggen.
emails=E-mailadressen
manage_emails=E-mailadressen beheren
email_desc=Uw primaire e-mailadres zal worden gebruikt voor meldingen en andere administratieve taken.
primary=Primair
primary_email=Instellen als primair
delete_email=Verwijder
add_new_email=Nieuw e-mailadres toevoegen
add_email=E-mailadres toevoegen
add_email_success=Het e-mailadres was toegevoegd.
manage_ssh_keys=Beheer SSH sleutels
add_key=Sleutel toevoegen
ssh_desc=Dit is een lijst van alle SSH sleutels die gekoppeld zijn aan uw account. Verwijder alle sleutels die u niet herkent.
@@ -368,10 +389,34 @@ diff.stats_desc=<strong>%d gewijzigde bestanden</strong> met <strong>toevoeginge
diff.bin=BIN
diff.view_file=Bestand weergeven
release.releases=Releases
release.new_release=Nieuwe release
release.draft=Concept
release.prerelease=Voorlopige versie
release.stable=Stabiel
release.edit=bewerken
release.ahead=<strong>%d</strong> aanpassingen aan %s sinds deze versie
release.source_code=Broncode
release.tag_name=Tagnaam
release.target=Doel
release.tag_helper=Kies een bestaande tag, of creëer een nieuwe tag bij publiceren.
release.release_title=Release titel
release.content_with_md=Inhoud met <a href="%s">Markeringen</a>
release.write=Schrijf
release.preview=Voorbeeld
release.content_placeholder=Schrijf enige inhoud
release.loading=Laden...
release.prerelease_desc=Dit is een beta-versie
release.prerelease_helper=Wij wijzen u erop dat deze release is niet geschikt voor productie doeleinden.
release.publish=Release publiceren
release.save_draft=Concept opslaan
release.edit_release=Release bewerken
release.tag_name_already_exist=Versie met deze naam bestaat al.
[org]
org_name_holder=Organisatienaam
org_name_helper=Een goede organisatienaam is kort en memorabel.
org_email_helper=Alle notificaties en bevestigingen worden op het e-mailadres van de organisatie ontvangen.
org_email_helper=Alle notificaties en bevestigingen worden gestuurd naar het e-mailadres van de organisatie.
create_org=Nieuwe organisatie aanmaken
repo_updated=Geupdate
people=Mensen
@@ -467,6 +512,13 @@ dashboard.delete_inactivate_accounts=Verwijder alle inactieve accounts
dashboard.delete_inactivate_accounts_success=Alle inactivering van rekeningen hebben verwijderd.
dashboard.delete_repo_archives=Verwijderen van alle repositories archieven
dashboard.delete_repo_archives_success=Alle repositories archieven hebben verwijderd.
dashboard.git_gc_repos=Garbage collectie uitvoeren
dashboard.git_gc_repos_success=Garbage collectie met succes uitgevoerd.
dashboard.resync_all_sshkeys=Herschrijf '.ssh/authorized_keys' (Let op: alle sleutels die niet van Gogs zijn zullen verloren gaan!)
dashboard.resync_all_sshkeys_success=Alle publieke sleutels zijn herschreven.
dashboard.resync_all_update_hooks=Herschrijf alle repositorie-hooks (nodig als de configuratie bestandslocatie is gewijzigd)
dashboard.resync_all_update_hooks_success=Alle repositorie-hooks zijn herschreven.
dashboard.server_uptime=Uptime server
dashboard.current_goroutine=Huidige Goroutines
dashboard.current_memory_usage=Huidige geheugen gebruik
@@ -586,6 +638,7 @@ config.db_path_helper=(alleen voor "sqlite3")
config.service_config=Serviceconfiguratie
config.register_email_confirm=E-mailbevestiging registreren
config.disable_register=Registratie uitgeschakeld
config.show_registration_button=Registeren knop weergeven
config.require_sign_in_view=Inloggen vereist om te kunnen inzien
config.mail_notify=E-mailnotificaties
config.enable_cache_avatar=Avatar Cache inschakelen
@@ -594,6 +647,7 @@ config.reset_password_code_lives=Reset wachtwoord Code leven
config.webhook_config=Webhook configuratie
config.task_interval=Taakinterval
config.deliver_timeout=Bezorging verlooptijd
config.skip_tls_verify=TLS certificaat controle overslaan
config.mailer_config=Mailerconfiguatie
config.mailer_enabled=Ingeschakeld
config.mailer_name=Naam
@@ -641,8 +695,8 @@ notices.delete_success=Systeem bericht is met succes verwijderd.
[action]
create_repo=repositorie aangemaakt in <a href="%s/%s">%s</a>
commit_repo=push update naar <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a
create_issue=opende issue in <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue=reactie op issue <a href="%s/%s/issues/%s">%s#%s</a>
create_issue=`opende issue in <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`reactie op issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=repositorie verplaatst naar <code>%s</code> naar <a href="/%s%s">%s</a>
push_tag=geduwd label <a href="%s/%s/src/%s"> %s</a> naar <a href="%s/%s"> %s</a>
compare_2_commits=Weergave vergelijking voor deze 2 commits
@@ -668,16 +722,3 @@ years=%d jaren %s
raw_seconds=seconden
raw_minutes=minuten

724
conf/locale/locale_ru-RU.ini Executable file
View File

@@ -0,0 +1,724 @@
app_desc=Удобная служба для собственного Git-репозитория, написанная на языке Go
home=Главная
dashboard=Панель мониторинга
explore=Обзор
help=Помощь
sign_in=Войти
social_sign_in=Вход через соцсеть: 2-й шаг <small>свяжите учетную запись</small>
sign_out=Выход
sign_up=Регистрация
register=Зарегистрироваться
website=Веб-сайт
version=Версия
page=Страница
template=Шаблон
language=Язык
username=Имя пользователя
email=Эл. почта
password=Пароль
re_type=Повтор
captcha=Captcha
repository=Репозиторий
organization=Организация
mirror=Зеркало
new_repo=Новый репозиторий
new_migrate=Новая Миграция
new_fork=Новый проект из репозитория
new_org=Новая Организация
manage_org=Управление Организацией
admin_panel=Панель администратора
account_settings=Настройки аккаунта
settings=Настройки
news_feed=Лента новостей
pull_requests=Pull Requests
issues=Вопросы
cancel=Отмена
[install]
install=Установка
title=Установочные шаги для первого запуска
requite_db_desc=Для Gogs требуется MySQL, PostgreSQL или SQLite3.
db_type=Тип базы данных
host=Хост
user=Пользователь
password=Пароль
db_name=Имя базы данных
db_helper=Для MySQL используйте тип таблиц InnoDB с кодировкой utf8_general_ci.
ssl_mode=Режим SSL
path=Путь
sqlite_helper=Путь к файлу базы данных SQLite3.
general_title=Общие параметры Gogs
repo_path=Путь корня репозитория
repo_path_helper=Всех удаленные репозитории Git будет сохранены в этой директории.
run_user=Пользователь
run_user_helper=У пользователя должен быть доступ к пути к корню репозитория и к запуску Gogs.
domain=Домен
domain_helper=Влияет на URL-адреса для клонирования по SSH.
http_port=Порт HTTP
http_port_helper=Номер порта, который приложение будет слушать.
app_url=URL приложения
app_url_helper=Этот параметр влияет на URL для клонирования по HTTP/HTTPS и на адреса в электронной почте.
email_title=Настройки службы электронной почты (опционально)
smtp_host=Узел SMTP
mailer_user=Электронная почта отправителя
mailer_password=Пароль отправителя
notify_title=Настройки уведомлений(опционально)
register_confirm=Включить подтверждение регистрации
mail_notify=Разрешить почтовые уведомления
admin_title=Настройки учётной записи администратора
admin_name=Имя пользователя
admin_password=Пароль
confirm_password=Подтвердить пароль
admin_email=Эл. почта
install_gogs=Установить Gogs
test_git_failed=Не удалось проверить 'git' команду: %v
sqlite3_not_available=Ваша версия не поддерживает SQLite3, пожалуйста скачайте официальную бинарную версию от %s, а не версию gobuild.
invalid_db_setting=Настройки базы данных не правильные: %v
invalid_repo_path=Недопустимый путь к корню репозитория: %v
run_user_not_match=Текущий пользователь не является пользователем для запуска: %s -> %s
save_config_failed=Не удалось сохранить конфигурацию: %v
invalid_admin_setting=Указан недопустимый параметр учетной записи администратора: %v
install_success=Добро пожаловать! Мы рады, что вы выбрали Gogs. Веселитесь и берегите себя.
[home]
uname_holder=Имя пользователь или E-mail
password_holder=Пароль
switch_dashboard_context=Переключить контекст панели управления
my_repos=Мои репозитории
collaborative_repos=Совместные репозитории
my_orgs=Моя Организация
my_mirrors=Мои зеркала
[explore]
repos=Репозитории
[auth]
create_new_account=Создать новый аккаунт
register_hepler_msg=Уже есть аккаунт? Авторизуйтесь!
social_register_hepler_msg=Уже есть учетная запись? Свяжите ее с соцсетью!
disable_register_prompt=Извините, возможность регистрации отключена. Пожалуйста, свяжитесь с администратором сайта.
disable_register_mail=К сожалению подтверждение регистрации по почте отключено.
remember_me=Запомнить меня
forgot_password=Забыли пароль
forget_password=Забыли пароль?
sign_up_now=Нужен аккаунт? Зарегистрируйтесь.
confirmation_mail_sent_prompt=Новое письмо для подтверждения было направлено на <b>%s</b>, пожалуйста, проверьте ваш почтовый ящик в течение %d часов для завершения регистрации.
sign_in_email=Войдите в свой адрес электронной почты
active_your_account=Активируйте свой аккаунт
resent_limit_prompt=Вы слишком часто отправляете письмо с активацией. Подождите 3 минуты, пожалуйста.
has_unconfirmed_mail=Здравствуйте, %s! У вас есть неподтвержденный адрес электронной почты (<b>%s</b>). Если вам не приходило письмо с подтверждением или нужно выслать новое письмо, нажмите на кнопку ниже.
resend_mail=Нажмите здесь, чтобы переотправить активационное письмо
email_not_associate=Этот адрес электронной почты не связан ни с одной учетной записью.
send_reset_mail=Нажмите сюда, чтобы отправить письмо для сброса пароля
reset_password=Сброс пароля
invalid_code=Извините, ваш код подтверждения истек или не является допустимым.
reset_password_helper=Нажмите здесь, чтобы сбросить свой пароль
password_too_short=Длина пароля не менее 6 символов.
[form]
UserName=Пользователь
RepoName=Имя репозитория
Email=Адрес эл. почты
Password=Пароль
Retype=Введите пароль еще раз
SSHTitle=Имя SSH ключа
HttpsUrl=URL HTTPS
PayloadUrl=Payload URL
TeamName=Название команды
AuthName=Имя авторизации
AdminEmail=Электронная почта администратора
require_error=«не может быть пустым.»
alpha_dash_error=«должен быть допустимым символьным, числовым или dash(-_) значением.»
alpha_dash_dot_error=«должен быть допустимым символьным, числовым или dash(-_) символами, включая точку.»
min_size_error=«должен содержать по крайней мере %s символов.»
max_size_error=` должен содержать максимум %s символов.`
email_error=«не является адресом электронной почты.»
url_error=«не является допустимым URL-адресом.»
unknown_error=Неизвестная ошибка:
captcha_incorrect=CAPTCHA не совпадает.
password_not_match=Пароль и подтверждение пароля не совпадают.
username_been_taken=Имя пользователя уже принято.
repo_name_been_taken=Имя репозитория уже принято.
org_name_been_taken=Название организации было уже принято.
team_name_been_taken=Название команды было уже принято.
email_been_used=Адрес электронной почты уже используется.
ssh_key_been_used=Имя открытого ключа уже используется.
illegal_username=Ваше имя пользователя содержит недопустимые символы.
illegal_repo_name=Имя репозитория содержит недопустимые знаки.
illegal_org_name=Название организации содержит недопустимые знаки.
illegal_team_name=Имя группы содержит недопустимые знаки.
username_password_incorrect=Имя пользователя или пароль не правильный.
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=Gogs не может проверить ваш SSH-ключ, но мы допускаем, что он действителен. Пожалуйста, удостоверьтесь самостоятельно, что ключ действителен.
auth_failed=Ошибка аутентификации: %v
still_own_repo=На вашем аккаунте все еще остается как минимум один репозиторий, сначала вам нужно удалить или передать его.
still_has_org=Вы находитесь в организации, сперва Вам необходимо покинуть ее или удалить.
org_still_own_repo=Данная организация все еще является владельцем репозиториев, необходимо удалить или переместить их в начале.
still_own_user=Эта проверка подлинности по-прежнему используется некоторыми пользователями, вы должны переместить их и затем снова удалить.
target_branch_not_exist=Целевая ветка не существует
[user]
change_avatar=Измените ваш аватар на gravatar.com
change_custom_avatar=Измените ваш аватар в настройках
join_on=Присоединилась к
repositories=Репозитории
activity=Активность
followers=Подписчики
starred=Избранное
following=Подписан
[settings]
profile=Профиль
password=Пароль
ssh_keys=SSH ключи
social=Учетные записи в соцсетях
applications=Приложения
orgs=Организации
delete=Удалить аккаунт
uid=UID
public_profile=Открытый профиль
profile_desc=Адрес вашей электронной почты является публичным и будет использован для любых уведомлений, связанных с аккаунтом, а также для любых действий, совершенных через сайт.
full_name=ФИО
website=Веб-сайт
location=Местоположение
update_profile=Обновить профиль
update_profile_success=Ваш профиль был успешно обновлен.
change_username=Имя пользователя изменено
change_username_desc=Имя пользователя изменено, вы хотите продолжить? Это повлияет на все ссылки, связанные с вашей учетной записью.
continue=Далее
cancel=Отмена
enable_custom_avatar=Включить собственный аватар
enable_custom_avatar_helper=Включите эту опцию, чтоб отключить загрузку с Gravatar
choose_new_avatar=Выбрать новый аватар
update_avatar=Обновить настройку аватара
uploaded_avatar_not_a_image=Загружаемый файл не является изображением.
no_custom_avatar_available=Собственный аватар недоступен, включить его невозможно.
update_avatar_success=Настройка вашего аватара обновлена успешно.
change_password=Сменить пароль
old_password=Текущий пароль
new_password=Новый пароль
password_incorrect=Текущий пароль не правильный.
change_password_success=Пароль сменен успешно. Теперь вы можете войти с новым паролем.
emails=Адреса электронной почты
manage_emails=Управление адресами электронной почты
email_desc=Ваш основной адрес электронной почты будет использован для уведомлений и других операций.
primary=Основной
primary_email=Установить как основной
delete_email=Удалить
add_new_email=Добавить новый адрес электронной почты
add_email=Добавить электронную почту
add_email_success=Новый адрес электронной почты успешно добавлен.
manage_ssh_keys=Управление SSH ключами
add_key=Добавить ключ
ssh_desc=Это список ключей SSH связанных с вашей учетной записью. Удаляйте любые неизвестные вам ключи.
ssh_helper=<strong>Нужна помощь?</strong> Ознакомьтесь с нашим путеводителем по <a href="%s">созданию SSH-ключей</a> или посмотрите решения <a href="%s">частых проблем, связанных с SSH</a>.
add_new_key=Добавить SSH ключ
key_name=Имя ключа
key_content=Содержимое
add_key_success=Был добавлен новый ключ SSH!
delete_key=Удалить
add_on=Добавлено
last_used=Последний раз использовался
no_activity=Еще не применялся
manage_social=Управление привязанными учетными записями в соцсетях
social_desc=Это список привязанных учетных записей в соцсетях. Удаляйте любые неизвестные вам привязки.
unbind=Отвязать
unbind_success=Социальная учетная запись отвязана.
manage_access_token=Управление Токенами Персонального Доступа
generate_new_token=Создать новый token
tokens_desc=Созданные вами токены могут использоваться для доступа к Gogs API.
new_token_desc=Пока что каждый токен будет иметь полный доступ к вашей учетной записи.
token_name=Имя маркера
generate_token=Генерировать маркер
generate_token_succees=Успешно создан новый токен доступа! Пожалуйста сделайте копию вашего нового токена персонального доступа. Вы не сможете увидеть его снова!
delete_token=Удалить
delete_token_success=Персональный токен доступа был успешно удален! Не забудьте так же обновить ваши приложения.
delete_account=Удалить свой аккаунт
delete_prompt=Этим действием вы удалите свою учетную запись навсегда и <strong>НЕ СМОЖЕТЕ</strong> ее вернуть!
confirm_delete_account=Подтвердите удаление
delete_account_title=Удаление аккаунта
delete_account_desc=Эта учетная запись будет удалена насовсем. Вы хотите продолжить?
[repo]
owner=Владелец
repo_name=Имя репозитория
repo_name_helper=Лучшие названия репозиториев коротки, запоминаемы и <strong>уникальны</strong>.
visibility=Видимость
visiblity_helper=Это хранилище &mdash; <span class="label label-red label-radius">частное</span>
fork_repo=Ответвить репозиторий
fork_from=Ответвление от
fork_visiblity_helper=Ответвленному репозиторию нельзя поменять уровень видимости
repo_desc=Описание
repo_lang=Язык
repo_lang_helper=Выберите файл .gitignore
license=Лицензия
license_helper=Выберите файл лицензии
init_readme=Создать репозиторий с файлом README.md
create_repo=Создание репозитория
default_branch=Ветка по умолчанию
mirror_interval=Интервал зеркалирования (час)
goget_meta=Meta-тег для go get
goget_meta_helper=Репозиторий будет доступен для <span class="label label-blue label-radius">go get</span>
need_auth=Требуется авторизация
migrate_type=Тип миграции
migrate_type_helper=Этот репозиторий будет <span class="label label-blue label-radius">зеркалом</span>
migrate_repo=Перенос репозитория
copy_link=Копировать
click_to_copy=Скопировать в буфер обмена
copied=Успешно скопировано
clone_helper=Нужна помощь в клонировании? Посетите страницу <a target="_blank" href="%s">помощи</a>!
unwatch=Перестать следить
watch=Следить
unstar=Убрать из избранного
star=В избранное
fork=Ответвить
no_desc=Нет описания
quick_guide=Краткое руководство
clone_this_repo=Клонировать репозиторий
create_new_repo_command=Создать новый репозиторий из командной строки
push_exist_repo=Отправить существующий репозиторий из командной строки
branch=Ветка
tree=Дерево
branch_and_tags=Ветки и метки
branches=Ветки
tags=Метки
issues=Обсуждения
commits=Коммиты
releases=Релизы
file_raw=Raw
file_history=История
file_view_raw=View Raw
commits.commits=Коммиты
commits.search=Поиск коммитов
commits.find=Найти
commits.author=Автор
commits.message=Сообщение
commits.date=Дата
commits.older=Раньше
commits.newer=Новее
settings=Настройки
settings.options=Опции
settings.collaboration=Сотрудничество
settings.hooks=Автоматическое обновление
settings.githooks=Git хуки
settings.deploy_keys=Deploy Keys
settings.basic_settings=Основные параметры
settings.danger_zone=Опасная зона
settings.site=Официальный сайт
settings.update_settings=Обновить настройки
settings.change_reponame=Имя репозитория изменено
settings.change_reponame_desc=Имя хранилища изменено, вы хотите продолжить? Это действие повлияет на все ссылки, относящиеся к этому репозиторию.
settings.transfer=Передать права собственности
settings.transfer_desc=Transfer this repo to another user or to an organization where you have admin rights.
settings.new_owner_has_same_repo=У нового владельца уже есть хранилище с таким названием.
settings.delete=Удалить этот репозиторий
settings.delete_desc=Как только вы удалите репозиторий — пути назад не будет. Удостоверьтесь, что вам это точно нужно.
settings.transfer_notices=<p>- You will lose access if new owner is a individual user.</p><p>- You will remain access if new owner is an organization and you're one of the owners.</p>
settings.update_settings_success=Настройка репозитория обновлена успешно.
settings.transfer_owner=Новый владелец
settings.make_transfer=Выполнить передачу
settings.transfer_succeed=Repository ownership has been transferred successfully.
settings.confirm_delete=Подтвердить удаление
settings.add_collaborator=Добавить нового соавтора
settings.add_collaborator_success=Был добавлен новый соавтор.
settings.remove_collaborator_success=Соавтор был удален.
settings.user_is_org_member=User is organization member who cannot be added as a collaborator.
settings.add_webhook=Добавить Webhook
settings.hooks_desc=Webhooks allow external services to be notified when certain events happen on Gogs. When the specified events happen, we'll send a POST request to each of the URLs you provide. Learn more in our <a target="_blank" href="%s">Webhooks Guide</a>.
settings.githooks_desc=Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to apply custom operations.
settings.githook_edit_desc=If hook is not active, sample content will be presented. Leave content to be blank will disable this hook.
settings.githook_name=Название Hook'a
settings.githook_content=Перехватить содержание
settings.update_githook=Обновить Hook
settings.remove_hook_success=Webhook has been removed.
settings.add_webhook_desc=Well send a <code>POST</code> request to the URL below with details of any subscribed events. You can also specify which data format you'd like to receive (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). More information can be found in <a target="_blank" href="%s">Webhooks Guide</a>.
settings.payload_url=Payload URL
settings.content_type=Тип содержимого
settings.secret=Secret
settings.event_desc=Which events would you like to trigger this webhook?
settings.event_push_only=Just the <code>push</code> event.
settings.active=Активен
settings.active_helper=We will deliver event details when this hook is triggered.
settings.add_hook_success=New webhook has been added.
settings.update_webhook=Update Webhook
settings.update_hook_success=Webhook has been updated.
settings.delete_webhook=Удалить автоматическое обновление
settings.recent_deliveries=Recent Deliveries
settings.hook_type=Тип перехватчика
settings.add_slack_hook_desc=Add <a href="%s">Slack</a> integration to your repository.
settings.slack_token=Token
settings.slack_domain=Домен
settings.slack_channel=Канал
diff.browse_source=Просмотр исходного кода
diff.parent=Родитель
diff.commit=Сommit
diff.data_not_available=Данные Diff не доступны.
diff.show_diff_stats=Show Diff Stats
diff.stats_desc=<strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong>
diff.bin=BIN
diff.view_file=Просмотреть файл
release.releases=Релизы
release.new_release=Новый релиз
release.draft=Черновик
release.prerelease=Предрелиз
release.stable=Стабильный
release.edit=Редактировать
release.ahead=<strong>%d</strong> commits to %s since this release
release.source_code=Исходный код
release.tag_name=Имя тега
release.target=Цель
release.tag_helper=Choose an existing tag, or create a new tag on publish.
release.release_title=Название релиза
release.content_with_md=Содержимое с <a href="%s">Markdown</a>
release.write=Запись
release.preview=Предварительный просмотр
release.content_placeholder=Write some content
release.loading=Загрузка...
release.prerelease_desc=Это предварительный релиз
release.prerelease_helper=Well point out that this release is identified as non-production ready.
release.publish=Опубликовать релиз
release.save_draft=Сохранить черновик
release.edit_release=Редактировать релиз
release.tag_name_already_exist=Релиз с этим именем тега уже существует.
[org]
org_name_holder=Название организации
org_name_helper=Лучшие названия организаций коротки и запоминаемы.
org_email_helper=Organization's E-mail receives all notifications and confirmations.
create_org=Создать Организацию
repo_updated=Обновлено
people=Люди
invite_someone=Пригласить кого-нибудь
teams=Команды
lower_members=Участники
lower_repositories=Репозитории
create_new_team=Создать Новую Команду
org_desc=Описание
team_name=Название команды
team_desc=Описание
team_name_helper=You'll use this name to mention this team in conversations.
team_desc_helper=What is this team all about?
team_permission_desc=What permission level should this team have?
settings=Настройки
settings.options=Опции
settings.full_name=Полное имя
settings.website=Сайт
settings.location=Местоположение
settings.update_settings=Обновить настройки
settings.change_orgname=Имя Организации изменено
settings.change_orgname_desc=Organization name has been changed, do you want to continue? This will affect all links relate to this organization.
settings.update_setting_success=Organization setting has been updated successfully.
settings.delete=Удалить Организацию
settings.delete_account=Удалить Эту Организацию
settings.delete_prompt=The operation will delete this organization permanently, and <strong>CANNOT</strong> be undone!
settings.confirm_delete_account=Подтвердить удаление
settings.delete_org_title=Удаление Организации
settings.delete_org_desc=This organization is going to be deleted permanently, do you want to continue?
settings.hooks_desc=Добавьте автоматическое обновление, который будет вызываться для <strong>всех репозиций</strong> под этой Группой.
members.public=Публичный
members.public_helper=Сделать Приватным
members.private=Приватный
members.private_helper=Сделать Публичным
members.owner=Владелец
members.member=Участник
members.conceal=Conceal
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=This team will be able to push/pull to its repositories, as well as add other collaborators to them.
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=This team is going to be deleted, do you want to continue? Members of this team may lose access to some repositories.
teams.delete_team_success=Given team has been deleted successfully.
teams.read_permission_desc=This team grants <strong>Read</strong> access: members can view and clone the team's repositories.
teams.write_permission_desc=This team grants <strong>Write</strong> access: members can read from and push to the team's repositories.
teams.admin_permission_desc=This team grants <strong>Admin</strong> access: members can read from, push to, and add collaborators to the team's repositories.
teams.repositories=Репозитории группы разработки
teams.add_team_repository=Добавить репозиторий группы разработки
teams.remove_repo=Удалить
teams.add_nonexistent_repo=Вы добавляете в отсутствующий репозиторий, пожалуйста сначала его создайте.
[admin]
dashboard=Панель управления
users=Пользователи
organizations=Организации
repositories=Репозитории
authentication=Авторизация
config=Настройки
notices=System Notices
monitor=Мониторинг
prev=Предыдущий.
next=Следующий
dashboard.statistic=Статистика
dashboard.operations=Операции
dashboard.system_status=System Monitor 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=Operation Name
dashboard.operation_switch=Переключить
dashboard.operation_run=Запуск
dashboard.clean_unbind_oauth=Clean unbound OAuthes
dashboard.clean_unbind_oauth_success=All unbind OAuthes have been deleted successfully.
dashboard.delete_inactivate_accounts=Удалить все неактивированные учетные записи
dashboard.delete_inactivate_accounts_success=Все неактивированные учетные записи удалены успешно.
dashboard.delete_repo_archives=Удаление всех архивов репозиториев
dashboard.delete_repo_archives_success=Все архивы репозиториев были успешно удалены.
dashboard.git_gc_repos=Выполнить сборку мусора на репозиториях
dashboard.git_gc_repos_success=Сборка мусора на всех репозиториях успешно выполнена.
dashboard.resync_all_sshkeys=Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success=All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Время непрерывной работы сервера
dashboard.current_goroutine=Current Goroutines
dashboard.current_memory_usage=Текущее использование памяти
dashboard.total_memory_allocated=Всего памяти выделено
dashboard.memory_obtained=Memory Obtained
dashboard.pointer_lookup_times=Pointer Lookup Times
dashboard.memory_allocate_times=Memory Allocate Times
dashboard.memory_free_times=Memory Free Times
dashboard.current_heap_usage=Current Heap Usage
dashboard.heap_memory_obtained=Heap Memory Obtained
dashboard.heap_memory_idle=Heap Memory Idle
dashboard.heap_memory_in_use=Heap Memory In Use
dashboard.heap_memory_released=Heap Memory Released
dashboard.heap_objects=Heap Objects
dashboard.bootstrap_stack_usage=Bootstrap Stack Usage
dashboard.stack_memory_obtained=Stack Memory Obtained
dashboard.mspan_structures_usage=MSpan Structures Usage
dashboard.mspan_structures_obtained=MSpan Structures Obtained
dashboard.mcache_structures_usage=MCache Structures Usage
dashboard.mcache_structures_obtained=MCache Structures Obtained
dashboard.profiling_bucket_hash_table_obtained=Profiling Bucket Hash Table Obtained
dashboard.gc_metadata_obtained=GC Metadada Obtained
dashboard.other_system_allocation_obtained=Other System Allocation Obtained
dashboard.next_gc_recycle=Next GC Recycle
dashboard.last_gc_time=Since Last GC Time
dashboard.total_gc_time=Total GC Pause
dashboard.total_gc_pause=Total GC Pause
dashboard.last_gc_pause=Last GC Pause
dashboard.gc_times=GC Times
users.user_manage_panel=User Manage Panel
users.new_account=Создать новый аккаунт
users.name=Имя
users.activated=Активирован
users.admin=Администратор
users.repos=Репозитории
users.created=Создано
users.edit=Редактировать
users.auth_source=Источник авторизации
users.local=Локальный
users.auth_login_name=Authorization Login Name
users.update_profile_success=Профиль учетной записи обновлен успешно.
users.edit_account=Изменение учетной записи
users.is_activated=Эта учетная запись активирована
users.is_admin=У этой учетной записи есть права администратора
users.allow_git_hook=Пользователь имеет право создать Git перехватчик
users.update_profile=Обновить профиль учетной записи
users.delete_account=Удалить эту учетную запись
users.still_own_repo=На вашем аккаунте все еще остается как минимум один репозиторий, сначала вам нужно удалить или передать его.
users.still_has_org=This account still have membership of organization, you have to left or delete them first.
orgs.org_manage_panel=Управление группами
orgs.name=Имя
orgs.teams=Команды
orgs.members=Участники
repos.repo_manage_panel=Repository Manage Panel
repos.owner=Владелец
repos.name=Имя
repos.private=Приватный
repos.watches=Следят
repos.stars=В избранном
repos.issues=Вопросы
auths.auth_manage_panel=Authorization Manage Panel
auths.new=Add New Authorization Source
auths.name=Имя
auths.type=Тип
auths.enabled=Включено
auths.updated=Обновлено
auths.auth_type=Тип авторизации
auths.auth_name=Название авторизации
auths.domain=Домен
auths.host=Хост
auths.port=Порт
auths.base_dn=Base DN
auths.attributes=Search Attributes
auths.filter=Фильтр поиска
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=Тип авторизации SMTP
auths.smtphost=Узел SMTP
auths.smtpport=SMTP-порт
auths.enable_tls=Включение шифрования TLS
auths.enable_auto_register=Включить автоматическую регистрацию
auths.tips=Советы
auths.edit=Редактировать параметры авторизации
auths.activated=Эта аутентификация активирована
auths.update_success=Настройка авторизации обновлена успешно.
auths.update=Обновить параметры авторизации
auths.delete=Удалить эту авторизацию
auths.delete_auth_title=Удаление авторизации
auths.delete_auth_desc=Эта авторизация будет удалена. Вы хотите продолжить?
config.server_config=Конфигурация сервера
config.app_name=Имя приложения
config.app_ver=Версия приложения
config.app_url=URL приложения
config.domain=Домен
config.offline_mode=Автономный режим
config.disable_router_log=Отключение журнала маршрутизатора
config.run_user=Запуск пользователем
config.run_mode=Режим выполнения
config.repo_root_path=Repository Root Path
config.static_file_root_path=Static File Root Path
config.log_file_root_path=Log File Root Path
config.script_type=Тип сценария
config.reverse_auth_user=Reverse Authentication User
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=Path
config.db_path_helper=(for "sqlite3" only)
config.service_config=Service Configuration
config.register_email_confirm=Require E-mail Confirmation
config.disable_register=Отключить регистрацию
config.show_registration_button=Show Register Button
config.require_sign_in_view=Для просмотра необходима авторизация
config.mail_notify=Почтовые уведомления
config.enable_cache_avatar=Кешировать аватар
config.active_code_lives=Active Code Lives
config.reset_password_code_lives=Reset Password Code Lives
config.webhook_config=Настройка автоматического обновления репозиции
config.task_interval=Интервал задания
config.deliver_timeout=Задержка доставки
config.skip_tls_verify=Skip TLS Verify
config.mailer_config=Настройки почты
config.mailer_enabled=Включено
config.mailer_name=Имя
config.mailer_host=Сервер
config.mailer_user=Пользователь
config.oauth_config=Конфигурация OAuth
config.oauth_enabled=Включено
config.cache_config=Настройки кеша
config.cache_adapter=Cache Adapter
config.cache_interval=Cache Interval
config.cache_conn=Cache Connection
config.session_config=Session Configuration
config.session_provider=Session Provider
config.provider_config=Provider Config
config.cookie_name=Имя файла cookie
config.enable_set_cookie=Enable Set Cookie
config.gc_interval_time=GC Interval Time
config.session_life_time=Время жизни сессии
config.https_only=Только HTTPS
config.cookie_life_time=Время жизни файла cookie
config.picture_config=Настройка изображения
config.picture_service=Picture Service
config.disable_gravatar=Отключить Gravatar
config.log_config=Конфигурация журнала
config.log_mode=Режим журналирования
monitor.cron=Задачи cron
monitor.name=Имя
monitor.schedule=Расписание
monitor.next=В следующий раз
monitor.previous=Предыдущий раз
monitor.execute_times=Execute Times
monitor.process=Запущенные процессы
monitor.desc=Описание
monitor.start=Start Time
monitor.execute_time=Время выполнения
notices.system_notice_list=Система уведомлений
notices.type=Тип
notices.type_1=Репозиторий
notices.desc=Описание
notices.op=Op.
notices.delete_success=System notice has been deleted successfully.
[action]
create_repo=создан репозиторий <a href="%s/%s"> %s</a>
commit_repo=pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a>
create_issue=`opened issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`commented on issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=transfered repository <code>%s</code> to <a href="/%s%s">%s</a>
push_tag=pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a>
compare_2_commits=View comparison for these 2 commits
[tool]
ago=ago
from_now=from now
now=сейчас
1s=1 second %s
1m=1 minute %s
1h=1 hour %s
1d=1 day %s
1w=1 week %s
1mon=1 month %s
1y=1 year %s
seconds=%d секунд %s
minutes=%d минут %s
hours=%d часов %s
days=%d days %s
weeks=%d weeks %s
months=%d months %s
years=%d years %s
raw_seconds=seconds
raw_minutes=minutes

View File

@@ -59,6 +59,8 @@ run_user=运行系统用户
run_user_helper=该用户必须具有对仓库根目录和运行 Gogs 的操作权限。
domain=域名
domain_helper=该设置影响 SSH 克隆地址。
http_port=HTTP 端口号
http_port_helper=应用监听的端口号
app_url=应用 URL
app_url_helper=该设置影响 HTTP/HTTPS 克隆地址和一些邮箱中的链接。
email_title=邮件服务设置(可选)
@@ -173,6 +175,7 @@ target_branch_not_exist=目标分支不存在。
[user]
change_avatar=到 gravatar.com 上修改您的头像
change_custom_avatar=到个人设置中修改头像
join_on=加入于
repositories=仓库列表
activity=公开活动
@@ -202,12 +205,30 @@ change_username_desc=用户名被修改,您确定要继续操作吗?这将
continue=继续操作
cancel=取消操作
enable_custom_avatar=启动自定义头像
enable_custom_avatar_helper=激活该选项来禁止从 Gravatar 获取头像
choose_new_avatar=选择新的头像
update_avatar=更新头像设置
uploaded_avatar_not_a_image=上传的文件不是一张图片!
no_custom_avatar_available=未上传过自定义头像,无法激活该选项。
update_avatar_success=您的头像设置更新成功!
change_password=修改密码
old_password=当前密码
new_password=新的密码
password_incorrect=当前密码不正确!
change_password_success=密码修改成功!您现在可以使用新的密码登录。
emails=邮箱地址
manage_emails=管理邮箱地址
email_desc=您的主要邮箱地址将被用于通知提醒和其它操作。
primary=主要
primary_email=设为主要
delete_email=删除
add_new_email=添加新的邮箱地址
add_email=添加邮箱
add_email_success=新的邮箱地址添加成功!
manage_ssh_keys=管理 SSH 密钥
add_key=增加密钥
ssh_desc=以下是与您帐户所关联的 SSH 密钥,如果您发现有陌生的密钥,请立即删除它!
@@ -368,6 +389,30 @@ diff.stats_desc=共有 <strong> %d 个文件被更改</strong>,包括 <strong>
diff.bin=二进制
diff.view_file=查看文件
release.releases=版本发布
release.new_release=发布新版
release.draft=草稿
release.prerelease=预发行
release.stable=稳定
release.edit=编辑
release.ahead=在该版本发布之后已有 <strong>%d</strong> 次代码提交到 %s 分支
release.source_code=源代码
release.tag_name=标签名称
release.target=目标分支
release.tag_helper=选择或创建一个已经存在的标签
release.release_title=发布标题
release.content_with_md=使用 <a href="%s">Markdown</a> 编辑内容
release.write=内容编辑
release.preview=效果预览
release.content_placeholder=请输入内容
release.loading=正在加载...
release.prerelease_desc=这是一个预发行版本
release.prerelease_helper=我们会告知用户不建议将本次发布投入生产环境使用。
release.publish=发布版本
release.save_draft=保存草稿
release.edit_release=编辑发布信息
release.tag_name_already_exist=已经存在使用相同标签进行发布的版本。
[org]
org_name_holder=组织名称
org_name_helper=伟大的组织都有一个简短而寓意深刻的名字。
@@ -467,6 +512,13 @@ dashboard.delete_inactivate_accounts=删除所有未激活帐户
dashboard.delete_inactivate_accounts_success=所有未激活帐号清除成功!
dashboard.delete_repo_archives=删除所有仓库存档
dashboard.delete_repo_archives_success=所有仓库存档清除成功!
dashboard.git_gc_repos=对仓库进行垃圾回收
dashboard.git_gc_repos_success=所有仓库垃圾回收成功!
dashboard.resync_all_sshkeys=重新生成 '.ssh/autorized_key' 文件(警告:不是 Gogs 的密钥也会被删除)
dashboard.resync_all_sshkeys_success=所有公钥重新生成成功!
dashboard.resync_all_update_hooks=重新生成所有仓库的 Update 钩子(用于自定义配置文件被修改)
dashboard.resync_all_update_hooks_success=所有仓库的 Update 钩子重新生成成功!
dashboard.server_uptime=服务运行时间
dashboard.current_goroutine=当前 Goroutines 数量
dashboard.current_memory_usage=当前内存使用量
@@ -586,6 +638,7 @@ config.db_path_helper=(仅限 "sqlite3" 使用)
config.service_config=服务配置
config.register_email_confirm=注册邮件确认
config.disable_register=关闭注册功能
config.show_registration_button=显示注册按钮
config.require_sign_in_view=强制登录浏览
config.mail_notify=邮件通知提醒
config.enable_cache_avatar=开启缓存头像
@@ -594,6 +647,7 @@ config.reset_password_code_lives=重置密码链接有效期
config.webhook_config=Web 钩子配置
config.task_interval=任务周期
config.deliver_timeout=推送超时
config.skip_tls_verify=忽略 TLS 验证
config.mailer_config=邮件配置
config.mailer_enabled=启用服务
config.mailer_name=发送者名称
@@ -641,8 +695,8 @@ notices.delete_success=系统提示删除成功!
[action]
create_repo=创建了仓库 <a href="%s/%s">%s</a>
commit_repo=推送了 <a href="%s/%s/src/%s">%s</a> 分支的代码到 <a href="%s/%s">%s</a>
create_issue=创建了工单 <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue=评论了工单 <a href="%s/%s/issues/%s">%s#%s</a>
create_issue=`创建了工单 <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`评论了工单 <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=将仓库 <code>%s</code> 转移至 <a href="/%s%s">%s</a>
push_tag=推送了标签 <a href="%s/%s/src/%s">%s</a> 到 <a href="%s/%s">%s</a>
compare_2_commits=查看 2 次提交的内容对比
@@ -668,16 +722,3 @@ years=%d 年%s
raw_seconds=
raw_minutes=分钟

View File

@@ -58,10 +58,12 @@ repo_path_helper=所有 Git 遠程倉庫都將被存放於該目錄。
run_user=執行系統用戶
run_user_helper=該用戶必須具有對倉庫根目錄和執行 Gogs 的操作權限。
domain=域名
domain_helper=該設置影響 SSH 製地址。
domain_helper=該設置影響 SSH 製地址。
http_port=HTTP 端口號
http_port_helper=應用監聽的端口號
app_url=應用 URL
app_url_helper=該設置影響 HTTP/HTTPS 製地址和一些郵箱中的連結。
email_title=郵件服務設置(可選
app_url_helper=該設置影響 HTTP/HTTPS 製地址和一些郵箱中的連結。
email_title=電子郵件服務設定(可選)
smtp_host=SMTP 主機
mailer_user=發送郵箱
mailer_password=發送郵箱密碼
@@ -109,7 +111,7 @@ confirmation_mail_sent_prompt=一封新的確認郵件已經被發送至 <b>%s</
sign_in_email=登錄到您的郵箱
active_your_account=激活您的帳戶
resent_limit_prompt=對不起,您請求發送激活郵件過於頻繁,請等待 3 分鐘後再試!
has_unconfirmed_mail=%s 您好,系統檢測到您有一封發送至 <b>%s</b> 但未被確認的郵件。如果您未收到激活郵件,或需要重新發送,請單擊下方的按鈕。
has_unconfirmed_mail=%s 您好,您有一封發送至( <b>%s</b>) 但未被確認的郵件。如果您未收到激活郵件,或需要重新發送,請單擊下方的按鈕。
resend_mail=單擊此處重新發送確認郵件
email_not_associate=您輸入的郵箱地址未被關聯到任何帳號!
send_reset_mail=單擊此處(重新)發送您的密碼重置郵件
@@ -173,6 +175,7 @@ target_branch_not_exist=目標分支不存在
[user]
change_avatar=到 gravatar.com 上修改您的頭像
change_custom_avatar=到個人設置中修改頭像
join_on=加入於
repositories=倉庫列表
activity=公開活動
@@ -202,12 +205,30 @@ change_username_desc=用戶名被修改,您確定要繼續操作嗎?這將
continue=繼續操作
cancel=取消操作
enable_custom_avatar=啟動自定義頭像
enable_custom_avatar_helper=激活該選項來禁止從 Gravatar 獲取頭像
choose_new_avatar=選擇新的頭像
update_avatar=更新頭像設置
uploaded_avatar_not_a_image=上傳的文件不是一張圖片!
no_custom_avatar_available=沒有任何自定義頭像,無法激活該選項。
update_avatar_success=您的頭像設置更新成功!
change_password=修改密碼
old_password=當前密碼
new_password=新的密碼
password_incorrect=當前密碼不正確!
change_password_success=密碼修改成功!您現在可以使用新的密碼登錄。
emails=電子郵件地址
manage_emails=管理電子郵件地址
email_desc=您的主要邮箱地址将被用于通知提醒和其它操作。
primary=主要
primary_email=设为主要
delete_email=刪除
add_new_email=添加新的電子郵件地址
add_email=添加電子郵件
add_email_success=新的邮箱地址添加成功。
manage_ssh_keys=管理 SSH 密鑰
add_key=增加密鑰
ssh_desc=以下是與您帳戶所關聯的 SSH 密鑰,如果您發現有陌生的密鑰,請立即刪除它!
@@ -232,7 +253,7 @@ tokens_desc=您可以使用這些已生成的令牌來操作 Gogs API。
new_token_desc=目前為止,任何令牌都對您的帳戶擁有完整的操作權限。
token_name=令牌名稱
generate_token=生成令牌
generate_token_succees=新的操作令牌生成成功!您必須立即製到一個安全的地方,因為該令牌只會顯示一次!
generate_token_succees=新的操作令牌生成成功!您必須立即製到一個安全的地方,因為該令牌只會顯示一次!
delete_token=删除令牌
delete_token_success=個人操作令牌刪除成功!請更新與該令牌有關的所有應用。
@@ -268,9 +289,9 @@ migrate_type=遷移類型
migrate_type_helper=本倉庫將是 <span class="label label-blue label-radius">鏡像</span>
migrate_repo=遷移倉庫
copy_link=製連結
click_to_copy=製到剪切簿
copied=製成功
copy_link=製連結
click_to_copy=製到剪切簿
copied=製成功
clone_helper=不知道如何操作?訪問 <a target="_blank"href="%s"> 帮助説明</a>
unwatch=取消關註
watch=關註
@@ -280,7 +301,7 @@ fork=派生
no_desc=暫無描述
quick_guide=快速幫助
clone_this_repo=製當前倉庫
clone_this_repo=製當前倉庫
create_new_repo_command=從命令行創建一個新的倉庫
push_exist_repo=從命令行推送已經創建的倉庫
@@ -368,6 +389,30 @@ diff.stats_desc=共有 <strong> %d 個文件被更改</strong>,包括 <strong>
diff.bin=二進制
diff.view_file=查看文件
release.releases=版本發佈
release.new_release=發佈新版本
release.draft=草稿
release.prerelease=預發佈版本
release.stable=穩定
release.edit=編輯
release.ahead=在該版本發佈之後已有 <strong>%d</strong> 次代碼提交到 %s 分支
release.source_code=源代碼
release.tag_name=標籤名稱
release.target=目標分支
release.tag_helper=選擇或創建一個已存在的標籤
release.release_title=發佈標題
release.content_with_md=使用 <a href="%s">Markdown</a> 編輯內容
release.write=內容編輯
release.preview=效果預覽
release.content_placeholder=請輸入內容
release.loading=正在加載...
release.prerelease_desc=這是一個預發佈版本
release.prerelease_helper=我們會告知用戶不建議將本發佈投入生產環境使用。
release.publish=發佈版本
release.save_draft=保在草稿
release.edit_release=編輯發佈信息
release.tag_name_already_exist=已經存在使用相同標籤的發佈版本。
[org]
org_name_holder=組織名稱
org_name_helper=偉大的組織都有一個簡短而寓意深刻的名字。
@@ -419,11 +464,11 @@ members.invite_now=立即邀請
teams.join=加入團隊
teams.leave=離開團隊
teams.read_access=讀取權限
teams.read_access_helper=這個團隊將擁有查看和製所屬倉庫的權限。
teams.read_access_helper=這個團隊將擁有查看和製所屬倉庫的權限。
teams.write_access=寫入權限
teams.write_access_helper=這個團隊將擁有查看、製和推送所屬倉庫的權限。
teams.write_access_helper=這個團隊將擁有查看、製和推送所屬倉庫的權限。
teams.admin_access=管理權限
teams.admin_access_helper=這個團隊將擁有查看、製、推送和添加其他組織成員到團隊的權限。
teams.admin_access_helper=這個團隊將擁有查看、製、推送和添加其他組織成員到團隊的權限。
teams.no_desc=該團隊暫無描述
teams.settings=團隊設置
teams.owners_permission_desc=管理員團隊對 <strong>所有倉庫</strong> 具有操作權限,且對組織具有 <strong>管理員權限</strong>。
@@ -434,9 +479,9 @@ teams.add_team_member=添加團隊成員
teams.delete_team_title=團隊刪除操作
teams.delete_team_desc=刪除操作會永久清除有關該團隊的信息,您確定要繼續操作嗎?團隊成員可能會失去對某些倉庫的操作權限。
teams.delete_team_success=指定團隊刪除成功!
teams.read_permission_desc=該團隊擁有對所屬倉庫的 <strong>讀取</strong> 權限,團隊成員可以進行查看和製等只讀操作。
teams.read_permission_desc=該團隊擁有對所屬倉庫的 <strong>讀取</strong> 權限,團隊成員可以進行查看和製等只讀操作。
teams.write_permission_desc=該團隊擁有對所屬倉庫的 <strong>讀取</strong> 和 <strong>寫入</strong> 的權限。
teams.admin_permission_desc=該團隊擁有一定的 <strong>管理</strong> 權限,團隊成員可以讀取、製、推送以及添加其它倉庫協作者。
teams.admin_permission_desc=該團隊擁有一定的 <strong>管理</strong> 權限,團隊成員可以讀取、製、推送以及添加其它倉庫協作者。
teams.repositories=團隊倉庫
teams.add_team_repository=添加團隊倉庫
teams.remove_repo=移除倉庫
@@ -467,6 +512,13 @@ dashboard.delete_inactivate_accounts=刪除所有未激活帳戶
dashboard.delete_inactivate_accounts_success=所有未激活帳號清除成功!
dashboard.delete_repo_archives=刪除所有倉庫存檔
dashboard.delete_repo_archives_success=所有倉庫存檔清除成功!
dashboard.git_gc_repos=對倉庫進行垃圾回收
dashboard.git_gc_repos_success=所有倉庫的垃圾回收已成功完成!
dashboard.resync_all_sshkeys=重新生成 '.ssh/autorized_key' 文件(警告:不是 Gogs 的密鑰也會被刪除)
dashboard.resync_all_sshkeys_success=所有公鑰重新生成成功!
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=服務執行時間
dashboard.current_goroutine=當前 Goroutines 數量
dashboard.current_memory_usage=當前內存使用量
@@ -584,8 +636,9 @@ config.db_ssl_mode_helper=(僅限 "postgres" 使用)
config.db_path=數據庫路徑
config.db_path_helper=(僅限 "sqlite3" 使用)
config.service_config=服務配置
config.register_email_confirm=註冊郵件確認
config.register_email_confirm=註冊電子郵件確認
config.disable_register=關閉註冊功能
config.show_registration_button=顯示註冊按鈕
config.require_sign_in_view=強制登錄瀏覽
config.mail_notify=郵件通知提醒
config.enable_cache_avatar=開啟緩存頭像
@@ -594,6 +647,7 @@ config.reset_password_code_lives=重置密碼連結有效期
config.webhook_config=Web 鉤子配置
config.task_interval=任務周期
config.deliver_timeout=推送超時
config.skip_tls_verify=Skip TLS Verify
config.mailer_config=郵件配置
config.mailer_enabled=啟用服務
config.mailer_name=發送者名稱
@@ -641,8 +695,8 @@ notices.delete_success=系統提示刪除成功!
[action]
create_repo=創建了倉庫 <a href="%s/%s">%s</a>
commit_repo=推送了 <a href="%s/%s/src/%s">%s</a> 分支的代碼到 <a href="%s/%s">%s</a>
create_issue=創建了問題 <a href="%s/%s/issues/%s">%s#%s</a>
comment_issue=評論了問題 <a href="%s/%s/issues/%s">%s#%s</a>
create_issue=`創建了問題 <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`評論了問題 <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=將倉庫 <code>%s</code> 轉移至 <a href="/%s%s">%s</a>
push_tag=推送了標籤 <a href="%s/%s/src/%s">%s</a> 到 <a href="%s/%s">%s</a>
compare_2_commits=查看 2 次提交的內容對比
@@ -668,16 +722,3 @@ years=%d 年%s
raw_seconds=
raw_minutes=分鐘

View File

@@ -30,7 +30,7 @@ The `config` file contains lines which will in the gogs docker container end up
Here you can define things like the MySQL server for your database block.
The `fig` file will just be added to `fig.yml`, which is used by fig to manage your containers.
This inculdes container linking!
This includes container linking!
Just have a look at them and it will be clear how to write your own blocks.
@@ -53,7 +53,7 @@ Example:
More sophisticated Example
--------------------------
Her is a more elaborated example
Here is a more elaborated example
```sh
./assemble_blocks.sh docker_gogs w_db_cache_session option_db_postgresql option_cache_redis option_session_mysql
@@ -86,4 +86,4 @@ This will pull in the `Dockerfile` from `docker_gogs` instead of the one from `d
`Dockerfile`s for the `master` and `dev` branch are provided as `docker_gogs` and `docker_gogs_dev`
[fig]:http://www.fig.sh/
[fig]:http://www.fig.sh/

View File

@@ -46,7 +46,7 @@ ENV HOME /home/git
ENV USER git
ENV PATH $GOGS_PATH:$PATH
RUN git config --global user.name "GoGS"
RUN git config --global user.name "GoGS" && git config --global user.email "gogitservice@gmail.com"
ENTRYPOINT ["/tmp/init_gogs.sh"]
CMD ["gogs", "web"]

View File

@@ -47,7 +47,7 @@ ENV HOME /home/git
ENV USER git
ENV PATH $GOGS_PATH:$PATH
RUN git config --global user.name "GoGS"
RUN git config --global user.name "GoGS" && git config --global user.email "gogitservice@gmail.com"
ENTRYPOINT ["/tmp/init_gogs.sh"]
CMD ["gogs", "web"]

View File

@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const APP_VER = "0.5.8.1118 Beta"
const APP_VER = "0.5.13.0212 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
@@ -33,7 +33,6 @@ func main() {
cmd.CmdWeb,
cmd.CmdServ,
cmd.CmdUpdate,
cmd.CmdFix,
cmd.CmdDump,
cmd.CmdCert,
}

View File

@@ -41,12 +41,21 @@ var (
var (
// Same as Github. See https://help.github.com/articles/closing-issues-via-commit-messages
IssueKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
IssueKeywordsPat *regexp.Regexp
IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
IssueReopenKeywords = []string{"reopen", "reopens", "reopened"}
IssueCloseKeywordsPat, IssueReopenKeywordsPat *regexp.Regexp
IssueReferenceKeywordsPat *regexp.Regexp
)
func assembleKeywordsPattern(words []string) string {
return fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(words, "|"))
}
func init() {
IssueKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(IssueKeywords, "|")))
IssueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueCloseKeywords))
IssueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueReopenKeywords))
IssueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`)
}
// Action represents user operation type and other information to repository.,
@@ -58,6 +67,7 @@ type Action struct {
ActUserId int64 // Action user id.
ActUserName string // Action user name.
ActEmail string
ActAvatar string `xorm:"-"`
RepoId int64
RepoUserName string
RepoName string
@@ -88,7 +98,7 @@ func (a Action) GetRepoName() string {
}
func (a Action) GetRepoLink() string {
return path.Join(a.RepoUserName, a.RepoName)
return path.Join(setting.AppSubUrl, a.RepoUserName, a.RepoName)
}
func (a Action) GetBranch() string {
@@ -109,9 +119,39 @@ func (a Action) GetIssueInfos() []string {
func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, commits []*base.PushCommit) error {
for _, c := range commits {
refs := IssueKeywordsPat.FindAllString(c.Message, -1)
for _, ref := range IssueReferenceKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
return !unicode.IsDigit(c)
})
for _, ref := range refs {
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
} else if strings.Contains(ref, "/") == false {
// FIXME: We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
if err != nil {
return err
}
url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil {
return err
}
}
for _, ref := range IssueCloseKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
return !unicode.IsDigit(c)
@@ -132,23 +172,14 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
issue, err := GetIssueByRef(ref)
if err != nil {
return err
}
url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMIT, message, nil); err != nil {
return err
}
if issue.RepoId == repoId {
if issue.IsClosed {
continue
}
issue.IsClosed = true
if err = UpdateIssue(issue); err != nil {
@@ -162,13 +193,60 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
// If commit happened in the referenced repository, it means the issue can be closed.
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, CLOSE, "", nil); err != nil {
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_CLOSE, "", nil); err != nil {
return err
}
}
}
for _, ref := range IssueReopenKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
return !unicode.IsDigit(c)
})
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
} else if strings.Contains(ref, "/") == false {
// We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
if err != nil {
return err
}
if issue.RepoId == repoId {
if !issue.IsClosed {
continue
}
issue.IsClosed = false
if err = UpdateIssue(issue); err != nil {
return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
return err
}
if err = ChangeMilestoneIssueStats(issue); err != nil {
return err
}
// If commit happened in the referenced repository, it means the issue can be closed.
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_REOPEN, "", nil); err != nil {
return err
}
}
}
}
return nil
}
@@ -331,7 +409,6 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
}
}
go DeliverHooks()
return nil
}
@@ -348,7 +425,7 @@ func NewRepoAction(u *User, repo *Repository) (err error) {
return err
}
// TransferRepoAction adds new action for transfering repository.
// TransferRepoAction adds new action for transferring repository.
func TransferRepoAction(u, newUser *User, repo *Repository) (err error) {
action := &Action{
ActUserId: u.Id,

View File

@@ -6,6 +6,7 @@ package models
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
@@ -13,8 +14,12 @@ import (
"strings"
"time"
"golang.org/x/net/html/charset"
"golang.org/x/text/transform"
"github.com/Unknwon/com"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
@@ -55,6 +60,8 @@ type DiffFile struct {
Index int
Addition, Deletion int
Type int
IsCreated bool
IsDeleted bool
IsBin bool
Sections []*DiffSection
}
@@ -80,6 +87,8 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
leftLine, rightLine int
isTooLong bool
// FIXME: use first 30 lines to detect file encoding. Should use cache in the future.
buf bytes.Buffer
)
diff := &Diff{Files: make([]*DiffFile, 0)}
@@ -97,6 +106,11 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
i = i + 1
// FIXME: use first 30 lines to detect file encoding.
if i <= 30 {
buf.WriteString(line)
}
// Diff data too large, we only show the first about maxlines lines
if i == maxlines {
isTooLong = true
@@ -169,10 +183,16 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
switch {
case strings.HasPrefix(scanner.Text(), "new file"):
curFile.Type = DIFF_FILE_ADD
curFile.IsDeleted = false
curFile.IsCreated = true
case strings.HasPrefix(scanner.Text(), "deleted"):
curFile.Type = DIFF_FILE_DEL
curFile.IsCreated = false
curFile.IsDeleted = true
case strings.HasPrefix(scanner.Text(), "index"):
curFile.Type = DIFF_FILE_CHANGE
curFile.IsCreated = false
curFile.IsDeleted = false
}
if curFile.Type > 0 {
break
@@ -181,6 +201,25 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
}
}
// FIXME: use first 30 lines to detect file encoding.
charsetLabel, err := base.DetectEncoding(buf.Bytes())
if charsetLabel != "utf8" && err == nil {
encoding, _ := charset.Lookup(charsetLabel)
if encoding != nil {
d := encoding.NewDecoder()
for _, f := range diff.Files {
for _, sec := range f.Sections {
for _, l := range sec.Lines {
if c, _, err := transform.String(d, l.Content); err == nil {
l.Content = c
}
}
}
}
}
}
return diff, nil
}

View File

@@ -472,8 +472,8 @@ func UpdateIssueUserPairByAssignee(aid, iid int64) error {
if aid == 0 {
return nil
}
rawSql = "UPDATE `issue_user` SET is_assigned = true WHERE uid = ? AND issue_id = ?"
_, err := x.Exec(rawSql, aid, iid)
rawSql = "UPDATE `issue_user` SET is_assigned = ? WHERE uid = ? AND issue_id = ?"
_, err := x.Exec(rawSql, true, aid, iid)
return err
}
@@ -859,22 +859,16 @@ type CommentType int
const (
// Plain comment, can be associated with a commit (CommitId > 0) and a line (Line > 0)
COMMENT CommentType = iota
// Reopen action
REOPEN
// Close action
CLOSE
// Reference from another issue
ISSUE
COMMENT_TYPE_COMMENT CommentType = iota
COMMENT_TYPE_REOPEN
COMMENT_TYPE_CLOSE
// References.
COMMENT_TYPE_ISSUE
// Reference from some commit (not part of a pull request)
COMMIT
COMMENT_TYPE_COMMIT
// Reference from some pull request
PULL
COMMENT_TYPE_PULL
)
// Comment represents a comment in commit and issue page.
@@ -908,7 +902,7 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
// Check comment type.
switch cmtType {
case COMMENT:
case COMMENT_TYPE_COMMENT:
rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, issueId); err != nil {
sess.Rollback()
@@ -929,13 +923,13 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
return nil, err
}
}
case REOPEN:
case COMMENT_TYPE_REOPEN:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
return nil, err
}
case CLOSE:
case COMMENT_TYPE_CLOSE:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()

View File

@@ -18,6 +18,7 @@ import (
"github.com/gogits/gogs/modules/auth/ldap"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/uuid"
)
type LoginType int
@@ -40,7 +41,7 @@ var LoginTypes = map[LoginType]string{
SMTP: "SMTP",
}
// Ensure structs implmented interface.
// Ensure structs implemented interface.
var (
_ core.Conversion = &LDAPConfig{}
_ core.Conversion = &SMTPConfig{}
@@ -225,33 +226,35 @@ func UserSignIn(uname, passwd string) (*User, error) {
}
}
// Query if name/passwd can login against the LDAP direcotry pool
// Query if name/passwd can login against the LDAP directory pool
// Create a local user if success
// Return the same LoginUserPlain semantic
// FIXME: https://github.com/gogits/gogs/issues/672
func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAPConfig, autoRegister bool) (*User, error) {
mail, logged := cfg.Ldapsource.SearchEntry(name, passwd)
if !logged {
// user not in LDAP, do nothing
// User not in LDAP, do nothing
return nil, ErrUserNotExist
}
if !autoRegister {
return u, nil
}
// fake a local user creation
// Fallback.
if len(mail) == 0 {
mail = uuid.NewV4().String() + "@localhost"
}
u = &User{
LowerName: strings.ToLower(name),
Name: strings.ToLower(name),
Name: name,
LoginType: LDAP,
LoginSource: sourceId,
LoginName: name,
IsActive: true,
Passwd: passwd,
Email: mail,
IsActive: true,
}
err := CreateUser(u)
return u, err
return u, CreateUser(u)
}
type loginAuth struct {
@@ -315,7 +318,7 @@ func SmtpAuth(host string, port int, a smtp.Auth, useTls bool) error {
return ErrUnsupportedLoginType
}
// Query if name/passwd can login against the LDAP direcotry pool
// Query if name/passwd can login against the LDAP directory pool
// Create a local user if success
// Return the same LoginUserPlain semantic
func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTPConfig, autoRegister bool) (*User, error) {

View File

@@ -0,0 +1,53 @@
package migrations
import (
"errors"
"github.com/go-xorm/xorm"
)
type migration func(*xorm.Engine) error
// The version table. Should have only one row with id==1
type Version struct {
Id int64
Version int64
}
// This is a sequence of migrations. Add new migrations to the bottom of the list.
// If you want to "retire" a migration, replace it with "expiredMigration"
var migrations = []migration{}
// Migrate database to current version
func Migrate(x *xorm.Engine) error {
if err := x.Sync(new(Version)); err != nil {
return err
}
currentVersion := &Version{Id: 1}
has, err := x.Get(currentVersion)
if err != nil {
return err
} else if !has {
if _, err = x.InsertOne(currentVersion); err != nil {
return err
}
}
v := currentVersion.Version
for i, migration := range migrations[v:] {
if err = migration(x); err != nil {
return err
}
currentVersion.Version = v + int64(i) + 1
if _, err = x.Id(1).Update(currentVersion); err != nil {
return err
}
}
return nil
}
func expiredMigration(x *xorm.Engine) error {
return errors.New("You are migrating from a too old gogs version")
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/go-xorm/xorm"
_ "github.com/lib/pq"
// "github.com/gogits/gogs/models/migrations"
"github.com/gogits/gogs/modules/setting"
)
@@ -22,7 +23,10 @@ import (
type Engine interface {
Delete(interface{}) (int64, error)
Exec(string, ...interface{}) (sql.Result, error)
Get(interface{}) (bool, error)
Insert(...interface{}) (int64, error)
Id(interface{}) *xorm.Session
Where(string, ...interface{}) *xorm.Session
}
var (
@@ -31,7 +35,7 @@ var (
HasEngine bool
DbCfg struct {
Type, Host, Name, User, Pwd, Path, SslMode string
Type, Host, Name, User, Passwd, Path, SSLMode string
}
EnableSQLite3 bool
@@ -45,22 +49,23 @@ func init() {
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
new(Mirror), new(Release), new(LoginSource), new(Webhook),
new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
new(Notice))
new(Notice), new(EmailAddress))
}
func LoadModelsConfig() {
DbCfg.Type = setting.Cfg.MustValue("database", "DB_TYPE")
sec := setting.Cfg.Section("database")
DbCfg.Type = sec.Key("DB_TYPE").String()
if DbCfg.Type == "sqlite3" {
UseSQLite3 = true
}
DbCfg.Host = setting.Cfg.MustValue("database", "HOST")
DbCfg.Name = setting.Cfg.MustValue("database", "NAME")
DbCfg.User = setting.Cfg.MustValue("database", "USER")
if len(DbCfg.Pwd) == 0 {
DbCfg.Pwd = setting.Cfg.MustValue("database", "PASSWD")
DbCfg.Host = sec.Key("HOST").String()
DbCfg.Name = sec.Key("NAME").String()
DbCfg.User = sec.Key("USER").String()
if len(DbCfg.Passwd) == 0 {
DbCfg.Passwd = sec.Key("PASSWD").String()
}
DbCfg.SslMode = setting.Cfg.MustValue("database", "SSL_MODE")
DbCfg.Path = setting.Cfg.MustValue("database", "PATH", "data/gogs.db")
DbCfg.SSLMode = sec.Key("SSL_MODE").String()
DbCfg.Path = sec.Key("PATH").MustString("data/gogs.db")
}
func getEngine() (*xorm.Engine, error) {
@@ -68,7 +73,7 @@ func getEngine() (*xorm.Engine, error) {
switch DbCfg.Type {
case "mysql":
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name)
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
case "postgres":
var host, port = "127.0.0.1", "5432"
fields := strings.Split(DbCfg.Host, ":")
@@ -79,7 +84,7 @@ func getEngine() (*xorm.Engine, error) {
port = fields[1]
}
cnnstr = fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode)
DbCfg.User, DbCfg.Passwd, host, port, DbCfg.Name, DbCfg.SSLMode)
case "sqlite3":
if !EnableSQLite3 {
return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type)
@@ -95,7 +100,7 @@ func getEngine() (*xorm.Engine, error) {
func NewTestEngine(x *xorm.Engine) (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("models.init(fail to connect to database): %v", err)
return fmt.Errorf("connect to database: %v", err)
}
return x.Sync(tables...)
@@ -104,10 +109,10 @@ func NewTestEngine(x *xorm.Engine) (err error) {
func SetEngine() (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("models.init(fail to connect to database): %v", err)
return fmt.Errorf("connect to database: %v", err)
}
// WARNNING: for serv command, MUST remove the output to os.stdout,
// WARNING: for serv command, MUST remove the output to os.stdout,
// so use log file to instead print to stdout.
logPath := path.Join(setting.LogRootPath, "xorm.log")
os.MkdirAll(path.Dir(logPath), os.ModePerm)
@@ -130,6 +135,11 @@ func NewEngine() (err error) {
if err = SetEngine(); err != nil {
return err
}
// if err = migrations.Migrate(x); err != nil {
// return err
// }
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
return fmt.Errorf("sync database struct error: %v\n", err)
}

View File

@@ -79,7 +79,7 @@ func UpdateOauth2(oa *Oauth2) error {
return err
}
// GetOauthByUserId returns list of oauthes that are releated to given user.
// GetOauthByUserId returns list of oauthes that are related to given user.
func GetOauthByUserId(uid int64) ([]*Oauth2, error) {
socials := make([]*Oauth2, 0, 5)
err := x.Find(&socials, Oauth2{Uid: uid})

View File

@@ -12,7 +12,6 @@ import (
"strings"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/base"
)
@@ -25,8 +24,8 @@ var (
ErrLastOrgOwner = errors.New("The user to remove is the last member in owner team")
)
// IsOrgOwner returns true if given user is in the owner team.
func (org *User) IsOrgOwner(uid int64) bool {
// IsOwnedBy returns true if given user is in the owner team.
func (org *User) IsOwnedBy(uid int64) bool {
return IsOrganizationOwner(org.Id, uid)
}
@@ -77,6 +76,17 @@ func (org *User) RemoveMember(uid int64) error {
return RemoveOrgUser(org.Id, uid)
}
// IsOrgEmailUsed returns true if the e-mail has been used in organization account.
func IsOrgEmailUsed(email string) (bool, error) {
if len(email) == 0 {
return false, nil
}
return x.Get(&User{
Email: email,
Type: ORGANIZATION,
})
}
// CreateOrganization creates record of a new organization.
func CreateOrganization(org, owner *User) (*User, error) {
if !IsLegalName(org.Name) {
@@ -90,7 +100,7 @@ func CreateOrganization(org, owner *User) (*User, error) {
return nil, ErrUserAlreadyExist
}
isExist, err = IsEmailUsed(org.Email)
isExist, err = IsOrgEmailUsed(org.Email)
if err != nil {
return nil, err
} else if isExist {
@@ -159,6 +169,24 @@ func CreateOrganization(org, owner *User) (*User, error) {
return org, sess.Commit()
}
// GetOrgByName returns organization by given name.
func GetOrgByName(name string) (*User, error) {
if len(name) == 0 {
return nil, ErrOrgNotExist
}
u := &User{
LowerName: strings.ToLower(name),
Type: ORGANIZATION,
}
has, err := x.Get(u)
if err != nil {
return nil, err
} else if !has {
return nil, ErrOrgNotExist
}
return u, nil
}
// CountOrganizations returns number of organizations.
func CountOrganizations() int64 {
count, _ := x.Where("type=1").Count(new(User))
@@ -229,7 +257,7 @@ func IsOrganizationMember(orgId, uid int64) bool {
return has
}
// IsPublicMembership returns ture if given user public his/her membership.
// IsPublicMembership returns true if given user public his/her membership.
func IsPublicMembership(orgId, uid int64) bool {
has, _ := x.Where("uid=?", uid).And("org_id=?", orgId).And("is_public=?", true).Get(new(OrgUser))
return has
@@ -362,7 +390,7 @@ func RemoveOrgUser(orgId, uid int64) error {
return err
}
for _, t := range ts {
if err = removeTeamMemberWithSess(org.Id, t.Id, u.Id, sess); err != nil {
if err = removeTeamMember(sess, org.Id, t.Id, u.Id); err != nil {
return err
}
}
@@ -457,18 +485,18 @@ func (t *Team) RemoveMember(uid int64) error {
}
// addAccessWithAuthorize inserts or updates access with given mode.
func addAccessWithAuthorize(sess *xorm.Session, access *Access, mode AccessType) error {
has, err := x.Get(access)
func addAccessWithAuthorize(e Engine, access *Access, mode AccessType) error {
has, err := e.Get(access)
if err != nil {
return fmt.Errorf("fail to get access: %v", err)
}
access.Mode = mode
if has {
if _, err = sess.Id(access.Id).Update(access); err != nil {
if _, err = e.Id(access.Id).Update(access); err != nil {
return fmt.Errorf("fail to update access: %v", err)
}
} else {
if _, err = sess.Insert(access); err != nil {
if _, err = e.Insert(access); err != nil {
return fmt.Errorf("fail to insert access: %v", err)
}
}
@@ -507,7 +535,7 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
mode := AuthorizeToAccessType(t.Authorize)
for _, u := range t.Members {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, t.Id)
auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, t.Id)
if err != nil {
sess.Rollback()
return err
@@ -523,7 +551,7 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
return err
}
}
if err = WatchRepo(u.Id, repo.Id, true); err != nil {
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
sess.Rollback()
return err
}
@@ -564,7 +592,7 @@ func (t *Team) RemoveRepository(repoId int64) error {
// Remove access to team members.
for _, u := range t.Members {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, t.Id)
auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, t.Id)
if err != nil {
sess.Rollback()
return err
@@ -578,7 +606,7 @@ func (t *Team) RemoveRepository(repoId int64) error {
if _, err = sess.Delete(access); err != nil {
sess.Rollback()
return fmt.Errorf("fail to delete access: %v", err)
} else if err = WatchRepo(u.Id, repo.Id, false); err != nil {
} else if err = watchRepo(sess, u.Id, repo.Id, false); err != nil {
sess.Rollback()
return err
}
@@ -649,10 +677,9 @@ func GetTeam(orgId int64, name string) (*Team, error) {
return t, nil
}
// GetTeamById returns team by given ID.
func GetTeamById(teamId int64) (*Team, error) {
func getTeamById(e Engine, teamId int64) (*Team, error) {
t := new(Team)
has, err := x.Id(teamId).Get(t)
has, err := e.Id(teamId).Get(t)
if err != nil {
return nil, err
} else if !has {
@@ -661,9 +688,13 @@ func GetTeamById(teamId int64) (*Team, error) {
return t, nil
}
// GetHighestAuthorize returns highest repository authorize level for given user and team.
func GetHighestAuthorize(orgId, uid, repoId, teamId int64) (AuthorizeType, error) {
ts, err := GetUserTeams(orgId, uid)
// GetTeamById returns team by given ID.
func GetTeamById(teamId int64) (*Team, error) {
return getTeamById(x, teamId)
}
func getHighestAuthorize(e Engine, orgId, uid, repoId, teamId int64) (AuthorizeType, error) {
ts, err := getUserTeams(e, orgId, uid)
if err != nil {
return 0, err
}
@@ -685,6 +716,11 @@ func GetHighestAuthorize(orgId, uid, repoId, teamId int64) (AuthorizeType, error
return auth, nil
}
// GetHighestAuthorize returns highest repository authorize level for given user and team.
func GetHighestAuthorize(orgId, uid, repoId, teamId int64) (AuthorizeType, error) {
return getHighestAuthorize(x, orgId, uid, repoId, teamId)
}
// UpdateTeam updates information of team.
func UpdateTeam(t *Team, authChanged bool) (err error) {
if !IsLegalName(t.Name) {
@@ -837,10 +873,14 @@ type TeamUser struct {
TeamId int64
}
func isTeamMember(e Engine, orgId, teamId, uid int64) bool {
has, _ := e.Where("uid=?", uid).And("org_id=?", orgId).And("team_id=?", teamId).Get(new(TeamUser))
return has
}
// IsTeamMember returns true if given user is a member of team.
func IsTeamMember(orgId, teamId, uid int64) bool {
has, _ := x.Where("uid=?", uid).And("org_id=?", orgId).And("team_id=?", teamId).Get(new(TeamUser))
return has
return isTeamMember(x, orgId, teamId, uid)
}
// GetTeamMembers returns all members in given team of organization.
@@ -850,17 +890,16 @@ func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
return us, err
}
// GetUserTeams returns all teams that user belongs to in given origanization.
func GetUserTeams(orgId, uid int64) ([]*Team, error) {
func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
tus := make([]*TeamUser, 0, 5)
if err := x.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
if err := e.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
return nil, err
}
ts := make([]*Team, len(tus))
for i, tu := range tus {
t := new(Team)
has, err := x.Id(tu.TeamId).Get(t)
has, err := e.Id(tu.TeamId).Get(t)
if err != nil {
return nil, err
} else if !has {
@@ -871,6 +910,11 @@ func GetUserTeams(orgId, uid int64) ([]*Team, error) {
return ts, nil
}
// GetUserTeams returns all teams that user belongs to in given organization.
func GetUserTeams(orgId, uid int64) ([]*Team, error) {
return getUserTeams(x, orgId, uid)
}
// AddTeamMember adds new member to given team of given organization.
func AddTeamMember(orgId, teamId, uid int64) error {
if IsTeamMember(orgId, teamId, uid) {
@@ -927,7 +971,7 @@ func AddTeamMember(orgId, teamId, uid int64) error {
// Give access to team repositories.
mode := AuthorizeToAccessType(t.Authorize)
for _, repo := range t.Repos {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, teamId)
auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, teamId)
if err != nil {
sess.Rollback()
return err
@@ -964,13 +1008,13 @@ func AddTeamMember(orgId, teamId, uid int64) error {
return sess.Commit()
}
func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) error {
if !IsTeamMember(orgId, teamId, uid) {
func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
if !isTeamMember(e, orgId, teamId, uid) {
return nil
}
// Get team and its repositories.
t, err := GetTeamById(teamId)
t, err := getTeamById(e, teamId)
if err != nil {
return err
}
@@ -1004,19 +1048,16 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
TeamId: teamId,
}
if _, err := sess.Delete(tu); err != nil {
sess.Rollback()
if _, err := e.Delete(tu); err != nil {
return err
} else if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
sess.Rollback()
} else if _, err = e.Id(t.Id).AllCols().Update(t); err != nil {
return err
}
// Delete access to team repositories.
for _, repo := range t.Repos {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, teamId)
auth, err := getHighestAuthorize(e, t.OrgId, u.Id, repo.Id, teamId)
if err != nil {
sess.Rollback()
return err
}
@@ -1026,17 +1067,14 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
}
// Delete access if this is the last team user belongs to.
if auth == 0 {
if _, err = sess.Delete(access); err != nil {
sess.Rollback()
if _, err = e.Delete(access); err != nil {
return fmt.Errorf("fail to delete access: %v", err)
} else if err = WatchRepo(u.Id, repo.Id, false); err != nil {
sess.Rollback()
} else if err = watchRepo(e, u.Id, repo.Id, false); err != nil {
return err
}
} else if auth < t.Authorize {
// Downgrade authorize level.
if err = addAccessWithAuthorize(sess, access, AuthorizeToAccessType(auth)); err != nil {
sess.Rollback()
if err = addAccessWithAuthorize(e, access, AuthorizeToAccessType(auth)); err != nil {
return err
}
}
@@ -1044,17 +1082,15 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
// This must exist.
ou := new(OrgUser)
_, err = sess.Where("uid=?", uid).And("org_id=?", org.Id).Get(ou)
_, err = e.Where("uid=?", uid).And("org_id=?", org.Id).Get(ou)
if err != nil {
sess.Rollback()
return err
}
ou.NumTeams--
if t.IsOwnerTeam() {
ou.IsOwner = false
}
if _, err = sess.Id(ou.Id).AllCols().Update(ou); err != nil {
sess.Rollback()
if _, err = e.Id(ou.Id).AllCols().Update(ou); err != nil {
return err
}
return nil
@@ -1067,7 +1103,8 @@ func RemoveTeamMember(orgId, teamId, uid int64) error {
if err := sess.Begin(); err != nil {
return err
}
if err := removeTeamMemberWithSess(orgId, teamId, uid, sess); err != nil {
if err := removeTeamMember(sess, orgId, teamId, uid); err != nil {
sess.Rollback()
return err
}
return sess.Commit()

View File

@@ -6,6 +6,8 @@ package models
import (
"bufio"
"encoding/base64"
"encoding/binary"
"errors"
"fmt"
"io"
@@ -27,11 +29,11 @@ import (
const (
// "### autogenerated by gitgos, DO NOT EDIT\n"
_TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
_TPL_PUBLICK_KEY = `command="%s serv key-%d --config='%s'",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
)
var (
ErrKeyAlreadyExist = errors.New("Public key already exist")
ErrKeyAlreadyExist = errors.New("Public key already exists")
ErrKeyNotExist = errors.New("Public key does not exist")
ErrKeyUnableVerify = errors.New("Unable to verify public key")
)
@@ -39,7 +41,7 @@ var (
var sshOpLocker = sync.Mutex{}
var (
SshPath string // SSH directory.
SSHPath string // SSH directory.
appPath string // Execution(binary) path.
)
@@ -70,9 +72,9 @@ func init() {
appPath = strings.Replace(appPath, "\\", "/", -1)
// Determine and create .ssh path.
SshPath = filepath.Join(homeDir(), ".ssh")
if err = os.MkdirAll(SshPath, 0700); err != nil {
log.Fatal(4, "fail to create SshPath(%s): %v\n", SshPath, err)
SSHPath = filepath.Join(homeDir(), ".ssh")
if err = os.MkdirAll(SSHPath, 0700); err != nil {
log.Fatal(4, "fail to create '%s': %v", SSHPath, err)
}
}
@@ -89,9 +91,14 @@ type PublicKey struct {
HasUsed bool `xorm:"-"`
}
// OmitEmail returns content of public key but without e-mail address.
func (k *PublicKey) OmitEmail() string {
return strings.Join(strings.Split(k.Content, " ")[:2], " ")
}
// GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string {
return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, key.Content)
return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, setting.CustomConf, key.Content)
}
var (
@@ -106,6 +113,85 @@ var (
}
)
func extractTypeFromBase64Key(key string) (string, error) {
b, err := base64.StdEncoding.DecodeString(key)
if err != nil || len(b) < 4 {
return "", errors.New("Invalid key format")
}
keyLength := int(binary.BigEndian.Uint32(b))
if len(b) < 4+keyLength {
return "", errors.New("Invalid key format")
}
return string(b[4 : 4+keyLength]), nil
}
// Parse any key string in openssh or ssh2 format to clean openssh string (rfc4253)
func ParseKeyString(content string) (string, error) {
// Transform all legal line endings to a single "\n"
s := strings.Replace(strings.Replace(strings.TrimSpace(content), "\r\n", "\n", -1), "\r", "\n", -1)
lines := strings.Split(s, "\n")
var keyType, keyContent, keyComment string
if len(lines) == 1 {
// Parse openssh format
parts := strings.Fields(lines[0])
switch len(parts) {
case 0:
return "", errors.New("Empty key")
case 1:
keyContent = parts[0]
case 2:
keyType = parts[0]
keyContent = parts[1]
default:
keyType = parts[0]
keyContent = parts[1]
keyComment = parts[2]
}
// If keyType is not given, extract it from content. If given, validate it
if len(keyType) == 0 {
if t, err := extractTypeFromBase64Key(keyContent); err == nil {
keyType = t
} else {
return "", err
}
} else {
if t, err := extractTypeFromBase64Key(keyContent); err != nil || keyType != t {
return "", err
}
}
} else {
// Parse SSH2 file format.
continuationLine := false
for _, line := range lines {
// Skip lines that:
// 1) are a continuation of the previous line,
// 2) contain ":" as that are comment lines
// 3) contain "-" as that are begin and end tags
if continuationLine || strings.ContainsAny(line, ":-") {
continuationLine = strings.HasSuffix(line, "\\")
} else {
keyContent = keyContent + line
}
}
if t, err := extractTypeFromBase64Key(keyContent); err == nil {
keyType = t
} else {
return "", err
}
}
return keyType + " " + keyContent + " " + keyComment, nil
}
// CheckPublicKeyString checks if the given public key string is recognized by SSH.
func CheckPublicKeyString(content string) (bool, error) {
content = strings.TrimRight(content, "\n\r")
@@ -158,16 +244,17 @@ func CheckPublicKeyString(content string) (bool, error) {
}
// saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
func saveAuthorizedKeyFile(key *PublicKey) error {
func saveAuthorizedKeyFile(keys ...*PublicKey) error {
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
fpath := filepath.Join(SshPath, "authorized_keys")
fpath := filepath.Join(SSHPath, "authorized_keys")
f, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return err
}
defer f.Close()
finfo, err := f.Stat()
if err != nil {
return err
@@ -183,8 +270,12 @@ func saveAuthorizedKeyFile(key *PublicKey) error {
}
}
_, err = f.WriteString(key.GetAuthorizedString())
return err
for _, key := range keys {
if _, err = f.WriteString(key.GetAuthorizedString()); err != nil {
return err
}
}
return nil
}
// AddPublicKey adds new public key to database and authorized_keys file.
@@ -327,8 +418,8 @@ func DeletePublicKey(key *PublicKey) error {
return err
}
fpath := filepath.Join(SshPath, "authorized_keys")
tmpPath := filepath.Join(SshPath, "authorized_keys.tmp")
fpath := filepath.Join(SSHPath, "authorized_keys")
tmpPath := filepath.Join(SSHPath, "authorized_keys.tmp")
if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
return err
} else if err = os.Remove(fpath); err != nil {
@@ -336,3 +427,37 @@ func DeletePublicKey(key *PublicKey) error {
}
return os.Rename(tmpPath, fpath)
}
// RewriteAllPublicKeys removes any authorized key and rewrite all keys from database again.
func RewriteAllPublicKeys() error {
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
tmpPath := filepath.Join(SSHPath, "authorized_keys.tmp")
f, err := os.Create(tmpPath)
if err != nil {
return err
}
defer os.Remove(tmpPath)
err = x.Iterate(new(PublicKey), func(idx int, bean interface{}) (err error) {
_, err = f.WriteString((bean.(*PublicKey)).GetAuthorizedString())
return err
})
f.Close()
if err != nil {
return err
}
fpath := filepath.Join(SSHPath, "authorized_keys")
if com.IsExist(fpath) {
if err = os.Remove(fpath); err != nil {
return err
}
}
if err = os.Rename(tmpPath, fpath); err != nil {
return err
}
return nil
}

View File

@@ -7,7 +7,6 @@ package models
import (
"errors"
"fmt"
"html"
"html/template"
"io/ioutil"
"os"
@@ -31,7 +30,7 @@ import (
)
const (
TPL_UPDATE_HOOK = "#!/usr/bin/env %s\n%s update $1 $2 $3\n"
_TPL_UPDATE_HOOK = "#!/usr/bin/env %s\n%s update $1 $2 $3 --config='%s'\n"
)
var (
@@ -105,21 +104,18 @@ func NewRepoContext() {
log.Fatal(4, "Gogs requires Git version greater or equal to 1.7.1")
}
// Check if server has basic git setting and set if not.
if stdout, stderr, err := process.Exec("NewRepoContext(get setting)", "git", "config", "--get", "user.name"); err != nil || strings.TrimSpace(stdout) == "" {
// ExitError indicates user.name is not set
if _, ok := err.(*exec.ExitError); ok || strings.TrimSpace(stdout) == "" {
stndrdUserName := "Gogs"
stndrdUserEmail := "gogitservice@gmail.com"
if _, stderr, gerr := process.Exec("NewRepoContext(set name)", "git", "config", "--global", "user.name", stndrdUserName); gerr != nil {
log.Fatal(4, "Fail to set git user.name(%s): %s", gerr, stderr)
// Check if server has user.email and user.name set correctly and set if they're not.
for configKey, defaultValue := range map[string]string{"user.name": "Gogs", "user.email": "gogitservice@gmail.com"} {
if stdout, stderr, err := process.Exec("NewRepoContext(get setting)", "git", "config", "--get", configKey); err != nil || strings.TrimSpace(stdout) == "" {
// ExitError indicates this config is not set
if _, ok := err.(*exec.ExitError); ok || strings.TrimSpace(stdout) == "" {
if _, stderr, gerr := process.Exec("NewRepoContext(set "+configKey+")", "git", "config", "--global", configKey, defaultValue); gerr != nil {
log.Fatal(4, "Fail to set git %s(%s): %s", configKey, gerr, stderr)
}
log.Info("Git config %s set to %s", configKey, defaultValue)
} else {
log.Fatal(4, "Fail to get git %s(%s): %s", configKey, err, stderr)
}
if _, stderr, gerr := process.Exec("NewRepoContext(set email)", "git", "config", "--global", "user.email", stndrdUserEmail); gerr != nil {
log.Fatal(4, "Fail to set git user.email(%s): %s", gerr, stderr)
}
log.Info("Git user.name and user.email set to %s <%s>", stndrdUserName, stndrdUserEmail)
} else {
log.Fatal(4, "Fail to get git user.name(%s): %s", err, stderr)
}
}
@@ -221,11 +217,9 @@ func (repo *Repository) HasAccess(uname string) bool {
// DescriptionHtml does special handles to description and return HTML string.
func (repo *Repository) DescriptionHtml() template.HTML {
sanitize := func(s string) string {
// TODO(nuss-justin): Improve sanitization. Strip all tags?
ss := html.EscapeString(s)
return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss)
return fmt.Sprintf(`<a href="%[1]s" target="_blank">%[1]s</a>`, s)
}
return template.HTML(DescPattern.ReplaceAllStringFunc(base.XSSString(repo.Description), sanitize))
return template.HTML(DescPattern.ReplaceAllStringFunc(base.Sanitizer.Sanitize(repo.Description), sanitize))
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
@@ -241,9 +235,30 @@ func IsRepositoryExist(u *User, repoName string) (bool, error) {
return com.IsDir(RepoPath(u.Name, repoName)), nil
}
// CloneLink represents different types of clone URLs of repository.
type CloneLink struct {
SSH string
HTTPS string
Git string
}
// CloneLink returns clone URLs of repository.
func (repo *Repository) CloneLink() (cl CloneLink, err error) {
if err = repo.GetOwner(); err != nil {
return cl, err
}
if setting.SSHPort != 22 {
cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName)
} else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName)
}
cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.LowerName, repo.LowerName)
return cl, nil
}
var (
illegalEquals = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"}
illegalSuffixs = []string{".git"}
illegalSuffixs = []string{".git", ".keys"}
)
// IsLegalName returns false if name contains illegal characters.
@@ -308,28 +323,6 @@ func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) er
return nil
}
// MirrorUpdate checks and updates mirror repositories.
func MirrorUpdate() {
if err := x.Iterate(new(Mirror), func(idx int, bean interface{}) error {
m := bean.(*Mirror)
if m.NextUpdate.After(time.Now()) {
return nil
}
repoPath := filepath.Join(setting.RepoRootPath, m.RepoName+".git")
if _, stderr, err := process.ExecDir(10*time.Minute,
repoPath, fmt.Sprintf("MirrorUpdate: %s", repoPath),
"git", "remote", "update"); err != nil {
return errors.New("git remote update: " + stderr)
}
m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour)
return UpdateMirror(m)
}); err != nil {
log.Error(4, "repo.MirrorUpdate: %v", err)
}
}
// MigrateRepository migrates a existing repository from other project hosting.
func MigrateRepository(u *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
repo, err := CreateRepository(u, name, desc, "", "", private, mirror, false)
@@ -364,13 +357,16 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
os.RemoveAll(repoPath)
}
// this command could for both migrate and mirror
// FIXME: this command could for both migrate and mirror
_, stderr, err := process.ExecTimeout(10*time.Minute,
fmt.Sprintf("MigrateRepository: %s", repoPath),
"git", "clone", "--mirror", "--bare", url, repoPath)
if err != nil {
return repo, errors.New("git clone: " + stderr)
return repo, fmt.Errorf("git clone --mirror --bare: %v", stderr)
} else if err = createUpdateHook(repoPath); err != nil {
return repo, fmt.Errorf("create update hook: %v", err)
}
return repo, UpdateRepository(repo)
}
@@ -409,15 +405,9 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
return nil
}
func createHookUpdate(hookPath, content string) error {
pu, err := os.OpenFile(hookPath, os.O_CREATE|os.O_WRONLY, 0777)
if err != nil {
return err
}
defer pu.Close()
_, err = pu.WriteString(content)
return err
func createUpdateHook(repoPath string) error {
return ioutil.WriteFile(path.Join(repoPath, "hooks/update"),
[]byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"", setting.CustomConf)), 0777)
}
// InitRepository initializes README and .gitignore if needed.
@@ -429,9 +419,7 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa
return err
}
// hook/post-update
if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"),
fmt.Sprintf(TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"")); err != nil {
if err := createUpdateHook(repoPath); err != nil {
return err
}
@@ -511,6 +499,11 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa
}
if len(fileName) == 0 {
// Re-fetch the repository from database before updating it (else it would
// override changes that were done earlier with sql)
if repo, err = GetRepositoryById(repo.Id); err != nil {
return err
}
repo.IsBare = true
repo.DefaultBranch = "master"
return UpdateRepository(repo)
@@ -833,13 +826,16 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) {
userName = strings.ToLower(userName)
oldRepoName = strings.ToLower(oldRepoName)
newRepoName = strings.ToLower(newRepoName)
if !IsLegalName(newRepoName) {
return ErrRepoNameIllegal
}
// Update accesses.
accesses := make([]Access, 0, 10)
if err = x.Find(&accesses, &Access{RepoName: strings.ToLower(userName + "/" + oldRepoName)}); err != nil {
if err = x.Find(&accesses, &Access{RepoName: userName + "/" + oldRepoName}); err != nil {
return err
}
@@ -878,7 +874,7 @@ func UpdateRepository(repo *Repository) error {
return err
}
// DeleteRepository deletes a repository for a user or orgnaztion.
// DeleteRepository deletes a repository for a user or organization.
func DeleteRepository(uid, repoId int64, userName string) error {
repo := &Repository{Id: repoId, OwnerId: uid}
has, err := x.Get(repo)
@@ -1140,18 +1136,8 @@ type SearchOption struct {
Private bool
}
// FilterSQLInject tries to prevent SQL injection.
func FilterSQLInject(key string) string {
key = strings.TrimSpace(key)
key = strings.Split(key, " ")[0]
key = strings.Replace(key, ",", "", -1)
return key
}
// SearchRepositoryByName returns given number of repositories whose name contains keyword.
func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
// Prevent SQL inject.
opt.Keyword = FilterSQLInject(opt.Keyword)
if len(opt.Keyword) == 0 {
return repos, nil
}
@@ -1183,6 +1169,113 @@ func DeleteRepositoryArchives() error {
})
}
// RewriteRepositoryUpdateHook rewrites all repositories' update hook.
func RewriteRepositoryUpdateHook() error {
return x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
if err := repo.GetOwner(); err != nil {
return err
}
return createUpdateHook(RepoPath(repo.Owner.Name, repo.Name))
})
}
var (
// Prevent duplicate tasks.
isMirrorUpdating = false
isGitFscking = false
)
// MirrorUpdate checks and updates mirror repositories.
func MirrorUpdate() {
if isMirrorUpdating {
return
}
isMirrorUpdating = true
defer func() { isMirrorUpdating = false }()
mirrors := make([]*Mirror, 0, 10)
if err := x.Iterate(new(Mirror), func(idx int, bean interface{}) error {
m := bean.(*Mirror)
if m.NextUpdate.After(time.Now()) {
return nil
}
repoPath := filepath.Join(setting.RepoRootPath, m.RepoName+".git")
if _, stderr, err := process.ExecDir(10*time.Minute,
repoPath, fmt.Sprintf("MirrorUpdate: %s", repoPath),
"git", "remote", "update"); err != nil {
desc := fmt.Sprintf("Fail to update mirror repository(%s): %s", repoPath, stderr)
log.Error(4, desc)
if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "Fail to add notice: %v", err)
}
return nil
}
m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour)
mirrors = append(mirrors, m)
return nil
}); err != nil {
log.Error(4, "MirrorUpdate: %v", err)
}
for i := range mirrors {
if err := UpdateMirror(mirrors[i]); err != nil {
log.Error(4, "UpdateMirror", fmt.Sprintf("%s: %v", mirrors[i].RepoName, err))
}
}
}
// GitFsck calls 'git fsck' to check repository health.
func GitFsck() {
if isGitFscking {
return
}
isGitFscking = true
defer func() { isGitFscking = false }()
args := append([]string{"fsck"}, setting.Git.Fsck.Args...)
if err := x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
if err := repo.GetOwner(); err != nil {
return err
}
repoPath := RepoPath(repo.Owner.Name, repo.Name)
_, _, err := process.ExecDir(-1, repoPath, "Repository health check", "git", args...)
if err != nil {
desc := fmt.Sprintf("Fail to health check repository(%s)", repoPath)
log.Warn(desc)
if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "Fail to add notice: %v", err)
}
}
return nil
}); err != nil {
log.Error(4, "repo.Fsck: %v", err)
}
}
func GitGcRepos() error {
args := append([]string{"gc"}, setting.Git.GcArgs...)
return x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
if err := repo.GetOwner(); err != nil {
return err
}
_, stderr, err := process.ExecDir(-1, RepoPath(repo.Owner.Name, repo.Name), "Repository garbage collection", "git", args...)
if err != nil {
return fmt.Errorf("%v: %v", err, stderr)
}
return nil
})
}
// __ __ __ .__
// / \ / \_____ _/ |_ ____ | |__
// \ \/\/ /\__ \\ __\/ ___\| | \
@@ -1190,7 +1283,7 @@ func DeleteRepositoryArchives() error {
// \__/\ / (____ /__| \___ >___| /
// \/ \/ \/ \/
// Watch is connection request for receiving repository notifycation.
// Watch is connection request for receiving repository notification.
type Watch struct {
Id int64
UserId int64 `xorm:"UNIQUE(watch)"`
@@ -1203,7 +1296,7 @@ func IsWatching(uid, repoId int64) bool {
return has
}
func watchRepoWithEngine(e Engine, uid, repoId int64, watch bool) (err error) {
func watchRepo(e Engine, uid, repoId int64, watch bool) (err error) {
if watch {
if IsWatching(uid, repoId) {
return nil
@@ -1226,7 +1319,7 @@ func watchRepoWithEngine(e Engine, uid, repoId int64, watch bool) (err error) {
// Watch or unwatch repository.
func WatchRepo(uid, repoId int64, watch bool) (err error) {
return watchRepoWithEngine(x, uid, repoId, watch)
return watchRepo(x, uid, repoId, watch)
}
// GetWatchers returns all watchers of given repository.
@@ -1414,14 +1507,14 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
log.Error(4, "GetMembers: %v", err)
} else {
for _, u := range t.Members {
if err = watchRepoWithEngine(sess, u.Id, repo.Id, true); err != nil {
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo2: %v", err)
}
}
}
}
} else {
if err = watchRepoWithEngine(sess, u.Id, repo.Id, true); err != nil {
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo3: %v", err)
}
}

View File

@@ -5,18 +5,23 @@
package models
import (
"bytes"
"container/list"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"image"
"image/jpeg"
"os"
"path/filepath"
"strings"
"time"
"github.com/Unknwon/com"
"github.com/nfnt/resize"
"github.com/gogits/gogs/modules/avatar"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
@@ -37,6 +42,8 @@ var (
ErrUserNotExist = errors.New("User does not exist")
ErrUserNotKeyOwner = errors.New("User does not the owner of public key")
ErrEmailAlreadyUsed = errors.New("E-mail already used")
ErrEmailNotExist = errors.New("E-mail does not exist")
ErrEmailNotActivated = errors.New("E-mail address has not been activated")
ErrUserNameIllegal = errors.New("User name contains illegal characters")
ErrLoginSourceNotExist = errors.New("Login source does not exist")
ErrLoginSourceNotActived = errors.New("Login source is not actived")
@@ -45,33 +52,41 @@ var (
// User represents the object of individual and member of organization.
type User struct {
Id int64
LowerName string `xorm:"UNIQUE NOT NULL"`
Name string `xorm:"UNIQUE NOT NULL"`
FullName string
Email string `xorm:"UNIQUE NOT NULL"`
Passwd string `xorm:"NOT NULL"`
LoginType LoginType
LoginSource int64 `xorm:"NOT NULL DEFAULT 0"`
LoginName string
Type UserType
Orgs []*User `xorm:"-"`
Repos []*Repository `xorm:"-"`
Id int64
LowerName string `xorm:"UNIQUE NOT NULL"`
Name string `xorm:"UNIQUE NOT NULL"`
FullName string
// Email is the primary email address (to be used for communication).
Email string `xorm:"UNIQUE(s) NOT NULL"`
Passwd string `xorm:"NOT NULL"`
LoginType LoginType
LoginSource int64 `xorm:"NOT NULL DEFAULT 0"`
LoginName string
Type UserType `xorm:"UNIQUE(s)"`
Orgs []*User `xorm:"-"`
Repos []*Repository `xorm:"-"`
Location string
Website string
Rands string `xorm:"VARCHAR(10)"`
Salt string `xorm:"VARCHAR(10)"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
// Permissions.
IsActive bool
IsAdmin bool
AllowGitHook bool
// Avatar.
Avatar string `xorm:"VARCHAR(2048) NOT NULL"`
AvatarEmail string `xorm:"NOT NULL"`
UseCustomAvatar bool
// Counters.
NumFollowers int
NumFollowings int
NumStars int
NumRepos int
Avatar string `xorm:"VARCHAR(2048) NOT NULL"`
AvatarEmail string `xorm:"NOT NULL"`
Location string
Website string
IsActive bool
IsAdmin bool
AllowGitHook bool
Rands string `xorm:"VARCHAR(10)"`
Salt string `xorm:"VARCHAR(10)"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
// For organization.
Description string
@@ -81,6 +96,16 @@ type User struct {
Members []*User `xorm:"-"`
}
// EmailAdresses is the list of all email addresses of a user. Can contain the
// primary email address, but is not obligatory
type EmailAddress struct {
Id int64
Uid int64 `xorm:"INDEX NOT NULL"`
Email string `xorm:"UNIQUE NOT NULL"`
IsActivated bool
IsPrimary bool `xorm:"-"`
}
// DashboardLink returns the user dashboard page link.
func (u *User) DashboardLink() string {
if u.IsOrganization() {
@@ -96,9 +121,12 @@ func (u *User) HomeLink() string {
// AvatarLink returns user gravatar link.
func (u *User) AvatarLink() string {
if setting.DisableGravatar {
switch {
case u.UseCustomAvatar:
return setting.AppSubUrl + "/avatars/" + com.ToStr(u.Id)
case setting.DisableGravatar:
return setting.AppSubUrl + "/img/avatar_default.jpg"
} else if setting.Service.EnableCacheAvatar {
case setting.Service.EnableCacheAvatar:
return setting.AppSubUrl + "/avatar/" + u.Avatar
}
return setting.GravatarSource + u.Avatar
@@ -126,6 +154,48 @@ func (u *User) ValidtePassword(passwd string) bool {
return u.Passwd == newUser.Passwd
}
// CustomAvatarPath returns user custom avatar file path.
func (u *User) CustomAvatarPath() string {
return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
}
// UploadAvatar saves custom avatar for user.
// FIXME: split uploads to different subdirs in case we have massive users.
func (u *User) UploadAvatar(data []byte) error {
u.UseCustomAvatar = true
img, _, err := image.Decode(bytes.NewReader(data))
if err != nil {
return err
}
m := resize.Resize(200, 200, img, resize.NearestNeighbor)
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Id(u.Id).AllCols().Update(u); err != nil {
sess.Rollback()
return err
}
os.MkdirAll(setting.AvatarUploadPath, os.ModePerm)
fw, err := os.Create(u.CustomAvatarPath())
if err != nil {
sess.Rollback()
return err
}
defer fw.Close()
if err = jpeg.Encode(fw, m, nil); err != nil {
sess.Rollback()
return err
}
return sess.Commit()
}
// IsOrganization returns true if user is actually a organization.
func (u *User) IsOrganization() bool {
return u.Type == ORGANIZATION
@@ -191,6 +261,9 @@ func IsEmailUsed(email string) (bool, error) {
if len(email) == 0 {
return false, nil
}
if has, err := x.Get(&EmailAddress{Email: email}); has || err != nil {
return has, err
}
return x.Get(&User{Email: email})
}
@@ -220,8 +293,8 @@ func CreateUser(u *User) error {
}
u.LowerName = strings.ToLower(u.Name)
u.Avatar = base.EncodeMd5(u.Email)
u.AvatarEmail = u.Email
u.Avatar = avatar.HashEmail(u.AvatarEmail)
u.Rands = GetUserSalt()
u.Salt = GetUserSalt()
u.EncodePasswd()
@@ -298,6 +371,25 @@ func VerifyUserActiveCode(code string) (user *User) {
return nil
}
// verify active code when active account
func VerifyActiveEmailCode(code, email string) *EmailAddress {
minutes := setting.Service.ActiveCodeLives
if user := getVerifyUser(code); user != nil {
// time limit code
prefix := code[:base.TimeLimitCodeLength]
data := com.ToStr(user.Id) + email + user.LowerName + user.Passwd + user.Rands
if base.VerifyTimeLimitCode(data, minutes, prefix) {
emailAddress := &EmailAddress{Email: email}
if has, _ := x.Get(emailAddress); has {
return emailAddress
}
}
}
return nil
}
// ChangeUserName changes all corresponding setting from old user name to new one.
func ChangeUserName(u *User, newUserName string) (err error) {
if !IsLegalName(newUserName) {
@@ -361,6 +453,13 @@ func ChangeUserName(u *User, newUserName string) (err error) {
// UpdateUser updates user's information.
func UpdateUser(u *User) error {
has, err := x.Where("id!=?", u.Id).And("type=?", INDIVIDUAL).And("email=?", u.Email).Get(new(User))
if err != nil {
return err
} else if has {
return ErrEmailAlreadyUsed
}
u.LowerName = strings.ToLower(u.Name)
if len(u.Location) > 255 {
@@ -373,7 +472,13 @@ func UpdateUser(u *User) error {
u.Description = u.Description[:255]
}
_, err := x.Id(u.Id).AllCols().Update(u)
if u.AvatarEmail == "" {
u.AvatarEmail = u.Email
}
u.Avatar = avatar.HashEmail(u.AvatarEmail)
u.FullName = base.Sanitizer.Sanitize(u.FullName)
_, err = x.Id(u.Id).AllCols().Update(u)
return err
}
@@ -419,6 +524,10 @@ func DeleteUser(u *User) error {
if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil {
return err
}
// Delete all alternative email addresses
if _, err = x.Delete(&EmailAddress{Uid: u.Id}); err != nil {
return err
}
// Delete all SSH keys.
keys := make([]*PublicKey, 0, 10)
if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
@@ -439,9 +548,12 @@ func DeleteUser(u *User) error {
return err
}
// DeleteInactivateUsers deletes all inactivate users.
// DeleteInactivateUsers deletes all inactivate users and email addresses.
func DeleteInactivateUsers() error {
_, err := x.Where("is_active=?", false).Delete(new(User))
if err == nil {
_, err = x.Where("is_activated=?", false).Delete(new(EmailAddress))
}
return err
}
@@ -515,43 +627,151 @@ func GetUserIdsByNames(names []string) []int64 {
return ids
}
// UserCommit represtns a commit with validation of user.
// Get all email addresses
func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
emails := make([]*EmailAddress, 0, 5)
err := x.Where("uid=?", uid).Find(&emails)
if err != nil {
return nil, err
}
u, err := GetUserById(uid)
if err != nil {
return nil, err
}
isPrimaryFound := false
for _, email := range emails {
if email.Email == u.Email {
isPrimaryFound = true
email.IsPrimary = true
} else {
email.IsPrimary = false
}
}
// We alway want the primary email address displayed, even if it's not in
// the emailaddress table (yet)
if !isPrimaryFound {
emails = append(emails, &EmailAddress{Email: u.Email, IsActivated: true, IsPrimary: true})
}
return emails, nil
}
func AddEmailAddress(email *EmailAddress) error {
used, err := IsEmailUsed(email.Email)
if err != nil {
return err
} else if used {
return ErrEmailAlreadyUsed
}
_, err = x.Insert(email)
return err
}
func (email *EmailAddress) Activate() error {
email.IsActivated = true
if _, err := x.Id(email.Id).AllCols().Update(email); err != nil {
return err
}
if user, err := GetUserById(email.Uid); err != nil {
return err
} else {
user.Rands = GetUserSalt()
return UpdateUser(user)
}
}
func DeleteEmailAddress(email *EmailAddress) error {
has, err := x.Get(email)
if err != nil {
return err
} else if !has {
return ErrEmailNotExist
}
if _, err = x.Delete(email); err != nil {
return err
}
return nil
}
func MakeEmailPrimary(email *EmailAddress) error {
has, err := x.Get(email)
if err != nil {
return err
} else if !has {
return ErrEmailNotExist
}
if !email.IsActivated {
return ErrEmailNotActivated
}
user := &User{Id: email.Uid}
has, err = x.Get(user)
if err != nil {
return err
} else if !has {
return ErrUserNotExist
}
// Make sure the former primary email doesn't disappear
former_primary_email := &EmailAddress{Email: user.Email}
has, err = x.Get(former_primary_email)
if err != nil {
return err
} else if !has {
former_primary_email.Uid = user.Id
former_primary_email.IsActivated = user.IsActive
x.Insert(former_primary_email)
}
user.Email = email.Email
_, err = x.Id(user.Id).AllCols().Update(user)
return err
}
// UserCommit represents a commit with validation of user.
type UserCommit struct {
UserName string
User *User
*git.Commit
}
// ValidateCommitWithEmail chceck if author's e-mail of commit is corresponsind to a user.
func ValidateCommitWithEmail(c *git.Commit) (uname string) {
func ValidateCommitWithEmail(c *git.Commit) *User {
u, err := GetUserByEmail(c.Author.Email)
if err == nil {
uname = u.Name
if err != nil {
return nil
}
return uname
return u
}
// ValidateCommitsWithEmails checks if authors' e-mails of commits are corresponding to users.
func ValidateCommitsWithEmails(oldCommits *list.List) *list.List {
emails := map[string]string{}
emails := map[string]*User{}
newCommits := list.New()
e := oldCommits.Front()
for e != nil {
c := e.Value.(*git.Commit)
uname := ""
var u *User
if v, ok := emails[c.Author.Email]; !ok {
u, err := GetUserByEmail(c.Author.Email)
if err == nil {
uname = u.Name
}
emails[c.Author.Email] = uname
u, _ = GetUserByEmail(c.Author.Email)
emails[c.Author.Email] = u
} else {
uname = v
u = v
}
newCommits.PushBack(UserCommit{
UserName: uname,
Commit: c,
User: u,
Commit: c,
})
e = e.Next()
}
@@ -563,19 +783,31 @@ func GetUserByEmail(email string) (*User, error) {
if len(email) == 0 {
return nil, ErrUserNotExist
}
// First try to find the user by primary email
user := &User{Email: strings.ToLower(email)}
has, err := x.Get(user)
if err != nil {
return nil, err
} else if !has {
return nil, ErrUserNotExist
}
return user, nil
if has {
return user, nil
}
// Otherwise, check in alternative list for activated email addresses
emailAddress := &EmailAddress{Email: strings.ToLower(email), IsActivated: true}
has, err = x.Get(emailAddress)
if err != nil {
return nil, err
}
if has {
return GetUserById(emailAddress.Uid)
}
return nil, ErrUserNotExist
}
// SearchUserByName returns given number of users whose name contains keyword.
func SearchUserByName(opt SearchOption) (us []*User, err error) {
opt.Keyword = FilterSQLInject(opt.Keyword)
if len(opt.Keyword) == 0 {
return us, nil
}
@@ -586,7 +818,7 @@ func SearchUserByName(opt SearchOption) (us []*User, err error) {
return us, err
}
// Follow is connection request for receiving user notifycation.
// Follow is connection request for receiving user notification.
type Follow struct {
Id int64
UserId int64 `xorm:"unique(follow)"`

View File

@@ -5,6 +5,7 @@
package models
import (
"crypto/tls"
"encoding/json"
"errors"
"io/ioutil"
@@ -99,7 +100,7 @@ func (w *Webhook) UpdateEvent() error {
return err
}
// HasPushEvent returns true if hook enbaled push event.
// HasPushEvent returns true if hook enabled push event.
func (w *Webhook) HasPushEvent() bool {
if w.PushOnly {
return true
@@ -307,13 +308,14 @@ func DeliverHooks() {
defer func() { isShooting = false }()
tasks := make([]*HookTask, 0, 10)
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second
x.Where("is_delivered=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
req := httplib.Post(t.Url).SetTimeout(timeout, timeout).
Header("X-Gogs-Delivery", t.Uuid).
Header("X-Gogs-Event", string(t.EventType))
Header("X-Gogs-Event", string(t.EventType)).
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify})
switch t.ContentType {
case JSON:
@@ -329,7 +331,7 @@ func DeliverHooks() {
case GOGS:
{
if _, err := req.Response(); err != nil {
log.Error(4, "Delivery: %v", err)
log.Error(5, "Delivery: %v", err)
} else {
t.IsSucceed = true
}
@@ -337,15 +339,15 @@ func DeliverHooks() {
case SLACK:
{
if res, err := req.Response(); err != nil {
log.Error(4, "Delivery: %v", err)
log.Error(5, "Delivery: %v", err)
} else {
defer res.Body.Close()
contents, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Error(4, "%s", err)
log.Error(5, "%s", err)
} else {
if string(contents) != "ok" {
log.Error(4, "slack failed with: %s", string(contents))
log.Error(5, "slack failed with: %s", string(contents))
} else {
t.IsSucceed = true
}

View File

@@ -256,11 +256,11 @@ func ReadPacket(reader io.Reader) (*Packet, error) {
}
func DecodeString(data []byte) (ret string) {
for _, c := range data {
ret += fmt.Sprintf("%c", c)
}
// for _, c := range data {
// ret += fmt.Sprintf("%c", c)
// }
return
return string(data)
}
func DecodeInteger(data []byte) (ret uint64) {

View File

@@ -14,7 +14,7 @@ import (
)
type MarkdownForm struct {
Text string `form:"text" binding:"Required"`
Text string `form:"text"`
Mode string `form:"mode"`
Context string `form:"context"`
}
@@ -49,19 +49,19 @@ func validateApiReq(errs binding.Errors, data map[string]interface{}, f auth.For
if errs[0].FieldNames[0] == field.Name {
switch errs[0].Classification {
case binding.RequiredError:
case binding.ERR_REQUIRED:
data["ErrorMsg"] = fieldName + " cannot be empty"
case binding.AlphaDashError:
case binding.ERR_ALPHA_DASH:
data["ErrorMsg"] = fieldName + " must be valid alpha or numeric or dash(-_) characters"
case binding.AlphaDashDotError:
case binding.ERR_ALPHA_DASH_DOT:
data["ErrorMsg"] = fieldName + " must be valid alpha or numeric or dash(-_) or dot characters"
case binding.MinSizeError:
case binding.ERR_MIN_SIZE:
data["ErrorMsg"] = fieldName + " must contain at least " + auth.GetMinSize(field) + " characters"
case binding.MaxSizeError:
case binding.ERR_MAX_SIZE:
data["ErrorMsg"] = fieldName + " must contain at most " + auth.GetMaxSize(field) + " characters"
case binding.EmailError:
case binding.ERR_EMAIL:
data["ErrorMsg"] = fieldName + " is not a valid e-mail address"
case binding.UrlError:
case binding.ERR_URL:
data["ErrorMsg"] = fieldName + " is not a valid URL"
default:
data["ErrorMsg"] = "Unknown error: " + errs[0].Classification

View File

@@ -9,6 +9,7 @@ import (
"reflect"
"strings"
"github.com/Unknwon/com"
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/binding"
"github.com/macaron-contrib/session"
@@ -17,6 +18,7 @@ import (
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/modules/uuid"
)
// SignedInId returns the id of signed in user.
@@ -60,6 +62,7 @@ func SignedInId(req *http.Request, sess session.Store) int64 {
}
// SignedInUser returns the user object of signed user.
// It returns a bool value to indicate whether user uses basic auth or not.
func SignedInUser(req *http.Request, sess session.Store) (*models.User, bool) {
if !models.HasEngine {
return nil, false
@@ -75,8 +78,25 @@ func SignedInUser(req *http.Request, sess session.Store) (*models.User, bool) {
if err != nil {
if err != models.ErrUserNotExist {
log.Error(4, "GetUserByName: %v", err)
return nil, false
}
// Check if enabled auto-registration.
if setting.Service.EnableReverseProxyAutoRegister {
u := &models.User{
Name: webAuthUser,
Email: uuid.NewV4().String() + "@localhost",
Passwd: webAuthUser,
IsActive: true,
}
if err = models.CreateUser(u); err != nil {
// FIXME: should I create a system notice?
log.Error(4, "CreateUser: %v", err)
return nil, false
} else {
return u, false
}
}
return nil, false
}
return u, false
}
@@ -116,6 +136,10 @@ type Form interface {
binding.Validator
}
func init() {
binding.SetNameMapper(com.ToSnakeCase)
}
// AssignForm assign form values back to the template data.
func AssignForm(form interface{}, data map[string]interface{}) {
typ := reflect.TypeOf(form)
@@ -133,6 +157,8 @@ func AssignForm(form interface{}, data map[string]interface{}) {
// Allow ignored fields in the struct
if fieldName == "-" {
continue
} else if len(fieldName) == 0 {
fieldName = com.ToSnakeCase(field.Name)
}
data[fieldName] = val.Field(i).Interface()
@@ -185,19 +211,19 @@ func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaro
data["Err_"+field.Name] = true
trName := l.Tr("form." + field.Name)
switch errs[0].Classification {
case binding.RequiredError:
case binding.ERR_REQUIRED:
data["ErrorMsg"] = trName + l.Tr("form.require_error")
case binding.AlphaDashError:
case binding.ERR_ALPHA_DASH:
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")
case binding.AlphaDashDotError:
case binding.ERR_ALPHA_DASH_DOT:
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error")
case binding.MinSizeError:
case binding.ERR_MIN_SIZE:
data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field))
case binding.MaxSizeError:
case binding.ERR_MAX_SIZE:
data["ErrorMsg"] = trName + l.Tr("form.max_size_error", GetMaxSize(field))
case binding.EmailError:
case binding.ERR_EMAIL:
data["ErrorMsg"] = trName + l.Tr("form.email_error")
case binding.UrlError:
case binding.ERR_URL:
data["ErrorMsg"] = trName + l.Tr("form.url_error")
default:
data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + errs[0].Classification

View File

@@ -20,7 +20,7 @@ type Ldapsource struct {
Port int // port number
UseSSL bool // Use SSL
BaseDN string // Base DN
Attributes string // Attribut to search
Attributes string // Attribute to search
Filter string // Query filter to validate entry
MsAdSAFormat string // in the case of MS AD Simple Authen, the format to use (see: http://msdn.microsoft.com/en-us/library/cc223499.aspx)
Enabled bool // if this source is disabled
@@ -37,7 +37,7 @@ func AddSource(name string, host string, port int, usessl bool, basedn string, a
Authensource = append(Authensource, ldaphost)
}
//LoginUser : try to login an user to LDAP sources, return requested (attribut,true) if ok, ("",false) other wise
//LoginUser : try to login an user to LDAP sources, return requested (attribute,true) if ok, ("",false) other wise
//First match wins
//Returns first attribute if exists
func LoginUser(name, passwd string) (a string, r bool) {

View File

@@ -21,9 +21,9 @@ type CreateRepoForm struct {
RepoName string `form:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(255)"`
AutoInit bool `form:"auto_init"`
Gitignore string `form:"gitignore"`
License string `form:"license"`
InitReadme bool `form:"init_readme"`
}
func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
@@ -164,7 +164,6 @@ func (f *NewReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) bin
}
type EditReleaseForm struct {
Target string `form:"tag_target" binding:"Required"`
Title string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
Draft string `form:"draft"`

View File

@@ -5,31 +5,34 @@
package auth
import (
"mime/multipart"
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/binding"
)
type InstallForm struct {
Database string `form:"database" binding:"Required"`
DbHost string `form:"host"`
DbUser string `form:"user"`
DbPasswd string `form:"passwd"`
DatabaseName string `form:"database_name"`
SslMode string `form:"ssl_mode"`
DatabasePath string `form:"database_path"`
RepoRootPath string `form:"repo_path" binding:"Required"`
RunUser string `form:"run_user" binding:"Required"`
Domain string `form:"domain" binding:"Required"`
AppUrl string `form:"app_url" binding:"Required"`
SmtpHost string `form:"smtp_host"`
SmtpEmail string `form:"mailer_user"`
SmtpPasswd string `form:"mailer_pwd"`
RegisterConfirm string `form:"register_confirm"`
MailNotify string `form:"mail_notify"`
AdminName string `form:"admin_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
AdminPasswd string `form:"admin_pwd" binding:"Required;MinSize(6);MaxSize(255)"`
ConfirmPasswd string `form:"confirm_passwd" binding:"Required;MinSize(6);MaxSize(255)"`
AdminEmail string `form:"admin_email" binding:"Required;Email;MaxSize(50)"`
DbType string `binding:"Required"`
DbHost string
DbUser string
DbPasswd string
DbName string
SSLMode string
DbPath string
RepoRootPath string `binding:"Required"`
RunUser string `binding:"Required"`
Domain string `binding:"Required"`
HTTPPort string `binding:"Required"`
AppUrl string `binding:"Required"`
SMTPHost string
SMTPEmail string
SMTPPasswd string
RegisterConfirm string
MailNotify string
AdminName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
AdminPasswd string `binding:"Required;MinSize(6);MaxSize(255)"`
AdminConfirmPasswd string `binding:"Required;MinSize(6);MaxSize(255)"`
AdminEmail string `binding:"Required;Email;MaxSize(50)"`
}
func (f *InstallForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
@@ -86,6 +89,23 @@ func (f *UpdateProfileForm) Validate(ctx *macaron.Context, errs binding.Errors)
return validate(errs, ctx.Data, f, ctx.Locale)
}
type UploadAvatarForm struct {
Enable bool `form:"enable"`
Avatar *multipart.FileHeader `form:"avatar"`
}
func (f *UploadAvatarForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}
type AddEmailForm struct {
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
}
func (f *AddEmailForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}
type ChangePasswordForm struct {
OldPassword string `form:"old_password" binding:"Required;MinSize(6);MaxSize(255)"`
Password string `form:"password" binding:"Required;MinSize(6);MaxSize(255)"`

View File

@@ -38,18 +38,24 @@ import (
var gravatarSource string
func init() {
func UpdateGravatarSource() {
gravatarSource = setting.GravatarSource
log.Debug("avatar.UpdateGravatarSource(gavatar source): %s", gravatarSource)
if !strings.HasPrefix(gravatarSource, "http:") {
gravatarSource = "http:" + gravatarSource
log.Debug("avatar.UpdateGravatarSource(update gavatar source): %s", gravatarSource)
}
}
// hash email to md5 string
// keep this func in order to make this package indenpent
// keep this func in order to make this package independent
func HashEmail(email string) string {
// https://en.gravatar.com/site/implement/hash/
email = strings.TrimSpace(email)
email = strings.ToLower(email)
h := md5.New()
h.Write([]byte(strings.ToLower(email)))
h.Write([]byte(email))
return hex.EncodeToString(h.Sum(nil))
}
@@ -121,17 +127,19 @@ func (this *Avatar) Encode(wr io.Writer, size int) (err error) {
if img, err = decodeImageFile(imgPath); err != nil {
return
}
m := resize.Resize(uint(size), 0, img, resize.Lanczos3)
m := resize.Resize(uint(size), 0, img, resize.NearestNeighbor)
return jpeg.Encode(wr, m, nil)
}
// get image from gravatar.com
func (this *Avatar) Update() {
UpdateGravatarSource()
thunder.Fetch(gravatarSource+this.Hash+"?"+this.reqParams,
this.imagePath)
}
func (this *Avatar) UpdateTimeout(timeout time.Duration) (err error) {
UpdateGravatarSource()
select {
case <-time.After(timeout):
err = fmt.Errorf("get gravatar image %s timeout", this.Hash)

View File

@@ -63,12 +63,18 @@ func IsImageFile(data []byte) (string, bool) {
return contentType, false
}
// IsReadmeFile returns true if given file name suppose to be a README file.
func IsReadmeFile(name string) bool {
name = strings.ToLower(name)
if len(name) < 6 {
return false
} else if len(name) == 6 {
if name == "readme" {
return true
}
return false
}
if name[:6] == "readme" {
if name[:7] == "readme." {
return true
}
return false
@@ -100,10 +106,11 @@ func (options *CustomRender) Image(out *bytes.Buffer, link []byte, title []byte,
}
var (
MentionPattern = regexp.MustCompile(`@[0-9a-zA-Z_]{1,}`)
commitPattern = regexp.MustCompile(`(\s|^)https?.*commit/[0-9a-zA-Z]+(#+[0-9a-zA-Z-]*)?`)
issueFullPattern = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`)
issueIndexPattern = regexp.MustCompile(`#[0-9]+`)
MentionPattern = regexp.MustCompile(`(\s|^)@[0-9a-zA-Z_]+`)
commitPattern = regexp.MustCompile(`(\s|^)https?.*commit/[0-9a-zA-Z]+(#+[0-9a-zA-Z-]*)?`)
issueFullPattern = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`)
issueIndexPattern = regexp.MustCompile(`( |^)#[0-9]+`)
sha1CurrentPattern = regexp.MustCompile(`\b[0-9a-f]{40}\b`)
)
func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
@@ -121,8 +128,9 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
if !inCodeBlock && !bytes.HasPrefix(line, tab) {
ms := MentionPattern.FindAll(line, -1)
for _, m := range ms {
m = bytes.TrimSpace(m)
line = bytes.Replace(line, m,
[]byte(fmt.Sprintf(`<a href="%s/user/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
[]byte(fmt.Sprintf(`<a href="%s/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
}
}
@@ -153,10 +161,25 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
` <a href="%s">#%s</a>`, m, ShortSha(string(m[i+7:j])))), -1)
}
ms = issueIndexPattern.FindAll(rawBytes, -1)
rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix)
rawBytes = RenderSha1CurrentPattern(rawBytes, urlPrefix)
return rawBytes
}
func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
ms := sha1CurrentPattern.FindAll(rawBytes, -1)
for _, m := range ms {
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
`<a href="%s/issues/%s">%s</a>`, urlPrefix, m[1:], m)), -1)
`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, ShortSha(string(m)))), -1)
}
return rawBytes
}
func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string) []byte {
ms := issueIndexPattern.FindAll(rawBytes, -1)
for _, m := range ms {
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`<a href="%s/issues/%s">%s</a>`,
urlPrefix, strings.TrimPrefix(string(m[1:]), "#"), m)), -1)
}
return rawBytes
}
@@ -196,7 +219,7 @@ func RenderRawMarkdown(body []byte, urlPrefix string) []byte {
func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
body := RenderSpecialLink(rawBytes, urlPrefix)
body = RenderRawMarkdown(body, urlPrefix)
body = XSS(body)
body = Sanitizer.SanitizeBytes(body)
return body
}

View File

@@ -7,20 +7,21 @@ package base
import (
"container/list"
"encoding/json"
"errors"
"fmt"
"html/template"
"runtime"
"strings"
"time"
"github.com/gogits/gogs/modules/mahonia"
"golang.org/x/net/html/charset"
"golang.org/x/text/transform"
"github.com/gogits/chardet"
"github.com/gogits/gogs/modules/setting"
"github.com/saintfish/chardet"
)
func Str2html(raw string) template.HTML {
return template.HTML(raw)
return template.HTML(Sanitizer.Sanitize(raw))
}
func Range(l int) []int {
@@ -47,22 +48,37 @@ func ShortSha(sha1 string) string {
return sha1
}
func ToUtf8WithErr(content []byte) (error, string) {
func DetectEncoding(content []byte) (string, error) {
detector := chardet.NewTextDetector()
result, err := detector.DetectBest(content)
return result.Charset, err
}
func ToUtf8WithErr(content []byte) (error, string) {
charsetLabel, err := DetectEncoding(content)
if err != nil {
return err, ""
}
if result.Charset == "utf8" {
if charsetLabel == "utf8" {
return nil, string(content)
}
decoder := mahonia.NewDecoder(result.Charset)
if decoder != nil {
return nil, decoder.ConvertString(string(content))
encoding, _ := charset.Lookup(charsetLabel)
if encoding == nil {
return fmt.Errorf("unknow char decoder %s", charsetLabel), string(content)
}
return errors.New("unknow char decoder"), string(content)
result, n, err := transform.String(encoding.NewDecoder(), string(content))
// If there is an error, we concatenate the nicely decoded part and the
// original left over. This way we won't loose data.
if err != nil {
result = result + string(content[n:])
}
return err, result
}
func ToUtf8(content string) string {
@@ -70,6 +86,11 @@ func ToUtf8(content string) string {
return res
}
// RenderCommitMessage renders commit message with XSS-safe and special links.
func RenderCommitMessage(msg, urlPrefix string) template.HTML {
return template.HTML(string(RenderIssueIndexPattern([]byte(template.HTMLEscapeString(msg)), urlPrefix)))
}
var mailDomains = map[string]string{
"gmail.com": "gmail.com",
}
@@ -97,7 +118,6 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
},
"AvatarLink": AvatarLink,
"str2html": Str2html, // TODO: Legacy
"Str2html": Str2html,
"TimeSince": TimeSince,
"FileSize": FileSize,
@@ -144,6 +164,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
"EscapePound": func(str string) string {
return strings.Replace(str, "#", "%23", -1)
},
"RenderCommitMessage": RenderCommitMessage,
}
type Actioner interface {

View File

@@ -11,21 +11,23 @@ import (
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"hash"
"html/template"
"math"
"regexp"
"strings"
"time"
"github.com/Unknwon/com"
"github.com/Unknwon/i18n"
"github.com/microcosm-cc/bluemonday"
"github.com/gogits/gogs/modules/avatar"
"github.com/gogits/gogs/modules/setting"
)
var Sanitizer = bluemonday.UGCPolicy()
// Encode string to md5 hex value.
func EncodeMd5(str string) string {
m := md5.New()
@@ -40,20 +42,14 @@ func EncodeSha1(str string) string {
return hex.EncodeToString(h.Sum(nil))
}
func BasicAuthDecode(encoded string) (user string, name string, err error) {
var s []byte
s, err = base64.StdEncoding.DecodeString(encoded)
func BasicAuthDecode(encoded string) (string, string, error) {
s, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
return user, name, err
return "", "", err
}
a := strings.Split(string(s), ":")
if len(a) == 2 {
user, name = a[0], a[1]
} else {
err = errors.New("decode failed")
}
return user, name, err
auth := strings.SplitN(string(s), ":", 2)
return auth[0], auth[1], nil
}
func BasicAuthEncode(username, password string) string {
@@ -177,10 +173,13 @@ func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string
func AvatarLink(email string) string {
if setting.DisableGravatar {
return setting.AppSubUrl + "/img/avatar_default.jpg"
} else if setting.Service.EnableCacheAvatar {
return setting.AppSubUrl + "/avatar/" + EncodeMd5(email)
}
return setting.GravatarSource + EncodeMd5(email)
gravatarHash := avatar.HashEmail(email)
if setting.Service.EnableCacheAvatar {
return setting.AppSubUrl + "/avatar/" + gravatarHash
}
return setting.GravatarSource + gravatarHash
}
// Seconds-based time units
@@ -476,29 +475,3 @@ func DateFormat(t time.Time, format string) string {
format = replacer.Replace(format)
return t.Format(format)
}
type xssFilter struct {
reg *regexp.Regexp
repl []byte
}
var (
whiteSpace = []byte(" ")
xssFilters = []xssFilter{
{regexp.MustCompile(`\ [ONon]\w*=["]*`), whiteSpace},
{regexp.MustCompile(`<[SCRIPTscript]{6}`), whiteSpace},
{regexp.MustCompile(`=[` + "`" + `'"]*[JAVASCRIPTjavascript \t\0&#x0D;]*:`), whiteSpace},
}
)
// XSS goes through all the XSS filters to make user input content as safe as possible.
func XSS(in []byte) []byte {
for _, filter := range xssFilters {
in = filter.reg.ReplaceAll(in, filter.repl)
}
return in
}
func XSSString(in string) string {
return string(XSS([]byte(in)))
}

View File

@@ -15,7 +15,10 @@ var c = New()
func NewCronContext() {
c.AddFunc("Update mirrors", "@every 1h", models.MirrorUpdate)
c.AddFunc("Deliver hooks", fmt.Sprintf("@every %dm", setting.WebhookTaskInterval), models.DeliverHooks)
c.AddFunc("Deliver hooks", fmt.Sprintf("@every %dm", setting.Webhook.TaskInterval), models.DeliverHooks)
if setting.Git.Fsck.Enable {
c.AddFunc("Repository health check", fmt.Sprintf("@every %dh", setting.Git.Fsck.Interval), models.GitFsck)
}
c.Start()
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/gogits/gogs/modules/asn1-ber"
)
// debbuging type
// debugging type
// - has a Printf method to write the debug output
type debugging bool

View File

@@ -162,7 +162,7 @@ func newLogger(buffer int64) *Logger {
return l
}
// SetLogger sets new logger instanse with given logger adapter and config.
// SetLogger sets new logger instance with given logger adapter and config.
func (l *Logger) SetLogger(adapter string, config string) error {
l.lock.Lock()
defer l.lock.Unlock()

View File

@@ -1,844 +0,0 @@
package mahonia
import (
"fmt"
"sync"
)
// Converters for simple 8-bit character sets.
type eightBitInfo struct {
Name string
Aliases []string
// the character used for characters that can't be converted
SubstitutionChar byte
// a string containing all 256 characters, in order.
Repertoire string
// used to synchronize unpacking Repertoire into the conversion tables
once *sync.Once
// true if the first 128 characters are the same as US-ASCII
asciiCompatible bool
byte2char [256]rune
char2byte map[rune]byte
}
const asciiRepertoire = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f"
func (info *eightBitInfo) register() {
var cs Charset
cs.Name = info.Name
cs.Aliases = info.Aliases
info.once = new(sync.Once)
cs.NewDecoder = func() Decoder {
info.once.Do(func() { info.unpack() })
return func(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
c = info.byte2char[p[0]]
if c == 0xfffd {
status = INVALID_CHAR
} else {
status = SUCCESS
}
size = 1
return
}
}
cs.NewEncoder = func() Encoder {
info.once.Do(func() { info.unpack() })
return func(p []byte, c rune) (size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
if c < 128 && info.asciiCompatible {
p[0] = byte(c)
return 1, SUCCESS
}
b, ok := info.char2byte[c]
if !ok {
b = info.SubstitutionChar
status = INVALID_CHAR
} else {
status = SUCCESS
}
p[0] = b
size = 1
return
}
}
RegisterCharset(&cs)
}
func (info *eightBitInfo) unpack() {
info.asciiCompatible = info.Repertoire[:128] == asciiRepertoire
info.char2byte = make(map[rune]byte, 256)
i := 0
for _, c := range info.Repertoire {
info.byte2char[i] = c
if c != 0xfffd {
info.char2byte[c] = byte(i)
}
i++
}
if i != 256 {
panic(fmt.Errorf("%s has only %d characters", info.Name, i))
}
}
func init() {
for i := 0; i < len(eightBitCharsets); i++ {
eightBitCharsets[i].register()
}
}
var eightBitCharsets = []eightBitInfo{
{
Name: "ISO-8859-2",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u02d8\u0141\u00a4\u013d\u015a\u00a7\u00a8\u0160\u015e\u0164\u0179\u00ad\u017d\u017b\u00b0\u0105\u02db\u0142\u00b4\u013e\u015b\u02c7\u00b8\u0161\u015f\u0165\u017a\u02dd\u017e\u017c\u0154\u00c1\u00c2\u0102\u00c4\u0139\u0106\u00c7\u010c\u00c9\u0118\u00cb\u011a\u00cd\u00ce\u010e\u0110\u0143\u0147\u00d3\u00d4\u0150\u00d6\u00d7\u0158\u016e\u00da\u0170\u00dc\u00dd\u0162\u00df\u0155\u00e1\u00e2\u0103\u00e4\u013a\u0107\u00e7\u010d\u00e9\u0119\u00eb\u011b\u00ed\u00ee\u010f\u0111\u0144\u0148\u00f3\u00f4\u0151\u00f6\u00f7\u0159\u016f\u00fa\u0171\u00fc\u00fd\u0163\u02d9",
Aliases: []string{"ISO_8859-2:1987", "iso-ir-101", "latin2", "l2", "csISOLatin2"},
},
{
Name: "ISO-8859-3",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0126\u02d8\u00a3\u00a4\ufffd\u0124\u00a7\u00a8\u0130\u015e\u011e\u0134\u00ad\ufffd\u017b\u00b0\u0127\u00b2\u00b3\u00b4\u00b5\u0125\u00b7\u00b8\u0131\u015f\u011f\u0135\u00bd\ufffd\u017c\u00c0\u00c1\u00c2\ufffd\u00c4\u010a\u0108\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\ufffd\u00d1\u00d2\u00d3\u00d4\u0120\u00d6\u00d7\u011c\u00d9\u00da\u00db\u00dc\u016c\u015c\u00df\u00e0\u00e1\u00e2\ufffd\u00e4\u010b\u0109\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\ufffd\u00f1\u00f2\u00f3\u00f4\u0121\u00f6\u00f7\u011d\u00f9\u00fa\u00fb\u00fc\u016d\u015d\u02d9",
Aliases: []string{"ISO_8859-3:1988", "iso-ir-109", "latin3", "l3", "csISOLatin3"},
},
{
Name: "ISO-8859-4",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0138\u0156\u00a4\u0128\u013b\u00a7\u00a8\u0160\u0112\u0122\u0166\u00ad\u017d\u00af\u00b0\u0105\u02db\u0157\u00b4\u0129\u013c\u02c7\u00b8\u0161\u0113\u0123\u0167\u014a\u017e\u014b\u0100\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u012e\u010c\u00c9\u0118\u00cb\u0116\u00cd\u00ce\u012a\u0110\u0145\u014c\u0136\u00d4\u00d5\u00d6\u00d7\u00d8\u0172\u00da\u00db\u00dc\u0168\u016a\u00df\u0101\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u012f\u010d\u00e9\u0119\u00eb\u0117\u00ed\u00ee\u012b\u0111\u0146\u014d\u0137\u00f4\u00f5\u00f6\u00f7\u00f8\u0173\u00fa\u00fb\u00fc\u0169\u016b\u02d9",
Aliases: []string{"ISO_8859-4:1988", "iso-ir-110", "latin4", "l4", "csISOLatin4"},
},
{
Name: "ISO-8859-5",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u00ad\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u2116\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u00a7\u045e\u045f",
Aliases: []string{"ISO_8859-5:1988", "iso-ir-144", "cyrillic", "csISOLatinCyrillic"},
},
{
Name: "ISO-8859-6",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\ufffd\ufffd\u00a4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u060c\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u061b\ufffd\ufffd\ufffd\u061f\ufffd\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063a\ufffd\ufffd\ufffd\ufffd\ufffd\u0640\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u064b\u064c\u064d\u064e\u064f\u0650\u0651\u0652\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd",
Aliases: []string{"ISO_8859-6:1987", "iso-ir-127", "ECMA-114", "ASMO-708", "arabic", "csISOLatinArabic"},
},
{
Name: "ISO-8859-7",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u2018\u2019\u00a3\u20ac\u20af\u00a6\u00a7\u00a8\u00a9\u037a\u00ab\u00ac\u00ad\ufffd\u2015\u00b0\u00b1\u00b2\u00b3\u0384\u0385\u0386\u00b7\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd",
Aliases: []string{"ISO_8859-7:2003", "iso-ir-126", "ELOT_928", "ECMA-118", "greek", "greek8", "csISOLatinGreek"},
},
{
Name: "ISO-8859-8",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2017\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\u200e\u200f\ufffd",
Aliases: []string{"ISO_8859-8:1999", "iso-ir-138", "hebrew", "csISOLatinHebrew"},
},
{
Name: "ISO-8859-9",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u011e\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u0130\u015e\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u011f\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u0131\u015f\u00ff",
Aliases: []string{"ISO_8859-9:1999", "iso-ir-148", "latin5", "l5", "csISOLatin5"},
},
{
Name: "ISO-8859-10",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0112\u0122\u012a\u0128\u0136\u00a7\u013b\u0110\u0160\u0166\u017d\u00ad\u016a\u014a\u00b0\u0105\u0113\u0123\u012b\u0129\u0137\u00b7\u013c\u0111\u0161\u0167\u017e\u2015\u016b\u014b\u0100\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u012e\u010c\u00c9\u0118\u00cb\u0116\u00cd\u00ce\u00cf\u00d0\u0145\u014c\u00d3\u00d4\u00d5\u00d6\u0168\u00d8\u0172\u00da\u00db\u00dc\u00dd\u00de\u00df\u0101\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u012f\u010d\u00e9\u0119\u00eb\u0117\u00ed\u00ee\u00ef\u00f0\u0146\u014d\u00f3\u00f4\u00f5\u00f6\u0169\u00f8\u0173\u00fa\u00fb\u00fc\u00fd\u00fe\u0138",
Aliases: []string{"iso_8859-10:1992", "l6", "iso-ir-157", "latin6", "csISOLatin6"},
},
{
Name: "ISO-8859-11",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd",
Aliases: []string{"iso_8859-11:2001", "Latin/Thai", "TIS-620"},
},
{
Name: "ISO-8859-13",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u201d\u00a2\u00a3\u00a4\u201e\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u201c\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u2019",
Aliases: []string{"latin7", "Baltic Rim"},
},
{
Name: "ISO-8859-14",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u1e02\u1e03\u00a3\u010a\u010b\u1e0a\u00a7\u1e80\u00a9\u1e82\u1e0b\u1ef2\u00ad\u00ae\u0178\u1e1e\u1e1f\u0120\u0121\u1e40\u1e41\u00b6\u1e56\u1e81\u1e57\u1e83\u1e60\u1ef3\u1e84\u1e85\u1e61\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0174\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u1e6a\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u0176\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0175\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u1e6b\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u0177\u00ff",
Aliases: []string{"iso-ir-199", "ISO_8859-14:1998", "latin8", "iso-celtic", "l8"},
},
{
Name: "ISO-8859-15",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u20ac\u00a5\u0160\u00a7\u0161\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u017d\u00b5\u00b6\u00b7\u017e\u00b9\u00ba\u00bb\u0152\u0153\u0178\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff",
Aliases: []string{"Latin-9"},
},
{
Name: "ISO-8859-16",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0104\u0105\u0141\u20ac\u201e\u0160\u00a7\u0161\u00a9\u0218\u00ab\u0179\u00ad\u017a\u017b\u00b0\u00b1\u010c\u0142\u017d\u201d\u00b6\u00b7\u017e\u010d\u0219\u00bb\u0152\u0153\u0178\u017c\u00c0\u00c1\u00c2\u0102\u00c4\u0106\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0110\u0143\u00d2\u00d3\u00d4\u0150\u00d6\u015a\u0170\u00d9\u00da\u00db\u00dc\u0118\u021a\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u0107\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0111\u0144\u00f2\u00f3\u00f4\u0151\u00f6\u015b\u0171\u00f9\u00fa\u00fb\u00fc\u0119\u021b\u00ff",
Aliases: []string{"iso-ir-226", "ISO_8859-16:2001", "latin10", "l10"},
},
{
Name: "macos-0_2-10.2",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u00ff\u0178\u2044\u20ac\u2039\u203a\ufb01\ufb02\u2021\u00b7\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\u0131\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7",
Aliases: []string{"macos-0_2-10.2", "macintosh", "mac", "csMacintosh", "windows-10000", "macroman"},
},
{
Name: "macos-6_2-10.4",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00b9\u00b2\u00c9\u00b3\u00d6\u00dc\u0385\u00e0\u00e2\u00e4\u0384\u00a8\u00e7\u00e9\u00e8\u00ea\u00eb\u00a3\u2122\u00ee\u00ef\u2022\u00bd\u2030\u00f4\u00f6\u00a6\u20ac\u00f9\u00fb\u00fc\u2020\u0393\u0394\u0398\u039b\u039e\u03a0\u00df\u00ae\u00a9\u03a3\u03aa\u00a7\u2260\u00b0\u00b7\u0391\u00b1\u2264\u2265\u00a5\u0392\u0395\u0396\u0397\u0399\u039a\u039c\u03a6\u03ab\u03a8\u03a9\u03ac\u039d\u00ac\u039f\u03a1\u2248\u03a4\u00ab\u00bb\u2026\u00a0\u03a5\u03a7\u0386\u0388\u0153\u2013\u2015\u201c\u201d\u2018\u2019\u00f7\u0389\u038a\u038c\u038e\u03ad\u03ae\u03af\u03cc\u038f\u03cd\u03b1\u03b2\u03c8\u03b4\u03b5\u03c6\u03b3\u03b7\u03b9\u03be\u03ba\u03bb\u03bc\u03bd\u03bf\u03c0\u03ce\u03c1\u03c3\u03c4\u03b8\u03c9\u03c2\u03c7\u03c5\u03b6\u03ca\u03cb\u0390\u03b0\u00ad",
Aliases: []string{"macos-6_2-10.4", "x-mac-greek", "windows-10006", "macgr"},
},
{
Name: "macos-7_3-10.2",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u2020\u00b0\u0490\u00a3\u00a7\u2022\u00b6\u0406\u00ae\u00a9\u2122\u0402\u0452\u2260\u0403\u0453\u221e\u00b1\u2264\u2265\u0456\u00b5\u0491\u0408\u0404\u0454\u0407\u0457\u0409\u0459\u040a\u045a\u0458\u0405\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u040b\u045b\u040c\u045c\u0455\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u201e\u040e\u045e\u040f\u045f\u2116\u0401\u0451\u044f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u20ac",
Aliases: []string{"macos-7_3-10.2", "x-mac-cyrillic", "windows-10007", "mac-cyrillic", "maccy"},
},
{
Name: "macos-29-10.2",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u0100\u0101\u00c9\u0104\u00d6\u00dc\u00e1\u0105\u010c\u00e4\u010d\u0106\u0107\u00e9\u0179\u017a\u010e\u00ed\u010f\u0112\u0113\u0116\u00f3\u0117\u00f4\u00f6\u00f5\u00fa\u011a\u011b\u00fc\u2020\u00b0\u0118\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u0119\u00a8\u2260\u0123\u012e\u012f\u012a\u2264\u2265\u012b\u0136\u2202\u2211\u0142\u013b\u013c\u013d\u013e\u0139\u013a\u0145\u0146\u0143\u00ac\u221a\u0144\u0147\u2206\u00ab\u00bb\u2026\u00a0\u0148\u0150\u00d5\u0151\u014c\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u014d\u0154\u0155\u0158\u2039\u203a\u0159\u0156\u0157\u0160\u201a\u201e\u0161\u015a\u015b\u00c1\u0164\u0165\u00cd\u017d\u017e\u016a\u00d3\u00d4\u016b\u016e\u00da\u016f\u0170\u0171\u0172\u0173\u00dd\u00fd\u0137\u017b\u0141\u017c\u0122\u02c7",
Aliases: []string{"macos-29-10.2", "x-mac-centraleurroman", "windows-10029", "x-mac-ce", "macce", "maccentraleurope"},
},
{
Name: "macos-35-10.2",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca\u00ff\u0178\u011e\u011f\u0130\u0131\u015e\u015f\u2021\u00b7\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\uf8a0\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7",
Aliases: []string{"macos-35-10.2", "x-mac-turkish", "windows-10081", "mactr"},
},
{
Name: "windows-1250",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\ufffd\u201e\u2026\u2020\u2021\ufffd\u2030\u0160\u2039\u015a\u0164\u017d\u0179\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\u0161\u203a\u015b\u0165\u017e\u017a\u00a0\u02c7\u02d8\u0141\u00a4\u0104\u00a6\u00a7\u00a8\u00a9\u015e\u00ab\u00ac\u00ad\u00ae\u017b\u00b0\u00b1\u02db\u0142\u00b4\u00b5\u00b6\u00b7\u00b8\u0105\u015f\u00bb\u013d\u02dd\u013e\u017c\u0154\u00c1\u00c2\u0102\u00c4\u0139\u0106\u00c7\u010c\u00c9\u0118\u00cb\u011a\u00cd\u00ce\u010e\u0110\u0143\u0147\u00d3\u00d4\u0150\u00d6\u00d7\u0158\u016e\u00da\u0170\u00dc\u00dd\u0162\u00df\u0155\u00e1\u00e2\u0103\u00e4\u013a\u0107\u00e7\u010d\u00e9\u0119\u00eb\u011b\u00ed\u00ee\u010f\u0111\u0144\u0148\u00f3\u00f4\u0151\u00f6\u00f7\u0159\u016f\u00fa\u0171\u00fc\u00fd\u0163\u02d9",
},
{
Name: "windows-1251",
Aliases: []string{"CP1251"},
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0402\u0403\u201a\u0453\u201e\u2026\u2020\u2021\u20ac\u2030\u0409\u2039\u040a\u040c\u040b\u040f\u0452\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\u0459\u203a\u045a\u045c\u045b\u045f\u00a0\u040e\u045e\u0408\u00a4\u0490\u00a6\u00a7\u0401\u00a9\u0404\u00ab\u00ac\u00ad\u00ae\u0407\u00b0\u00b1\u0406\u0456\u0491\u00b5\u00b6\u00b7\u0451\u2116\u0454\u00bb\u0458\u0405\u0455\u0457\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f",
},
{
Name: "windows-1252",
Aliases: []string{"cp1252"},
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0160\u2039\u0152\ufffd\u017d\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u0161\u203a\u0153\ufffd\u017e\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff",
},
{
Name: "windows-1253",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\ufffd\u2030\ufffd\u2039\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\ufffd\u203a\ufffd\ufffd\ufffd\ufffd\u00a0\u0385\u0386\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\ufffd\u00ab\u00ac\u00ad\u00ae\u2015\u00b0\u00b1\u00b2\u00b3\u0384\u00b5\u00b6\u00b7\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd",
},
{
Name: "windows-1254",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0160\u2039\u0152\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u0161\u203a\u0153\ufffd\ufffd\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u011e\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u0130\u015e\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u011f\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u0131\u015f\u00ff",
},
{
Name: "windows-1255",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\ufffd\u2039\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\ufffd\u203a\ufffd\ufffd\ufffd\ufffd\u00a0\u00a1\u00a2\u00a3\u20aa\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\u00bf\u05b0\u05b1\u05b2\u05b3\u05b4\u05b5\u05b6\u05b7\u05b8\u05b9\ufffd\u05bb\u05bc\u05bd\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05f0\u05f1\u05f2\u05f3\u05f4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\u200e\u200f\ufffd",
},
{
Name: "windows-1256",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\u067e\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0679\u2039\u0152\u0686\u0698\u0688\u06af\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u06a9\u2122\u0691\u203a\u0153\u200c\u200d\u06ba\u00a0\u060c\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u06be\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u061b\u00bb\u00bc\u00bd\u00be\u061f\u06c1\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u00d7\u0637\u0638\u0639\u063a\u0640\u0641\u0642\u0643\u00e0\u0644\u00e2\u0645\u0646\u0647\u0648\u00e7\u00e8\u00e9\u00ea\u00eb\u0649\u064a\u00ee\u00ef\u064b\u064c\u064d\u064e\u00f4\u064f\u0650\u00f7\u0651\u00f9\u0652\u00fb\u00fc\u200e\u200f\u06d2",
},
{
Name: "windows-1257",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\ufffd\u201e\u2026\u2020\u2021\ufffd\u2030\ufffd\u2039\ufffd\u00a8\u02c7\u00b8\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\ufffd\u203a\ufffd\u00af\u02db\ufffd\u00a0\ufffd\u00a2\u00a3\u00a4\ufffd\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u02d9",
},
{
Name: "windows-1258",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\ufffd\u2039\u0152\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\ufffd\u203a\u0153\ufffd\ufffd\u0178\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u0102\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u0300\u00cd\u00ce\u00cf\u0110\u00d1\u0309\u00d3\u00d4\u01a0\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u01af\u0303\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u0301\u00ed\u00ee\u00ef\u0111\u00f1\u0323\u00f3\u00f4\u01a1\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u01b0\u20ab\u00ff",
},
{
Name: "windows-874",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\ufffd\ufffd\ufffd\ufffd\u2026\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd",
},
{
Name: "IBM037",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"cp037", "ebcdic-cp-us", "ebcdic-cp-ca", "ebcdic-cp-wt", "ebcdic-cp-nl", "csIBM037"},
},
{
Name: "ibm-273_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00c4.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec~\u00dc$*);^-/\u00c2[\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00dfstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00fcJKLMNOPQR\u00b9\u00fb}\u00f9\u00fa\u00ff\u00d6\u00f7STUVWXYZ\u00b2\u00d4\\\u00d2\u00d3\u00d50123456789\u00b3\u00db]\u00d9\u00da\u009f",
Aliases: []string{"ibm-273_P100-1995", "ibm-273", "IBM273", "CP273", "csIBM273", "ebcdic-de", "273"},
},
{
Name: "ibm-277_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3}\u00e7\u00f1#.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f8,%_>?\u00a6\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00c6\u00d8'=\"@abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba{\u00b8[]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e6ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-277_P100-1995", "ibm-277", "IBM277", "cp277", "EBCDIC-CP-DK", "EBCDIC-CP-NO", "csIBM277", "ebcdic-dk", "277"},
},
{
Name: "ibm-278_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-278_P100-1995", "ibm-278", "IBM278", "cp278", "ebcdic-cp-fi", "ebcdic-cp-se", "csIBM278", "ebcdic-sv", "278"},
},
{
Name: "ibm-280_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4{\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&]\u00ea\u00eb}\u00ed\u00ee\u00ef~\u00df\u00e9$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f2,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f9:\u00a3\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00ecstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e0ABCDEFGHI\u00ad\u00f4\u00f6\u00a6\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc`\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-280_P100-1995", "ibm-280", "IBM280", "CP280", "ebcdic-cp-it", "csIBM280", "280"},
},
{
Name: "ibm-284_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00a6[.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7#\u00f1,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00d1@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^!\u00af~\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-284_P100-1995", "ibm-284", "IBM284", "CP284", "ebcdic-cp-es", "csIBM284", "cpibm284", "284"},
},
{
Name: "ibm-285_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1$.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!\u00a3*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00afstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2[\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^]~\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-285_P100-1995", "ibm-285", "IBM285", "CP285", "ebcdic-cp-gb", "csIBM285", "cpibm285", "ebcdic-gb", "285"},
},
{
Name: "ibm-290_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\uff69\u00a3.<(+|&\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\ufffd\uff70\ufffd!\u00a5*);\u00ac-/abcdefgh\ufffd,%_>?[ijklmnop`:#@'=\"]\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\uff7aq\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82\uff83\uff84\uff85\uff86\uff87\uff88\uff89r\ufffd\uff8a\uff8b\uff8c~\u203e\uff8d\uff8e\uff8f\uff90\uff91\uff92\uff93\uff94\uff95s\uff96\uff97\uff98\uff99^\u00a2\\tuvwxyz\uff9a\uff9b\uff9c\uff9d\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f",
Aliases: []string{"ibm-290_P100-1995", "ibm-290", "IBM290", "cp290", "EBCDIC-JP-kana", "csIBM290"},
},
{
Name: "ibm-297_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4@\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&{\u00ea\u00eb}\u00ed\u00ee\u00ef\u00ec\u00df\u00a7$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f9,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00b5:\u00a3\u00e0'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4`\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9]\u00b6\u00bc\u00bd\u00be\u00ac|\u00af~\u00b4\u00d7\u00e9ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc\u00a6\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-297_P100-1995", "ibm-297", "IBM297", "cp297", "ebcdic-cp-fr", "csIBM297", "cpibm297", "297"},
},
{
Name: "ibm-420_X120-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0651\ufe7d\u0640\u200b\u0621\u0622\ufe82\u0623\u00a2.<(+|&\ufe84\u0624\ufffd\ufffd\u0626\u0627\ufe8e\u0628\ufe91!$*);\u00ac-/\u0629\u062a\ufe97\u062b\ufe9b\u062c\ufe9f\u062d\u00a6,%_>?\ufea3\u062e\ufea7\u062f\u0630\u0631\u0632\u0633\ufeb3\u060c:#@'=\"\u0634abcdefghi\ufeb7\u0635\ufebb\u0636\ufebf\u0637\u0638jklmnopqr\u0639\ufeca\ufecb\ufecc\u063a\ufece\ufecf\u00f7stuvwxyz\ufed0\u0641\ufed3\u0642\ufed7\u0643\ufedb\u0644\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\u0645\ufee3\u0646\ufee7\u0647\u061bABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\u0648\u061fJKLMNOPQR\u0649\ufef0\u064a\ufef2\ufef3\u0660\u00d7\ufffdSTUVWXYZ\u0661\u0662\ufffd\u0663\u0664\u06650123456789\ufffd\u0666\u0667\u0668\u0669\u009f",
Aliases: []string{"ibm-420_X120-1999", "ibm-420", "IBM420", "cp420", "ebcdic-cp-ar1", "csIBM420", "420"},
},
{
Name: "IBM424",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u00a2.<(+|&\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1!$*);\u00ac-/\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u00a6,%_>?\ufffd\u05ea\ufffd\ufffd\u00a0\ufffd\ufffd\ufffd\u2017`:#@'=\"\ufffdabcdefghi\u00ab\u00bb\ufffd\ufffd\ufffd\u00b1\u00b0jklmnopqr\ufffd\ufffd\ufffd\u00b8\ufffd\u00a4\u00b5~stuvwxyz\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\u00b9\ufffd\ufffd\ufffd\ufffd\ufffd\\\u00f7STUVWXYZ\u00b2\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\u00b3\ufffd\ufffd\ufffd\ufffd\u009f",
Aliases: []string{"cp424", "ebcdic-cp-he", "csIBM424"},
},
{
Name: "IBM437",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00a2\u00a3\u00a5\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u00b5\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"cp437", "437", "csPC8CodePage437"},
},
{
Name: "IBM500",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"CP500", "ebcdic-cp-be", "ebcdic-cp-ch", "csIBM500"},
},
{
Name: "ibm-720_P100-1997",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\u00e9\u00e2\ufffd\u00e0\ufffd\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\ufffd\ufffd\ufffd\ufffd\u0651\u0652\u00f4\u00a4\u0640\u00fb\u00f9\u0621\u0622\u0623\u0624\u00a3\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0636\u0637\u0638\u0639\u063a\u0641\u00b5\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u2261\u064b\u064c\u064d\u064e\u064f\u0650\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-720_P100-1997", "ibm-720", "windows-720", "DOS-720"},
},
{
Name: "IBM737",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03c9\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u0386\u0388\u0389\u038a\u038c\u038e\u038f\u00b1\u2265\u2264\u03aa\u03ab\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"cp737", "cp737_DOSGreek"},
},
{
Name: "IBM775",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0106\u00fc\u00e9\u0101\u00e4\u0123\u00e5\u0107\u0142\u0113\u0156\u0157\u012b\u0179\u00c4\u00c5\u00c9\u00e6\u00c6\u014d\u00f6\u0122\u00a2\u015a\u015b\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u00a4\u0100\u012a\u00f3\u017b\u017c\u017a\u201d\u00a6\u00a9\u00ae\u00ac\u00bd\u00bc\u0141\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u0104\u010c\u0118\u0116\u2563\u2551\u2557\u255d\u012e\u0160\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u0172\u016a\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u017d\u0105\u010d\u0119\u0117\u012f\u0161\u0173\u016b\u017e\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u00d3\u00df\u014c\u0143\u00f5\u00d5\u00b5\u0144\u0136\u0137\u013b\u013c\u0146\u0112\u0145\u2019\u00ad\u00b1\u201c\u00be\u00b6\u00a7\u00f7\u201e\u00b0\u2219\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0",
Aliases: []string{"cp775", "csPC775Baltic"},
},
{
Name: "ibm-803_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$.<(+|\u05d0\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd!\u00a2*);\u00ac-/\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd,%_>?\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd:#@'=\"\ufffd\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdJKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f",
Aliases: []string{"ibm-803_P100-1999", "ibm-803", "cp803"},
},
{
Name: "ibm-838_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07[\u00a2.<(+|&\u0e48\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e]!$*);\u00ac-/\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15^\u00a6,%_>?\u0e3f\u0e4e\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c`:#@'=\"\u0e4fabcdefghi\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e5ajklmnopqr\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e5b~stuvwxyz\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34{ABCDEFGHI\u0e49\u0e35\u0e36\u0e37\u0e38\u0e39}JKLMNOPQR\u0e3a\u0e40\u0e41\u0e42\u0e43\u0e44\\\u0e4aSTUVWXYZ\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a0123456789\u0e4b\u0e4c\u0e4d\u0e4b\u0e4c\u009f",
Aliases: []string{"ibm-838_P100-1995", "ibm-838", "IBM838", "IBM-Thai", "csIBMThai", "cp838", "838", "ibm-9030"},
},
{
Name: "IBM850",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00f0\u00d0\u00ca\u00cb\u00c8\u0131\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\u00fe\u00de\u00da\u00db\u00d9\u00fd\u00dd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0",
Aliases: []string{"cp850", "850", "csPC850Multilingual"},
},
{
Name: "ibm-851_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u0386\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u0388\u00c4\u0389\u038a\ufffd\u038c\u00f4\u00f6\u038e\u00fb\u00f9\u038f\u00d6\u00dc\u03ac\u00a3\u03ad\u03ae\u03af\u03ca\u0390\u03cc\u03cd\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u00bd\u0398\u0399\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u039a\u039b\u039c\u039d\u2563\u2551\u2557\u255d\u039e\u039f\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u03a0\u03a1\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u2518\u250c\u2588\u2584\u03b4\u03b5\u2580\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u00b4\u00ad\u00b1\u03c5\u03c6\u03c7\u00a7\u03c8\u00b8\u00b0\u00a8\u03c9\u03cb\u03b0\u03ce\u25a0\u00a0",
Aliases: []string{"ibm-851_P100-1995", "ibm-851", "IBM851", "cp851", "851", "csPC851"},
},
{
Name: "IBM852",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u00c7\u00fc\u00e9\u00e2\u00e4\u016f\u0107\u00e7\u0142\u00eb\u0150\u0151\u00ee\u0179\u00c4\u0106\u00c9\u0139\u013a\u00f4\u00f6\u013d\u013e\u015a\u015b\u00d6\u00dc\u0164\u0165\u0141\u00d7\u010d\u00e1\u00ed\u00f3\u00fa\u0104\u0105\u017d\u017e\u0118\u0119\u00ac\u017a\u010c\u015f\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u011a\u015e\u2563\u2551\u2557\u255d\u017b\u017c\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u0102\u0103\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u0111\u0110\u010e\u00cb\u010f\u0147\u00cd\u00ce\u011b\u2518\u250c\u2588\u2584\u0162\u016e\u2580\u00d3\u00df\u00d4\u0143\u0144\u0148\u0160\u0161\u0154\u00da\u0155\u0170\u00fd\u00dd\u0163\u00b4\u00ad\u02dd\u02db\u02c7\u02d8\u00a7\u00f7\u00b8\u00b0\u00a8\u02d9\u0171\u0158\u0159\u25a0\u00a0",
Aliases: []string{"cp852", "852", "csPCp852"},
},
{
Name: "IBM855",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0452\u0402\u0453\u0403\u0451\u0401\u0454\u0404\u0455\u0405\u0456\u0406\u0457\u0407\u0458\u0408\u0459\u0409\u045a\u040a\u045b\u040b\u045c\u040c\u045e\u040e\u045f\u040f\u044e\u042e\u044a\u042a\u0430\u0410\u0431\u0411\u0446\u0426\u0434\u0414\u0435\u0415\u0444\u0424\u0433\u0413\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u0445\u0425\u0438\u0418\u2563\u2551\u2557\u255d\u0439\u0419\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u043a\u041a\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u043b\u041b\u043c\u041c\u043d\u041d\u043e\u041e\u043f\u2518\u250c\u2588\u2584\u041f\u044f\u2580\u042f\u0440\u0420\u0441\u0421\u0442\u0422\u0443\u0423\u0436\u0416\u0432\u0412\u044c\u042c\u2116\u00ad\u044b\u042b\u0437\u0417\u0448\u0428\u044d\u042d\u0449\u0429\u0447\u0427\u00a7\u25a0\u00a0",
Aliases: []string{"cp855", "855", "csIBM855"},
},
{
Name: "IBM856",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\u00a3\ufffd\u00d7\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae\u00ac\u00bd\u00bc\ufffd\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufffd\ufffd\ufffd\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufffd\ufffd\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2518\u250c\u2588\u2584\u00a6\ufffd\u2580\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00b5\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0",
Aliases: []string{"cp856", "cp856_Hebrew_PC"},
},
{
Name: "ibm-857_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u0131\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u0130\u00d6\u00dc\u00f8\u00a3\u00d8\u015e\u015f\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u011e\u011f\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00ba\u00aa\u00ca\u00cb\u00c8\ufffd\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\ufffd\u00d7\u00da\u00db\u00d9\u00ec\u00ff\u00af\u00b4\u00ad\u00b1\ufffd\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-857_P100-1995", "ibm-857", "IBM857", "cp857", "857", "csIBM857", "windows-857"},
},
{
Name: "ibm-858_P100-1997",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u00c1\u00c2\u00c0\u00a9\u2563\u2551\u2557\u255d\u00a2\u00a5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u00e3\u00c3\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u00a4\u00f0\u00d0\u00ca\u00cb\u00c8\u20ac\u00cd\u00ce\u00cf\u2518\u250c\u2588\u2584\u00a6\u00cc\u2580\u00d3\u00df\u00d4\u00d2\u00f5\u00d5\u00b5\u00fe\u00de\u00da\u00db\u00d9\u00fd\u00dd\u00af\u00b4\u00ad\u00b1\u2017\u00be\u00b6\u00a7\u00f7\u00b8\u00b0\u00a8\u00b7\u00b9\u00b3\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-858_P100-1997", "ibm-858", "IBM00858", "CCSID00858", "CP00858", "PC-Multilingual-850+euro", "cp858", "windows-858"},
},
{
Name: "ibm-860_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e3\u00e0\u00c1\u00e7\u00ea\u00ca\u00e8\u00cd\u00d4\u00ec\u00c3\u00c2\u00c9\u00c0\u00c8\u00f4\u00f5\u00f2\u00da\u00f9\u00cc\u00d5\u00dc\u00a2\u00a3\u00d9\u20a7\u00d3\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00d2\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-860_P100-1995", "ibm-860", "IBM860", "cp860", "860", "csIBM860"},
},
{
Name: "ibm-861_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00d0\u00f0\u00de\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00fe\u00fb\u00dd\u00fd\u00d6\u00dc\u00f8\u00a3\u00d8\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00c1\u00cd\u00d3\u00da\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-861_P100-1995", "ibm-861", "IBM861", "cp861", "861", "cp-is", "csIBM861", "windows-861"},
},
{
Name: "ibm-862_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u00a2\u00a3\u00a5\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-862_P100-1995", "ibm-862", "IBM862", "cp862", "862", "csPC862LatinHebrew", "DOS-862", "windows-862"},
},
{
Name: "ibm-863_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00c2\u00e0\u00b6\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u2017\u00c0\u00a7\u00c9\u00c8\u00ca\u00f4\u00cb\u00cf\u00fb\u00f9\u00a4\u00d4\u00dc\u00a2\u00a3\u00d9\u00db\u0192\u00a6\u00b4\u00f3\u00fa\u00a8\u00b8\u00b3\u00af\u00ce\u2310\u00ac\u00bd\u00bc\u00be\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-863_P100-1995", "ibm-863", "IBM863", "cp863", "863", "csIBM863"},
},
{
Name: "ibm-864_X110-1999",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00b0\u00b7\u2219\u221a\u2592\u2500\u2502\u253c\u2524\u252c\u251c\u2534\u2510\u250c\u2514\u2518\u03b2\u221e\u03c6\u00b1\u00bd\u00bc\u2248\u00ab\u00bb\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\u200b\u00a0\u00ad\ufe82\u00a3\u00a4\ufe84\ufffd\ufffd\ufe8e\ufe8f\ufe95\ufe99\u060c\ufe9d\ufea1\ufea5\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\ufed1\u061b\ufeb1\ufeb5\ufeb9\u061f\u00a2\ufe80\ufe81\ufe83\ufe85\ufeca\ufe8b\ufe8d\ufe91\ufe93\ufe97\ufe9b\ufe9f\ufea3\ufea7\ufea9\ufeab\ufead\ufeaf\ufeb3\ufeb7\ufebb\ufebf\ufec3\ufec7\ufecb\ufecf\u00a6\u00ac\u00f7\u00d7\ufec9\u0640\ufed3\ufed7\ufedb\ufedf\ufee3\ufee7\ufeeb\ufeed\ufeef\ufef3\ufebd\ufecc\ufece\ufecd\ufee1\ufe7d\ufe7c\ufee5\ufee9\ufeec\ufef0\ufef2\ufed0\ufed5\ufef5\ufef6\ufedd\ufed9\ufef1\u25a0\ufffd",
Aliases: []string{"ibm-864_X110-1999", "ibm-864", "IBM864", "cp864", "csIBM864"},
},
{
Name: "ibm-865_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u20a7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00a4\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-865_P100-1995", "ibm-865", "IBM865", "cp865", "865", "csIBM865"},
},
{
Name: "IBM866",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0404\u0454\u0407\u0457\u040e\u045e\u00b0\u2219\u00b7\u221a\u2116\u00a4\u25a0\u00a0",
Aliases: []string{"cp866", "866", "csIBM866"},
},
{
Name: "ibm-867_P100-1998",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u00a2\u00a3\u00a5\ufffd\u20aa\u200e\u200f\u202a\u202b\u202d\u202e\u202c\ufffd\ufffd\u2310\u00ac\u00bd\u00bc\u20ac\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0",
Aliases: []string{"ibm-867_P100-1998", "ibm-867"},
},
{
Name: "ibm-868_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u061b\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufeb7\ufeb9\ufebb\ufebd\u2563\u2551\u2557\u255d\ufebf\ufec3\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufec7\ufec9\u255a\u2554\u2569\u2566\u2560\u2550\u256c\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\u2518\u250c\u2588\u2584\ufed7\ufb8e\u2580\ufedb\ufb92\ufb94\ufedd\ufedf\ufee0\ufee1\ufee3\ufb9e\ufee5\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\u00ad\ufbaa\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd\ufbfe\ufbb0\ufbae\ufe7c\ufe7d\ufffd\u25a0\u00a0",
Aliases: []string{"ibm-868_P100-1995", "ibm-868", "IBM868", "CP868", "868", "csIBM868", "cp-ar"},
},
{
Name: "ibm-869_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0386\ufffd\u0387\u00ac\u00a6\u2018\u2019\u0388\u2015\u0389\u038a\u03aa\u038c\ufffd\ufffd\u038e\u03ab\u00a9\u038f\u00b2\u00b3\u03ac\u00a3\u03ad\u03ae\u03af\u03ca\u0390\u03cc\u03cd\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u00bd\u0398\u0399\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u039a\u039b\u039c\u039d\u2563\u2551\u2557\u255d\u039e\u039f\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u03a0\u03a1\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u2518\u250c\u2588\u2584\u03b4\u03b5\u2580\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u00b4\u00ad\u00b1\u03c5\u03c6\u03c7\u00a7\u03c8\u0385\u00b0\u00a8\u03c9\u03cb\u03b0\u03ce\u25a0\u00a0",
Aliases: []string{"ibm-869_P100-1995", "ibm-869", "IBM869", "cp869", "869", "cp-gr", "csIBM869", "windows-869"},
},
{
Name: "ibm-870_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u0163\u00e1\u0103\u010d\u00e7\u0107[.<(+!&\u00e9\u0119\u00eb\u016f\u00ed\u00ee\u013e\u013a\u00df]$*);^-/\u00c2\u00c4\u02dd\u00c1\u0102\u010c\u00c7\u0106|,%_>?\u02c7\u00c9\u0118\u00cb\u016e\u00cd\u00ce\u013d\u0139`:#@'=\"\u02d8abcdefghi\u015b\u0148\u0111\u00fd\u0159\u015f\u00b0jklmnopqr\u0142\u0144\u0161\u00b8\u02db\u00a4\u0105~stuvwxyz\u015a\u0147\u0110\u00dd\u0158\u015e\u02d9\u0104\u017c\u0162\u017b\u00a7\u017e\u017a\u017d\u0179\u0141\u0143\u0160\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u0155\u00f3\u0151}JKLMNOPQR\u011a\u0171\u00fc\u0165\u00fa\u011b\\\u00f7STUVWXYZ\u010f\u00d4\u00d6\u0154\u00d3\u01500123456789\u010e\u0170\u00dc\u0164\u00da\u009f",
Aliases: []string{"ibm-870_P100-1995", "ibm-870", "IBM870", "CP870", "ebcdic-cp-roece", "ebcdic-cp-yu", "csIBM870"},
},
{
Name: "ibm-871_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00de.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00c6$*);\u00d6-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f0:#\u00d0'=\"\u00d8abcdefghi\u00ab\u00bb`\u00fd{\u00b1\u00b0jklmnopqr\u00aa\u00ba}\u00b8]\u00a4\u00b5\u00f6stuvwxyz\u00a1\u00bf@\u00dd[\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\\\u00d7\u00feABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u00e6JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\u00b4\u00f7STUVWXYZ\u00b2\u00d4^\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-871_P100-1995", "ibm-871", "IBM871", "ebcdic-cp-is", "csIBM871", "CP871", "ebcdic-is", "871"},
},
{
Name: "ibm-874_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0e48\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\u0e49\u0e4a\u0e4b\u0e4c\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\u00a2\u00ac\u00a6\u00a0",
Aliases: []string{"ibm-874_P100-1995", "ibm-874", "ibm-9066", "cp874", "tis620.2533", "eucTH"},
},
{
Name: "ibm-875_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\ufffdSTUVWXYZ\u00b2\u00a7\ufffd\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\ufffd\ufffd\u00bb\u009f",
Aliases: []string{"ibm-875_P100-1995", "ibm-875", "IBM875", "cp875", "875"},
},
{
Name: "ibm-901_P100-1999",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u201d\u00a2\u00a3\u20ac\u201e\u00a6\u00a7\u00d8\u00a9\u0156\u00ab\u00ac\u00ad\u00ae\u00c6\u00b0\u00b1\u00b2\u00b3\u201c\u00b5\u00b6\u00b7\u00f8\u00b9\u0157\u00bb\u00bc\u00bd\u00be\u00e6\u0104\u012e\u0100\u0106\u00c4\u00c5\u0118\u0112\u010c\u00c9\u0179\u0116\u0122\u0136\u012a\u013b\u0160\u0143\u0145\u00d3\u014c\u00d5\u00d6\u00d7\u0172\u0141\u015a\u016a\u00dc\u017b\u017d\u00df\u0105\u012f\u0101\u0107\u00e4\u00e5\u0119\u0113\u010d\u00e9\u017a\u0117\u0123\u0137\u012b\u013c\u0161\u0144\u0146\u00f3\u014d\u00f5\u00f6\u00f7\u0173\u0142\u015b\u016b\u00fc\u017c\u017e\u2019",
Aliases: []string{"ibm-901_P100-1999", "ibm-901"},
},
{
Name: "ibm-902_P100-1999",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u20ac\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0160\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u017d\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0161\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u017e\u00ff",
Aliases: []string{"ibm-902_P100-1999", "ibm-902"},
},
{
Name: "ibm-916_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\ufffd\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00d7\u00ab\u00ac\u00ad\u00ae\u203e\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u2022\u00b8\u00b9\u00f7\u00bb\u00bc\u00bd\u00be\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u2017\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd",
Aliases: []string{"ibm-916_P100-1995", "ibm-916", "cp916", "916"},
},
{
Name: "ibm-918_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u060c\u061b\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f[.<(+!&\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99]$*);^-/\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5`,%_>?\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9:#@'=\"\ufea7abcdefghi\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8ajklmnopqr\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\ufebd~stuvwxyz\ufebf\ufec3\ufec7\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb|\ufb92\ufb94\ufedd\ufedf{ABCDEFGHI\u00ad\ufee0\ufee1\ufee3\ufb9e\ufee5}JKLMNOPQR\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\\\ufbaaSTUVWXYZ\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd0123456789\ufbfe\ufbb0\ufbae\ufe7c\ufe7d\u009f",
Aliases: []string{"ibm-918_P100-1995", "ibm-918", "IBM918", "CP918", "ebcdic-cp-ar2", "csIBM918"},
},
{
Name: "ibm-922_P100-1999",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0160\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u017d\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0161\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u017e\u00ff",
Aliases: []string{"ibm-922_P100-1999", "ibm-922", "IBM922", "cp922", "922"},
},
{
Name: "ibm-1006_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u061b\u00ad\u061f\ufe81\ufe8d\ufe8e\uf8fb\ufe8f\ufe91\ufb56\ufb58\ufe93\ufe95\ufe97\ufb66\ufb68\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufb88\ufeab\ufead\ufb8c\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\ufebd\ufebf\ufec3\ufec7\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb\ufb92\ufb94\ufedd\ufedf\ufee0\ufee1\ufee3\ufb9e\ufee5\ufee7\ufe85\ufeed\ufba6\ufba8\ufba9\ufbaa\ufe80\ufe89\ufe8a\ufe8b\ufbfc\ufbfd\ufbfe\ufbb0\ufbae\ufe7c\ufe7d",
Aliases: []string{"ibm-1006_P100-1995", "ibm-1006", "IBM1006", "cp1006", "1006"},
},
{
Name: "ibm-1025_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0453\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0403\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u00a7STUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f",
Aliases: []string{"ibm-1025_P100-1995", "ibm-1025", "cp1025", "1025"},
},
{
Name: "ibm-1026_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5{\u00f1\u00c7.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u011e\u0130*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5[\u00d1\u015f,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u0131:\u00d6\u015e'=\u00dc\u00d8abcdefghi\u00ab\u00bb}`\u00a6\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5\u00f6stuvwxyz\u00a1\u00bf]$@\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e7ABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u011fJKLMNOPQR\u00b9\u00fb\\\u00f9\u00fa\u00ff\u00fc\u00f7STUVWXYZ\u00b2\u00d4#\u00d2\u00d3\u00d50123456789\u00b3\u00db\"\u00d9\u00da\u009f",
Aliases: []string{"ibm-1026_P100-1995", "ibm-1026", "IBM1026", "CP1026", "csIBM1026", "1026"},
},
{
Name: "ibm-1047_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u00d0[\u00de\u00ae\u00ac\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00dd\u00a8\u00af]\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1047_P100-1995", "ibm-1047", "IBM1047", "cp1047", "1047"},
},
{
Name: "ibm-1097_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u060c\u064b\ufe81\ufe82\uf8fa\ufe8d\ufe8e\uf8fb\u00a4.<(+|&\ufe80\ufe83\ufe84\uf8f9\ufe85\ufe8b\ufe8f\ufe91\ufb56!$*);\u00ac-/\ufb58\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\u061b,%_>?\ufb7c\ufea1\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf`:#@'=\"\ufb8aabcdefghi\u00ab\u00bb\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9jklmnopqr\ufebb\ufebd\ufebf\ufec1\ufec3\ufec5\ufec7~stuvwxyz\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\ufed5\ufed7\ufb8e\ufedb\ufb92\ufb94[]\ufedd\ufedf\ufee1\u00d7{ABCDEFGHI\u00ad\ufee3\ufee5\ufee7\ufeed\ufee9}JKLMNOPQR\ufeeb\ufeec\ufba4\ufbfc\ufbfd\ufbfe\\\u061fSTUVWXYZ\u0640\u06f0\u06f1\u06f2\u06f3\u06f40123456789\u06f5\u06f6\u06f7\u06f8\u06f9\u009f",
Aliases: []string{"ibm-1097_P100-1995", "ibm-1097", "cp1097", "1097"},
},
{
Name: "ibm-1098_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\ufffd\ufffd\u060c\u061b\u061f\u064b\ufe81\ufe82\uf8fa\ufe8d\ufe8e\uf8fb\ufe80\ufe83\ufe84\uf8f9\ufe85\ufe8b\ufe8f\ufe91\ufb56\ufb58\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufb7a\ufb7c\u00d7\ufea1\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf\ufb8a\ufeb1\ufeb3\ufeb5\ufeb7\ufeb9\ufebb\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\ufebd\ufebf\ufec1\ufec3\u2563\u2551\u2557\u255d\u00a4\ufec5\u2510\u2514\u2534\u252c\u251c\u2500\u253c\ufec7\ufec9\u255a\u2554\u2569\u2566\u2560\u2550\u256c\ufffd\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1\ufed3\u2518\u250c\u2588\u2584\ufed5\ufed7\u2580\ufb8e\ufedb\ufb92\ufb94\ufedd\ufedf\ufee1\ufee3\ufee5\ufee7\ufeed\ufee9\ufeeb\ufeec\ufba4\ufbfc\u00ad\ufbfd\ufbfe\u0640\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u25a0\u00a0",
Aliases: []string{"ibm-1098_P100-1995", "ibm-1098", "IBM1098", "cp1098", "1098"},
},
{
Name: "ibm-1112_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0161\u00e4\u0105\u012f\u016b\u00e5\u0113\u017e\u00a2.<(+|&\u00e9\u0119\u0117\u010d\u0173\u201e\u201c\u0123\u00df!$*);\u00ac-/\u0160\u00c4\u0104\u012e\u016a\u00c5\u0112\u017d\u00a6,%_>?\u00f8\u00c9\u0118\u0116\u010c\u0172\u012a\u013b\u0122`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0101\u017c\u0144\u00b1\u00b0jklmnopqr\u0156\u0157\u00e6\u0137\u00c6\u00a4\u00b5~stuvwxyz\u201d\u017a\u0100\u017b\u0143\u00ae^\u00a3\u012b\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u0179\u0136\u013c\u00d7{ABCDEFGHI\u00ad\u014d\u00f6\u0146\u00f3\u00f5}JKLMNOPQR\u00b9\u0107\u00fc\u0142\u015b\u2019\\\u00f7STUVWXYZ\u00b2\u014c\u00d6\u0145\u00d3\u00d50123456789\u00b3\u0106\u00dc\u0141\u015a\u009f",
Aliases: []string{"ibm-1112_P100-1995", "ibm-1112", "cp1112", "1112"},
},
{
Name: "ibm-1122_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00a4\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u0161\u00fd\u017e\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u0160\u00dd\u017d\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1122_P100-1999", "ibm-1122", "cp1122", "1122"},
},
{
Name: "ibm-1123_P100-1995",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0491\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0490\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u00a7STUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f",
Aliases: []string{"ibm-1123_P100-1995", "ibm-1123", "cp1123", "1123"},
},
{
Name: "ibm-1124_P100-1996",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0401\u0402\u0490\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u00ad\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u2116\u0451\u0452\u0491\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u00a7\u045e\u045f",
Aliases: []string{"ibm-1124_P100-1996", "ibm-1124", "cp1124", "1124"},
},
{
Name: "ibm-1125_P100-1997",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0490\u0491\u0404\u0454\u0406\u0456\u0407\u0457\u00f7\u00b1\u2116\u00a4\u25a0\u00a0",
Aliases: []string{"ibm-1125_P100-1997", "ibm-1125", "cp1125"},
},
{
Name: "ibm-1129_P100-1997",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u0153\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1\u00b2\u00b3\u0178\u00b5\u00b6\u00b7\u0152\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u0102\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u0300\u00cd\u00ce\u00cf\u0110\u00d1\u0309\u00d3\u00d4\u01a0\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u01af\u0303\u00df\u00e0\u00e1\u00e2\u0103\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u0301\u00ed\u00ee\u00ef\u0111\u00f1\u0323\u00f3\u00f4\u01a1\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u01b0\u20ab\u00ff",
Aliases: []string{"ibm-1129_P100-1997", "ibm-1129"},
},
{
Name: "ibm-1130_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u0103\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u0303\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u0102\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u20ab`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0111\u0309\u0300\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u0152\u00c6\u00a4\u00b5~stuvwxyz\u00a1\u00bf\u0110\u0323\u0301\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u0153\u0178\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u01b0\u00f3\u01a1}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u01af\u00d3\u01a00123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1130_P100-1997", "ibm-1130"},
},
{
Name: "ibm-1131_P100-1997",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1c\x1b\x7f\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x1a\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0401\u0451\u0404\u0454\u0407\u0457\u040e\u045e\u0406\u0456\u00b7\u00a4\u0490\u0491\u2219\u00a0",
Aliases: []string{"ibm-1131_P100-1997", "ibm-1131", "cp1131"},
},
{
Name: "ibm-1132_P100-1998",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e81\u0e82\u0e84\u0e87\u0e88\u0eaa\u0e8a[\u00a2.<(+|&\ufffd\u0e8d\u0e94\u0e95\u0e96\u0e97\u0e99\u0e9a]!$*);\u00ac-/\u0e9b\u0e9c\u0e9d\u0e9e\u0e9f\u0ea1\u0ea2^\u00a6,%_>?\u20ad\ufffd\u0ea3\u0ea5\u0ea7\u0eab\u0ead\u0eae\ufffd`:#@'=\"\ufffdabcdefghi\ufffd\ufffd\u0eaf\u0eb0\u0eb2\u0eb3\ufffdjklmnopqr\u0eb4\u0eb5\u0eb6\u0eb7\u0eb8\u0eb9\ufffd~stuvwxyz\u0ebc\u0eb1\u0ebb\u0ebd\ufffd\ufffd\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\ufffd\u0ec0\u0ec1\u0ec2\u0ec3\u0ec4{ABCDEFGHI\ufffd\u0ec8\u0ec9\u0eca\u0ecb\u0ecc}JKLMNOPQR\u0ecd\u0ec6\ufffd\u0edc\u0edd\ufffd\\\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f",
Aliases: []string{"ibm-1132_P100-1998", "ibm-1132"},
},
{
Name: "ibm-1133_P100-1997",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u0e81\u0e82\u0e84\u0e87\u0e88\u0eaa\u0e8a\u0e8d\u0e94\u0e95\u0e96\u0e97\u0e99\u0e9a\u0e9b\u0e9c\u0e9d\u0e9e\u0e9f\u0ea1\u0ea2\u0ea3\u0ea5\u0ea7\u0eab\u0ead\u0eae\ufffd\ufffd\ufffd\u0eaf\u0eb0\u0eb2\u0eb3\u0eb4\u0eb5\u0eb6\u0eb7\u0eb8\u0eb9\u0ebc\u0eb1\u0ebb\u0ebd\ufffd\ufffd\ufffd\u0ec0\u0ec1\u0ec2\u0ec3\u0ec4\u0ec8\u0ec9\u0eca\u0ecb\u0ecc\u0ecd\u0ec6\ufffd\u0edc\u0eddk\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\ufffd\ufffd\u00a2\u00ac\u00a6\u00a0",
Aliases: []string{"ibm-1133_P100-1997", "ibm-1133"},
},
{
Name: "ibm-1137_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0901\u0902\u0903\u0905\u0906\u0907\u0908\u0909\u090a.<(+|&\u090b\u090c\u090d\u090e\u090f\u0910\u0911\u0912\u0913!$*);^-/\u0914\u0915\u0916\u0917\u0918\u0919\u091a\u091b\u091c,%_>?\u091d\u091e\u091f\u0920\u0921\u0922\u0923\u0924\u0925`:#@'=\"\u0926abcdefghi\u0927\u0928\u092a\u092b\u092c\u092d\u092ejklmnopqr\u092f\u0930\u0932\u0933\u0935\u0936\u200c~stuvwxyz\u0937\u0938\u0939[\u093c\u093d\u093e\u093f\u0940\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u0949\u094a]\u094b\u094c{ABCDEFGHI\u094d\u0950\u0951\u0952\ufffd\ufffd}JKLMNOPQR\u0960\u0961\u0962\u0963\u0964\u0965\\\u200dSTUVWXYZ\u0966\u0967\u0968\u0969\u096a\u096b0123456789\u096c\u096d\u096e\u096f\u0970\u009f",
Aliases: []string{"ibm-1137_P100-1999", "ibm-1137"},
},
{
Name: "ibm-1140_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1140_P100-1997", "ibm-1140", "IBM01140", "CCSID01140", "CP01140", "cp1140", "ebcdic-us-37+euro"},
},
{
Name: "ibm-1141_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00c4.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec~\u00dc$*);^-/\u00c2[\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00dfstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00fcJKLMNOPQR\u00b9\u00fb}\u00f9\u00fa\u00ff\u00d6\u00f7STUVWXYZ\u00b2\u00d4\\\u00d2\u00d3\u00d50123456789\u00b3\u00db]\u00d9\u00da\u009f",
Aliases: []string{"ibm-1141_P100-1997", "ibm-1141", "IBM01141", "CCSID01141", "CP01141", "cp1141", "ebcdic-de-273+euro"},
},
{
Name: "ibm-1142_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3}\u00e7\u00f1#.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f8,%_>?\u00a6\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00c6\u00d8'=\"@abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba{\u00b8[]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e6ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1142_P100-1997", "ibm-1142", "IBM01142", "CCSID01142", "CP01142", "cp1142", "ebcdic-dk-277+euro", "ebcdic-no-277+euro"},
},
{
Name: "ibm-1143_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1143_P100-1997", "ibm-1143", "IBM01143", "CCSID01143", "CP01143", "cp1143", "ebcdic-fi-278+euro", "ebcdic-se-278+euro"},
},
{
Name: "ibm-1144_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4{\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&]\u00ea\u00eb}\u00ed\u00ee\u00ef~\u00df\u00e9$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f2,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f9:\u00a3\u00a7'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00ecstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9@\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e0ABCDEFGHI\u00ad\u00f4\u00f6\u00a6\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc`\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1144_P100-1997", "ibm-1144", "IBM01144", "CCSID01144", "CP01144", "cp1144", "ebcdic-it-280+euro"},
},
{
Name: "ibm-1145_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00a6[.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7#\u00f1,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:\u00d1@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^!\u00af~\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1145_P100-1997", "ibm-1145", "IBM01145", "CCSID01145", "CP01145", "cp1145", "ebcdic-es-284+euro"},
},
{
Name: "ibm-1146_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1$.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!\u00a3*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00afstuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2[\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be^]~\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1146_P100-1997", "ibm-1146", "IBM01146", "CCSID01146", "CP01146", "cp1146", "ebcdic-gb-285+euro"},
},
{
Name: "ibm-1147_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4@\u00e1\u00e3\u00e5\\\u00f1\u00b0.<(+!&{\u00ea\u00eb}\u00ed\u00ee\u00ef\u00ec\u00df\u00a7$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00f9,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00b5:\u00a3\u00e0'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1[jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac`\u00a8stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2#\u00a5\u00b7\u00a9]\u00b6\u00bc\u00bd\u00be\u00ac|\u00af~\u00b4\u00d7\u00e9ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5\u00e8JKLMNOPQR\u00b9\u00fb\u00fc\u00a6\u00fa\u00ff\u00e7\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1147_P100-1997", "ibm-1147", "IBM01147", "CCSID01147", "CP01147", "cp1147", "ebcdic-fr-297+euro"},
},
{
Name: "ibm-1148_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1148_P100-1997", "ibm-1148", "IBM01148", "CCSID01148", "CP01148", "cp1148", "ebcdic-international-500+euro"},
},
{
Name: "ibm-1149_P100-1997",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00de.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u00c6$*);\u00d6-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00f0:#\u00d0'=\"\u00d8abcdefghi\u00ab\u00bb`\u00fd{\u00b1\u00b0jklmnopqr\u00aa\u00ba}\u00b8]\u20ac\u00b5\u00f6stuvwxyz\u00a1\u00bf@\u00dd[\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\\\u00d7\u00feABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u00e6JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\u00b4\u00f7STUVWXYZ\u00b2\u00d4^\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1149_P100-1997", "ibm-1149", "IBM01149", "CCSID01149", "CP01149", "cp1149", "ebcdic-is-871+euro"},
},
{
Name: "ibm-1153_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u0163\u00e1\u0103\u010d\u00e7\u0107[.<(+!&\u00e9\u0119\u00eb\u016f\u00ed\u00ee\u013e\u013a\u00df]$*);^-/\u00c2\u00c4\u02dd\u00c1\u0102\u010c\u00c7\u0106|,%_>?\u02c7\u00c9\u0118\u00cb\u016e\u00cd\u00ce\u013d\u0139`:#@'=\"\u02d8abcdefghi\u015b\u0148\u0111\u00fd\u0159\u015f\u00b0jklmnopqr\u0142\u0144\u0161\u00b8\u02db\u20ac\u0105~stuvwxyz\u015a\u0147\u0110\u00dd\u0158\u015e\u02d9\u0104\u017c\u0162\u017b\u00a7\u017e\u017a\u017d\u0179\u0141\u0143\u0160\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u0155\u00f3\u0151}JKLMNOPQR\u011a\u0171\u00fc\u0165\u00fa\u011b\\\u00f7STUVWXYZ\u010f\u00d4\u00d6\u0154\u00d3\u01500123456789\u010e\u0170\u00dc\u0164\u00da\u009f",
Aliases: []string{"ibm-1153_P100-1999", "ibm-1153"},
},
{
Name: "ibm-1154_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0453\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0403\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u20acSTUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f",
Aliases: []string{"ibm-1154_P100-1999", "ibm-1154"},
},
{
Name: "ibm-1155_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5{\u00f1\u00c7.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u011e\u0130*);^-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5[\u00d1\u015f,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u0131:\u00d6\u015e'=\u00dc\u00d8abcdefghi\u00ab\u00bb}`\u00a6\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5\u00f6stuvwxyz\u00a1\u00bf]$@\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e7ABCDEFGHI\u00ad\u00f4~\u00f2\u00f3\u00f5\u011fJKLMNOPQR\u00b9\u00fb\\\u00f9\u00fa\u00ff\u00fc\u00f7STUVWXYZ\u00b2\u00d4#\u00d2\u00d3\u00d50123456789\u00b3\u00db\"\u00d9\u00da\u009f",
Aliases: []string{"ibm-1155_P100-1999", "ibm-1155"},
},
{
Name: "ibm-1156_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0161\u00e4\u0105\u012f\u016b\u00e5\u0113\u017e\u00a2.<(+|&\u00e9\u0119\u0117\u010d\u0173\u201e\u201c\u0123\u00df!$*);\u00ac-/\u0160\u00c4\u0104\u012e\u016a\u00c5\u0112\u017d\u00a6,%_>?\u00f8\u00c9\u0118\u0116\u010c\u0172\u012a\u013b\u0122`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0101\u017c\u0144\u00b1\u00b0jklmnopqr\u0156\u0157\u00e6\u0137\u00c6\u20ac\u00b5~stuvwxyz\u201d\u017a\u0100\u017b\u0143\u00ae^\u00a3\u012b\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u0179\u0136\u013c\u00d7{ABCDEFGHI\u00ad\u014d\u00f6\u0146\u00f3\u00f5}JKLMNOPQR\u00b9\u0107\u00fc\u0142\u015b\u2019\\\u00f7STUVWXYZ\u00b2\u014c\u00d6\u0145\u00d3\u00d50123456789\u00b3\u0106\u00dc\u0141\u015a\u009f",
Aliases: []string{"ibm-1156_P100-1999", "ibm-1156"},
},
{
Name: "ibm-1157_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2{\u00e0\u00e1\u00e3}\u00e7\u00f1\u00a7.<(+!&`\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df\u20ac\u00c5*);^-/\u00c2#\u00c0\u00c1\u00c3$\u00c7\u00d1\u00f6,%_>?\u00f8\\\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc\u00e9:\u00c4\u00d6'=\"\u00d8abcdefghi\u00ab\u00bb\u0161\u00fd\u017e\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6]\u00b5\u00fcstuvwxyz\u00a1\u00bf\u0160\u00dd\u017d\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9[\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u00a8\u00b4\u00d7\u00e4ABCDEFGHI\u00ad\u00f4\u00a6\u00f2\u00f3\u00f5\u00e5JKLMNOPQR\u00b9\u00fb~\u00f9\u00fa\u00ff\u00c9\u00f7STUVWXYZ\u00b2\u00d4@\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1157_P100-1999", "ibm-1157"},
},
{
Name: "ibm-1158_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0452\u0491\u0451\u0454\u0455\u0456\u0457\u0458[.<(+!&\u0459\u045a\u045b\u045c\u045e\u045f\u042a\u2116\u0402]$*);^-/\u0490\u0401\u0404\u0405\u0406\u0407\u0408\u0409|,%_>?\u040a\u040b\u040c\u00ad\u040e\u040f\u044e\u0430\u0431`:#@'=\"\u0446abcdefghi\u0434\u0435\u0444\u0433\u0445\u0438\u0439jklmnopqr\u043a\u043b\u043c\u043d\u043e\u043f\u044f~stuvwxyz\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413{ABCDEFGHI\u0425\u0418\u0419\u041a\u041b\u041c}JKLMNOPQR\u041d\u041e\u041f\u042f\u0420\u0421\\\u20acSTUVWXYZ\u0422\u0423\u0416\u0412\u042c\u042b0123456789\u0417\u0428\u042d\u0429\u0427\u009f",
Aliases: []string{"ibm-1158_P100-1999", "ibm-1158"},
},
{
Name: "ibm-1160_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07[\u00a2.<(+|&\u0e48\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e]!$*);\u00ac-/\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15^\u00a6,%_>?\u0e3f\u0e4e\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c`:#@'=\"\u0e4fabcdefghi\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e5ajklmnopqr\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e5b~stuvwxyz\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34{ABCDEFGHI\u0e49\u0e35\u0e36\u0e37\u0e38\u0e39}JKLMNOPQR\u0e3a\u0e40\u0e41\u0e42\u0e43\u0e44\\\u0e4aSTUVWXYZ\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a0123456789\u0e4b\u0e4c\u0e4d\u0e4b\u20ac\u009f",
Aliases: []string{"ibm-1160_P100-1999", "ibm-1160"},
},
{
Name: "ibm-1162_P100-1999",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u20ac\u0081\u0082\u0083\u0084\u2026\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\ufffd\ufffd\ufffd\ufffd\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b\ufffd\ufffd\ufffd\ufffd",
Aliases: []string{"ibm-1162_P100-1999", "ibm-1162"},
},
{
Name: "ibm-1164_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u0103\u00e5\u00e7\u00f1[.<(+!&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u0303\u00df]$*);^-/\u00c2\u00c4\u00c0\u00c1\u0102\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u20ab`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u0111\u0309\u0300\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u0152\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u0110\u0323\u0301\u00ae\u00a2\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be\u00ac|\u00af\u0153\u0178\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u01b0\u00f3\u01a1}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u01af\u00d3\u01a00123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ibm-1164_P100-1999", "ibm-1164"},
},
{
Name: "ibm-4517_P100-2005",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\ufe7c\ufe7d\u0640\u200b\ufe80\ufe81\ufe82\ufe83\u00b0.<(+!&\ufe84\ufe85\ufffd\ufffd\ufe8b\ufe8d\ufe8e\ufe8f\ufe91\u00a7$*);^-/\ufe93\ufe95\ufe97\ufe99\ufe9b\ufe9d\ufe9f\ufea1\u00fa,%_>?\ufea3\ufea5\ufea7\ufea9\ufeab\ufead\ufeaf\ufeb1\ufeb3\u00a3:\u00b5\u00e1'=\"\ufeb5abcdefghi\ufeb7\ufeb9\ufebb\ufebd\ufebf\ufec3\ufec7jklmnopqr\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\u00a8stuvwxyz\ufed0\ufed1\ufed3\ufed5\ufed7\ufed9\ufedb\ufedd\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\ufee1\ufee3\ufee5\ufee7\ufee9\u00e9ABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\ufeed\u00e8JKLMNOPQR\ufeef\ufef0\ufef1\ufef2\ufef3\ufffd\u00e7\u2007STUVWXYZ\u00f7\u060c\ufffd\u00d7\u061f\u061b0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f",
Aliases: []string{"ibm-4517_P100-2005", "ibm-4517"},
},
{
Name: "ibm-4899_P100-1998",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$.<(+|\u05d0\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd!\u00a2*);\u00ac-/\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd,%_>?\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd:#@'=\"\ufffd\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\ufffd\ufffd\u20ac\ufffd\u20aa\ufffd\ufffd\ufffd\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdJKLMNOPQR\ufffd\u202d\u202e\u202c\ufffd\ufffd\ufffd\ufffdSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\u202a\u202b\u200e\u200f\u009f",
Aliases: []string{"ibm-4899_P100-1998", "ibm-4899"},
},
{
Name: "ibm-4909_P100-1999",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0\u2018\u2019\u00a3\u20ac\ufffd\u00a6\u00a7\u00a8\u00a9\ufffd\u00ab\u00ac\u00ad\ufffd\u2015\u00b0\u00b1\u00b2\u00b3\u00b4\u0385\u0386\u0387\u0388\u0389\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\ufffd\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\ufffd",
Aliases: []string{"ibm-4909_P100-1999", "ibm-4909"},
},
{
Name: "ibm-4971_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\ufffdSTUVWXYZ\u00b2\u00a7\ufffd\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\u20ac\ufffd\u00bb\u009f",
Aliases: []string{"ibm-4971_P100-1999", "ibm-4971"},
},
{
Name: "ibm-5123_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \ufffd\uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\u00a2.<(+|&\uff69\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\uff70\uff71!$*);\u00ac-/\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\ufffd,%_>?\uff7a\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82`:#@'=\"\ufffdabcdefghi\uff83\uff84\uff85\uff86\uff87\uff88\ufffdjklmnopqr\uff89\uff8a\uff8b\uff8c\uff8d\uff8e\u203e~stuvwxyz\uff8f\uff90\uff91[\uff92\uff93^\u00a3\u00a5\uff94\uff95\uff96\uff97\uff98\uff99\uff9a\uff9b\uff9c\uff9d]\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\\\u20acSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f",
Aliases: []string{"ibm-5123_P100-1999", "ibm-5123"},
},
{
Name: "ibm-8482_P100-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \uff61\uff62\uff63\uff64\uff65\uff66\uff67\uff68\uff69\u00a3.<(+|&\uff6a\uff6b\uff6c\uff6d\uff6e\uff6f\ufffd\uff70\ufffd!\u00a5*);\u00ac-/abcdefgh\ufffd,%_>?[ijklmnop`:#@'=\"]\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78\uff79\uff7aq\uff7b\uff7c\uff7d\uff7e\uff7f\uff80\uff81\uff82\uff83\uff84\uff85\uff86\uff87\uff88\uff89r\ufffd\uff8a\uff8b\uff8c~\u203e\uff8d\uff8e\uff8f\uff90\uff91\uff92\uff93\uff94\uff95s\uff96\uff97\uff98\uff99^\u00a2\\tuvwxyz\uff9a\uff9b\uff9c\uff9d\uff9e\uff9f{ABCDEFGHI\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd$\u20acSTUVWXYZ\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\ufffd\ufffd\ufffd\ufffd\ufffd\u009f",
Aliases: []string{"ibm-8482_P100-1999", "ibm-8482"},
},
{
Name: "ibm-9067_X100-2005",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399[.<(+!&\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3]$*);^-/\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab|,%_>?\u00a8\u0386\u0388\u0389\u00a0\u038a\u038c\u038e\u038f`:#@'=\"\u0385abcdefghi\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u00b0jklmnopqr\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u00b4~stuvwxyz\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u00a3\u03ac\u03ad\u03ae\u03ca\u03af\u03cc\u03cd\u03cb\u03ce\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8{ABCDEFGHI\u00ad\u03c9\u0390\u03b0\u2018\u2015}JKLMNOPQR\u00b1\u00bd\ufffd\u0387\u2019\u00a6\\\u20afSTUVWXYZ\u00b2\u00a7\u037a\ufffd\u00ab\u00ac0123456789\u00b3\u00a9\u20ac\ufffd\u00bb\u009f",
Aliases: []string{"ibm-9067_X100-2005", "ibm-9067"},
},
{
Name: "ibm-12712_P100-1998",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u00a2.<(+|&\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1!$*);\u00ac-/\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u00a6,%_>?\ufffd\u05ea\ufffd\ufffd\u00a0\ufffd\ufffd\ufffd\u2017`:#@'=\"\ufffdabcdefghi\u00ab\u00bb\ufffd\ufffd\ufffd\u00b1\u00b0jklmnopqr\ufffd\ufffd\u20ac\u00b8\u20aa\u00a4\u00b5~stuvwxyz\ufffd\ufffd\ufffd\ufffd\ufffd\u00ae^\u00a3\u00a5\u2022\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u203e\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\ufffd\ufffd\ufffd\ufffd\ufffd}JKLMNOPQR\u00b9\u202d\u202e\u202c\ufffd\ufffd\\\u00f7STUVWXYZ\u00b2\ufffd\ufffd\ufffd\ufffd\ufffd0123456789\u00b3\u202a\u202b\u200e\u200f\u009f",
Aliases: []string{"ibm-12712_P100-1998", "ibm-12712", "ebcdic-he"},
},
{
Name: "ibm-16804_X110-1999",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\u0085\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u0651\ufe7d\u0640\u200b\u0621\u0622\ufe82\u0623\u00a2.<(+|&\ufe84\u0624\ufffd\ufffd\u0626\u0627\ufe8e\u0628\ufe91!$*);\u00ac-/\u0629\u062a\ufe97\u062b\ufe9b\u062c\ufe9f\u062d\u00a6,%_>?\ufea3\u062e\ufea7\u062f\u0630\u0631\u0632\u0633\ufeb3\u060c:#@'=\"\u0634abcdefghi\ufeb7\u0635\ufebb\u0636\ufebf\u0637\u0638jklmnopqr\u0639\ufeca\ufecb\ufecc\u063a\ufece\ufecf\u00f7stuvwxyz\ufed0\u0641\ufed3\u0642\ufed7\u0643\ufedb\u0644\ufef5\ufef6\ufef7\ufef8\ufffd\ufffd\ufefb\ufefc\ufedf\u0645\ufee3\u0646\ufee7\u0647\u061bABCDEFGHI\u00ad\ufeeb\ufffd\ufeec\ufffd\u0648\u061fJKLMNOPQR\u0649\ufef0\u064a\ufef2\ufef3\u0660\u00d7\u2007STUVWXYZ\u0661\u0662\ufffd\u0663\u0664\u06650123456789\u20ac\u0666\u0667\u0668\u0669\u009f",
Aliases: []string{"ibm-16804_X110-1999", "ibm-16804", "ebcdic-ar"},
},
{
Name: "KOI8-R",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\u2580\u2584\u2588\u258c\u2590\u2591\u2592\u2593\u2320\u25a0\u2219\u221a\u2248\u2264\u2265\u00a0\u2321\u00b0\u00b2\u00b7\u00f7\u2550\u2551\u2552\u0451\u2553\u2554\u2555\u2556\u2557\u2558\u2559\u255a\u255b\u255c\u255d\u255e\u255f\u2560\u2561\u0401\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569\u256a\u256b\u256c\u00a9\u044e\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u044f\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u042f\u0420\u0421\u0422\u0423\u0416\u0412\u042c\u042b\u0417\u0428\u042d\u0429\u0427\u042a",
Aliases: []string{"csKOI8R"},
},
{
Name: "KOI8-U",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\u2580\u2584\u2588\u258c\u2590\u2591\u2592\u2593\u2320\u25a0\u2219\u221a\u2248\u2264\u2265\u00a0\u2321\u00b0\u00b2\u00b7\u00f7\u2550\u2551\u2552\u0451\u0454\u2554\u0456\u0457\u2557\u2558\u2559\u255a\u255b\u0491\u255d\u255e\u255f\u2560\u2561\u0401\u0404\u2563\u0406\u0407\u2566\u2567\u2568\u2569\u256a\u0490\u256c\u00a9\u044e\u0430\u0431\u0446\u0434\u0435\u0444\u0433\u0445\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u044f\u0440\u0441\u0442\u0443\u0436\u0432\u044c\u044b\u0437\u0448\u044d\u0449\u0447\u044a\u042e\u0410\u0411\u0426\u0414\u0415\u0424\u0413\u0425\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u042f\u0420\u0421\u0422\u0423\u0416\u0412\u042c\u042b\u0417\u0428\u042d\u0429\u0427\u042a",
},
{
Name: "ibm-1051_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u00c0\u00c2\u00c8\u00ca\u00cb\u00ce\u00cf\u00b4`\u02c6\u00a8\u02dc\u00d9\u00db\u00a3\u203e\u00dd\u00fd\u02da\u00c7\u00e7\u00d1\u00f1\u00a1\u00bf\u00a4\u00a3\u00a5\u00a7\u0192\u00a2\u00e2\u00ea\u00f4\u00fb\u00e1\u00e9\u00f3\u00fa\u00e0\u00e8\u00f2\u00f9\u00e4\u00eb\u00f6\u00fc\u00c5\u00ee\u00d8\u00c6\u00e5\u00ed\u00f8\u00e6\u00c4\u00ec\u00d6\u00dc\u00c9\u00ef\u00df\u00d4\u00c1\u00c3\u00e3\u00d0\u00f0\u00cd\u00cc\u00d3\u00d2\u00d5\u00f5\u0160\u0161\u00da\u0178\u00ff\u00de\u00fe\u00b7\u03bc\u00b6\u00be-\u00bc\u00bd\u00aa\u00ba\u00ab\u25a0\u00bb\u00b1\ufffd",
Aliases: []string{"ibm-1051_P100-1995", "ibm-1051", "hp-roman8", "roman8", "r8", "csHPRoman8"},
},
{
Name: "ibm-1276_P100-1995",
SubstitutionChar: '?',
Repertoire: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&\u2019()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\u2018abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\ufffd\u00a1\u00a2\u00a3\u2044\u00a5\u0192\u00a7\u00a4'\u201c\u00ab\u2039\u203a\ufb01\ufb02\ufffd\u2013\u2020\u2021\u00b7\ufffd\u00b6\u2022\u201a\u201e\u201d\u00bb\u2026\u2030\ufffd\u00bf\ufffd`\u00b4\u02c6\u02dc\u00af\u02d8\u02d9\u00a8\ufffd\u02da\u00b8\ufffd\u02dd\u02db\u02c7\u2014\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u00c6\ufffd\u00aa\ufffd\ufffd\ufffd\ufffd\u0141\u00d8\u0152\u00ba\ufffd\ufffd\ufffd\ufffd\ufffd\u00e6\ufffd\ufffd\ufffd\u0131\ufffd\ufffd\u0142\u00f8\u0153\u00df\ufffd\ufffd\ufffd\ufffd",
Aliases: []string{"ibm-1276_P100-1995", "ibm-1276", "Adobe-Standard-Encoding", "csAdobeStandardEncoding"},
},
{
Name: "ebcdic-xml-us",
SubstitutionChar: 0x6f,
Repertoire: "\x00\x01\x02\x03\u009c\t\u0086\x7f\u0097\u008d\u008e\v\f\r\x0e\x0f\x10\x11\x12\x13\u009d\n\b\u0087\x18\x19\u0092\u008f\x1c\x1d\x1e\x1f\u0080\u0081\u0082\u0083\u0084\n\x17\x1b\u0088\u0089\u008a\u008b\u008c\x05\x06\a\u0090\u0091\x16\u0093\u0094\u0095\u0096\x04\u0098\u0099\u009a\u009b\x14\x15\u009e\x1a \u00a0\u00e2\u00e4\u00e0\u00e1\u00e3\u00e5\u00e7\u00f1\u00a2.<(+|&\u00e9\u00ea\u00eb\u00e8\u00ed\u00ee\u00ef\u00ec\u00df!$*);\u00ac-/\u00c2\u00c4\u00c0\u00c1\u00c3\u00c5\u00c7\u00d1\u00a6,%_>?\u00f8\u00c9\u00ca\u00cb\u00c8\u00cd\u00ce\u00cf\u00cc`:#@'=\"\u00d8abcdefghi\u00ab\u00bb\u00f0\u00fd\u00fe\u00b1\u00b0jklmnopqr\u00aa\u00ba\u00e6\u00b8\u00c6\u20ac\u00b5~stuvwxyz\u00a1\u00bf\u00d0\u00dd\u00de\u00ae^\u00a3\u00a5\u00b7\u00a9\u00a7\u00b6\u00bc\u00bd\u00be[]\u00af\u00a8\u00b4\u00d7{ABCDEFGHI\u00ad\u00f4\u00f6\u00f2\u00f3\u00f5}JKLMNOPQR\u00b9\u00fb\u00fc\u00f9\u00fa\u00ff\\\u00f7STUVWXYZ\u00b2\u00d4\u00d6\u00d2\u00d3\u00d50123456789\u00b3\u00db\u00dc\u00d9\u00da\u009f",
Aliases: []string{"ebcdic-xml-us"},
},
}

View File

@@ -1,76 +0,0 @@
package mahonia
// Converters for ASCII and ISO-8859-1
func init() {
for i := 0; i < len(asciiCharsets); i++ {
RegisterCharset(&asciiCharsets[i])
}
}
var asciiCharsets = []Charset{
{
Name: "US-ASCII",
NewDecoder: func() Decoder { return decodeASCIIRune },
NewEncoder: func() Encoder { return encodeASCIIRune },
Aliases: []string{"ASCII", "US", "ISO646-US", "IBM367", "cp367", "ANSI_X3.4-1968", "iso-ir-6", "ANSI_X3.4-1986", "ISO_646.irv:1991", "csASCII"},
},
{
Name: "ISO-8859-1",
NewDecoder: func() Decoder { return decodeLatin1Rune },
NewEncoder: func() Encoder { return encodeLatin1Rune },
Aliases: []string{"latin1", "ISO Latin 1", "IBM819", "cp819", "ISO_8859-1:1987", "iso-ir-100", "l1", "csISOLatin1"},
},
}
func decodeASCIIRune(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
b := p[0]
if b > 127 {
return 0xfffd, 1, INVALID_CHAR
}
return rune(b), 1, SUCCESS
}
func encodeASCIIRune(p []byte, c rune) (size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
if c < 128 {
p[0] = byte(c)
return 1, SUCCESS
}
p[0] = '?'
return 1, INVALID_CHAR
}
func decodeLatin1Rune(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
return rune(p[0]), 1, SUCCESS
}
func encodeLatin1Rune(p []byte, c rune) (size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
if c < 256 {
p[0] = byte(c)
return 1, SUCCESS
}
p[0] = '?'
return 1, INVALID_CHAR
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,89 +0,0 @@
package mahonia
// Converters for Big 5 encoding.
import (
"sync"
)
func init() {
RegisterCharset(&Charset{
Name: "Big5",
Aliases: []string{"csBig5"},
NewDecoder: func() Decoder {
return decodeBig5Rune
},
NewEncoder: func() Encoder {
big5Once.Do(reverseBig5Table)
return encodeBig5Rune
},
})
}
func decodeBig5Rune(p []byte) (r rune, size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
b := p[0]
if b < 128 {
return rune(b), 1, SUCCESS
}
if len(p) < 2 {
status = NO_ROOM
return
}
c := int(p[0])<<8 + int(p[1])
c = int(big5ToUnicode[c])
if c > 0 {
return rune(c), 2, SUCCESS
}
return 0xfffd, 1, INVALID_CHAR
}
func encodeBig5Rune(p []byte, r rune) (size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
if r < 128 {
p[0] = byte(r)
return 1, SUCCESS
}
if len(p) < 2 {
status = NO_ROOM
return
}
if r < 0x10000 {
c := unicodeToBig5[r]
if c > 0 {
p[0] = byte(c >> 8)
p[1] = byte(c)
return 2, SUCCESS
}
}
p[0] = '?'
return 1, INVALID_CHAR
}
var big5Once sync.Once
var unicodeToBig5 []uint16
func reverseBig5Table() {
unicodeToBig5 = make([]uint16, 65536)
for big5, unicode := range big5ToUnicode {
if unicode > 0 {
unicodeToBig5[unicode] = uint16(big5)
}
}
}

View File

@@ -1,115 +0,0 @@
// This package is a character-set conversion library for Go.
//
// (DEPRECATED: use code.google.com/p/go.text/encoding, perhaps along with
// code.google.com/p/go.net/html/charset)
package mahonia
import (
"bytes"
"unicode"
)
// Status is the type for the status return value from a Decoder or Encoder.
type Status int
const (
// SUCCESS means that the character was converted with no problems.
SUCCESS = Status(iota)
// INVALID_CHAR means that the source contained invalid bytes, or that the character
// could not be represented in the destination encoding.
// The Encoder or Decoder should have output a substitute character.
INVALID_CHAR
// NO_ROOM means there were not enough input bytes to form a complete character,
// or there was not enough room in the output buffer to write a complete character.
// No bytes were written, and no internal state was changed in the Encoder or Decoder.
NO_ROOM
// STATE_ONLY means that bytes were read or written indicating a state transition,
// but no actual character was processed. (Examples: byte order marks, ISO-2022 escape sequences)
STATE_ONLY
)
// A Decoder is a function that decodes a character set, one character at a time.
// It works much like utf8.DecodeRune, but has an aditional status return value.
type Decoder func(p []byte) (c rune, size int, status Status)
// An Encoder is a function that encodes a character set, one character at a time.
// It works much like utf8.EncodeRune, but has an additional status return value.
type Encoder func(p []byte, c rune) (size int, status Status)
// A Charset represents a character set that can be converted, and contains functions
// to create Converters to encode and decode strings in that character set.
type Charset struct {
// Name is the character set's canonical name.
Name string
// Aliases returns a list of alternate names.
Aliases []string
// NewDecoder returns a Decoder to convert from the charset to Unicode.
NewDecoder func() Decoder
// NewEncoder returns an Encoder to convert from Unicode to the charset.
NewEncoder func() Encoder
}
// The charsets are stored in charsets under their canonical names.
var charsets = make(map[string]*Charset)
// aliases maps their aliases to their canonical names.
var aliases = make(map[string]string)
// simplifyName converts a name to lower case and removes non-alphanumeric characters.
// This is how the names are used as keys to the maps.
func simplifyName(name string) string {
var buf bytes.Buffer
for _, c := range name {
switch {
case unicode.IsDigit(c):
buf.WriteRune(c)
case unicode.IsLetter(c):
buf.WriteRune(unicode.ToLower(c))
default:
}
}
return buf.String()
}
// RegisterCharset adds a charset to the charsetMap.
func RegisterCharset(cs *Charset) {
name := cs.Name
charsets[name] = cs
aliases[simplifyName(name)] = name
for _, alias := range cs.Aliases {
aliases[simplifyName(alias)] = name
}
}
// GetCharset fetches a charset by name.
// If the name is not found, it returns nil.
func GetCharset(name string) *Charset {
return charsets[aliases[simplifyName(name)]]
}
// NewDecoder returns a Decoder to decode the named charset.
// If the name is not found, it returns nil.
func NewDecoder(name string) Decoder {
cs := GetCharset(name)
if cs == nil {
return nil
}
return cs.NewDecoder()
}
// NewEncoder returns an Encoder to encode the named charset.
func NewEncoder(name string) Encoder {
cs := GetCharset(name)
if cs == nil {
return nil
}
return cs.NewEncoder()
}

View File

@@ -1,135 +0,0 @@
package mahonia
import (
"unicode/utf8"
)
// ConvertString converts a string from UTF-8 to e's encoding.
func (e Encoder) ConvertString(s string) string {
dest := make([]byte, len(s)+10)
destPos := 0
for _, rune := range s {
retry:
size, status := e(dest[destPos:], rune)
if status == NO_ROOM {
newDest := make([]byte, len(dest)*2)
copy(newDest, dest)
dest = newDest
goto retry
}
if status == STATE_ONLY {
destPos += size
goto retry
}
destPos += size
}
return string(dest[:destPos])
}
// ConvertString converts a string from d's encoding to UTF-8.
func (d Decoder) ConvertString(s string) string {
bytes := []byte(s)
runes := make([]rune, len(s))
destPos := 0
for len(bytes) > 0 {
c, size, status := d(bytes)
if status == STATE_ONLY {
bytes = bytes[size:]
continue
}
if status == NO_ROOM {
c = 0xfffd
size = len(bytes)
status = INVALID_CHAR
}
bytes = bytes[size:]
runes[destPos] = c
destPos++
}
return string(runes[:destPos])
}
// ConvertStringOK converts a string from UTF-8 to e's encoding. It also
// returns a boolean indicating whether every character was converted
// successfully.
func (e Encoder) ConvertStringOK(s string) (result string, ok bool) {
dest := make([]byte, len(s)+10)
destPos := 0
ok = true
for i, r := range s {
// The following test is copied from utf8.ValidString.
if r == utf8.RuneError && ok {
_, size := utf8.DecodeRuneInString(s[i:])
if size == 1 {
ok = false
}
}
retry:
size, status := e(dest[destPos:], r)
switch status {
case NO_ROOM:
newDest := make([]byte, len(dest)*2)
copy(newDest, dest)
dest = newDest
goto retry
case STATE_ONLY:
destPos += size
goto retry
case INVALID_CHAR:
ok = false
}
destPos += size
}
return string(dest[:destPos]), ok
}
// ConvertStringOK converts a string from d's encoding to UTF-8.
// It also returns a boolean indicating whether every character was converted
// successfully.
func (d Decoder) ConvertStringOK(s string) (result string, ok bool) {
bytes := []byte(s)
runes := make([]rune, len(s))
destPos := 0
ok = true
for len(bytes) > 0 {
c, size, status := d(bytes)
switch status {
case STATE_ONLY:
bytes = bytes[size:]
continue
case NO_ROOM:
c = 0xfffd
size = len(bytes)
ok = false
case INVALID_CHAR:
ok = false
}
bytes = bytes[size:]
runes[destPos] = c
destPos++
}
return string(runes[:destPos]), ok
}

View File

@@ -1,76 +0,0 @@
package mahonia
import (
"unicode/utf8"
)
// Converters for Microsoft's version of the EUC-JP encoding
func init() {
RegisterCharset(&Charset{
Name: "cp51932",
Aliases: []string{"windows-51932"},
NewDecoder: func() Decoder {
return decodeCP51932
},
NewEncoder: func() Encoder {
msJISTable.Reverse()
return encodeCP51932
},
})
}
func decodeCP51932(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
return 0, 0, NO_ROOM
}
b := p[0]
switch {
case b < 0x80:
return rune(b), 1, SUCCESS
case b == 0x8e:
if len(p) < 2 {
return 0, 0, NO_ROOM
}
b2 := p[1]
if b2 < 0xa1 || b2 > 0xdf {
return utf8.RuneError, 1, INVALID_CHAR
}
return rune(b2) + (0xff61 - 0xa1), 2, SUCCESS
case 0xa1 <= b && b <= 0xfe:
return msJISTable.DecodeHigh(p)
}
return utf8.RuneError, 1, INVALID_CHAR
}
func encodeCP51932(p []byte, c rune) (size int, status Status) {
if len(p) == 0 {
return 0, NO_ROOM
}
if c < 0x80 {
p[0] = byte(c)
return 1, SUCCESS
}
if len(p) < 2 {
return 0, NO_ROOM
}
if c > 0xffff {
p[0] = '?'
return 1, INVALID_CHAR
}
if 0xff61 <= c && c <= 0xff9f {
p[0] = 0x8e
p[1] = byte(c - (0xff61 - 0xa1))
return 2, SUCCESS
}
return msJISTable.EncodeHigh(p, c)
}

View File

@@ -1,179 +0,0 @@
package mahonia
// decoding HTML entities
import (
"sort"
)
// EntityDecoder returns a Decoder that decodes HTML character entities.
// If there is no valid character entity at the current position, it returns INVALID_CHAR.
// So it needs to be combined with another Decoder via FallbackDecoder.
func EntityDecoder() Decoder {
var leftover rune // leftover rune from two-rune entity
return func(p []byte) (r rune, size int, status Status) {
if leftover != 0 {
r = leftover
leftover = 0
return r, 0, SUCCESS
}
if len(p) == 0 {
return 0, 0, NO_ROOM
}
if p[0] != '&' {
return 0xfffd, 1, INVALID_CHAR
}
if len(p) < 3 {
return 0, 1, NO_ROOM
}
r, size, status = 0xfffd, 1, INVALID_CHAR
n := 1 // number of bytes read so far
if p[n] == '#' {
n++
c := p[n]
hex := false
if c == 'x' || c == 'X' {
hex = true
n++
}
var x rune
for n < len(p) {
c = p[n]
n++
if hex {
if '0' <= c && c <= '9' {
x = 16*x + rune(c) - '0'
continue
} else if 'a' <= c && c <= 'f' {
x = 16*x + rune(c) - 'a' + 10
continue
} else if 'A' <= c && c <= 'F' {
x = 16*x + rune(c) - 'A' + 10
continue
}
} else if '0' <= c && c <= '9' {
x = 10*x + rune(c) - '0'
continue
}
if c != ';' {
n--
}
break
}
if n == len(p) && p[n-1] != ';' {
return 0, 0, NO_ROOM
}
size = n
if p[n-1] == ';' {
n--
}
if hex {
n--
}
n--
// Now n is the number of actual digits read.
if n == 0 {
return 0xfffd, 1, INVALID_CHAR
}
if 0x80 <= x && x <= 0x9F {
// Replace characters from Windows-1252 with UTF-8 equivalents.
x = replacementTable[x-0x80]
} else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF {
// Replace invalid characters with the replacement character.
return 0xfffd, size, INVALID_CHAR
}
r = x
status = SUCCESS
return
}
// Look for a named entity in EntityList.
possible := entityList
for len(possible) > 0 {
if len(p) <= n {
leftover = 0
return 0, 0, NO_ROOM
}
c := p[n]
// Narrow down the selection in possible to those items that have c in the
// appropriate byte.
first := sort.Search(len(possible), func(i int) bool {
e := possible[i].name
if len(e) < n {
return false
}
return e[n-1] >= c
})
possible = possible[first:]
last := sort.Search(len(possible), func(i int) bool {
return possible[i].name[n-1] > c
})
possible = possible[:last]
n++
if len(possible) > 0 && len(possible[0].name) == n-1 {
r, leftover = possible[0].r1, possible[0].r2
size = n
status = SUCCESS
// but don't return yet, since we need the longest match
}
}
return
}
}
// This table is copied from /src/pkg/html/escape.go in the Go source
//
// These replacements permit compatibility with old numeric entities that
// assumed Windows-1252 encoding.
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
var replacementTable = [...]rune{
'\u20AC', // First entry is what 0x80 should be replaced with.
'\u0081',
'\u201A',
'\u0192',
'\u201E',
'\u2026',
'\u2020',
'\u2021',
'\u02C6',
'\u2030',
'\u0160',
'\u2039',
'\u0152',
'\u008D',
'\u017D',
'\u008F',
'\u0090',
'\u2018',
'\u2019',
'\u201C',
'\u201D',
'\u2022',
'\u2013',
'\u2014',
'\u02DC',
'\u2122',
'\u0161',
'\u203A',
'\u0153',
'\u009D',
'\u017E',
'\u0178', // Last entry is 0x9F.
// 0x00->'\uFFFD' is handled programmatically.
// 0x0D->'\u000D' is a no-op.
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,102 +0,0 @@
package mahonia
import (
"unicode/utf8"
)
// Converters for the EUC-JP encoding
func init() {
RegisterCharset(&Charset{
Name: "EUC-JP",
Aliases: []string{"extended_unix_code_packed_format_for_japanese", "cseucpkdfmtjapanese"},
NewDecoder: func() Decoder {
return decodeEucJP
},
NewEncoder: func() Encoder {
jis0208Table.Reverse()
jis0212Table.Reverse()
return encodeEucJP
},
})
}
func decodeEucJP(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
return 0, 0, NO_ROOM
}
b := p[0]
switch {
case b < 0x80:
return rune(b), 1, SUCCESS
case b == 0x8e:
if len(p) < 2 {
return 0, 0, NO_ROOM
}
b2 := p[1]
if b2 < 0xa1 || b2 > 0xdf {
return utf8.RuneError, 1, INVALID_CHAR
}
return rune(b2) + (0xff61 - 0xa1), 2, SUCCESS
case b == 0x8f:
if len(p) < 3 {
return 0, 0, NO_ROOM
}
c, size, status = jis0212Table.DecodeHigh(p[1:3])
if status == SUCCESS {
size = 3
}
return
case 0xa1 <= b && b <= 0xfe:
return jis0208Table.DecodeHigh(p)
}
return utf8.RuneError, 1, INVALID_CHAR
}
func encodeEucJP(p []byte, c rune) (size int, status Status) {
if len(p) == 0 {
return 0, NO_ROOM
}
if c < 0x80 {
p[0] = byte(c)
return 1, SUCCESS
}
if len(p) < 2 {
return 0, NO_ROOM
}
if c > 0xffff {
p[0] = '?'
return 1, INVALID_CHAR
}
if 0xff61 <= c && c <= 0xff9f {
p[0] = 0x8e
p[1] = byte(c - (0xff61 - 0xa1))
return 2, SUCCESS
}
size, status = jis0208Table.EncodeHigh(p, c)
if status == SUCCESS {
return size, status
}
size, status = jis0212Table.EncodeHigh(p[1:], c)
switch status {
case SUCCESS:
p[0] = 0x8f
return size + 1, SUCCESS
case INVALID_CHAR:
p[0] = '?'
return 1, INVALID_CHAR
}
return size, status
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,89 +0,0 @@
package mahonia
// Converters for the EUC-KR encoding.
import (
"unicode/utf8"
)
func init() {
RegisterCharset(&Charset{
Name: "EUC-KR",
Aliases: []string{
"ibm-1363",
"KS_C_5601-1987",
"KS_C_5601-1989",
"KSC_5601",
"Korean",
"iso-ir-149",
"cp1363",
"5601",
"ksc",
"windows-949",
"ibm-970",
"cp970",
"970",
"cp949",
},
NewDecoder: func() Decoder {
return decodeEucKr
},
NewEncoder: func() Encoder {
eucKrOnce.Do(reverseEucKrTable)
return encodeEucKr
},
})
}
func decodeEucKr(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
return 0, 0, NO_ROOM
}
b := p[0]
if b < 0x80 {
return rune(b), 1, SUCCESS
}
if len(p) < 2 {
return 0, 0, NO_ROOM
}
euc := int(b)<<8 + int(p[1])
c = rune(eucKrToUnicode[euc])
if c == 0 {
return utf8.RuneError, 2, INVALID_CHAR
}
return c, 2, SUCCESS
}
func encodeEucKr(p []byte, c rune) (size int, status Status) {
if len(p) == 0 {
return 0, NO_ROOM
}
if c < 0x80 {
p[0] = byte(c)
return 1, SUCCESS
}
if len(p) < 2 {
return 0, NO_ROOM
}
if c > 0xffff {
p[0] = '?'
return 1, INVALID_CHAR
}
euc := unicodeToEucKr[c]
if euc == 0 {
p[0] = '?'
return 1, INVALID_CHAR
}
p[0] = byte(euc >> 8)
p[1] = byte(euc)
return 2, SUCCESS
}

View File

@@ -1,19 +0,0 @@
package mahonia
// FallbackDecoder combines a series of Decoders into one.
// If the first Decoder returns a status of INVALID_CHAR, the others are tried as well.
//
// Note: if the text to be decoded ends with a sequence of bytes that is not a valid character in the first charset,
// but it could be the beginning of a valid character, the FallbackDecoder will give a status of NO_ROOM instead of
// falling back to the other Decoders.
func FallbackDecoder(decoders ...Decoder) Decoder {
return func(p []byte) (c rune, size int, status Status) {
for _, d := range decoders {
c, size, status = d(p)
if status != INVALID_CHAR {
return
}
}
return 0, 1, INVALID_CHAR
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,156 +0,0 @@
package mahonia
import (
"sync"
)
// Converters for GB18030 encoding.
func init() {
RegisterCharset(&Charset{
Name: "GB18030",
NewDecoder: func() Decoder {
gb18030Once.Do(buildGB18030Tables)
return decodeGB18030Rune
},
NewEncoder: func() Encoder {
gb18030Once.Do(buildGB18030Tables)
return encodeGB18030Rune
},
})
}
func decodeGB18030Rune(p []byte) (r rune, size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
b := p[0]
if b < 128 {
return rune(b), 1, SUCCESS
}
if len(p) < 2 {
status = NO_ROOM
return
}
if p[0] < 0x81 || p[0] > 0xfe {
return 0xfffd, 1, INVALID_CHAR
}
if p[1] >= 0x40 {
// 2-byte character
c := uint16(p[0])<<8 + uint16(p[1])
r = rune(gbkToUnicode[c])
if r == 0 {
r = gbkToUnicodeExtra[c]
}
if r != 0 {
return r, 2, SUCCESS
}
} else if p[1] >= 0x30 {
// 4-byte character
if len(p) < 4 {
return 0, 0, NO_ROOM
}
if p[2] < 0x81 || p[2] > 0xfe || p[3] < 0x30 || p[3] > 0x39 {
return 0xfffd, 1, INVALID_CHAR
}
code := uint32(p[0])<<24 + uint32(p[1])<<16 + uint32(p[2])<<8 + uint32(p[3])
lin := gb18030Linear(code)
if lin <= maxGB18030Linear {
r = rune(gb18030LinearToUnicode[lin])
if r != 0 {
return r, 4, SUCCESS
}
}
for _, rng := range gb18030Ranges {
if lin >= rng.firstGB && lin <= rng.lastGB {
return rng.firstRune + rune(lin) - rune(rng.firstGB), 4, SUCCESS
}
}
}
return 0xfffd, 1, INVALID_CHAR
}
func encodeGB18030Rune(p []byte, r rune) (size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
if r < 128 {
p[0] = byte(r)
return 1, SUCCESS
}
if len(p) < 2 {
status = NO_ROOM
return
}
var c uint16
if r < 0x10000 {
c = unicodeToGBK[r]
} else {
c = unicodeToGBKExtra[r]
}
if c != 0 {
p[0] = byte(c >> 8)
p[1] = byte(c)
return 2, SUCCESS
}
if len(p) < 4 {
return 0, NO_ROOM
}
if r < 0x10000 {
f := unicodeToGB18030[r]
if f != 0 {
p[0] = byte(f >> 24)
p[1] = byte(f >> 16)
p[2] = byte(f >> 8)
p[3] = byte(f)
return 4, SUCCESS
}
}
for _, rng := range gb18030Ranges {
if r >= rng.firstRune && r <= rng.lastRune {
lin := rng.firstGB + uint32(r) - uint32(rng.firstRune)
p[0] = byte(lin/(10*126*10)) + 0x81
p[1] = byte(lin/(126*10)%10) + 0x30
p[2] = byte(lin/10%126) + 0x81
p[3] = byte(lin%10) + 0x30
return 4, SUCCESS
}
}
p[0] = 0x1a
return 1, INVALID_CHAR
}
var gb18030Once sync.Once
// Mapping from gb18039Linear values to Unicode.
var gb18030LinearToUnicode []uint16
var unicodeToGB18030 []uint32
func buildGB18030Tables() {
gb18030LinearToUnicode = make([]uint16, maxGB18030Linear+1)
unicodeToGB18030 = make([]uint32, 65536)
for _, data := range gb18030Data {
gb18030LinearToUnicode[gb18030Linear(data.gb18030)] = data.unicode
unicodeToGB18030[data.unicode] = data.gb18030
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,78 +0,0 @@
package mahonia
// Converters for GBK encoding.
func init() {
RegisterCharset(&Charset{
Name: "GBK",
Aliases: []string{"GB2312"}, // GBK is a superset of GB2312.
NewDecoder: func() Decoder {
return decodeGBKRune
},
NewEncoder: func() Encoder {
return encodeGBKRune
},
})
}
func decodeGBKRune(p []byte) (r rune, size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
b := p[0]
if b < 128 {
return rune(b), 1, SUCCESS
}
if len(p) < 2 {
status = NO_ROOM
return
}
c := uint16(p[0])<<8 + uint16(p[1])
r = rune(gbkToUnicode[c])
if r == 0 {
r = gbkToUnicodeExtra[c]
}
if r != 0 {
return r, 2, SUCCESS
}
return 0xfffd, 1, INVALID_CHAR
}
func encodeGBKRune(p []byte, r rune) (size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
if r < 128 {
p[0] = byte(r)
return 1, SUCCESS
}
if len(p) < 2 {
status = NO_ROOM
return
}
var c uint16
if r < 0x10000 {
c = unicodeToGBK[r]
} else {
c = unicodeToGBKExtra[r]
}
if c != 0 {
p[0] = byte(c >> 8)
p[1] = byte(c)
return 2, SUCCESS
}
p[0] = 0x1a
return 1, INVALID_CHAR
}

View File

@@ -1,124 +0,0 @@
package mahonia
import (
"unicode/utf8"
)
// converters for ISO-2022-JP encoding
const esc = 27
func init() {
type jpEncoding int
const (
ascii jpEncoding = iota
jisX0201Roman
jisX0208
)
RegisterCharset(&Charset{
Name: "ISO-2022-JP",
NewDecoder: func() Decoder {
encoding := ascii
return func(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
return 0, 0, NO_ROOM
}
b := p[0]
if b == esc {
if len(p) < 3 {
return 0, 0, NO_ROOM
}
switch p[1] {
case '(':
switch p[2] {
case 'B':
encoding = ascii
return 0, 3, STATE_ONLY
case 'J':
encoding = jisX0201Roman
return 0, 3, STATE_ONLY
}
case '$':
switch p[2] {
case '@', 'B':
encoding = jisX0208
return 0, 3, STATE_ONLY
}
}
}
switch encoding {
case ascii:
if b > 127 {
return utf8.RuneError, 1, INVALID_CHAR
}
return rune(b), 1, SUCCESS
case jisX0201Roman:
if b > 127 {
return utf8.RuneError, 1, INVALID_CHAR
}
switch b {
case '\\':
return 0xA5, 1, SUCCESS
case '~':
return 0x203E, 1, SUCCESS
}
return rune(b), 1, SUCCESS
case jisX0208:
return jis0208Table.DecodeLow(p)
}
panic("unreachable")
}
},
NewEncoder: func() Encoder {
jis0208Table.Reverse()
encoding := ascii
return func(p []byte, c rune) (size int, status Status) {
if len(p) == 0 {
return 0, NO_ROOM
}
if c < 128 {
if encoding != ascii {
if len(p) < 4 {
return 0, NO_ROOM
}
p[0], p[1], p[2] = esc, '(', 'B'
p[3] = byte(c)
encoding = ascii
return 4, SUCCESS
}
p[0] = byte(c)
return 1, SUCCESS
}
if c > 65535 {
return 0, INVALID_CHAR
}
jis := jis0208Table.FromUnicode[c]
if jis == [2]byte{0, 0} && c != rune(jis0208Table.Data[0][0]) {
return 0, INVALID_CHAR
}
if encoding != jisX0208 {
if len(p) < 3 {
return 0, NO_ROOM
}
p[0], p[1], p[2] = esc, '$', 'B'
encoding = jisX0208
return 3, STATE_ONLY
}
p[0] = jis[0] + 0x21
p[1] = jis[1] + 0x21
return 2, SUCCESS
}
},
})
}

View File

@@ -1,162 +0,0 @@
package mahonia
var jis0201ToUnicode = [256]uint16{
0x20: 0x0020, // SPACE
0x21: 0x0021, // EXCLAMATION MARK
0x22: 0x0022, // QUOTATION MARK
0x23: 0x0023, // NUMBER SIGN
0x24: 0x0024, // DOLLAR SIGN
0x25: 0x0025, // PERCENT SIGN
0x26: 0x0026, // AMPERSAND
0x27: 0x0027, // APOSTROPHE
0x28: 0x0028, // LEFT PARENTHESIS
0x29: 0x0029, // RIGHT PARENTHESIS
0x2A: 0x002A, // ASTERISK
0x2B: 0x002B, // PLUS SIGN
0x2C: 0x002C, // COMMA
0x2D: 0x002D, // HYPHEN-MINUS
0x2E: 0x002E, // FULL STOP
0x2F: 0x002F, // SOLIDUS
0x30: 0x0030, // DIGIT ZERO
0x31: 0x0031, // DIGIT ONE
0x32: 0x0032, // DIGIT TWO
0x33: 0x0033, // DIGIT THREE
0x34: 0x0034, // DIGIT FOUR
0x35: 0x0035, // DIGIT FIVE
0x36: 0x0036, // DIGIT SIX
0x37: 0x0037, // DIGIT SEVEN
0x38: 0x0038, // DIGIT EIGHT
0x39: 0x0039, // DIGIT NINE
0x3A: 0x003A, // COLON
0x3B: 0x003B, // SEMICOLON
0x3C: 0x003C, // LESS-THAN SIGN
0x3D: 0x003D, // EQUALS SIGN
0x3E: 0x003E, // GREATER-THAN SIGN
0x3F: 0x003F, // QUESTION MARK
0x40: 0x0040, // COMMERCIAL AT
0x41: 0x0041, // LATIN CAPITAL LETTER A
0x42: 0x0042, // LATIN CAPITAL LETTER B
0x43: 0x0043, // LATIN CAPITAL LETTER C
0x44: 0x0044, // LATIN CAPITAL LETTER D
0x45: 0x0045, // LATIN CAPITAL LETTER E
0x46: 0x0046, // LATIN CAPITAL LETTER F
0x47: 0x0047, // LATIN CAPITAL LETTER G
0x48: 0x0048, // LATIN CAPITAL LETTER H
0x49: 0x0049, // LATIN CAPITAL LETTER I
0x4A: 0x004A, // LATIN CAPITAL LETTER J
0x4B: 0x004B, // LATIN CAPITAL LETTER K
0x4C: 0x004C, // LATIN CAPITAL LETTER L
0x4D: 0x004D, // LATIN CAPITAL LETTER M
0x4E: 0x004E, // LATIN CAPITAL LETTER N
0x4F: 0x004F, // LATIN CAPITAL LETTER O
0x50: 0x0050, // LATIN CAPITAL LETTER P
0x51: 0x0051, // LATIN CAPITAL LETTER Q
0x52: 0x0052, // LATIN CAPITAL LETTER R
0x53: 0x0053, // LATIN CAPITAL LETTER S
0x54: 0x0054, // LATIN CAPITAL LETTER T
0x55: 0x0055, // LATIN CAPITAL LETTER U
0x56: 0x0056, // LATIN CAPITAL LETTER V
0x57: 0x0057, // LATIN CAPITAL LETTER W
0x58: 0x0058, // LATIN CAPITAL LETTER X
0x59: 0x0059, // LATIN CAPITAL LETTER Y
0x5A: 0x005A, // LATIN CAPITAL LETTER Z
0x5B: 0x005B, // LEFT SQUARE BRACKET
0x5C: 0x00A5, // YEN SIGN
0x5D: 0x005D, // RIGHT SQUARE BRACKET
0x5E: 0x005E, // CIRCUMFLEX ACCENT
0x5F: 0x005F, // LOW LINE
0x60: 0x0060, // GRAVE ACCENT
0x61: 0x0061, // LATIN SMALL LETTER A
0x62: 0x0062, // LATIN SMALL LETTER B
0x63: 0x0063, // LATIN SMALL LETTER C
0x64: 0x0064, // LATIN SMALL LETTER D
0x65: 0x0065, // LATIN SMALL LETTER E
0x66: 0x0066, // LATIN SMALL LETTER F
0x67: 0x0067, // LATIN SMALL LETTER G
0x68: 0x0068, // LATIN SMALL LETTER H
0x69: 0x0069, // LATIN SMALL LETTER I
0x6A: 0x006A, // LATIN SMALL LETTER J
0x6B: 0x006B, // LATIN SMALL LETTER K
0x6C: 0x006C, // LATIN SMALL LETTER L
0x6D: 0x006D, // LATIN SMALL LETTER M
0x6E: 0x006E, // LATIN SMALL LETTER N
0x6F: 0x006F, // LATIN SMALL LETTER O
0x70: 0x0070, // LATIN SMALL LETTER P
0x71: 0x0071, // LATIN SMALL LETTER Q
0x72: 0x0072, // LATIN SMALL LETTER R
0x73: 0x0073, // LATIN SMALL LETTER S
0x74: 0x0074, // LATIN SMALL LETTER T
0x75: 0x0075, // LATIN SMALL LETTER U
0x76: 0x0076, // LATIN SMALL LETTER V
0x77: 0x0077, // LATIN SMALL LETTER W
0x78: 0x0078, // LATIN SMALL LETTER X
0x79: 0x0079, // LATIN SMALL LETTER Y
0x7A: 0x007A, // LATIN SMALL LETTER Z
0x7B: 0x007B, // LEFT CURLY BRACKET
0x7C: 0x007C, // VERTICAL LINE
0x7D: 0x007D, // RIGHT CURLY BRACKET
0x7E: 0x203E, // OVERLINE
0xA1: 0xFF61, // HALFWIDTH IDEOGRAPHIC FULL STOP
0xA2: 0xFF62, // HALFWIDTH LEFT CORNER BRACKET
0xA3: 0xFF63, // HALFWIDTH RIGHT CORNER BRACKET
0xA4: 0xFF64, // HALFWIDTH IDEOGRAPHIC COMMA
0xA5: 0xFF65, // HALFWIDTH KATAKANA MIDDLE DOT
0xA6: 0xFF66, // HALFWIDTH KATAKANA LETTER WO
0xA7: 0xFF67, // HALFWIDTH KATAKANA LETTER SMALL A
0xA8: 0xFF68, // HALFWIDTH KATAKANA LETTER SMALL I
0xA9: 0xFF69, // HALFWIDTH KATAKANA LETTER SMALL U
0xAA: 0xFF6A, // HALFWIDTH KATAKANA LETTER SMALL E
0xAB: 0xFF6B, // HALFWIDTH KATAKANA LETTER SMALL O
0xAC: 0xFF6C, // HALFWIDTH KATAKANA LETTER SMALL YA
0xAD: 0xFF6D, // HALFWIDTH KATAKANA LETTER SMALL YU
0xAE: 0xFF6E, // HALFWIDTH KATAKANA LETTER SMALL YO
0xAF: 0xFF6F, // HALFWIDTH KATAKANA LETTER SMALL TU
0xB0: 0xFF70, // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
0xB1: 0xFF71, // HALFWIDTH KATAKANA LETTER A
0xB2: 0xFF72, // HALFWIDTH KATAKANA LETTER I
0xB3: 0xFF73, // HALFWIDTH KATAKANA LETTER U
0xB4: 0xFF74, // HALFWIDTH KATAKANA LETTER E
0xB5: 0xFF75, // HALFWIDTH KATAKANA LETTER O
0xB6: 0xFF76, // HALFWIDTH KATAKANA LETTER KA
0xB7: 0xFF77, // HALFWIDTH KATAKANA LETTER KI
0xB8: 0xFF78, // HALFWIDTH KATAKANA LETTER KU
0xB9: 0xFF79, // HALFWIDTH KATAKANA LETTER KE
0xBA: 0xFF7A, // HALFWIDTH KATAKANA LETTER KO
0xBB: 0xFF7B, // HALFWIDTH KATAKANA LETTER SA
0xBC: 0xFF7C, // HALFWIDTH KATAKANA LETTER SI
0xBD: 0xFF7D, // HALFWIDTH KATAKANA LETTER SU
0xBE: 0xFF7E, // HALFWIDTH KATAKANA LETTER SE
0xBF: 0xFF7F, // HALFWIDTH KATAKANA LETTER SO
0xC0: 0xFF80, // HALFWIDTH KATAKANA LETTER TA
0xC1: 0xFF81, // HALFWIDTH KATAKANA LETTER TI
0xC2: 0xFF82, // HALFWIDTH KATAKANA LETTER TU
0xC3: 0xFF83, // HALFWIDTH KATAKANA LETTER TE
0xC4: 0xFF84, // HALFWIDTH KATAKANA LETTER TO
0xC5: 0xFF85, // HALFWIDTH KATAKANA LETTER NA
0xC6: 0xFF86, // HALFWIDTH KATAKANA LETTER NI
0xC7: 0xFF87, // HALFWIDTH KATAKANA LETTER NU
0xC8: 0xFF88, // HALFWIDTH KATAKANA LETTER NE
0xC9: 0xFF89, // HALFWIDTH KATAKANA LETTER NO
0xCA: 0xFF8A, // HALFWIDTH KATAKANA LETTER HA
0xCB: 0xFF8B, // HALFWIDTH KATAKANA LETTER HI
0xCC: 0xFF8C, // HALFWIDTH KATAKANA LETTER HU
0xCD: 0xFF8D, // HALFWIDTH KATAKANA LETTER HE
0xCE: 0xFF8E, // HALFWIDTH KATAKANA LETTER HO
0xCF: 0xFF8F, // HALFWIDTH KATAKANA LETTER MA
0xD0: 0xFF90, // HALFWIDTH KATAKANA LETTER MI
0xD1: 0xFF91, // HALFWIDTH KATAKANA LETTER MU
0xD2: 0xFF92, // HALFWIDTH KATAKANA LETTER ME
0xD3: 0xFF93, // HALFWIDTH KATAKANA LETTER MO
0xD4: 0xFF94, // HALFWIDTH KATAKANA LETTER YA
0xD5: 0xFF95, // HALFWIDTH KATAKANA LETTER YU
0xD6: 0xFF96, // HALFWIDTH KATAKANA LETTER YO
0xD7: 0xFF97, // HALFWIDTH KATAKANA LETTER RA
0xD8: 0xFF98, // HALFWIDTH KATAKANA LETTER RI
0xD9: 0xFF99, // HALFWIDTH KATAKANA LETTER RU
0xDA: 0xFF9A, // HALFWIDTH KATAKANA LETTER RE
0xDB: 0xFF9B, // HALFWIDTH KATAKANA LETTER RO
0xDC: 0xFF9C, // HALFWIDTH KATAKANA LETTER WA
0xDD: 0xFF9D, // HALFWIDTH KATAKANA LETTER N
0xDE: 0xFF9E, // HALFWIDTH KATAKANA VOICED SOUND MARK
0xDF: 0xFF9F, // HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,88 +0,0 @@
package mahonia
import (
"sync"
"unicode/utf8"
)
// A kutenTable holds the data for a double-byte character set, arranged by ku
// (区, zone) and ten (点, position). These can be converted to various actual
// encoding schemes.
type kutenTable struct {
// Data[ku][ten] is the unicode value for the character at that zone and
// position.
Data [94][94]uint16
// FromUnicode holds the ku and ten for each Unicode code point.
// It is not available until Reverse() has been called.
FromUnicode [][2]byte
// once is used to synchronize the generation of FromUnicode.
once sync.Once
}
// Reverse generates FromUnicode.
func (t *kutenTable) Reverse() {
t.once.Do(func() {
t.FromUnicode = make([][2]byte, 65536)
for ku := range t.Data {
for ten, unicode := range t.Data[ku] {
t.FromUnicode[unicode] = [2]byte{byte(ku), byte(ten)}
}
}
})
}
// DecodeLow decodes a character from an encoding that does not have the high
// bit set.
func (t *kutenTable) DecodeLow(p []byte) (c rune, size int, status Status) {
if len(p) < 2 {
return 0, 0, NO_ROOM
}
ku := p[0] - 0x21
ten := p[1] - 0x21
if ku > 93 || ten > 93 {
return utf8.RuneError, 1, INVALID_CHAR
}
u := t.Data[ku][ten]
if u == 0 {
return utf8.RuneError, 1, INVALID_CHAR
}
return rune(u), 2, SUCCESS
}
// DecodeHigh decodes a character from an encoding that has the high bit set.
func (t *kutenTable) DecodeHigh(p []byte) (c rune, size int, status Status) {
if len(p) < 2 {
return 0, 0, NO_ROOM
}
ku := p[0] - 0xa1
ten := p[1] - 0xa1
if ku > 93 || ten > 93 {
return utf8.RuneError, 1, INVALID_CHAR
}
u := t.Data[ku][ten]
if u == 0 {
return utf8.RuneError, 1, INVALID_CHAR
}
return rune(u), 2, SUCCESS
}
// EncodeHigh encodes a character in an encoding that has the high bit set.
func (t *kutenTable) EncodeHigh(p []byte, c rune) (size int, status Status) {
if len(p) < 2 {
return 0, NO_ROOM
}
if c > 0xffff {
p[0] = '?'
return 1, INVALID_CHAR
}
kuten := t.FromUnicode[c]
if kuten == [2]byte{0, 0} && c != rune(t.Data[0][0]) {
p[0] = '?'
return 1, INVALID_CHAR
}
p[0] = kuten[0] + 0xa1
p[1] = kuten[1] + 0xa1
return 2, SUCCESS
}

View File

@@ -1,229 +0,0 @@
package mahonia
import (
"bytes"
"io/ioutil"
"testing"
)
var nameTests = map[string]string{
"utf8": "utf8",
"ISO 8859-1": "iso88591",
"Big5": "big5",
"": "",
}
func TestSimplifyName(t *testing.T) {
for name, simple := range nameTests {
if simple != simplifyName(name) {
t.Errorf("%s came out as %s instead of as %s", name, simplifyName(name), simple)
}
}
}
var testData = []struct {
utf8, other, otherEncoding string
}{
{"Résumé", "Résumé", "utf8"},
{"Résumé", "R\xe9sum\xe9", "latin-1"},
{"これは漢字です。", "S0\x8c0o0\"oW[g0Y0\x020", "UTF-16LE"},
{"これは漢字です。", "0S0\x8c0oo\"[W0g0Y0\x02", "UTF-16BE"},
{"これは漢字です。", "\xfe\xff0S0\x8c0oo\"[W0g0Y0\x02", "UTF-16"},
{"𝄢𝄞𝄪𝄫", "\xfe\xff\xd8\x34\xdd\x22\xd8\x34\xdd\x1e\xd8\x34\xdd\x2a\xd8\x34\xdd\x2b", "UTF-16"},
{"Hello, world", "Hello, world", "ASCII"},
{"Gdańsk", "Gda\xf1sk", "ISO-8859-2"},
{"Ââ Čč Đđ Ŋŋ Õõ Šš Žž Åå Ää", "\xc2\xe2 \xc8\xe8 \xa9\xb9 \xaf\xbf \xd5\xf5 \xaa\xba \xac\xbc \xc5\xe5 \xc4\xe4", "ISO-8859-10"},
{"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "ISO-8859-11"},
{"latviešu", "latvie\xf0u", "ISO-8859-13"},
{"Seònaid", "Se\xf2naid", "ISO-8859-14"},
{"€1 is cheap", "\xa41 is cheap", "ISO-8859-15"},
{"românește", "rom\xe2ne\xbate", "ISO-8859-16"},
{"nutraĵo", "nutra\xbco", "ISO-8859-3"},
{"Kalâdlit", "Kal\xe2dlit", "ISO-8859-4"},
{"русский", "\xe0\xe3\xe1\xe1\xda\xd8\xd9", "ISO-8859-5"},
{"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "ISO-8859-7"},
{"Kağan", "Ka\xf0an", "ISO-8859-9"},
{"Résumé", "R\x8esum\x8e", "macintosh"},
{"Gdańsk", "Gda\xf1sk", "windows-1250"},
{"русский", "\xf0\xf3\xf1\xf1\xea\xe8\xe9", "windows-1251"},
{"Résumé", "R\xe9sum\xe9", "windows-1252"},
{"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "windows-1253"},
{"Kağan", "Ka\xf0an", "windows-1254"},
{"עִבְרִית", "\xf2\xc4\xe1\xc0\xf8\xc4\xe9\xfa", "windows-1255"},
{"العربية", "\xc7\xe1\xda\xd1\xc8\xed\xc9", "windows-1256"},
{"latviešu", "latvie\xf0u", "windows-1257"},
{"Việt", "Vi\xea\xf2t", "windows-1258"},
{"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "windows-874"},
{"русский", "\xd2\xd5\xd3\xd3\xcb\xc9\xca", "KOI8-R"},
{"українська", "\xd5\xcb\xd2\xc1\xa7\xce\xd3\xd8\xcb\xc1", "KOI8-U"},
{"Hello 常用國字標準字體表", "Hello \xb1`\xa5\u03b0\xea\xa6r\xbc\u0437\u01e6r\xc5\xe9\xaa\xed", "big5"},
{"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gbk"},
{"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gb18030"},
{"עִבְרִית", "\x81\x30\xfb\x30\x81\x30\xf6\x34\x81\x30\xf9\x33\x81\x30\xf6\x30\x81\x30\xfb\x36\x81\x30\xf6\x34\x81\x30\xfa\x31\x81\x30\xfb\x38", "gb18030"},
{"㧯", "\x82\x31\x89\x38", "gb18030"},
{"これは漢字です。", "\x82\xb1\x82\xea\x82\xcd\x8a\xbf\x8e\x9a\x82\xc5\x82\xb7\x81B", "SJIS"},
{"Hello, 世界!", "Hello, \x90\xa2\x8aE!", "SJIS"},
{"イウエオカ", "\xb2\xb3\xb4\xb5\xb6", "SJIS"},
{"これは漢字です。", "\xa4\xb3\xa4\xec\xa4\u03f4\xc1\xbb\xfa\xa4\u01e4\xb9\xa1\xa3", "EUC-JP"},
{"これは漢字です。", "\xa4\xb3\xa4\xec\xa4\u03f4\xc1\xbb\xfa\xa4\u01e4\xb9\xa1\xa3", "CP51932"},
{"Thông tin bạn đồng hànhỌ", "Th\xabng tin b\xb9n \xae\xe5ng h\xb5nhO\xe4", "TCVN3"},
{"Hello, 世界!", "Hello, \x1b$B@$3&\x1b(B!", "ISO-2022-JP"},
{"네이트 | 즐거움의 시작, 슈파스(Spaβ) NATE", "\xb3\xd7\xc0\xcc\xc6\xae | \xc1\xf1\xb0\xc5\xbf\xf2\xc0\xc7 \xbd\xc3\xc0\xdb, \xbd\xb4\xc6\xc4\xbd\xba(Spa\xa5\xe2) NATE", "EUC-KR"},
}
func TestDecode(t *testing.T) {
for _, data := range testData {
d := NewDecoder(data.otherEncoding)
if d == nil {
t.Errorf("Could not create decoder for %s", data.otherEncoding)
continue
}
str := d.ConvertString(data.other)
if str != data.utf8 {
t.Errorf("Unexpected value: %#v (expected %#v)", str, data.utf8)
}
}
}
func TestDecodeTranslate(t *testing.T) {
for _, data := range testData {
d := NewDecoder(data.otherEncoding)
if d == nil {
t.Errorf("Could not create decoder for %s", data.otherEncoding)
continue
}
_, cdata, _ := d.Translate([]byte(data.other), true)
str := string(cdata)
if str != data.utf8 {
t.Errorf("Unexpected value: %#v (expected %#v)", str, data.utf8)
}
}
}
func TestEncode(t *testing.T) {
for _, data := range testData {
e := NewEncoder(data.otherEncoding)
if e == nil {
t.Errorf("Could not create encoder for %s", data.otherEncoding)
continue
}
str := e.ConvertString(data.utf8)
if str != data.other {
t.Errorf("Unexpected value: %#v (expected %#v)", str, data.other)
}
}
}
func TestReader(t *testing.T) {
for _, data := range testData {
d := NewDecoder(data.otherEncoding)
if d == nil {
t.Errorf("Could not create decoder for %s", data.otherEncoding)
continue
}
b := bytes.NewBufferString(data.other)
r := d.NewReader(b)
result, _ := ioutil.ReadAll(r)
str := string(result)
if str != data.utf8 {
t.Errorf("Unexpected value: %#v (expected %#v)", str, data.utf8)
}
}
}
func TestWriter(t *testing.T) {
for _, data := range testData {
e := NewEncoder(data.otherEncoding)
if e == nil {
t.Errorf("Could not create encoder for %s", data.otherEncoding)
continue
}
b := new(bytes.Buffer)
w := e.NewWriter(b)
w.Write([]byte(data.utf8))
str := b.String()
if str != data.other {
t.Errorf("Unexpected value: %#v (expected %#v)", str, data.other)
}
}
}
func TestFallback(t *testing.T) {
mixed := "résum\xe9 " // The space is needed because of the issue mentioned in the Note: in fallback.go
pure := "résumé "
d := FallbackDecoder(NewDecoder("utf8"), NewDecoder("ISO-8859-1"))
result := d.ConvertString(mixed)
if result != pure {
t.Errorf("Unexpected value: %#v (expected %#v)", result, pure)
}
}
func TestEntities(t *testing.T) {
escaped := "&notit; I'm &notin; I tell you&#X82&#32;&nLt; "
plain := "¬it; I'm ∉ I tell you\u201a \u226A\u20D2 "
d := FallbackDecoder(EntityDecoder(), NewDecoder("ISO-8859-1"))
result := d.ConvertString(escaped)
if result != plain {
t.Errorf("Unexpected value: %#v (expected %#v)", result, plain)
}
}
func TestConvertStringOK(t *testing.T) {
d := NewDecoder("ASCII")
if d == nil {
t.Fatal("Could not create decoder for ASCII")
}
str, ok := d.ConvertStringOK("hello")
if !ok {
t.Error("Spurious error found while decoding")
}
if str != "hello" {
t.Errorf("expected %#v, got %#v", "hello", str)
}
str, ok = d.ConvertStringOK("\x80")
if ok {
t.Error(`Failed to detect error decoding "\x80"`)
}
e := NewEncoder("ISO-8859-3")
if e == nil {
t.Fatal("Could not create encoder for ISO-8859-1")
}
str, ok = e.ConvertStringOK("nutraĵo")
if !ok {
t.Error("spurious error while encoding")
}
if str != "nutra\xbco" {
t.Errorf("expected %#v, got %#v", "nutra\xbco", str)
}
str, ok = e.ConvertStringOK("\x80abc")
if ok {
t.Error("failed to detect invalid UTF-8 while encoding")
}
str, ok = e.ConvertStringOK("русский")
if ok {
t.Error("failed to detect characters that couldn't be encoded")
}
}
func TestBadCharset(t *testing.T) {
d := NewDecoder("this is not a valid charset")
if d != nil {
t.Fatal("got a non-nil decoder for an invalid charset")
}
}

View File

@@ -1,40 +0,0 @@
package main
import (
"flag"
"io"
"log"
"os"
"github.com/gogits/gogs/modules/mahonia"
)
// An iconv workalike using mahonia.
var from = flag.String("f", "utf-8", "source character set")
var to = flag.String("t", "utf-8", "destination character set")
func main() {
flag.Parse()
var r io.Reader = os.Stdin
var w io.Writer = os.Stdout
if *from != "utf-8" {
decode := mahonia.NewDecoder(*from)
if decode == nil {
log.Fatalf("Could not create decoder for %s", *from)
}
r = decode.NewReader(r)
}
if *to != "utf-8" {
encode := mahonia.NewEncoder(*to)
if encode == nil {
log.Fatalf("Could not create decoder for %s", *to)
}
w = encode.NewWriter(w)
}
io.Copy(w, r)
}

View File

@@ -1,92 +0,0 @@
package mahonia
// Generic converters for multibyte character sets.
// An mbcsTrie contains the data to convert from the character set to Unicode.
// If a character would be encoded as "\x01\x02\x03", its unicode value would be found at t.children[1].children[2].children[3].rune
// children either is nil or has 256 elements.
type mbcsTrie struct {
// For leaf nodes, the Unicode character that is represented.
char rune
// For non-leaf nodes, the trie to decode the remainder of the character.
children []mbcsTrie
}
// A MBCSTable holds the data to convert to and from Unicode.
type MBCSTable struct {
toUnicode mbcsTrie
fromUnicode map[rune]string
}
// AddCharacter adds a character to the table. rune is its Unicode code point,
// and bytes contains the bytes used to encode it in the character set.
func (table *MBCSTable) AddCharacter(c rune, bytes string) {
if table.fromUnicode == nil {
table.fromUnicode = make(map[rune]string)
}
table.fromUnicode[c] = bytes
trie := &table.toUnicode
for i := 0; i < len(bytes); i++ {
if trie.children == nil {
trie.children = make([]mbcsTrie, 256)
}
b := bytes[i]
trie = &trie.children[b]
}
trie.char = c
}
func (table *MBCSTable) Decoder() Decoder {
return func(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
if p[0] == 0 {
return 0, 1, SUCCESS
}
trie := &table.toUnicode
for trie.char == 0 {
if trie.children == nil {
return 0xfffd, 1, INVALID_CHAR
}
if len(p) < size+1 {
return 0, 0, NO_ROOM
}
trie = &trie.children[p[size]]
size++
}
c = trie.char
status = SUCCESS
return
}
}
func (table *MBCSTable) Encoder() Encoder {
return func(p []byte, c rune) (size int, status Status) {
bytes := table.fromUnicode[c]
if bytes == "" {
if len(p) > 0 {
p[0] = '?'
return 1, INVALID_CHAR
} else {
return 0, NO_ROOM
}
}
if len(p) < len(bytes) {
return 0, NO_ROOM
}
return copy(p, bytes), SUCCESS
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,151 +0,0 @@
package mahonia
// This file is based on bufio.Reader in the Go standard library,
// which has the following copyright notice:
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
import (
"io"
"unicode/utf8"
)
const (
defaultBufSize = 4096
)
// Reader implements character-set decoding for an io.Reader object.
type Reader struct {
buf []byte
rd io.Reader
decode Decoder
r, w int
err error
}
// NewReader creates a new Reader that uses the receiver to decode text.
func (d Decoder) NewReader(rd io.Reader) *Reader {
b := new(Reader)
b.buf = make([]byte, defaultBufSize)
b.rd = rd
b.decode = d
return b
}
// fill reads a new chunk into the buffer.
func (b *Reader) fill() {
// Slide existing data to beginning.
if b.r > 0 {
copy(b.buf, b.buf[b.r:b.w])
b.w -= b.r
b.r = 0
}
// Read new data.
n, e := b.rd.Read(b.buf[b.w:])
b.w += n
if e != nil {
b.err = e
}
}
// Read reads data into p.
// It returns the number of bytes read into p.
// It calls Read at most once on the underlying Reader,
// hence n may be less than len(p).
// At EOF, the count will be zero and err will be os.EOF.
func (b *Reader) Read(p []byte) (n int, err error) {
n = len(p)
filled := false
if n == 0 {
return 0, b.err
}
if b.w == b.r {
if b.err != nil {
return 0, b.err
}
if n > len(b.buf) {
// Large read, empty buffer.
// Allocate a larger buffer for efficiency.
b.buf = make([]byte, n)
}
b.fill()
filled = true
if b.w == b.r {
return 0, b.err
}
}
i := 0
for i < n {
rune, size, status := b.decode(b.buf[b.r:b.w])
if status == STATE_ONLY {
b.r += size
continue
}
if status == NO_ROOM {
if b.err != nil {
rune = 0xfffd
size = b.w - b.r
if size == 0 {
break
}
status = INVALID_CHAR
} else if filled {
break
} else {
b.fill()
filled = true
continue
}
}
if i+utf8.RuneLen(rune) > n {
break
}
b.r += size
if rune < 128 {
p[i] = byte(rune)
i++
} else {
i += utf8.EncodeRune(p[i:], rune)
}
}
return i, nil
}
// ReadRune reads a single Unicode character and returns the
// rune and its size in bytes.
func (b *Reader) ReadRune() (c rune, size int, err error) {
read:
c, size, status := b.decode(b.buf[b.r:b.w])
if status == NO_ROOM && b.err == nil {
b.fill()
goto read
}
if status == STATE_ONLY {
b.r += size
goto read
}
if b.r == b.w {
return 0, 0, b.err
}
if status == NO_ROOM {
c = 0xfffd
size = b.w - b.r
status = INVALID_CHAR
}
b.r += size
return c, size, nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,88 +0,0 @@
package mahonia
// Converters for the Shift-JIS encoding.
import (
"unicode/utf8"
)
func init() {
RegisterCharset(&Charset{
Name: "Shift_JIS",
Aliases: []string{"MS_Kanji", "csShiftJIS", "SJIS", "ibm-943", "windows-31j", "cp932", "windows-932"},
NewDecoder: func() Decoder {
return decodeSJIS
},
NewEncoder: func() Encoder {
shiftJISOnce.Do(reverseShiftJISTable)
return encodeSJIS
},
})
}
func decodeSJIS(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
return 0, 0, NO_ROOM
}
b := p[0]
if b < 0x80 {
return rune(b), 1, SUCCESS
}
if 0xa1 <= b && b <= 0xdf {
return rune(b) + (0xff61 - 0xa1), 1, SUCCESS
}
if b == 0x80 || b == 0xa0 {
return utf8.RuneError, 1, INVALID_CHAR
}
if len(p) < 2 {
return 0, 0, NO_ROOM
}
jis := int(b)<<8 + int(p[1])
c = rune(shiftJISToUnicode[jis])
if c == 0 {
return utf8.RuneError, 2, INVALID_CHAR
}
return c, 2, SUCCESS
}
func encodeSJIS(p []byte, c rune) (size int, status Status) {
if len(p) == 0 {
return 0, NO_ROOM
}
if c < 0x80 {
p[0] = byte(c)
return 1, SUCCESS
}
if 0xff61 <= c && c <= 0xff9f {
// half-width katakana
p[0] = byte(c - (0xff61 - 0xa1))
return 1, SUCCESS
}
if len(p) < 2 {
return 0, NO_ROOM
}
if c > 0xffff {
p[0] = '?'
return 1, INVALID_CHAR
}
jis := unicodeToShiftJIS[c]
if jis == 0 {
p[0] = '?'
return 1, INVALID_CHAR
}
p[0] = byte(jis >> 8)
p[1] = byte(jis)
return 2, SUCCESS
}

View File

@@ -1,228 +0,0 @@
package mahonia
// Converters for TCVN3 encoding.
import (
"sync"
)
var (
onceTCVN3 sync.Once
dataTCVN3 = struct {
UnicodeToWord map[rune][2]byte
WordToUnicode [256]struct {
r rune
m *[256]rune
}
}{}
)
func init() {
p := new(Charset)
p.Name = "TCVN3"
p.NewDecoder = func() Decoder {
onceTCVN3.Do(buildTCVN3Tables)
return decodeTCVN3
}
p.NewEncoder = func() Encoder {
onceTCVN3.Do(buildTCVN3Tables)
return encodeTCVN3
}
RegisterCharset(p)
}
func decodeTCVN3(p []byte) (rune, int, Status) {
if len(p) == 0 {
return 0, 0, NO_ROOM
}
item := &dataTCVN3.WordToUnicode[p[0]]
if item.m != nil && len(p) > 1 {
if r := item.m[p[1]]; r != 0 {
return r, 2, SUCCESS
}
}
if item.r != 0 {
return item.r, 1, SUCCESS
}
if p[0] < 0x80 {
return rune(p[0]), 1, SUCCESS
}
return '?', 1, INVALID_CHAR
}
func encodeTCVN3(p []byte, c rune) (int, Status) {
if len(p) == 0 {
return 0, NO_ROOM
}
if c < rune(0x80) {
p[0] = byte(c)
return 1, SUCCESS
}
if v, ok := dataTCVN3.UnicodeToWord[c]; ok {
if v[1] != 0 {
if len(p) < 2 {
return 0, NO_ROOM
}
p[0] = v[0]
p[1] = v[1]
return 2, SUCCESS
} else {
p[0] = v[0]
return 1, SUCCESS
}
}
p[0] = '?'
return 1, INVALID_CHAR
}
func buildTCVN3Tables() {
dataTCVN3.UnicodeToWord = map[rune][2]byte{
// one byte
0x00C2: {0xA2, 0x00},
0x00CA: {0xA3, 0x00},
0x00D4: {0xA4, 0x00},
0x00E0: {0xB5, 0x00},
0x00E1: {0xB8, 0x00},
0x00E2: {0xA9, 0x00},
0x00E3: {0xB7, 0x00},
0x00E8: {0xCC, 0x00},
0x00E9: {0xD0, 0x00},
0x00EA: {0xAA, 0x00},
0x00EC: {0xD7, 0x00},
0x00ED: {0xDD, 0x00},
0x00F2: {0xDF, 0x00},
0x00F3: {0xE3, 0x00},
0x00F4: {0xAB, 0x00},
0x00F5: {0xE2, 0x00},
0x00F9: {0xEF, 0x00},
0x00FA: {0xF3, 0x00},
0x00FD: {0xFD, 0x00},
0x0102: {0xA1, 0x00},
0x0103: {0xA8, 0x00},
0x0110: {0xA7, 0x00},
0x0111: {0xAE, 0x00},
0x0129: {0xDC, 0x00},
0x0169: {0xF2, 0x00},
0x01A0: {0xA5, 0x00},
0x01A1: {0xAC, 0x00},
0x01AF: {0xA6, 0x00},
0x01B0: {0xAD, 0x00},
0x1EA1: {0xB9, 0x00},
0x1EA3: {0xB6, 0x00},
0x1EA5: {0xCA, 0x00},
0x1EA7: {0xC7, 0x00},
0x1EA9: {0xC8, 0x00},
0x1EAB: {0xC9, 0x00},
0x1EAD: {0xCB, 0x00},
0x1EAF: {0xBE, 0x00},
0x1EB1: {0xBB, 0x00},
0x1EB3: {0xBC, 0x00},
0x1EB5: {0xBD, 0x00},
0x1EB7: {0xC6, 0x00},
0x1EB9: {0xD1, 0x00},
0x1EBB: {0xCE, 0x00},
0x1EBD: {0xCF, 0x00},
0x1EBF: {0xD5, 0x00},
0x1EC1: {0xD2, 0x00},
0x1EC3: {0xD3, 0x00},
0x1EC5: {0xD4, 0x00},
0x1EC7: {0xD6, 0x00},
0x1EC9: {0xD8, 0x00},
0x1ECB: {0xDE, 0x00},
0x1ECD: {0xE4, 0x00},
0x1ECF: {0xE1, 0x00},
0x1ED1: {0xE8, 0x00},
0x1ED3: {0xE5, 0x00},
0x1ED5: {0xE6, 0x00},
0x1ED7: {0xE7, 0x00},
0x1ED9: {0xE9, 0x00},
0x1EDB: {0xED, 0x00},
0x1EDD: {0xEA, 0x00},
0x1EDF: {0xEB, 0x00},
0x1EE1: {0xEC, 0x00},
0x1EE3: {0xEE, 0x00},
0x1EE5: {0xF4, 0x00},
0x1EE7: {0xF1, 0x00},
0x1EE9: {0xF8, 0x00},
0x1EEB: {0xF5, 0x00},
0x1EED: {0xF6, 0x00},
0x1EEF: {0xF7, 0x00},
0x1EF1: {0xF9, 0x00},
0x1EF3: {0xFA, 0x00},
0x1EF5: {0xFE, 0x00},
0x1EF7: {0xFB, 0x00},
0x1EF9: {0xFC, 0x00},
// two bytes
0x00C0: {0x41, 0xB5},
0x00C1: {0x41, 0xB8},
0x00C3: {0x41, 0xB7},
0x00C8: {0x45, 0xCC},
0x00C9: {0x45, 0xD0},
0x00CC: {0x49, 0xD7},
0x00CD: {0x49, 0xDD},
0x00D2: {0x4F, 0xDF},
0x00D3: {0x4F, 0xE3},
0x00D5: {0x4F, 0xE2},
0x00D9: {0x55, 0xEF},
0x00DA: {0x55, 0xF3},
0x00DD: {0x59, 0xFD},
0x0128: {0x49, 0xDC},
0x0168: {0x55, 0xF2},
0x1EA0: {0x41, 0xB9},
0x1EA2: {0x41, 0xB6},
0x1EA4: {0xA2, 0xCA},
0x1EA6: {0xA2, 0xC7},
0x1EA8: {0xA2, 0xC8},
0x1EAA: {0xA2, 0xC9},
0x1EAC: {0xA2, 0xCB},
0x1EAE: {0xA1, 0xBE},
0x1EB0: {0xA1, 0xBB},
0x1EB2: {0xA1, 0xBC},
0x1EB4: {0xA1, 0xBD},
0x1EB6: {0xA1, 0xC6},
0x1EB8: {0x45, 0xD1},
0x1EBA: {0x45, 0xCE},
0x1EBC: {0x45, 0xCF},
0x1EBE: {0xA3, 0xD5},
0x1EC0: {0xA3, 0xD2},
0x1EC2: {0xA3, 0xD3},
0x1EC4: {0xA3, 0xD4},
0x1EC6: {0xA3, 0xD6},
0x1EC8: {0x49, 0xD8},
0x1ECA: {0x49, 0xDE},
0x1ECC: {0x4F, 0xE4},
0x1ECE: {0x4F, 0xE1},
0x1ED0: {0xA4, 0xE8},
0x1ED2: {0xA4, 0xE5},
0x1ED4: {0xA4, 0xE6},
0x1ED6: {0xA4, 0xE7},
0x1ED8: {0xA4, 0xE9},
0x1EDA: {0xA5, 0xED},
0x1EDC: {0xA5, 0xEA},
0x1EDE: {0xA5, 0xEB},
0x1EE0: {0xA5, 0xEC},
0x1EE2: {0xA5, 0xEE},
0x1EE4: {0x55, 0xF4},
0x1EE6: {0x55, 0xF1},
0x1EE8: {0xA6, 0xF8},
0x1EEA: {0xA6, 0xF5},
0x1EEC: {0xA6, 0xF6},
0x1EEE: {0xA6, 0xF7},
0x1EF0: {0xA6, 0xF9},
0x1EF2: {0x59, 0xFA},
0x1EF4: {0x59, 0xFE},
0x1EF6: {0x59, 0xFB},
0x1EF8: {0x59, 0xFC},
}
for r, b := range dataTCVN3.UnicodeToWord {
item := &dataTCVN3.WordToUnicode[b[0]]
if b[1] == 0 {
item.r = r
} else {
if item.m == nil {
item.m = new([256]rune)
}
item.m[b[1]] = r
}
}
}

View File

@@ -1,50 +0,0 @@
package mahonia
import "unicode/utf8"
// Translate enables a Decoder to implement go-charset's Translator interface.
func (d Decoder) Translate(data []byte, eof bool) (n int, cdata []byte, err error) {
cdata = make([]byte, len(data)+1)
destPos := 0
for n < len(data) {
rune, size, status := d(data[n:])
switch status {
case STATE_ONLY:
n += size
continue
case NO_ROOM:
if !eof {
return n, cdata[:destPos], nil
}
rune = 0xfffd
n = len(data)
default:
n += size
}
if rune < 128 {
if destPos >= len(cdata) {
cdata = doubleLength(cdata)
}
cdata[destPos] = byte(rune)
destPos++
} else {
if destPos+utf8.RuneLen(rune) > len(cdata) {
cdata = doubleLength(cdata)
}
destPos += utf8.EncodeRune(cdata[destPos:], rune)
}
}
return n, cdata[:destPos], nil
}
func doubleLength(b []byte) []byte {
b2 := make([]byte, 2*len(b))
copy(b2, b)
return b2
}

View File

@@ -1,170 +0,0 @@
package mahonia
import (
"unicode/utf16"
)
func init() {
for i := 0; i < len(utf16Charsets); i++ {
RegisterCharset(&utf16Charsets[i])
}
}
var utf16Charsets = []Charset{
{
Name: "UTF-16",
NewDecoder: func() Decoder {
var decodeRune Decoder
return func(p []byte) (c rune, size int, status Status) {
if decodeRune == nil {
// haven't read the BOM yet
if len(p) < 2 {
status = NO_ROOM
return
}
switch {
case p[0] == 0xfe && p[1] == 0xff:
decodeRune = decodeUTF16beRune
return 0, 2, STATE_ONLY
case p[0] == 0xff && p[1] == 0xfe:
decodeRune = decodeUTF16leRune
return 0, 2, STATE_ONLY
default:
decodeRune = decodeUTF16beRune
}
}
return decodeRune(p)
}
},
NewEncoder: func() Encoder {
wroteBOM := false
return func(p []byte, c rune) (size int, status Status) {
if !wroteBOM {
if len(p) < 2 {
status = NO_ROOM
return
}
p[0] = 0xfe
p[1] = 0xff
wroteBOM = true
return 2, STATE_ONLY
}
return encodeUTF16beRune(p, c)
}
},
},
{
Name: "UTF-16BE",
NewDecoder: func() Decoder { return decodeUTF16beRune },
NewEncoder: func() Encoder { return encodeUTF16beRune },
},
{
Name: "UTF-16LE",
NewDecoder: func() Decoder { return decodeUTF16leRune },
NewEncoder: func() Encoder { return encodeUTF16leRune },
},
}
func decodeUTF16beRune(p []byte) (r rune, size int, status Status) {
if len(p) < 2 {
status = NO_ROOM
return
}
c := rune(p[0])<<8 + rune(p[1])
if utf16.IsSurrogate(c) {
if len(p) < 4 {
status = NO_ROOM
return
}
c2 := rune(p[2])<<8 + rune(p[3])
c = utf16.DecodeRune(c, c2)
if c == 0xfffd {
return c, 2, INVALID_CHAR
} else {
return c, 4, SUCCESS
}
}
return c, 2, SUCCESS
}
func encodeUTF16beRune(p []byte, c rune) (size int, status Status) {
if c < 0x10000 {
if len(p) < 2 {
status = NO_ROOM
return
}
p[0] = byte(c >> 8)
p[1] = byte(c)
return 2, SUCCESS
}
if len(p) < 4 {
status = NO_ROOM
return
}
s1, s2 := utf16.EncodeRune(c)
p[0] = byte(s1 >> 8)
p[1] = byte(s1)
p[2] = byte(s2 >> 8)
p[3] = byte(s2)
return 4, SUCCESS
}
func decodeUTF16leRune(p []byte) (r rune, size int, status Status) {
if len(p) < 2 {
status = NO_ROOM
return
}
c := rune(p[1])<<8 + rune(p[0])
if utf16.IsSurrogate(c) {
if len(p) < 4 {
status = NO_ROOM
return
}
c2 := rune(p[3])<<8 + rune(p[2])
c = utf16.DecodeRune(c, c2)
if c == 0xfffd {
return c, 2, INVALID_CHAR
} else {
return c, 4, SUCCESS
}
}
return c, 2, SUCCESS
}
func encodeUTF16leRune(p []byte, c rune) (size int, status Status) {
if c < 0x10000 {
if len(p) < 2 {
status = NO_ROOM
return
}
p[1] = byte(c >> 8)
p[0] = byte(c)
return 2, SUCCESS
}
if len(p) < 4 {
status = NO_ROOM
return
}
s1, s2 := utf16.EncodeRune(c)
p[1] = byte(s1 >> 8)
p[0] = byte(s1)
p[3] = byte(s2 >> 8)
p[2] = byte(s2)
return 4, SUCCESS
}

View File

@@ -1,45 +0,0 @@
package mahonia
import "unicode/utf8"
func init() {
RegisterCharset(&Charset{
Name: "UTF-8",
NewDecoder: func() Decoder { return decodeUTF8Rune },
NewEncoder: func() Encoder { return encodeUTF8Rune },
})
}
func decodeUTF8Rune(p []byte) (c rune, size int, status Status) {
if len(p) == 0 {
status = NO_ROOM
return
}
if p[0] < 128 {
return rune(p[0]), 1, SUCCESS
}
c, size = utf8.DecodeRune(p)
if c == 0xfffd {
if utf8.FullRune(p) {
status = INVALID_CHAR
return
}
return 0, 0, NO_ROOM
}
status = SUCCESS
return
}
func encodeUTF8Rune(p []byte, c rune) (size int, status Status) {
size = utf8.RuneLen(c)
if size > len(p) {
return 0, NO_ROOM
}
return utf8.EncodeRune(p, c), SUCCESS
}

View File

@@ -1,108 +0,0 @@
package mahonia
import (
"io"
"unicode/utf8"
)
// Writer implements character-set encoding for an io.Writer object.
type Writer struct {
wr io.Writer
encode Encoder
inbuf []byte
outbuf []byte
}
// NewWriter creates a new Writer that uses the receiver to encode text.
func (e Encoder) NewWriter(wr io.Writer) *Writer {
w := new(Writer)
w.wr = wr
w.encode = e
return w
}
// Write encodes and writes the data from p.
func (w *Writer) Write(p []byte) (n int, err error) {
n = len(p)
if len(w.inbuf) > 0 {
w.inbuf = append(w.inbuf, p...)
p = w.inbuf
}
if len(w.outbuf) < len(p) {
w.outbuf = make([]byte, len(p)+10)
}
outpos := 0
for len(p) > 0 {
rune, size := utf8.DecodeRune(p)
if rune == 0xfffd && !utf8.FullRune(p) {
break
}
p = p[size:]
retry:
size, status := w.encode(w.outbuf[outpos:], rune)
if status == NO_ROOM {
newDest := make([]byte, len(w.outbuf)*2)
copy(newDest, w.outbuf)
w.outbuf = newDest
goto retry
}
if status == STATE_ONLY {
outpos += size
goto retry
}
outpos += size
}
w.inbuf = w.inbuf[:0]
if len(p) > 0 {
w.inbuf = append(w.inbuf, p...)
}
n1, err := w.wr.Write(w.outbuf[0:outpos])
if err != nil && n1 < n {
n = n1
}
return
}
func (w *Writer) WriteRune(c rune) (size int, err error) {
if len(w.inbuf) > 0 {
// There are leftover bytes, a partial UTF-8 sequence.
w.inbuf = w.inbuf[:0]
w.WriteRune(0xfffd)
}
if w.outbuf == nil {
w.outbuf = make([]byte, 16)
}
outpos := 0
retry:
size, status := w.encode(w.outbuf[outpos:], c)
if status == NO_ROOM {
w.outbuf = make([]byte, len(w.outbuf)*2)
goto retry
}
if status == STATE_ONLY {
outpos += size
goto retry
}
outpos += size
return w.wr.Write(w.outbuf[0:outpos])
}

View File

@@ -21,6 +21,7 @@ import (
const (
AUTH_ACTIVE base.TplName = "mail/auth/active"
AUTH_ACTIVATE_EMAIL base.TplName = "mail/auth/activate_email"
AUTH_REGISTER_SUCCESS base.TplName = "mail/auth/register_success"
AUTH_RESET_PASSWORD base.TplName = "mail/auth/reset_passwd"
@@ -30,9 +31,7 @@ const (
// Create New mail message use MailFrom and MailUser
func NewMailMessageFrom(To []string, from, subject, body string) Message {
msg := NewHtmlMessage(To, from, subject, body)
msg.User = setting.MailService.User
return msg
return NewHtmlMessage(To, from, subject, body)
}
// Create New mail message use MailFrom and MailUser
@@ -64,6 +63,17 @@ func CreateUserActiveCode(u *models.User, startInf interface{}) string {
return code
}
// create a time limit code for user active
func CreateUserEmailActivateCode(u *models.User, e *models.EmailAddress, startInf interface{}) string {
minutes := setting.Service.ActiveCodeLives
data := com.ToStr(u.Id) + e.Email + u.LowerName + u.Passwd + u.Rands
code := base.CreateTimeLimitCode(data, minutes, startInf)
// add tail hex username
code += hex.EncodeToString([]byte(u.LowerName))
return code
}
// Send user register mail with active code
func SendRegisterMail(r macaron.Render, u *models.User) {
code := CreateUserActiveCode(u, nil)
@@ -103,6 +113,27 @@ func SendActiveMail(r macaron.Render, u *models.User) {
SendAsync(&msg)
}
// Send email to verify secondary email.
func SendActivateEmail(r macaron.Render, user *models.User, email *models.EmailAddress) {
code := CreateUserEmailActivateCode(user, email, nil)
subject := "Verify your e-mail address"
data := GetMailTmplData(user)
data["Code"] = code
data["Email"] = email.Email
body, err := r.HTMLString(string(AUTH_ACTIVATE_EMAIL), data)
if err != nil {
log.Error(4, "mail.SendActiveMail(fail to render): %v", err)
return
}
msg := NewMailMessage([]string{email.Email}, subject, body)
msg.Info = fmt.Sprintf("UID: %d, send activate email to %s", user.Id, email.Email)
SendAsync(&msg)
}
// Send reset password email.
func SendResetPasswdMail(r macaron.Render, u *models.User) {
code := CreateUserActiveCode(u, nil)

View File

@@ -8,6 +8,7 @@ import (
"crypto/tls"
"fmt"
"net"
"net/mail"
"net/smtp"
"strings"
@@ -20,7 +21,6 @@ type Message struct {
From string
Subject string
Body string
User string
Type string
Massive bool
Info string
@@ -35,15 +35,14 @@ func (m Message) Content() string {
}
// create mail content
content := "From: \"" + m.From + "\" <" + m.User +
">\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
content := "From: " + m.From + "\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
return content
}
var mailQueue chan *Message
func NewMailerContext() {
mailQueue = make(chan *Message, setting.Cfg.MustInt("mailer", "SEND_BUFFER_LEN", 10))
mailQueue = make(chan *Message, setting.Cfg.Section("mailer").Key("SEND_BUFFER_LEN").MustInt(10))
go processMailQueue()
}
@@ -67,29 +66,67 @@ func processMailQueue() {
}
// sendMail allows mail with self-signed certificates.
func sendMail(hostAddressWithPort string, auth smtp.Auth, from string, recipients []string, msgContent []byte) error {
client, err := smtp.Dial(hostAddressWithPort)
func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte) error {
host, port, err := net.SplitHostPort(settings.Host)
if err != nil {
return err
}
host, _, _ := net.SplitHostPort(hostAddressWithPort)
tlsConn := &tls.Config{
InsecureSkipVerify: true,
tlsconfig := &tls.Config{
InsecureSkipVerify: settings.SkipVerify,
ServerName: host,
}
if err = client.StartTLS(tlsConn); err != nil {
conn, err := net.Dial("tcp", net.JoinHostPort(host, port))
if err != nil {
return err
}
defer conn.Close()
isSecureConn := false
// Start TLS directly if the port ends with 465 (SMTPS protocol)
if strings.HasSuffix(port, "465") {
conn = tls.Client(conn, tlsconfig)
isSecureConn = true
}
client, err := smtp.NewClient(conn, host)
if err != nil {
return err
}
if ok, _ := client.Extension("AUTH"); ok && auth != nil {
if err = client.Auth(auth); err != nil {
// If not using SMTPS, alway use STARTTLS if available
hasStartTLS, _ := client.Extension("STARTTLS")
if !isSecureConn && hasStartTLS {
if err = client.StartTLS(tlsconfig); err != nil {
return err
}
}
if err = client.Mail(from); err != nil {
canAuth, options := client.Extension("AUTH")
if canAuth && len(settings.User) > 0 {
var auth smtp.Auth
if strings.Contains(options, "CRAM-MD5") {
auth = smtp.CRAMMD5Auth(settings.User, settings.Passwd)
} else if strings.Contains(options, "PLAIN") {
auth = smtp.PlainAuth("", settings.User, settings.Passwd, host)
}
if auth != nil {
if err = client.Auth(auth); err != nil {
return err
}
}
}
if fromAddress, err := mail.ParseAddress(settings.From); err != nil {
return err
} else {
if err = client.Mail(fromAddress.Address); err != nil {
return err
}
}
for _, rec := range recipients {
@@ -116,7 +153,6 @@ func sendMail(hostAddressWithPort string, auth smtp.Auth, from string, recipient
// Direct Send mail message
func Send(msg *Message) (int, error) {
log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
host := strings.Split(setting.MailService.Host, ":")
// get message body
content := msg.Content()
@@ -127,14 +163,12 @@ func Send(msg *Message) (int, error) {
return 0, fmt.Errorf("empty email body")
}
auth := smtp.PlainAuth("", setting.MailService.User, setting.MailService.Passwd, host[0])
if msg.Massive {
// send mail to multiple emails one by one
num := 0
for _, to := range msg.To {
body := []byte("To: " + to + "\r\n" + content)
err := sendMail(setting.MailService.Host, auth, msg.From, []string{to}, body)
err := sendMail(setting.MailService, []string{to}, body)
if err != nil {
return num, err
}
@@ -145,7 +179,7 @@ func Send(msg *Message) (int, error) {
body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
// send to multiple emails in one message
err := sendMail(setting.MailService.Host, auth, msg.From, msg.To, body)
err := sendMail(setting.MailService, msg.To, body)
if err != nil {
return 0, err
} else {

View File

@@ -6,7 +6,6 @@ package middleware
import (
"net/url"
"strings"
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/csrf"
@@ -29,6 +28,12 @@ func Toggle(options *ToggleOptions) macaron.Handler {
return
}
// Checking non-logged users landing page.
if !ctx.IsSigned && ctx.Req.RequestURI == "/" && setting.LandingPageUrl != setting.LANDING_PAGE_HOME {
ctx.Redirect(string(setting.LandingPageUrl))
return
}
// Redirect to dashboard if user tries to visit any non-login page.
if options.SignOutRequire && ctx.IsSigned && ctx.Req.RequestURI != "/" {
ctx.Redirect(setting.AppSubUrl + "/")
@@ -44,11 +49,7 @@ func Toggle(options *ToggleOptions) macaron.Handler {
if options.SignInRequire {
if !ctx.IsSigned {
// Ignore watch repository operation.
if strings.HasSuffix(ctx.Req.RequestURI, "watch") {
return
}
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login")
return
} else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {

View File

@@ -39,29 +39,25 @@ type Context struct {
IsBasicAuth bool
Repo struct {
IsOwner bool
IsTrueOwner bool
IsWatching bool
IsBranch bool
IsTag bool
IsCommit bool
IsAdmin bool // Current user is admin level.
HasAccess bool
Repository *models.Repository
Owner *models.User
Commit *git.Commit
Tag *git.Tag
GitRepo *git.Repository
BranchName string
TagName string
TreeName string
CommitId string
RepoLink string
CloneLink struct {
SSH string
HTTPS string
Git string
}
IsOwner bool
IsTrueOwner bool
IsWatching bool
IsBranch bool
IsTag bool
IsCommit bool
IsAdmin bool // Current user is admin level.
HasAccess bool
Repository *models.Repository
Owner *models.User
Commit *git.Commit
Tag *git.Tag
GitRepo *git.Repository
BranchName string
TagName string
TreeName string
CommitId string
RepoLink string
CloneLink models.CloneLink
CommitsCount int
Mirror *models.Mirror
}
@@ -196,6 +192,8 @@ func Contexter() macaron.Handler {
ctx.Data["CsrfToken"] = x.GetToken()
ctx.Data["CsrfTokenHtml"] = template.HTML(`<input type="hidden" name="_csrf" value="` + x.GetToken() + `">`)
ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton
c.Map(ctx)
}
}

View File

@@ -48,7 +48,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Data["Org"] = org
if ctx.IsSigned {
ctx.Org.IsOwner = org.IsOrgOwner(ctx.User.Id)
ctx.Org.IsOwner = org.IsOwnedBy(ctx.User.Id)
if ctx.Org.IsOwner {
ctx.Org.IsMember = true
ctx.Org.IsAdminTeam = true

View File

@@ -55,7 +55,7 @@ func ApiRepoAssignment() macaron.Handler {
ctx.Repo.Owner = u
// Organization owner team members are true owners as well.
if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgOwner(ctx.User.Id) {
if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
ctx.Repo.IsTrueOwner = true
}
@@ -280,7 +280,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Repo.Owner = u
// Organization owner team members are true owners as well.
if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgOwner(ctx.User.Id) {
if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
ctx.Repo.IsTrueOwner = true
}
@@ -386,12 +386,12 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
ctx.Data["IsRepositoryTrueOwner"] = ctx.Repo.IsTrueOwner
if setting.SshPort != 22 {
ctx.Repo.CloneLink.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SshPort, u.LowerName, repo.LowerName)
} else {
ctx.Repo.CloneLink.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, u.LowerName, repo.LowerName)
ctx.Data["DisableSSH"] = setting.DisableSSH
ctx.Repo.CloneLink, err = repo.CloneLink()
if err != nil {
ctx.Handle(500, "CloneLink", err)
return
}
ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, u.LowerName, repo.LowerName)
ctx.Data["CloneLink"] = ctx.Repo.CloneLink
if ctx.Repo.Repository.IsGoget {
@@ -402,6 +402,8 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
// repo is bare and display enable
if ctx.Repo.Repository.IsBare {
log.Debug("Bare repository: %s", ctx.Repo.RepoLink)
// NOTE: to prevent templating error
ctx.Data["BranchName"] = ""
if displayBare {
ctx.HTML(200, "repo/bare")
}
@@ -451,7 +453,7 @@ func RequireTrueOwner() macaron.Handler {
}
}
// GitHookService checks if repsitory Git hooks service has been enabled.
// GitHookService checks if repository Git hooks service has been enabled.
func GitHookService() macaron.Handler {
return func(ctx *Context) {
if !ctx.User.AllowGitHook && !ctx.User.IsAdmin {

View File

@@ -16,11 +16,12 @@ import (
"time"
"github.com/Unknwon/com"
"github.com/Unknwon/goconfig"
"github.com/macaron-contrib/oauth2"
"github.com/macaron-contrib/session"
"gopkg.in/ini.v1"
"github.com/gogits/gogs/modules/log"
// "github.com/gogits/gogs-ng/modules/ssh"
// "github.com/gogits/gogs/modules/ssh"
)
type Scheme string
@@ -31,6 +32,13 @@ const (
FCGI Scheme = "fcgi"
)
type LandingPage string
const (
LANDING_PAGE_HOME LandingPage = "/"
LANDING_PAGE_EXPLORE LandingPage = "/explore"
)
var (
// App settings.
AppVer string
@@ -42,12 +50,14 @@ var (
Protocol Scheme
Domain string
HttpAddr, HttpPort string
SshPort int
DisableSSH bool
SSHPort int
OfflineMode bool
DisableRouterLog bool
CertFile, KeyFile string
StaticRootPath string
EnableGzip bool
LandingPageUrl LandingPage
// Security settings.
InstallLock bool
@@ -58,17 +68,21 @@ var (
ReverseProxyAuthUser string
// Webhook settings.
WebhookTaskInterval int
WebhookDeliverTimeout int
Webhook struct {
TaskInterval int
DeliverTimeout int
SkipTLSVerify bool
}
// Repository settings.
RepoRootPath string
ScriptType string
// Picture settings.
PictureService string
GravatarSource string
DisableGravatar bool
PictureService string
AvatarUploadPath string
GravatarSource string
DisableGravatar bool
// Log settings.
LogRootPath string
@@ -94,19 +108,27 @@ var (
EnableMemcache bool
// Session settings.
SessionProvider string
SessionConfig *session.Config
SessionConfig session.Options
// Git settings.
MaxGitDiffLines int
Git struct {
MaxGitDiffLines int
GcArgs []string `delim:" "`
Fsck struct {
Enable bool
Interval int
Args []string `delim:" "`
} `ini:"git.fsck"`
}
// I18n settings.
Langs, Names []string
// Global setting objects.
Cfg *goconfig.ConfigFile
Cfg *ini.File
ConfRootPath string
CustomPath string // Custom directory path.
CustomConf string
ProdMode bool
RunUser string
IsWindows bool
@@ -145,7 +167,7 @@ func NewConfigContext() {
}
ConfRootPath = path.Join(workDir, "conf")
Cfg, err = goconfig.LoadConfigFile(path.Join(workDir, "conf/app.ini"))
Cfg, err = ini.Load(path.Join(workDir, "conf/app.ini"))
if err != nil {
log.Fatal(4, "Fail to parse 'conf/app.ini': %v", err)
}
@@ -155,17 +177,24 @@ func NewConfigContext() {
CustomPath = path.Join(workDir, "custom")
}
cfgPath := path.Join(CustomPath, "conf/app.ini")
if com.IsFile(cfgPath) {
if err = Cfg.AppendFiles(cfgPath); err != nil {
log.Fatal(4, "Fail to load custom 'conf/app.ini': %v", err)
}
} else {
log.Warn("No custom 'conf/app.ini' found, please go to '/install'")
if len(CustomConf) == 0 {
CustomConf = path.Join(CustomPath, "conf/app.ini")
}
AppName = Cfg.MustValue("", "APP_NAME", "Gogs: Go Git Service")
AppUrl = Cfg.MustValue("server", "ROOT_URL", "http://localhost:3000/")
if com.IsFile(CustomConf) {
if err = Cfg.Append(CustomConf); err != nil {
log.Fatal(4, "Fail to load custom conf '%s': %v", CustomConf, err)
}
} else {
log.Warn("Custom config (%s) not found, ignore this if you're running first time", CustomConf)
}
Cfg.NameMapper = ini.AllCapsUnderscore
LogRootPath = Cfg.Section("log").Key("ROOT_PATH").MustString(path.Join(workDir, "log"))
sec := Cfg.Section("server")
AppName = Cfg.Section("").Key("APP_NAME").MustString("Gogs: Go Git Service")
AppUrl = sec.Key("ROOT_URL").MustString("http://localhost:3000/")
if AppUrl[len(AppUrl)-1] != '/' {
AppUrl += "/"
}
@@ -178,36 +207,44 @@ func NewConfigContext() {
AppSubUrl = strings.TrimSuffix(url.Path, "/")
Protocol = HTTP
if Cfg.MustValue("server", "PROTOCOL") == "https" {
if sec.Key("PROTOCOL").String() == "https" {
Protocol = HTTPS
CertFile = Cfg.MustValue("server", "CERT_FILE")
KeyFile = Cfg.MustValue("server", "KEY_FILE")
}
if Cfg.MustValue("server", "PROTOCOL") == "fcgi" {
CertFile = sec.Key("CERT_FILE").String()
KeyFile = sec.Key("KEY_FILE").String()
} else if sec.Key("PROTOCOL").String() == "fcgi" {
Protocol = FCGI
}
Domain = Cfg.MustValue("server", "DOMAIN", "localhost")
HttpAddr = Cfg.MustValue("server", "HTTP_ADDR", "0.0.0.0")
HttpPort = Cfg.MustValue("server", "HTTP_PORT", "3000")
SshPort = Cfg.MustInt("server", "SSH_PORT", 22)
OfflineMode = Cfg.MustBool("server", "OFFLINE_MODE")
DisableRouterLog = Cfg.MustBool("server", "DISABLE_ROUTER_LOG")
StaticRootPath = Cfg.MustValue("server", "STATIC_ROOT_PATH", workDir)
LogRootPath = Cfg.MustValue("log", "ROOT_PATH", path.Join(workDir, "log"))
EnableGzip = Cfg.MustBool("server", "ENABLE_GZIP")
Domain = sec.Key("DOMAIN").MustString("localhost")
HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
HttpPort = sec.Key("HTTP_PORT").MustString("3000")
DisableSSH = sec.Key("DISABLE_SSH").MustBool()
SSHPort = sec.Key("SSH_PORT").MustInt(22)
OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(workDir)
EnableGzip = sec.Key("ENABLE_GZIP").MustBool()
InstallLock = Cfg.MustBool("security", "INSTALL_LOCK")
SecretKey = Cfg.MustValue("security", "SECRET_KEY")
LogInRememberDays = Cfg.MustInt("security", "LOGIN_REMEMBER_DAYS")
CookieUserName = Cfg.MustValue("security", "COOKIE_USERNAME")
CookieRememberName = Cfg.MustValue("security", "COOKIE_REMEMBER_NAME")
ReverseProxyAuthUser = Cfg.MustValue("security", "REVERSE_PROXY_AUTHENTICATION_USER", "X-WEBAUTH-USER")
switch sec.Key("LANDING_PAGE").MustString("home") {
case "explore":
LandingPageUrl = LANDING_PAGE_EXPLORE
default:
LandingPageUrl = LANDING_PAGE_HOME
}
AttachmentPath = Cfg.MustValue("attachment", "PATH", "data/attachments")
AttachmentAllowedTypes = Cfg.MustValue("attachment", "ALLOWED_TYPES", "image/jpeg|image/png")
AttachmentMaxSize = Cfg.MustInt64("attachment", "MAX_SIZE", 32)
AttachmentMaxFiles = Cfg.MustInt("attachment", "MAX_FILES", 10)
AttachmentEnabled = Cfg.MustBool("attachment", "ENABLE", true)
sec = Cfg.Section("security")
InstallLock = sec.Key("INSTALL_LOCK").MustBool()
SecretKey = sec.Key("SECRET_KEY").String()
LogInRememberDays = sec.Key("LOGIN_REMEMBER_DAYS").MustInt()
CookieUserName = sec.Key("COOKIE_USERNAME").String()
CookieRememberName = sec.Key("COOKIE_REMEMBER_NAME").String()
ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER")
sec = Cfg.Section("attachment")
AttachmentPath = path.Join(workDir, sec.Key("PATH").MustString("data/attachments"))
AttachmentAllowedTypes = sec.Key("ALLOWED_TYPES").MustString("image/jpeg|image/png")
AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(32)
AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(10)
AttachmentEnabled = sec.Key("ENABLE").MustBool(true)
TimeFormat = map[string]string{
"ANSIC": time.ANSIC,
@@ -225,13 +262,13 @@ func NewConfigContext() {
"StampMilli": time.StampMilli,
"StampMicro": time.StampMicro,
"StampNano": time.StampNano,
}[Cfg.MustValue("time", "FORMAT", "RFC1123")]
}[Cfg.Section("time").Key("FORMAT").MustString("RFC1123")]
if err = os.MkdirAll(AttachmentPath, os.ModePerm); err != nil {
log.Fatal(4, "Could not create directory %s: %s", AttachmentPath, err)
}
RunUser = Cfg.MustValue("", "RUN_USER")
RunUser = Cfg.Section("").Key("RUN_USER").String()
curUser := os.Getenv("USER")
if len(curUser) == 0 {
curUser = os.Getenv("USERNAME")
@@ -241,59 +278,67 @@ func NewConfigContext() {
log.Fatal(4, "Expect user(%s) but current user is: %s", RunUser, curUser)
}
// Determine and create root git reposiroty path.
// Determine and create root git repository path.
homeDir, err := com.HomeDir()
if err != nil {
log.Fatal(4, "Fail to get home directory: %v", err)
}
RepoRootPath = Cfg.MustValue("repository", "ROOT", filepath.Join(homeDir, "gogs-repositories"))
sec = Cfg.Section("repository")
RepoRootPath = sec.Key("ROOT").MustString(filepath.Join(homeDir, "gogs-repositories"))
if !filepath.IsAbs(RepoRootPath) {
RepoRootPath = filepath.Join(workDir, RepoRootPath)
} else {
RepoRootPath = filepath.Clean(RepoRootPath)
}
if err = os.MkdirAll(RepoRootPath, os.ModePerm); err != nil {
log.Fatal(4, "Fail to create repository root path(%s): %v", RepoRootPath, err)
}
ScriptType = Cfg.MustValue("repository", "SCRIPT_TYPE", "bash")
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
PictureService = Cfg.MustValueRange("picture", "SERVICE", "server", []string{"server"})
switch Cfg.MustValue("picture", "GRAVATAR_SOURCE", "gravatar") {
sec = Cfg.Section("picture")
PictureService = sec.Key("SERVICE").In("server", []string{"server"})
AvatarUploadPath = path.Join(workDir, sec.Key("AVATAR_UPLOAD_PATH").MustString("data/avatars"))
os.MkdirAll(AvatarUploadPath, os.ModePerm)
switch sec.Key("GRAVATAR_SOURCE").MustString("gravatar") {
case "duoshuo":
GravatarSource = "http://gravatar.duoshuo.com/avatar/"
default:
GravatarSource = "//1.gravatar.com/avatar/"
}
DisableGravatar = Cfg.MustBool("picture", "DISABLE_GRAVATAR")
DisableGravatar = sec.Key("DISABLE_GRAVATAR").MustBool()
MaxGitDiffLines = Cfg.MustInt("git", "MAX_GITDIFF_LINES", 10000)
if err = Cfg.Section("git").MapTo(&Git); err != nil {
log.Fatal(4, "Fail to map Git settings: %v", err)
}
Langs = Cfg.MustValueArray("i18n", "LANGS", ",")
Names = Cfg.MustValueArray("i18n", "NAMES", ",")
Langs = Cfg.Section("i18n").Key("LANGS").Strings(",")
Names = Cfg.Section("i18n").Key("NAMES").Strings(",")
HasRobotsTxt = com.IsFile(path.Join(CustomPath, "robots.txt"))
}
var Service struct {
RegisterEmailConfirm bool
DisableRegistration bool
RequireSignInView bool
EnableCacheAvatar bool
EnableNotifyMail bool
EnableReverseProxyAuth bool
LdapAuth bool
ActiveCodeLives int
ResetPwdCodeLives int
RegisterEmailConfirm bool
DisableRegistration bool
ShowRegistrationButton bool
RequireSignInView bool
EnableCacheAvatar bool
EnableNotifyMail bool
EnableReverseProxyAuth bool
EnableReverseProxyAutoRegister bool
ActiveCodeLives int
ResetPwdCodeLives int
}
func newService() {
Service.ActiveCodeLives = Cfg.MustInt("service", "ACTIVE_CODE_LIVE_MINUTES", 180)
Service.ResetPwdCodeLives = Cfg.MustInt("service", "RESET_PASSWD_CODE_LIVE_MINUTES", 180)
Service.DisableRegistration = Cfg.MustBool("service", "DISABLE_REGISTRATION")
Service.RequireSignInView = Cfg.MustBool("service", "REQUIRE_SIGNIN_VIEW")
Service.EnableCacheAvatar = Cfg.MustBool("service", "ENABLE_CACHE_AVATAR")
Service.EnableReverseProxyAuth = Cfg.MustBool("service", "ENABLE_REVERSE_PROXY_AUTHENTICATION")
Service.ActiveCodeLives = Cfg.Section("service").Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180)
Service.ResetPwdCodeLives = Cfg.Section("service").Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180)
Service.DisableRegistration = Cfg.Section("service").Key("DISABLE_REGISTRATION").MustBool()
Service.ShowRegistrationButton = Cfg.Section("service").Key("SHOW_REGISTRATION_BUTTON").MustBool(!Service.DisableRegistration)
Service.RequireSignInView = Cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").MustBool()
Service.EnableCacheAvatar = Cfg.Section("service").Key("ENABLE_CACHE_AVATAR").MustBool()
Service.EnableReverseProxyAuth = Cfg.Section("service").Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
Service.EnableReverseProxyAutoRegister = Cfg.Section("service").Key("ENABLE_REVERSE_PROXY_AUTO_REGISTERATION").MustBool()
}
var logLevels = map[string]string{
@@ -309,17 +354,17 @@ func newLogService() {
log.Info("%s %s", AppName, AppVer)
// Get and check log mode.
LogModes = strings.Split(Cfg.MustValue("log", "MODE", "console"), ",")
LogModes = strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",")
LogConfigs = make([]string, len(LogModes))
for i, mode := range LogModes {
mode = strings.TrimSpace(mode)
modeSec := "log." + mode
if _, err := Cfg.GetSection(modeSec); err != nil {
sec, err := Cfg.GetSection("log." + mode)
if err != nil {
log.Fatal(4, "Unknown log mode: %s", mode)
}
// Log level.
levelName := Cfg.MustValueRange("log."+mode, "LEVEL", "Trace",
levelName := Cfg.Section("log."+mode).Key("LEVEL").In("Trace",
[]string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"})
level, ok := logLevels[levelName]
if !ok {
@@ -331,42 +376,42 @@ func newLogService() {
case "console":
LogConfigs[i] = fmt.Sprintf(`{"level":%s}`, level)
case "file":
logPath := Cfg.MustValue(modeSec, "FILE_NAME", path.Join(LogRootPath, "gogs.log"))
logPath := sec.Key("FILE_NAME").MustString(path.Join(LogRootPath, "gogs.log"))
os.MkdirAll(path.Dir(logPath), os.ModePerm)
LogConfigs[i] = fmt.Sprintf(
`{"level":%s,"filename":"%s","rotate":%v,"maxlines":%d,"maxsize":%d,"daily":%v,"maxdays":%d}`, level,
logPath,
Cfg.MustBool(modeSec, "LOG_ROTATE", true),
Cfg.MustInt(modeSec, "MAX_LINES", 1000000),
1<<uint(Cfg.MustInt(modeSec, "MAX_SIZE_SHIFT", 28)),
Cfg.MustBool(modeSec, "DAILY_ROTATE", true),
Cfg.MustInt(modeSec, "MAX_DAYS", 7))
sec.Key("LOG_ROTATE").MustBool(true),
sec.Key("MAX_LINES").MustInt(1000000),
1<<uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)),
sec.Key("DAILY_ROTATE").MustBool(true),
sec.Key("MAX_DAYS").MustInt(7))
case "conn":
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":"%s","addr":"%s"}`, level,
Cfg.MustBool(modeSec, "RECONNECT_ON_MSG"),
Cfg.MustBool(modeSec, "RECONNECT"),
Cfg.MustValueRange(modeSec, "PROTOCOL", "tcp", []string{"tcp", "unix", "udp"}),
Cfg.MustValue(modeSec, "ADDR", ":7020"))
sec.Key("RECONNECT_ON_MSG").MustBool(),
sec.Key("RECONNECT").MustBool(),
sec.Key("PROTOCOL").In("tcp", []string{"tcp", "unix", "udp"}),
sec.Key("ADDR").MustString(":7020"))
case "smtp":
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"username":"%s","password":"%s","host":"%s","sendTos":"%s","subject":"%s"}`, level,
Cfg.MustValue(modeSec, "USER", "example@example.com"),
Cfg.MustValue(modeSec, "PASSWD", "******"),
Cfg.MustValue(modeSec, "HOST", "127.0.0.1:25"),
Cfg.MustValue(modeSec, "RECEIVERS", "[]"),
Cfg.MustValue(modeSec, "SUBJECT", "Diagnostic message from serve"))
sec.Key("USER").MustString("example@example.com"),
sec.Key("PASSWD").MustString("******"),
sec.Key("HOST").MustString("127.0.0.1:25"),
sec.Key("RECEIVERS").MustString("[]"),
sec.Key("SUBJECT").MustString("Diagnostic message from serve"))
case "database":
LogConfigs[i] = fmt.Sprintf(`{"level":%s,"driver":"%s","conn":"%s"}`, level,
Cfg.MustValue(modeSec, "DRIVER"),
Cfg.MustValue(modeSec, "CONN"))
sec.Key("DRIVER").String(),
sec.Key("CONN").String())
}
log.NewLogger(Cfg.MustInt64("log", "BUFFER_LEN", 10000), mode, LogConfigs[i])
log.NewLogger(Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000), mode, LogConfigs[i])
log.Info("Log Mode: %s(%s)", strings.Title(mode), levelName)
}
}
func newCacheService() {
CacheAdapter = Cfg.MustValueRange("cache", "ADAPTER", "memory", []string{"memory", "redis", "memcache"})
CacheAdapter = Cfg.Section("cache").Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"})
if EnableRedis {
log.Info("Redis Enabled")
}
@@ -376,9 +421,9 @@ func newCacheService() {
switch CacheAdapter {
case "memory":
CacheInternal = Cfg.MustInt("cache", "INTERVAL", 60)
CacheInternal = Cfg.Section("cache").Key("INTERVAL").MustInt(60)
case "redis", "memcache":
CacheConn = strings.Trim(Cfg.MustValue("cache", "HOST"), "\" ")
CacheConn = strings.Trim(Cfg.Section("cache").Key("HOST").String(), "\" ")
default:
log.Fatal(4, "Unknown cache adapter: %s", CacheAdapter)
}
@@ -387,21 +432,14 @@ func newCacheService() {
}
func newSessionService() {
SessionProvider = Cfg.MustValueRange("session", "PROVIDER", "memory",
SessionConfig.Provider = Cfg.Section("session").Key("PROVIDER").In("memory",
[]string{"memory", "file", "redis", "mysql"})
SessionConfig = new(session.Config)
SessionConfig.ProviderConfig = strings.Trim(Cfg.MustValue("session", "PROVIDER_CONFIG"), "\" ")
SessionConfig.CookieName = Cfg.MustValue("session", "COOKIE_NAME", "i_like_gogits")
SessionConfig.ProviderConfig = strings.Trim(Cfg.Section("session").Key("PROVIDER_CONFIG").String(), "\" ")
SessionConfig.CookieName = Cfg.Section("session").Key("COOKIE_NAME").MustString("i_like_gogits")
SessionConfig.CookiePath = AppSubUrl
SessionConfig.Secure = Cfg.MustBool("session", "COOKIE_SECURE")
SessionConfig.EnableSetCookie = Cfg.MustBool("session", "ENABLE_SET_COOKIE", true)
SessionConfig.Gclifetime = Cfg.MustInt64("session", "GC_INTERVAL_TIME", 86400)
SessionConfig.Maxlifetime = Cfg.MustInt64("session", "SESSION_LIFE_TIME", 86400)
if SessionProvider == "file" {
os.MkdirAll(path.Dir(SessionConfig.ProviderConfig), os.ModePerm)
}
SessionConfig.Secure = Cfg.Section("session").Key("COOKIE_SECURE").MustBool()
SessionConfig.Gclifetime = Cfg.Section("session").Key("GC_INTERVAL_TIME").MustInt64(86400)
SessionConfig.Maxlifetime = Cfg.Section("session").Key("SESSION_LIFE_TIME").MustInt64(86400)
log.Info("Session Service Enabled")
}
@@ -412,12 +450,12 @@ type Mailer struct {
Host string
From string
User, Passwd string
SkipVerify bool
}
type OauthInfo struct {
ClientId, ClientSecret string
Scopes string
AuthUrl, TokenUrl string
oauth2.Options
AuthUrl, TokenUrl string
}
// Oauther represents oauth service.
@@ -433,23 +471,25 @@ var (
)
func newMailService() {
sec := Cfg.Section("mailer")
// Check mailer setting.
if !Cfg.MustBool("mailer", "ENABLED") {
if !sec.Key("ENABLED").MustBool() {
return
}
MailService = &Mailer{
Name: Cfg.MustValue("mailer", "NAME", AppName),
Host: Cfg.MustValue("mailer", "HOST"),
User: Cfg.MustValue("mailer", "USER"),
Passwd: Cfg.MustValue("mailer", "PASSWD"),
Name: sec.Key("NAME").MustString(AppName),
Host: sec.Key("HOST").String(),
User: sec.Key("USER").String(),
Passwd: sec.Key("PASSWD").String(),
SkipVerify: sec.Key("SKIP_VERIFY").MustBool(),
}
MailService.From = Cfg.MustValue("mailer", "FROM", MailService.User)
MailService.From = sec.Key("FROM").MustString(MailService.User)
log.Info("Mail Service Enabled")
}
func newRegisterMailService() {
if !Cfg.MustBool("service", "REGISTER_EMAIL_CONFIRM") {
if !Cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").MustBool() {
return
} else if MailService == nil {
log.Warn("Register Mail Service: Mail Service is not enabled")
@@ -460,7 +500,7 @@ func newRegisterMailService() {
}
func newNotifyMailService() {
if !Cfg.MustBool("service", "ENABLE_NOTIFY_MAIL") {
if !Cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").MustBool() {
return
} else if MailService == nil {
log.Warn("Notify Mail Service: Mail Service is not enabled")
@@ -471,8 +511,10 @@ func newNotifyMailService() {
}
func newWebhookService() {
WebhookTaskInterval = Cfg.MustInt("webhook", "TASK_INTERVAL", 1)
WebhookDeliverTimeout = Cfg.MustInt("webhook", "DELIVER_TIMEOUT", 5)
sec := Cfg.Section("webhook")
Webhook.TaskInterval = sec.Key("TASK_INTERVAL").MustInt(1)
Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5)
Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool()
}
func NewServices() {
@@ -484,5 +526,5 @@ func NewServices() {
newRegisterMailService()
newNotifyMailService()
newWebhookService()
// ssh.Listen("2022")
// ssh.Listen("2222")
}

View File

@@ -7,12 +7,12 @@ package social
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
oauth "github.com/gogits/oauth2"
"github.com/macaron-contrib/oauth2"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log"
@@ -27,78 +27,81 @@ type BasicUserInfo struct {
type SocialConnector interface {
Type() int
SetRedirectUrl(string)
UserInfo(*oauth.Token, *url.URL) (*BasicUserInfo, error)
AuthCodeURL(string) string
Exchange(string) (*oauth.Token, error)
UserInfo(*oauth2.Token, *url.URL) (*BasicUserInfo, error)
}
var (
SocialBaseUrl = "/user/login"
SocialMap = make(map[string]SocialConnector)
SocialMap = make(map[string]SocialConnector)
)
func NewOauthService() {
if !setting.Cfg.MustBool("oauth", "ENABLED") {
if !setting.Cfg.Section("oauth").Key("ENABLED").MustBool() {
return
}
oauth2.AppSubUrl = setting.AppSubUrl
setting.OauthService = &setting.Oauther{}
setting.OauthService.OauthInfos = make(map[string]*setting.OauthInfo)
socialConfigs := make(map[string]*oauth.Config)
socialConfigs := make(map[string]*oauth2.Options)
allOauthes := []string{"github", "google", "qq", "twitter", "weibo"}
// Load all OAuth config data.
for _, name := range allOauthes {
setting.OauthService.OauthInfos[name] = &setting.OauthInfo{
ClientId: setting.Cfg.MustValue("oauth."+name, "CLIENT_ID"),
ClientSecret: setting.Cfg.MustValue("oauth."+name, "CLIENT_SECRET"),
Scopes: setting.Cfg.MustValue("oauth."+name, "SCOPES"),
AuthUrl: setting.Cfg.MustValue("oauth."+name, "AUTH_URL"),
TokenUrl: setting.Cfg.MustValue("oauth."+name, "TOKEN_URL"),
sec := setting.Cfg.Section("oauth." + name)
if !sec.Key("ENABLED").MustBool() {
continue
}
socialConfigs[name] = &oauth.Config{
ClientId: setting.OauthService.OauthInfos[name].ClientId,
setting.OauthService.OauthInfos[name] = &setting.OauthInfo{
Options: oauth2.Options{
ClientID: sec.Key("CLIENT_ID").String(),
ClientSecret: sec.Key("CLIENT_SECRET").String(),
Scopes: sec.Key("SCOPES").Strings(" "),
PathLogin: "/user/login/oauth2/" + name,
PathCallback: setting.AppSubUrl + "/user/login/" + name,
RedirectURL: setting.AppUrl + "user/login/" + name,
},
AuthUrl: sec.Key("AUTH_URL").String(),
TokenUrl: sec.Key("TOKEN_URL").String(),
}
socialConfigs[name] = &oauth2.Options{
ClientID: setting.OauthService.OauthInfos[name].ClientID,
ClientSecret: setting.OauthService.OauthInfos[name].ClientSecret,
RedirectURL: strings.TrimSuffix(setting.AppUrl, "/") + SocialBaseUrl + name,
Scope: setting.OauthService.OauthInfos[name].Scopes,
AuthURL: setting.OauthService.OauthInfos[name].AuthUrl,
TokenURL: setting.OauthService.OauthInfos[name].TokenUrl,
Scopes: setting.OauthService.OauthInfos[name].Scopes,
}
}
enabledOauths := make([]string, 0, 10)
// GitHub.
if setting.Cfg.MustBool("oauth.github", "ENABLED") {
if setting.Cfg.Section("oauth.github").Key("ENABLED").MustBool() {
setting.OauthService.GitHub = true
newGitHubOauth(socialConfigs["github"])
enabledOauths = append(enabledOauths, "GitHub")
}
// Google.
if setting.Cfg.MustBool("oauth.google", "ENABLED") {
if setting.Cfg.Section("oauth.google").Key("ENABLED").MustBool() {
setting.OauthService.Google = true
newGoogleOauth(socialConfigs["google"])
enabledOauths = append(enabledOauths, "Google")
}
// QQ.
if setting.Cfg.MustBool("oauth.qq", "ENABLED") {
if setting.Cfg.Section("oauth.qq").Key("ENABLED").MustBool() {
setting.OauthService.Tencent = true
newTencentOauth(socialConfigs["qq"])
enabledOauths = append(enabledOauths, "QQ")
}
// Twitter.
if setting.Cfg.MustBool("oauth.twitter", "ENABLED") {
setting.OauthService.Twitter = true
newTwitterOauth(socialConfigs["twitter"])
enabledOauths = append(enabledOauths, "Twitter")
}
// if setting.Cfg.Section("oauth.twitter").Key( "ENABLED").MustBool() {
// setting.OauthService.Twitter = true
// newTwitterOauth(socialConfigs["twitter"])
// enabledOauths = append(enabledOauths, "Twitter")
// }
// Weibo.
if setting.Cfg.MustBool("oauth.weibo", "ENABLED") {
if setting.Cfg.Section("oauth.weibo").Key("ENABLED").MustBool() {
setting.OauthService.Weibo = true
newWeiboOauth(socialConfigs["weibo"])
enabledOauths = append(enabledOauths, "Weibo")
@@ -115,38 +118,25 @@ func NewOauthService() {
// \/ \/ \/
type SocialGithub struct {
Token *oauth.Token
*oauth.Transport
opts *oauth2.Options
}
func newGitHubOauth(opts *oauth2.Options) {
SocialMap["github"] = &SocialGithub{opts}
}
func (s *SocialGithub) Type() int {
return int(models.GITHUB)
}
func newGitHubOauth(config *oauth.Config) {
SocialMap["github"] = &SocialGithub{
Transport: &oauth.Transport{
Config: config,
Transport: http.DefaultTransport,
},
}
}
func (s *SocialGithub) SetRedirectUrl(url string) {
s.Transport.Config.RedirectURL = url
}
func (s *SocialGithub) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) {
transport := &oauth.Transport{
Token: token,
}
func (s *SocialGithub) UserInfo(token *oauth2.Token, _ *url.URL) (*BasicUserInfo, error) {
transport := s.opts.NewTransportFromToken(token)
var data struct {
Id int `json:"id"`
Name string `json:"login"`
Email string `json:"email"`
}
var err error
r, err := transport.Client().Get(s.Transport.Scope)
r, err := transport.Client().Get("https://api.github.com/user")
if err != nil {
return nil, err
}
@@ -169,38 +159,25 @@ func (s *SocialGithub) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo,
// \/ /_____/ \/
type SocialGoogle struct {
Token *oauth.Token
*oauth.Transport
opts *oauth2.Options
}
func (s *SocialGoogle) Type() int {
return int(models.GOOGLE)
}
func newGoogleOauth(config *oauth.Config) {
SocialMap["google"] = &SocialGoogle{
Transport: &oauth.Transport{
Config: config,
Transport: http.DefaultTransport,
},
}
func newGoogleOauth(opts *oauth2.Options) {
SocialMap["google"] = &SocialGoogle{opts}
}
func (s *SocialGoogle) SetRedirectUrl(url string) {
s.Transport.Config.RedirectURL = url
}
func (s *SocialGoogle) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) {
transport := &oauth.Transport{Token: token}
func (s *SocialGoogle) UserInfo(token *oauth2.Token, _ *url.URL) (*BasicUserInfo, error) {
transport := s.opts.NewTransportFromToken(token)
var data struct {
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
var err error
reqUrl := "https://www.googleapis.com/oauth2/v1/userinfo"
r, err := transport.Client().Get(reqUrl)
r, err := transport.Client().Get("https://www.googleapis.com/userinfo/v2/me")
if err != nil {
return nil, err
}
@@ -223,62 +200,35 @@ func (s *SocialGoogle) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo,
// \__> \__>
type SocialTencent struct {
Token *oauth.Token
*oauth.Transport
reqUrl string
opts *oauth2.Options
}
func newTencentOauth(opts *oauth2.Options) {
SocialMap["qq"] = &SocialTencent{opts}
}
func (s *SocialTencent) Type() int {
return int(models.QQ)
}
func newTencentOauth(config *oauth.Config) {
SocialMap["qq"] = &SocialTencent{
reqUrl: "https://open.t.qq.com/api/user/info",
Transport: &oauth.Transport{
Config: config,
Transport: http.DefaultTransport,
},
}
}
func (s *SocialTencent) SetRedirectUrl(url string) {
s.Transport.Config.RedirectURL = url
}
func (s *SocialTencent) UserInfo(token *oauth.Token, URL *url.URL) (*BasicUserInfo, error) {
var data struct {
Data struct {
Id string `json:"openid"`
Name string `json:"name"`
Email string `json:"email"`
} `json:"data"`
}
var err error
// https://open.t.qq.com/api/user/info?
//oauth_consumer_key=APP_KEY&
//access_token=ACCESSTOKEN&openid=openid
//clientip=CLIENTIP&oauth_version=2.a
//scope=all
var urls = url.Values{
"oauth_consumer_key": {s.Transport.Config.ClientId},
"access_token": {token.AccessToken},
"openid": URL.Query()["openid"],
"oauth_version": {"2.a"},
"scope": {"all"},
}
r, err := http.Get(s.reqUrl + "?" + urls.Encode())
func (s *SocialTencent) UserInfo(token *oauth2.Token, URL *url.URL) (*BasicUserInfo, error) {
r, err := http.Get("https://graph.z.qq.com/moc2/me?access_token=" + url.QueryEscape(token.AccessToken))
if err != nil {
return nil, err
}
defer r.Body.Close()
if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
vals, err := url.ParseQuery(string(body))
if err != nil {
return nil, err
}
return &BasicUserInfo{
Identity: data.Data.Id,
Name: data.Data.Name,
Email: data.Data.Email,
Identity: vals.Get("openid"),
}, nil
}
@@ -289,54 +239,54 @@ func (s *SocialTencent) UserInfo(token *oauth.Token, URL *url.URL) (*BasicUserIn
// |____| \/\_/ |__||__| |__| \___ >__|
// \/
type SocialTwitter struct {
Token *oauth.Token
*oauth.Transport
}
// type SocialTwitter struct {
// Token *oauth2.Token
// *oauth2.Transport
// }
func (s *SocialTwitter) Type() int {
return int(models.TWITTER)
}
// func (s *SocialTwitter) Type() int {
// return int(models.TWITTER)
// }
func newTwitterOauth(config *oauth.Config) {
SocialMap["twitter"] = &SocialTwitter{
Transport: &oauth.Transport{
Config: config,
Transport: http.DefaultTransport,
},
}
}
// func newTwitterOauth(config *oauth2.Config) {
// SocialMap["twitter"] = &SocialTwitter{
// Transport: &oauth.Transport{
// Config: config,
// Transport: http.DefaultTransport,
// },
// }
// }
func (s *SocialTwitter) SetRedirectUrl(url string) {
s.Transport.Config.RedirectURL = url
}
// func (s *SocialTwitter) SetRedirectUrl(url string) {
// s.Transport.Config.RedirectURL = url
// }
//https://github.com/mrjones/oauth
func (s *SocialTwitter) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) {
// transport := &oauth.Transport{Token: token}
// var data struct {
// Id string `json:"id"`
// Name string `json:"name"`
// Email string `json:"email"`
// }
// var err error
// //https://github.com/mrjones/oauth
// func (s *SocialTwitter) UserInfo(token *oauth2.Token, _ *url.URL) (*BasicUserInfo, error) {
// // transport := &oauth.Transport{Token: token}
// // var data struct {
// // Id string `json:"id"`
// // Name string `json:"name"`
// // Email string `json:"email"`
// // }
// // var err error
// reqUrl := "https://www.googleapis.com/oauth2/v1/userinfo"
// r, err := transport.Client().Get(reqUrl)
// if err != nil {
// return nil, err
// }
// defer r.Body.Close()
// if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
// return nil, err
// }
// return &BasicUserInfo{
// Identity: data.Id,
// Name: data.Name,
// Email: data.Email,
// }, nil
return nil, nil
}
// // reqUrl := "https://www.googleapis.com/oauth2/v1/userinfo"
// // r, err := transport.Client().Get(reqUrl)
// // if err != nil {
// // return nil, err
// // }
// // defer r.Body.Close()
// // if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
// // return nil, err
// // }
// // return &BasicUserInfo{
// // Identity: data.Id,
// // Name: data.Name,
// // Email: data.Email,
// // }, nil
// return nil, nil
// }
// __ __ ._____.
// / \ / \ ____ |__\_ |__ ____
@@ -346,37 +296,25 @@ func (s *SocialTwitter) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo
// \/ \/ \/
type SocialWeibo struct {
Token *oauth.Token
*oauth.Transport
opts *oauth2.Options
}
func newWeiboOauth(opts *oauth2.Options) {
SocialMap["weibo"] = &SocialWeibo{opts}
}
func (s *SocialWeibo) Type() int {
return int(models.WEIBO)
}
func newWeiboOauth(config *oauth.Config) {
SocialMap["weibo"] = &SocialWeibo{
Transport: &oauth.Transport{
Config: config,
Transport: http.DefaultTransport,
},
}
}
func (s *SocialWeibo) SetRedirectUrl(url string) {
s.Transport.Config.RedirectURL = url
}
func (s *SocialWeibo) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) {
transport := &oauth.Transport{Token: token}
func (s *SocialWeibo) UserInfo(token *oauth2.Token, _ *url.URL) (*BasicUserInfo, error) {
transport := s.opts.NewTransportFromToken(token)
var data struct {
Name string `json:"name"`
}
var err error
var urls = url.Values{
"access_token": {token.AccessToken},
"uid": {token.Extra["id_token"]},
"uid": {token.Extra("uid")},
}
reqUrl := "https://api.weibo.com/2/users/show.json"
r, err := transport.Client().Get(reqUrl + "?" + urls.Encode())
@@ -384,11 +322,12 @@ func (s *SocialWeibo) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo,
return nil, err
}
defer r.Body.Close()
if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
return nil, err
}
return &BasicUserInfo{
Identity: token.Extra["id_token"],
Identity: token.Extra("uid"),
Name: data.Name,
}, nil
}

View File

@@ -13,9 +13,8 @@ import (
"os/exec"
"strings"
"code.google.com/p/go.crypto/ssh"
"github.com/Unknwon/com"
"golang.org/x/crypto/ssh"
"github.com/gogits/gogs/modules/log"
)
@@ -35,8 +34,11 @@ func handleServerConn(keyId string, chans <-chan ssh.NewChannel) {
go func(in <-chan *ssh.Request) {
defer channel.Close()
for req := range in {
ok, payload := false, strings.TrimLeft(string(req.Payload), "\x00")
ok, payload := false, strings.TrimLeft(string(req.Payload), "\x00&")
fmt.Println("Request:", req.Type, req.WantReply, payload)
if req.WantReply {
fmt.Println(req.Reply(true, nil))
}
switch req.Type {
case "env":
args := strings.Split(strings.Replace(payload, "\x00", "", -1), "\v")
@@ -54,7 +56,7 @@ func handleServerConn(keyId string, chans <-chan ssh.NewChannel) {
case "exec":
os.Setenv("SSH_ORIGINAL_COMMAND", strings.TrimLeft(payload, "'("))
log.Info("Payload: %v", strings.TrimLeft(payload, "'("))
cmd := exec.Command("/Users/jiahuachen/Applications/Go/src/github.com/gogits/gogs-ng/gogs-ng", "serv", "key-"+keyId)
cmd := exec.Command("/Users/jiahuachen/Applications/Go/src/github.com/gogits/gogs/gogs", "serv", "key-"+keyId)
cmd.Stdout = channel
cmd.Stdin = channel
cmd.Stderr = channel.Stderr()
@@ -65,7 +67,6 @@ func handleServerConn(keyId string, chans <-chan ssh.NewChannel) {
}
}
fmt.Println("Done:", ok)
req.Reply(ok, nil) // BUG: Git on Mac seems not know this reply and hang?
}
fmt.Println("Done!!!")
}(requests)
@@ -101,7 +102,7 @@ func Listen(port string) {
config := &ssh.ServerConfig{
PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
// keyCache[string(ssh.MarshalAuthorizedKey(key))] = 2
return &ssh.Permissions{Extensions: map[string]string{"key-id": "2"}}, nil
return &ssh.Permissions{Extensions: map[string]string{"key-id": "1"}}, nil
},
}

View File

@@ -2,18 +2,6 @@
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
APP_NAME="gogs"
CLI="${APP_NAME}"
APP_USER=$(${CLI} config:get APP_USER)
@@ -21,28 +9,27 @@ APP_GROUP=$(${CLI} config:get APP_GROUP)
APP_CONFIG="/etc/${APP_NAME}/conf/app.ini"
case "$1" in
abort-upgrade|abort-remove|abort-deconfigure)
exit 0
;;
configure)
configure|*)
mkdir -p $(dirname ${APP_CONFIG})
chown ${APP_USER}.${APP_GROUP} $(dirname ${APP_CONFIG})
[ -f ${APP_CONFIG} ] || ${CLI} run cp conf/app.ini ${APP_CONFIG}
${CLI} config:set USER=${APP_USER}
${CLI} config:set GOGS_CUSTOM="/etc/${APP_NAME}"
PORT=$(${CLI} config:get PORT || echo "6000")
sed -i "s|HTTP_PORT = 3000|HTTP_PORT = ${PORT}|" ${APP_CONFIG}
sed -i "s|RUN_USER = git|RUN_USER = ${APP_USER}|" ${APP_CONFIG}
sed -i "s|RUN_MODE = dev|RUN_MODE = prod|" ${APP_CONFIG}
# setup symlink towards custom conf
mkdir -p /opt/${APP_NAME}/custom/conf
chown -R ${APP_USER}.${APP_GROUP} /opt/${APP_NAME}/custom
ln -f -s ${APP_CONFIG} /opt/${APP_NAME}/custom/conf/app.ini
# scale
${CLI} scale web=1 || true
;;
abort-upgrade|abort-remove|abort-deconfigure)
exit 0
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac

View File

@@ -303,6 +303,9 @@ var Gogits = {};
// api working
Gogits.getUsers = function (val, $target) {
var notEmpty = function (str) {
return str && str.length > 0;
}
$.ajax({
url: '/api/v1/users/search?q=' + val,
dataType: "json",
@@ -310,7 +313,11 @@ var Gogits = {};
if (json.ok && json.data.length) {
var html = '';
$.each(json.data, function (i, item) {
html += '<li><img src="' + item.avatar + '">' + item.username + '</li>';
html += '<li><img src="' + item.avatar + '">' + item.username;
if (notEmpty(item.full_name)) {
html += ' (' + item.full_name + ')';
}
html += '</li>';
});
$target.toggleShow();
$target.find('ul').html(html);
@@ -1045,22 +1052,6 @@ function initRepoSetting() {
return;
}
Gogits.getUsers($this.val(), $this.next());
/*$.ajax({
url: '/api/v1/users/search?q=' + $this.val(),
dataType: "json",
success: function (json) {
if (json.ok && json.data.length) {
var html = '';
$.each(json.data, function (i, item) {
html += '<li><img src="' + item.avatar + '">' + item.username + '</li>';
});
$this.next().toggleShow();
$this.next().find('ul').html(html);
} else {
$this.next().toggleHide();
}
}
});*/
}).on('focus', function () {
if (!$(this).val()) {
$(this).next().toggleHide();

View File

@@ -340,6 +340,33 @@ img.avatar-100 {
padding: 5px 15px;
color: #777;
}
.markdown table {
width: 100%;
overflow: auto;
word-break: normal;
margin: 15px 0;
border-collapse: collapse;
border-spacing: 0;
display: block;
}
.markdown table th {
font-weight: 700;
}
.markdown table th,
.markdown table td {
border: 1px solid #DDD;
padding: 6px 13px !important;
}
.markdown table tr {
background-color: #FFF;
border-top: 1px solid #CCC;
}
.markdown table tr:nth-child(2n) {
background-color: #F8F8F8;
}
.markdown p {
margin: 20px 0;
}
.markdown a {
color: #428BCA;
}
@@ -376,29 +403,6 @@ img.avatar-100 {
.markdown h4 {
font-size: 18px;
}
.markdown table {
border-collapse: collapse;
border-spacing: 0;
display: block;
overflow: auto;
width: 100%;
margin: 0 0 9px;
}
.markdown table th {
font-weight: 700;
}
.markdown table th,
.markdown table td {
border: 1px solid #DDD;
padding: 6px 13px;
}
.markdown table tr {
background-color: #FFF;
border-top: 1px solid #CCC;
}
.markdown table tr:nth-child(2n) {
background-color: #f8f8f8;
}
.markdown dl dt {
font-style: italic;
margin-top: 9px;
@@ -1062,6 +1066,9 @@ The register and sign-in page style
#repo-header-download-drop .btn > i {
margin-right: 6px;
}
#repo-header-download-drop input {
cursor: default;
}
#repo-header-download-drop button,
#repo-header-download-drop input {
font-size: 11px;
@@ -1071,7 +1078,8 @@ The register and sign-in page style
text-overflow: clip;
}
#repo-content {
padding: 18px 0;
padding-top: 18px;
padding-bottom: 18px;
}
.repo-wide-wrapper {
padding: 18px;
@@ -1213,6 +1221,9 @@ The register and sign-in page style
#repo-files-table {
margin-bottom: 20px;
}
#repo-files-table .sha .label {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
}
#repo-files-table th,
#repo-files-table td {
text-align: left;
@@ -1248,6 +1259,9 @@ The register and sign-in page style
color: #428BCA;
text-decoration: underline;
}
#repo-files-table td.message .text-truncate {
max-width: 360px;
}
#repo-files-table tbody {
background-color: #FFF;
}
@@ -1352,31 +1366,54 @@ The register and sign-in page style
#repo-create-cancel {
margin-left: 4em;
}
#release-new-target-branch-list,
#repo-create-owner-list {
top: 30px;
left: 0;
width: auto;
max-width: 300px;
}
#release-new-target-branch-list .octicon,
#repo-create-owner-list .octicon {
margin-right: 12px;
opacity: 0;
}
#release-new-target-branch-list .avatar,
#repo-create-owner-list .avatar {
width: 20px;
height: 20px;
}
#release-new-target-branch-list li,
#repo-create-owner-list li {
white-space: nowrap;
}
#release-new-target-branch-list li.checked .octicon,
#repo-create-owner-list li.checked .octicon {
opacity: 1;
}
#release-new-target-branch-list li a,
#repo-create-owner-list li a {
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
#release-new-target-branch-list {
margin-top: -1px;
min-width: 150px;
}
#release-new-title {
margin-top: 10px;
}
#release-new-content {
width: 100%;
}
#release-preview-btn .btn {
border-left: 0;
}
#release-preview.markdown {
margin-top: 5px;
background-color: transparent;
}
.file-name {
margin-left: 1em;
}
@@ -1416,7 +1453,7 @@ The register and sign-in page style
}
.code-view .lines-num span {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
line-height: 1.6;
line-height: 20px;
padding: 0 10px;
cursor: pointer;
display: block;
@@ -1510,6 +1547,9 @@ The register and sign-in page style
.commit-list .message span {
max-width: 500px;
}
.commit-message {
white-space: pre-wrap;
}
.diff-head-box {
margin-top: 10px;
}
@@ -1589,16 +1629,32 @@ The register and sign-in page style
background-color: #E0E0E0 !important;
border-color: #ADADAD !important;
}
.diff-file-box .code-diff tbody tr.tag-code td.selected-line,
.diff-file-box .code-diff tbody tr.tag-code td.selected-line pre {
background-color: #ffffdd !important;
}
.diff-file-box .code-diff tbody tr.same-code td.selected-line,
.diff-file-box .code-diff tbody tr.same-code td.selected-line pre {
background-color: #ffffdd !important;
}
.diff-file-box .code-diff tbody tr.del-code td,
.diff-file-box .code-diff tbody tr.del-code pre {
background-color: #ffe2dd !important;
border-color: #e9aeae !important;
}
.diff-file-box .code-diff tbody tr.del-code td.selected-line,
.diff-file-box .code-diff tbody tr.del-code td.selected-line pre {
background-color: #ffffdd !important;
}
.diff-file-box .code-diff tbody tr.add-code td,
.diff-file-box .code-diff tbody tr.add-code pre {
background-color: #d1ffd6 !important;
border-color: #b4e2b4 !important;
}
.diff-file-box .code-diff tbody tr.add-code td.selected-line,
.diff-file-box .code-diff tbody tr.add-code td.selected-line pre {
background-color: #ffffdd !important;
}
.diff-file-box .code-diff tbody tr:hover td,
.diff-file-box .code-diff tbody tr:hover pre {
background-color: #FFF8D2 !important;
@@ -1618,6 +1674,87 @@ The register and sign-in page style
margin-left: 44px;
margin-top: -15px;
}
#release h4 {
font-size: 18px;
}
#release h4 small {
font-weight: 400;
line-height: 1;
color: #999;
}
#release #release-head {
margin-top: 0;
margin-bottom: 0;
padding-bottom: 20px;
border-bottom: 1px solid #DDD;
}
#release #release-head .btn {
margin-left: 10px;
}
#release .release-item > div {
padding-top: 20px;
padding-bottom: 20px;
}
#release .release-item .label-green:hover {
background-color: #65ad4e;
}
#release .release-item .release-meta {
position: relative;
float: left;
padding-right: 15px;
}
#release .release-item .tag,
#release .release-item .commit {
display: block;
margin-top: 12px;
line-height: 20px;
}
#release .release-item .release-detail {
margin-top: -1px;
border-left: 1px solid #DDD;
position: relative;
float: left;
padding-left: 15px;
}
#release .release-item .title {
line-height: 25px;
margin-top: 0;
}
#release .release-item p.info {
line-height: 20px;
color: #666;
margin-bottom: 15px;
}
#release .release-item p.info > * {
margin-right: 10px;
}
#release .release-item .author img {
margin-top: -3px;
}
#release .release-item div.desc {
margin-bottom: 25px;
}
#release .release-item div.desc.markdown {
background-color: transparent;
}
#release .release-item .download a {
margin-right: 10px;
}
#release .release-item .dot {
width: 9px;
height: 9px;
background-color: #ccc;
z-index: 999;
position: absolute;
display: block;
left: -6px;
top: 27px;
border-radius: 6px;
border: 1px solid #FFF;
}
#release #release-new-form {
padding-top: 15px;
}
#admin-wrapper,
#setting-wrapper {
padding-bottom: 100px;
@@ -1649,6 +1786,7 @@ The register and sign-in page style
#org-setting-form,
#repo-setting-form,
#user-profile-form,
#add-email-form,
.repo-setting-form {
background-color: #FFF;
padding: 30px 0;
@@ -1657,6 +1795,7 @@ The register and sign-in page style
#org-setting-form textarea,
#repo-setting-form textarea,
#user-profile-form textarea,
#add-email-form textarea,
.repo-setting-form textarea {
margin-left: 4px;
height: 100px;
@@ -1665,11 +1804,13 @@ The register and sign-in page style
#org-setting-form label,
#repo-setting-form label,
#user-profile-form label,
#add-email-form label,
.repo-setting-form label,
#auth-setting-form .form-label,
#org-setting-form .form-label,
#repo-setting-form .form-label,
#user-profile-form .form-label,
#add-email-form .form-label,
.repo-setting-form .form-label {
width: 240px;
}
@@ -1677,6 +1818,7 @@ The register and sign-in page style
#org-setting-form .ipt,
#repo-setting-form .ipt,
#user-profile-form .ipt,
#add-email-form .ipt,
.repo-setting-form .ipt {
width: 360px;
}
@@ -1684,6 +1826,7 @@ The register and sign-in page style
#org-setting-form .field,
#repo-setting-form .field,
#user-profile-form .field,
#add-email-form .field,
.repo-setting-form .field {
margin-bottom: 24px;
}
@@ -1701,6 +1844,7 @@ The register and sign-in page style
#repo-hooks-history-panel,
#user-social-panel,
#user-applications-panel,
#user-email-panel,
#user-ssh-panel {
margin-bottom: 20px;
}
@@ -1708,6 +1852,7 @@ The register and sign-in page style
#repo-hooks-history-panel .setting-list,
#user-social-panel .setting-list,
#user-applications-panel .setting-list,
#user-email-panel .setting-list,
#user-ssh-panel .setting-list {
background-color: #FFF;
}
@@ -1715,6 +1860,7 @@ The register and sign-in page style
#repo-hooks-history-panel .setting-list li,
#user-social-panel .setting-list li,
#user-applications-panel .setting-list li,
#user-email-panel .setting-list li,
#user-ssh-panel .setting-list li {
padding: 8px 20px;
border-bottom: 1px solid #eaeaea;
@@ -1723,6 +1869,7 @@ The register and sign-in page style
#repo-hooks-history-panel .setting-list li.ssh:hover,
#user-social-panel .setting-list li.ssh:hover,
#user-applications-panel .setting-list li.ssh:hover,
#user-email-panel .setting-list li.ssh:hover,
#user-ssh-panel .setting-list li.ssh:hover {
background-color: #ffffEE;
}
@@ -1730,6 +1877,7 @@ The register and sign-in page style
#repo-hooks-history-panel .setting-list li i,
#user-social-panel .setting-list li i,
#user-applications-panel .setting-list li i,
#user-email-panel .setting-list li i,
#user-ssh-panel .setting-list li i {
padding-right: 5px;
}
@@ -1737,6 +1885,7 @@ The register and sign-in page style
#repo-hooks-history-panel .active-icon,
#user-social-panel .active-icon,
#user-applications-panel .active-icon,
#user-email-panel .active-icon,
#user-ssh-panel .active-icon {
width: 10px;
height: 10px;
@@ -1749,6 +1898,7 @@ The register and sign-in page style
#repo-hooks-history-panel .ssh-content,
#user-social-panel .ssh-content,
#user-applications-panel .ssh-content,
#user-email-panel .ssh-content,
#user-ssh-panel .ssh-content {
margin-left: 24px;
}
@@ -1756,6 +1906,7 @@ The register and sign-in page style
#repo-hooks-history-panel .ssh-content .octicon,
#user-social-panel .ssh-content .octicon,
#user-applications-panel .ssh-content .octicon,
#user-email-panel .ssh-content .octicon,
#user-ssh-panel .ssh-content .octicon {
margin-right: 4px;
}
@@ -1763,16 +1914,19 @@ The register and sign-in page style
#repo-hooks-history-panel .ssh-content .print,
#user-social-panel .ssh-content .print,
#user-applications-panel .ssh-content .print,
#user-email-panel .ssh-content .print,
#user-ssh-panel .ssh-content .print,
#repo-hooks-panel .ssh-content .access,
#repo-hooks-history-panel .ssh-content .access,
#user-social-panel .ssh-content .access,
#user-applications-panel .ssh-content .access,
#user-email-panel .ssh-content .access,
#user-ssh-panel .ssh-content .access,
#repo-hooks-panel .ssh-content .activity,
#repo-hooks-history-panel .ssh-content .activity,
#user-social-panel .ssh-content .activity,
#user-applications-panel .ssh-content .activity,
#user-email-panel .ssh-content .activity,
#user-ssh-panel .ssh-content .activity {
color: #888;
}
@@ -1780,6 +1934,7 @@ The register and sign-in page style
#repo-hooks-history-panel .ssh-content .access,
#user-social-panel .ssh-content .access,
#user-applications-panel .ssh-content .access,
#user-email-panel .ssh-content .access,
#user-ssh-panel .ssh-content .access {
max-width: 500px;
}
@@ -1787,6 +1942,7 @@ The register and sign-in page style
#repo-hooks-history-panel .ssh-btn,
#user-social-panel .ssh-btn,
#user-applications-panel .ssh-btn,
#user-email-panel .ssh-btn,
#user-ssh-panel .ssh-btn {
margin-top: 6px;
}
@@ -2019,10 +2175,14 @@ textarea#issue-add-content {
#issue-list-nav li.right {
margin-left: 4px;
}
#issue-new > a {
#issue-new > a,
#label-new > a,
#milestone-new > a {
padding: 0 !important;
}
#issue-new > a button {
#issue-new > a button,
#label-new > a button,
#milestone-new > a button {
height: 29px;
}
#issue-list-menu {
@@ -2059,10 +2219,6 @@ textarea#issue-add-content {
font-size: 15px;
margin: 0 6px;
}
#issue-list .item .index-num,
#pull-list .item .index-num {
padding: .25em .6em;
}
#issue-list .comment,
#pull-list .comment {
color: #666;
@@ -2070,10 +2226,6 @@ textarea#issue-add-content {
top: 6px;
right: 0;
}
#issue-list .issue-label,
#pull-list .issue-label {
padding: .25em .6em;
}
#issue-list .issue-label a,
#pull-list .issue-label a {
color: #FFF;
@@ -2090,6 +2242,53 @@ textarea#issue-add-content {
#pull-list .desc a:hover {
color: #03a2ef;
}
#issue-list-filter .drop > a {
width: 90px;
padding: 0;
margin-left: 12px;
text-align: center;
}
#issue-list-filter .drop-down {
z-index: 999;
width: 236px;
left: -158px;
top: 22px;
padding: 0 12px;
}
#issue-list-filter .drop-down h4 {
line-height: 40px;
border-bottom: 1px solid #CCC;
margin-bottom: 0;
}
#issue-list-filter .drop-down li {
line-height: 30px;
border-bottom: 1px dashed #EEE;
padding-left: 9px;
}
#issue-list-filter .drop-down li:hover {
background-color: #fcffec;
}
#issue-list-filter .drop-down > ul > li > a {
display: block;
}
#issue-list-filter .labels .color {
margin-top: 8px;
display: inline-block;
width: 12px;
height: 12px;
background-color: red;
margin-right: 9px;
margin-left: 9px;
}
#issue-list-filter .labels .name {
vertical-align: top;
display: inline-block;
color: #444;
}
#issue-list-filter .milestones a {
color: #444;
font-weight: bold;
}
#issue-list-pager {
margin: 18px 0 24px 0;
font-size: 14px;
@@ -2098,15 +2297,15 @@ textarea#issue-add-content {
#labels-num {
margin-right: 1em;
}
#label-list .right {
#label-list a.right {
margin-left: 1em;
color: #999;
line-height: 30px;
}
#label-list .right i {
#label-list a.right i {
margin-right: 3px;
}
#label-list .right:hover {
#label-list a.right:hover {
color: #444444;
}
#label-list .num {
@@ -2127,6 +2326,95 @@ textarea#issue-add-content {
margin-bottom: 12px;
border-bottom: 1px dashed #AAA;
}
#label-add-form .ipt,
#label-edit-form .ipt,
#label-delete-form .ipt {
font-size: 14px;
}
#label-add-form .ipt[name=name],
#label-edit-form .ipt[name=name],
#label-delete-form .ipt[name=name] {
width: 300px;
}
#label-add-form .btn,
#label-edit-form .btn,
#label-delete-form .btn {
height: 33px;
font-size: 14px;
margin-left: 12px;
}
#label-add-form {
padding: 18px 0;
border-bottom: 1px solid #DDD;
}
#label-delete-form span {
line-height: 33px;
}
.label-color-drop .ipt {
width: 100px;
}
.label-color-drop .drop-down {
width: 128px !important;
top: 22px !important;
left: 50px !important;
padding: 12px;
line-height: 16px;
}
.label-color-drop .drop-down a.color {
width: 16px;
height: 16px;
display: inline-block;
}
.label-color-drop label {
width: 24px;
height: 24px;
display: inline-block;
margin: 0 1em;
vertical-align: middle;
}
#milestone-list {
padding-top: 6px;
}
#milestone-list .title-text {
font-size: 16px;
}
#milestone-list .desc {
color: #999;
line-height: 30px;
}
#milestone-list .content {
width: 400px;
}
#milestone-list .item {
padding-bottom: 18px;
margin-bottom: 18px;
border-bottom: 1px dashed #AAA;
position: relative;
}
#milestone-list .action {
position: absolute;
top: 0;
right: 0;
}
#milestone-list .status-bar > .bar {
margin: -2px 8px 0 8px;
width: 360px;
background-color: #DDD;
height: 14px;
vertical-align: middle;
}
#milestone-list .status-bar .opening {
background-color: #65ad4e;
width: 40%;
height: 14px;
vertical-align: top;
}
#milestone-list .action-bar {
margin-top: 8px;
}
#milestone-list .action-bar a {
margin-left: 12px;
}
.org-header-alert .alert {
margin-top: 10px;
}
@@ -2414,5 +2702,5 @@ textarea#issue-add-content {
border-bottom: 2px solid #D26911;
}
#profile-body {
margin-left: 10px;
margin-left: 20px;
}

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