Compare commits

..

190 Commits

Author SHA1 Message Date
Eugene
c12b445ccd more commands 2024-03-01 20:25:39 +01:00
Eugene
5d8ff72850 Merge pull request #9451 from karur4n/fix-typos
Fix typos
2024-02-09 10:12:46 +01:00
Kazuki Furukawa
e247ff73b2 Fix typos 2024-02-09 12:31:52 +09:00
Eugene
ed5ff1113c Merge pull request #9432 from botprzemek/master
Added README.pl-PL.md and <a> anchors with Polish language availability
2024-01-30 20:06:50 +01:00
botprzemek
a5fcb83ad0 Added <a> anchors with Polish language availability.
Added README.pl-PL.md file - project's markdown translated to Polish.
2024-01-30 18:56:29 +01:00
Eugene
da5342b4a7 fixed #8097 - "close pane" hotkey doesn't kill the process 2024-01-26 20:19:16 +01:00
Eugene
3c7f1079dd Merge pull request #9419 from 0x973/master
updated contributors
2024-01-25 23:05:19 +01:00
0x973
c7e01eab0f updated contributors 2024-01-26 03:03:32 +08:00
Eugene
ffddc36ee0 updated contributors 2024-01-23 21:23:12 +01:00
Eugene
b2671826c6 Merge pull request #9410 from cfs4819/master
Improve sftp visual effects
2024-01-23 20:34:11 +01:00
Eugene
fec5d809b7 style tweak 2024-01-23 20:33:28 +01:00
cfs4819
cf09d95602 Improve sftp visual effects 2024-01-23 12:27:49 +08:00
cfs4819
266dfe15a3 Improve sftp visual effects 2024-01-23 12:02:53 +08:00
Eugene
868f7ba70e Merge pull request #9386 from Eugeny/all-contributors/add-ashneilson
add ashneilson as a contributor for code
2024-01-13 10:21:32 +01:00
allcontributors[bot]
b7f8652f5f update .all-contributorsrc [skip ci] 2024-01-13 09:12:55 +00:00
allcontributors[bot]
1f06800c39 update README.es-ES.md [skip ci] 2024-01-13 09:12:33 +00:00
allcontributors[bot]
7239193a4b update README.id-ID.md [skip ci] 2024-01-13 09:12:31 +00:00
allcontributors[bot]
35cb81c854 update README.pt-BR.md [skip ci] 2024-01-13 09:11:52 +00:00
allcontributors[bot]
614c1adf96 update README.ja-JP.md [skip ci] 2024-01-13 09:11:50 +00:00
allcontributors[bot]
eb15fe6aa6 update README.de-DE.md [skip ci] 2024-01-13 09:11:25 +00:00
allcontributors[bot]
afe716fcf4 update README.it-IT.md [skip ci] 2024-01-13 09:11:24 +00:00
allcontributors[bot]
2e50c18dba update README.ko-KR.md [skip ci] 2024-01-13 09:11:23 +00:00
allcontributors[bot]
209d3a9c5b update README.ru-RU.md [skip ci] 2024-01-13 09:11:22 +00:00
allcontributors[bot]
efc462ee4e update README.zh-CN.md [skip ci] 2024-01-13 09:11:21 +00:00
allcontributors[bot]
7b4af46bd4 update README.md [skip ci] 2024-01-13 09:11:20 +00:00
Eugene
c9339ea76a Merge pull request #9383 from ricado-group/master
Add Support for a Quick Connect CLI command
2024-01-13 10:11:18 +01:00
Ash Neilson
ac95f550d9 Added support for a Quick Connect CLI command 2024-01-12 01:51:53 +13:00
Eugene
cc3af1aa03 Merge pull request #9369 from Jazzmoon/master
Add web-auth-handler to plugin list
2023-12-30 14:24:44 +01:00
Cameron Maclean
a6ac5a2898 Add plugin. 2023-12-29 18:21:01 -05:00
Eugene
353e5a9550 Merge pull request #9360 from Mxmilu666/master
Fix Connection error while opening WinSCP session using IPV6 address
2023-12-24 11:21:42 +01:00
Mxmilu
2507317d6b Fix Connection error while opening WinSCP session using IPV6 address 2023-12-24 12:55:00 +08:00
Mxmilu
78a64a9025 Fix Connection error while opening WinSCP session using IPV6 address 2023-12-24 12:48:16 +08:00
Mxmilu
1369b5b299 Fix Connection error while opening WinSCP session using IPV6 address 2023-12-24 12:43:18 +08:00
Mxmilu
76931e69ad Fix Connection error while opening WinSCP session using IPV6 address 2023-12-24 12:37:11 +08:00
Mxmilu
e4ceb3ee6a Fix Connection error while opening WinSCP session using IPV6 address 2023-12-24 12:28:47 +08:00
Eugene
86196c9f7d Merge pull request #9309 from Eugeny/all-contributors/add-kimbob13 2023-12-06 16:15:26 +01:00
allcontributors[bot]
62e54cbf6e update .all-contributorsrc [skip ci] 2023-12-06 11:01:30 +00:00
allcontributors[bot]
cd8e414fc0 update README.pt-BR.md [skip ci] 2023-12-06 11:01:28 +00:00
allcontributors[bot]
60be3722a2 update README.es-ES.md [skip ci] 2023-12-06 11:00:42 +00:00
allcontributors[bot]
4e4ee4fc98 update README.ja-JP.md [skip ci] 2023-12-06 11:00:40 +00:00
allcontributors[bot]
d3b5a53179 update README.id-ID.md [skip ci] 2023-12-06 11:00:37 +00:00
allcontributors[bot]
2a51ce556f update README.de-DE.md [skip ci] 2023-12-06 11:00:27 +00:00
allcontributors[bot]
62dc3e04d0 update README.it-IT.md [skip ci] 2023-12-06 11:00:26 +00:00
allcontributors[bot]
db9d90e9b0 update README.ko-KR.md [skip ci] 2023-12-06 11:00:25 +00:00
allcontributors[bot]
86469334a0 update README.ru-RU.md [skip ci] 2023-12-06 11:00:24 +00:00
allcontributors[bot]
eec294fa2e update README.zh-CN.md [skip ci] 2023-12-06 11:00:23 +00:00
allcontributors[bot]
aac1976baa update README.md [skip ci] 2023-12-06 11:00:22 +00:00
Eugene
a4aa07c1f1 Merge pull request #9307 from kimbob13/implicit-cr-lf 2023-12-06 12:00:20 +01:00
ChangHwan Kim
2437dc5bdc edit suggested by linter 2023-12-06 10:31:04 +09:00
ChangHwan Kim
a8ef5963c3 add implicit cr and implicit lf for serial terminal similar to putty 2023-12-06 10:02:50 +09:00
Eugene
2dc64ae51b Merge branch 'master' of github.com:Eugeny/tabby 2023-12-05 10:57:16 +01:00
Eugene
0ba5517a31 Delete issue-translator.yml 2023-12-05 10:57:11 +01:00
Eugene
9f6263f3d4 Merge pull request #9264 from Clem-Fern/fix#9262 2023-12-01 14:44:44 +01:00
Clem Fern
f80db81857 fix(ssh): resolve group name in getJumpHostLabel 2023-11-21 21:45:42 +01:00
Clem Fern
3794081cef ref(ssh): use ProfilesService instead of ConfigService in profile settings 2023-11-21 21:43:03 +01:00
Eugene
38c9714c75 Merge pull request #9257 from Eugeny/all-contributors/add-zKXDEX 2023-11-21 10:19:23 +01:00
Eugene
3823efc82a Merge pull request #9249 from Clem-Fern/title-bar 2023-11-21 10:18:45 +01:00
Eugene
977deea2a0 cleanup 2023-11-20 23:47:54 +01:00
allcontributors[bot]
0153bdf490 update README.pt-BR.md [skip ci] 2023-11-20 22:45:09 +00:00
allcontributors[bot]
0b608bdb24 update README.id-ID.md [skip ci] 2023-11-20 22:44:43 +00:00
allcontributors[bot]
8180530892 update .all-contributorsrc [skip ci] 2023-11-20 22:44:31 +00:00
allcontributors[bot]
0e58bb28f9 update README.es-ES.md [skip ci] 2023-11-20 22:42:56 +00:00
allcontributors[bot]
7908de9634 update README.ja-JP.md [skip ci] 2023-11-20 22:42:55 +00:00
allcontributors[bot]
2743c332d5 update README.de-DE.md [skip ci] 2023-11-20 22:42:17 +00:00
allcontributors[bot]
1e8693a47d update README.it-IT.md [skip ci] 2023-11-20 22:42:16 +00:00
allcontributors[bot]
c97f88fde6 update README.ko-KR.md [skip ci] 2023-11-20 22:42:15 +00:00
allcontributors[bot]
b97d73e912 update README.ru-RU.md [skip ci] 2023-11-20 22:42:14 +00:00
allcontributors[bot]
e16cc34b4e update README.zh-CN.md [skip ci] 2023-11-20 22:42:13 +00:00
allcontributors[bot]
a2b87ea8cb update README.md [skip ci] 2023-11-20 22:42:12 +00:00
Eugene
fda98f7434 Merge pull request #9253 from zKXDEX/master 2023-11-20 23:42:08 +01:00
Eugene
aae0147d7d Merge pull request #9238 from Clem-Fern/fix-build 2023-11-20 23:39:55 +01:00
zKXDEX
c59e9c1d82 fixed keyboard shortcut (control + backspace) in windows 2023-11-19 23:20:21 +01:00
Eugene
b4abe29c51 Merge pull request #9251 from Clem-Fern/fix-portable 2023-11-19 14:58:56 +01:00
Clem Fern
1e096ede77 fix: do not use installer to update portable version Eugeny/tabby#7768 2023-11-19 13:25:30 +01:00
Clem Fern
2be079a51b fix: use data folder on portable app 2023-11-19 13:22:57 +01:00
Clem
be0d129c28 Merge branch 'fix-title-bar' into title-bar 2023-11-18 22:10:38 +01:00
Clem Fern
191807c09a fix f4af21bf71: exclude macos 2023-11-18 22:07:03 +01:00
Clem Fern
f4af21bf71 fix: force display title-bar when tab-bar on left/right 2023-11-18 17:29:39 +01:00
Clem Fern
845d6c6373 lint b4777fd4a8 2023-11-18 16:22:34 +01:00
Clem Fern
066a1a6bac lint b4777fd4a8 2023-11-18 16:19:09 +01:00
Clem Fern
b4777fd4a8 fix: force display title-bar when tab-bar on left/right 2023-11-18 16:14:51 +01:00
Eugene
3d83bc6e4e Merge pull request #9247 from moemoechu/master 2023-11-18 14:36:26 +01:00
Cat in the orange box
102c0f5ce7 Update README.md
Add tabby-highlight plugin.
2023-11-18 20:30:44 +08:00
Eugene
345e90c1f6 fixed #9239 - missing sync token field 2023-11-16 12:00:51 +01:00
Clem Fern
787936babd bump node-gyp in app (fix gyp Python >=3.11.0 issue) 2023-11-15 23:01:18 +01:00
Clem Fern
6c1b0c3ae7 macos arm build: use python 3 instead of deprecated python 2 2023-11-15 22:25:26 +01:00
Clem Fern
efe1772e8d bump electron, electron-builder, node-abi 2023-11-15 21:36:33 +01:00
Clem Fern
d1311ba53f Revert "fixed builds"
This reverts commit 0f6561e859.
2023-11-15 21:09:52 +01:00
Clem Fern
5a6911f928 Revert "bumped electron & electron-buidler"
This reverts commit 56d5d34bfd.
2023-11-15 21:09:49 +01:00
Clem Fern
2254436365 Revert "bumped node-abi"
This reverts commit f706d7d6cb.
2023-11-15 21:09:46 +01:00
Clem Fern
2c70c0fff5 Revert "bumped gyp"
This reverts commit c3a9f35953.
2023-11-15 21:09:42 +01:00
Clem Fern
ff450527ab Revert "disable prebuildify"
This reverts commit ae6c1308a8.
2023-11-15 21:09:38 +01:00
Clem Fern
3ba6ce889e Revert "revert electron bump"
This reverts commit f0a84d4d76.
2023-11-15 21:08:07 +01:00
Clem Fern
4ca425c2a8 Revert "enable npmRebuild"
This reverts commit 26a2a0c44e.
2023-11-15 21:07:39 +01:00
Clem Fern
70fb882e4d Revert "unset npmRebuild"
This reverts commit 31b063a964.
2023-11-15 21:07:19 +01:00
Clem Fern
86664c4eba Revert "Update build.yml"
This reverts commit 454391d31e.
2023-11-15 21:06:40 +01:00
Eugene
72149d2cb0 Merge pull request #9234 from moemoechu/master 2023-11-15 13:25:57 +01:00
Cat in the orange box
04a1b0fb44 add tabby-background plugin. 2023-11-15 19:52:28 +08:00
Eugene
f8614dffbc Merge pull request #9232 from Clem-Fern/fix-macos-build 2023-11-15 11:32:15 +01:00
Eugene
37ccba5c90 Update build-linux.mjs 2023-11-15 10:53:45 +01:00
Clem Fern
98719aafdc fix native modules rebuild on macos 2023-11-14 20:11:34 +01:00
Eugene
860ee3eaa9 Revert "fixes"
This reverts commit 4c0231cd67.
2023-11-10 18:01:31 +01:00
Eugene
454391d31e Update build.yml 2023-11-10 16:44:04 +01:00
Eugene
4c0231cd67 fixes 2023-11-10 16:01:55 +01:00
Eugene
31b063a964 unset npmRebuild 2023-11-10 15:15:53 +01:00
Eugene
26a2a0c44e enable npmRebuild 2023-11-10 14:42:29 +01:00
Eugene
f0a84d4d76 revert electron bump 2023-11-10 13:49:44 +01:00
Eugene
ae6c1308a8 disable prebuildify 2023-11-10 13:09:42 +01:00
Eugene
c3a9f35953 bumped gyp 2023-11-10 11:50:18 +01:00
Eugene
dc6c0357c2 lint 2023-11-10 10:16:06 +01:00
Eugene
f706d7d6cb bumped node-abi 2023-11-10 09:08:08 +01:00
Eugene
56d5d34bfd bumped electron & electron-buidler 2023-11-10 01:07:55 +01:00
Eugene
40246a409d ci: bumped macos image 2023-11-05 14:58:45 +01:00
Eugene
0f6561e859 fixed builds 2023-11-05 00:11:01 +01:00
Eugene
72c0692843 fixed builds 2023-11-04 23:34:14 +01:00
Eugene
26d6d14703 updated locales 2023-11-04 22:11:29 +01:00
Eugene
6a458d8b9b updated config sync settings tab 2023-10-15 21:08:18 +02:00
Eugene
3e9ee5b235 Merge pull request #9099 from Eugeny/all-contributors/add-aaronhuggins 2023-10-12 10:15:12 +02:00
allcontributors[bot]
4740824dd1 update README.pt-BR.md [skip ci] 2023-10-11 18:33:54 +00:00
allcontributors[bot]
51d48f07d7 update README.es-ES.md [skip ci] 2023-10-11 18:32:55 +00:00
allcontributors[bot]
a8d7fa33b5 update .all-contributorsrc [skip ci] 2023-10-11 18:32:21 +00:00
allcontributors[bot]
34fee58a7d update README.ja-JP.md [skip ci] 2023-10-11 18:32:18 +00:00
allcontributors[bot]
f276c50326 update README.id-ID.md [skip ci] 2023-10-11 18:31:36 +00:00
allcontributors[bot]
ca1241ee52 update README.de-DE.md [skip ci] 2023-10-11 18:30:53 +00:00
allcontributors[bot]
000bdde0cd update README.it-IT.md [skip ci] 2023-10-11 18:30:52 +00:00
allcontributors[bot]
34daa4c412 update README.ko-KR.md [skip ci] 2023-10-11 18:30:51 +00:00
allcontributors[bot]
39596588bb update README.ru-RU.md [skip ci] 2023-10-11 18:30:50 +00:00
allcontributors[bot]
1228b1a29a update README.zh-CN.md [skip ci] 2023-10-11 18:30:49 +00:00
allcontributors[bot]
f0636623ae update README.md [skip ci] 2023-10-11 18:30:48 +00:00
Eugene
4057e0cf59 Merge pull request #9098 from aaronhuggins/master 2023-10-11 20:30:31 +02:00
Aaron Huggins
0e8164fe4c Add Noctis colors plugin to themes section 2023-10-11 10:09:56 -05:00
Eugene
2b8fed164f Merge pull request #9084 from Ranhiru/reload-profiles-when-new-profiles-are-created 2023-10-09 13:08:26 +02:00
Eugene
e68bd6c746 Merge pull request #9082 from Ranhiru/fix-not-showing-custom-profiles-in-settings 2023-10-09 13:07:28 +02:00
Jude Cooray
f3196ac045 Refresh default profile selection when profiles are modified 2023-10-09 21:15:18 +11:00
Jude Cooray
57f20eca4f Show option group only if there are custom profiles 2023-10-09 21:06:42 +11:00
Jude Cooray
5d1a35a285 Show custom profiles in default profiles selection 2023-10-09 20:29:06 +11:00
Eugene
642db6a14a build a .dmg instead of a .pkg 2023-10-06 13:38:27 +02:00
Eugene
e739883840 updated locales 2023-10-06 13:38:21 +02:00
Eugene
bb27314696 bumped xterm to 5.3.0 2023-10-06 13:29:54 +02:00
Eugene
adeb6031dd Merge pull request #8918 from Clem-Fern/fix#8912 2023-10-06 13:21:36 +02:00
Eugene
34aeb797f3 Merge pull request #9066 from Clem-Fern/fix#8884 2023-10-06 13:20:43 +02:00
Clem Fern
7d5128a8ce fix(terminal): fallback to canvas if webgl renderer incompatible
ref Eugeny/tabby#8884
ref https://bugs.chromium.org/p/chromium/issues/detail?id=1476475
2023-10-05 22:49:42 +02:00
Eugene
83c0892546 Merge pull request #9060 from Eugeny/all-contributors/add-nwalser 2023-10-03 20:45:13 +02:00
allcontributors[bot]
9e705fb273 update README.pt-BR.md [skip ci] 2023-10-03 15:00:22 +00:00
allcontributors[bot]
c2b349de8f update .all-contributorsrc [skip ci] 2023-10-03 15:00:19 +00:00
allcontributors[bot]
3176a7744b update README.ja-JP.md [skip ci] 2023-10-03 15:00:06 +00:00
allcontributors[bot]
98dd4a0017 update README.es-ES.md [skip ci] 2023-10-03 14:59:27 +00:00
allcontributors[bot]
cfce2687bd update README.id-ID.md [skip ci] 2023-10-03 14:59:20 +00:00
allcontributors[bot]
2af7ad85f8 update README.de-DE.md [skip ci] 2023-10-03 14:58:49 +00:00
allcontributors[bot]
8616bdbea3 update README.it-IT.md [skip ci] 2023-10-03 14:58:48 +00:00
allcontributors[bot]
0505e5615d update README.ko-KR.md [skip ci] 2023-10-03 14:58:47 +00:00
allcontributors[bot]
8c2820056a update README.ru-RU.md [skip ci] 2023-10-03 14:58:46 +00:00
allcontributors[bot]
b1108a7b32 update README.zh-CN.md [skip ci] 2023-10-03 14:58:45 +00:00
allcontributors[bot]
bfe3430e9a update README.md [skip ci] 2023-10-03 14:58:44 +00:00
Eugene
612d6ef089 Merge pull request #9048 from nwalser/feature/specify-config-file-path
added possibility to set config file path in environment file
2023-10-03 16:58:16 +02:00
Nathaniel Walser
bd31db9c56 renamed env variable to TABBY_CONFIG_DIRECTORY 2023-10-03 08:06:16 +02:00
Nathaniel Walser
d1a837b11d fixed linting error and removed value from .env file 2023-09-30 21:30:25 +02:00
Nathaniel Walser
d70be3abf9 added possibility to set config file path in environment file 2023-09-30 21:07:14 +02:00
Eugene
422df52fea updated locales 2023-09-21 09:07:27 +02:00
Eugene
140d7e9f96 fixed #8936 - updated locales 2023-09-21 09:05:09 +02:00
Eugene
9a3bb1ae4b Merge branch 'master' of github.com:Eugeny/tabby 2023-09-21 09:04:42 +02:00
Eugene
169adedc48 fixed #9009 - allow color schemes per serial connection 2023-09-21 09:04:01 +02:00
Eugene
90ccd969f2 Merge pull request #9008 from JakubZ0/patch-1 2023-09-20 21:55:46 +02:00
Jakub Z
6ebfccda28 added catppuccin 2023-09-20 21:54:05 +02:00
Eugene
27bf7c4ad6 Merge pull request #8960 from Clem-Fern/fix#8915 2023-09-20 21:53:55 +02:00
Clem Fern
651861cd4a fix(core): selector prevent edit selection on keydown 2023-09-10 17:52:38 +02:00
Eugene
3ce2bb68c6 Merge pull request #8926 from Clem-Fern/ref-profiles-v2 2023-09-04 23:03:20 +02:00
Clem
e4169a54aa ref(settings): avoid useless object assign & deleting profile fields one by one 2023-09-04 20:04:47 +02:00
Clem
0d0bde82a0 Revert "wip fix(core): writeProfile avoid deleting profile fields one by one"
This reverts commit 30936b739e.
2023-09-02 21:29:29 +02:00
Clem
04b53ab366 ref(terminal) 7cde5c0807: clear service message on connection succeeds only 2023-09-02 20:52:25 +02:00
Clem
7cde5c0807 fix(terminal) Eugeny/tabby#8912: move frontend clear after session initialization (ref ef6b8a4eaa Eugeny/tabby#8726) 2023-09-02 17:51:08 +02:00
Eugene
cb71c79ecc Merge pull request #8911 from siebsie23/master
#8907 Fix for not being able to select the "Interactive" authentication method
2023-09-01 17:43:20 +02:00
Sibren
6843b87493 Merge branch 'Eugeny:master' into master 2023-09-01 13:32:33 +02:00
Sibren van Setten
a17da4b4af #8907 Fix interactive button not selectable 2023-09-01 13:32:13 +02:00
Eugene
5d5c545b4e Merge pull request #8910 from Eugeny/all-contributors/add-siebsie23 2023-09-01 10:53:38 +02:00
allcontributors[bot]
f7299ee321 update README.pt-BR.md [skip ci] 2023-09-01 08:51:22 +00:00
allcontributors[bot]
d1e97bf737 update README.de-DE.md [skip ci] 2023-09-01 08:51:21 +00:00
allcontributors[bot]
f9f1a809a1 update .all-contributorsrc [skip ci] 2023-09-01 08:50:47 +00:00
allcontributors[bot]
d881da94de update README.es-ES.md [skip ci] 2023-09-01 08:50:46 +00:00
allcontributors[bot]
3aaa68fe09 update README.ja-JP.md [skip ci] 2023-09-01 08:50:43 +00:00
allcontributors[bot]
ea84612788 update README.id-ID.md [skip ci] 2023-09-01 08:50:37 +00:00
allcontributors[bot]
16fcf3d7f8 update README.it-IT.md [skip ci] 2023-09-01 08:50:25 +00:00
allcontributors[bot]
4a02abdcc3 update README.ko-KR.md [skip ci] 2023-09-01 08:50:24 +00:00
allcontributors[bot]
98a5bfd338 update README.ru-RU.md [skip ci] 2023-09-01 08:50:23 +00:00
allcontributors[bot]
2dbc43f828 update README.zh-CN.md [skip ci] 2023-09-01 08:50:22 +00:00
allcontributors[bot]
0c93010da7 update README.md [skip ci] 2023-09-01 08:50:21 +00:00
Eugene
0329e7a8b6 Merge pull request #8897 from siebsie23/master 2023-09-01 10:50:18 +02:00
Sibren van Setten
26ac6b0aa3 Fix lint errors 2023-08-30 13:16:40 +02:00
Sibren van Setten
8bc2375aab Add show secret functionality to vault 2023-08-30 12:19:46 +02:00
Eugene
dc9a7d8fac fixed #8886 - crash on the color schemes settings tab 2023-08-29 22:41:03 +02:00
103 changed files with 7576 additions and 5032 deletions

View File

@@ -635,10 +635,10 @@
]
},
{
"login": "X-0x01",
"name": "X-0x01",
"login": "0x973",
"name": "0x973",
"avatar_url": "https://avatars.githubusercontent.com/u/19320096?v=4",
"profile": "http://pingbase.cn",
"profile": "https://github.com/0x973",
"contributions": [
"code"
]
@@ -1220,6 +1220,69 @@
"contributions": [
"code"
]
},
{
"login": "siebsie23",
"name": "Sibren",
"avatar_url": "https://avatars.githubusercontent.com/u/25083973?v=4",
"profile": "https://siebsie23.nl/",
"contributions": [
"code"
]
},
{
"login": "nwalser",
"name": "Nathaniel Walser",
"avatar_url": "https://avatars.githubusercontent.com/u/33339996?v=4",
"profile": "https://www.nathaniel-walser.com",
"contributions": [
"code"
]
},
{
"login": "aaronhuggins",
"name": "Aaron Huggins",
"avatar_url": "https://avatars.githubusercontent.com/u/16567111?v=4",
"profile": "https://github.com/aaronhuggins",
"contributions": [
"design"
]
},
{
"login": "zKXDEX",
"name": "KDex",
"avatar_url": "https://avatars.githubusercontent.com/u/66271780?v=4",
"profile": "https://zkxdex.github.io/",
"contributions": [
"code"
]
},
{
"login": "kimbob13",
"name": "ChangHwan Kim",
"avatar_url": "https://avatars.githubusercontent.com/u/26755098?v=4",
"profile": "https://github.com/kimbob13",
"contributions": [
"code"
]
},
{
"login": "ashneilson",
"name": "Ash Neilson",
"avatar_url": "https://avatars.githubusercontent.com/u/35913512?v=4",
"profile": "https://github.com/ashneilson",
"contributions": [
"code"
]
},
{
"login": "cfs4819",
"name": "Chen Fansong",
"avatar_url": "https://avatars.githubusercontent.com/u/53071761?v=4",
"profile": "https://github.com/cfs4819",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

1
.env Normal file
View File

@@ -0,0 +1 @@
# TABBY_CONFIG_DIRECTORY="PATH_TO_DIRECTORY"

View File

@@ -2,7 +2,7 @@ name: Package-Build
on: [push, pull_request]
jobs:
Lint:
runs-on: macos-11
runs-on: ubuntu-20.04
steps:
- name: Checkout
@@ -31,7 +31,7 @@ jobs:
run: yarn run lint
macOS-Build:
runs-on: macos-11
runs-on: macos-12
needs: Lint
strategy:
matrix:
@@ -53,6 +53,8 @@ jobs:
- name: Install deps
run: |
sudo -H pip3 install setuptools
npm config set python python3
sudo npm i -g yarn@1.22.1
yarn --network-timeout 1000000
env:
@@ -110,16 +112,16 @@ jobs:
- name: Package artifacts
run: |
mkdir artifact-pkg
mv dist/*.pkg artifact-pkg/
mkdir artifact-dmg
mv dist/*.dmg artifact-dmg/
mkdir artifact-zip
mv dist/*.zip artifact-zip/
- uses: actions/upload-artifact@master
name: Upload PKG
name: Upload DMG
with:
name: macOS .pkg (${{matrix.arch}})
path: artifact-pkg
name: macOS .dmg (${{matrix.arch}})
path: artifact-dmg
- uses: actions/upload-artifact@master
name: Upload ZIP
@@ -162,7 +164,7 @@ jobs:
- name: Install deps (amd64)
run: |
sudo apt-get update
sudo apt-get install libarchive-tools zsh
sudo apt-get install libarchive-tools zsh python3-distutils
- name: Install npm_modules (amd64)
run: |

View File

@@ -1,15 +0,0 @@
name: 'issue-translator'
on:
issue_comment:
types: [created]
issues:
types: [opened]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: tomsun28/issues-translate-action@v2.7
with:
IS_MODIFY_TITLE: true
CUSTOM_BOT_NOTE: The translator bot has detected that this issue body's language is not English, and has translated it automatically.

View File

@@ -20,7 +20,7 @@
<br/>
<p align="center">
Diese README ist auch verfügbar in: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:br: Português</a>
Diese README ist auch verfügbar in: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
@@ -243,7 +243,7 @@ Dank geht an diese wunderbaren Menschen ([emoji key](https://allcontributors.org
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -327,6 +327,15 @@ Dank geht an diese wunderbaren Menschen ([emoji key](https://allcontributors.org
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -21,7 +21,7 @@
<br/>
<p align="center">
Este fichero README está disponible en: <a href="./README.md">:gb: English</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:br: Português</a>
Este fichero README está disponible en: <a href="./README.md">:gb: English</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
@@ -245,7 +245,7 @@ Gracias a estas maravillosas personas ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -329,6 +329,15 @@ Gracias a estas maravillosas personas ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -21,7 +21,7 @@
<br/>
<p align="center">
This README is also available in: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.pt-BR.md">:br: Português</a>
This README is also available in: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
@@ -242,7 +242,7 @@ Terima kasih kepada mereka yang telah membantu ([emoji key](https://allcontribut
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -326,6 +326,15 @@ Terima kasih kepada mereka yang telah membantu ([emoji key](https://allcontribut
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -21,7 +21,7 @@
<br/>
<p align="center">
Questo README è disponibile anche in: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:br: Português</a>
Questo README è disponibile anche in: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
----
@@ -238,7 +238,7 @@ Grazie a queste persone meravigliose ([emoji key](https://allcontributors.org/do
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -322,6 +322,15 @@ Grazie a queste persone meravigliose ([emoji key](https://allcontributors.org/do
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -28,7 +28,7 @@
<br/>
<p align="center">
このREADMEは次の言語でもご覧いただけます: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:br: Português</a>
このREADMEは次の言語でもご覧いただけます: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
@@ -253,7 +253,7 @@ Windows上では、`Tabby.exe`がある場所と同じ場所に`data`フォル
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -337,6 +337,15 @@ Windows上では、`Tabby.exe`がある場所と同じ場所に`data`フォル
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -19,6 +19,11 @@
* [Repositories](https://packagecloud.io/eugeny/tabby): [Debian/Ubuntu-based](https://packagecloud.io/eugeny/tabby/install#bash-deb), [RPM-based](https://packagecloud.io/eugeny/tabby/install#bash-rpm)
* [Latest nightly build](https://nightly.link/Eugeny/tabby/workflows/build/master)
<br/>
<p align="center">
This README is also available in: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
**Tabby** (구 **Terminus**)는 Windows, macOS 및 Linux용으로 뛰어난 구성의 터미널 에뮬레이터, SSH 및 시리얼 클라이언트입니다.
@@ -232,7 +237,7 @@ Pull requests and plugins are welcome!
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -316,6 +321,15 @@ Pull requests and plugins are welcome!
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -29,7 +29,7 @@
<br/>
<p align="center">
This README is also available in: <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">🇧🇷 Português</a>
This README is also available in: <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
@@ -129,6 +129,9 @@ Plugins and themes can be installed directly from the Settings view inside Tabby
* [workspace-manager](https://github.com/composer404/tabby-workspace-manager) - allows creating custom workspace profiles based on the given config
* [search-in-browser](https://github.com/composer404/tabby-search-in-browser) - opens default system browser with a text selected from the Tabby's tab
* [sftp-tab](https://github.com/wljince007/tabby-sftp-tab) - open sftp tab for ssh connection like SecureCRT
* [background](https://github.com/moemoechu/tabby-background) - change Tabby background image and more...
* [highlight](https://github.com/moemoechu/tabby-highlight) - Tabby terminal keyword highlight plugin
* [web-auth-handler](https://github.com/Jazzmoon/tabby-web-auth-handler) - In-app web authentication popups (Built primarily for warpgate in-browser auth)
<a name="themes"></a>
@@ -139,6 +142,8 @@ Plugins and themes can be installed directly from the Settings view inside Tabby
* [gruvbox](https://github.com/porkloin/terminus-theme-gruvbox)
* [windows10](https://www.npmjs.com/package/terminus-theme-windows10)
* [altair](https://github.com/yxuko/terminus-altair)
* [catppuccin](https://github.com/catppuccin/tabby) - Soothing pastel theme for Tabby
* [noctis](https://github.com/aaronhuggins/tabby-colors-noctis) - color themes inspired by Noctis VS Code theme
# Sponsors <!-- omit in toc -->
@@ -254,7 +259,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -338,6 +343,15 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

363
README.pl-PL.md Normal file
View File

@@ -0,0 +1,363 @@
[![](docs/readme.png)](https://tabby.sh)
<p align="center">
<a href="https://github.com/Eugeny/tabby/releases/latest"><img alt="Wszystkie wydania na GitHubie" src="https://img.shields.io/github/downloads/eugeny/tabby/total.svg?label=POBRANIA&logo=github&style=for-the-badge"></a> &nbsp; <a href="https://nightly.link/Eugeny/tabby/workflows/build/master"><img src="https://shields.io/badge/-Nightly%20Builds-orange?logo=hackthebox&logoColor=fff&style=for-the-badge"/></a> &nbsp; <a href="https://matrix.to/#/#tabby-general:matrix.org"><img alt="Matrix" src="https://img.shields.io/matrix/tabby-general:matrix.org?logo=matrix&style=for-the-badge&color=magenta"></a> &nbsp <a href="https://translate.tabby.sh/"><img alt="Przetłumacz" src="https://shields.io/badge/Translate-UI-white?logo=googletranslate&style=for-the-badge&color=white&logoColor=fff"></a> &nbsp; <a href="https://twitter.com/eugeeeeny"><img alt="Twitter" src="https://shields.io/badge/Subscribe-News-blue?logo=twitter&style=for-the-badge&color=blue"></a>
</p>
<p align="center">
<a href="https://ko-fi.com/J3J8KWTF">
<img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=2" width="150">
</a>
</p>
---
> 👋 Zarządzasz zdalnymi środowiskami? Rzuć okiem na [WarpGate, inteligentny serwer typu bastion SSH/HTTP/MySQL](https://github.com/warp-tech/warpgate), świetnie współdziała z Tabby, pokochasz go!
> 👋 [Tabby-Web](https://github.com/Eugeny/tabby-web) poszukuje sponsorów. Nie jestem w stanie pokryć kosztów hostowania całej infrastruktury, jeśli jesteś zainteresowany wsparciem, proszę [skontakuj się ze mną!](https://twitter.com/eugeeeeny)
----
### Pobieranie:
* [Ostatnie wydania](https://github.com/Eugeny/tabby/releases/latest)
* [Repozytoria](https://packagecloud.io/eugeny/tabby): [Systemy Debian/Ubuntu](https://packagecloud.io/eugeny/tabby/install#bash-deb), [Środowiska RPM](https://packagecloud.io/eugeny/tabby/install#bash-rpm)
* [Ostatnie wydania developerskie](https://nightly.link/Eugeny/tabby/workflows/build/master)
<br/>
<p align="center">
Ten plik README jest również dostępny w językach: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">🇧🇷 Português</a>
</p>
----
[**Tabby**](https://tabby.sh) (formalnie **Terminus**) to wysoce konfigurowalny emulator konsoli, SSH oraz klienta konsoli szeregowej na systemy Windows 10, macOS oraz Linux
* Zintegrowany klient SSH i Telnet oraz menedżer sesji
* Zintegrowany klient terminala szeregowego
* Motywy and palety kolorów
* W pełni konfigurowalne skróty klawiszowe
* Dzielenie ekranu
* Zapamiętywanie okien z poprzednich sesji
* PowerShell (oraz PS Core), WSL, Git-Bash, Cygwin, MSYS2, Cmder i wsparcie dla CMD
* Bezpośredni transfer plików sesji SSH przez Zmodem
* Pełne wsparcie dla znaków Unicode wraz z podwójnymi znakami
* Nie zawieszanie się przy szybko wyświetlanych wynikach
* Pełne doświadczenie powłoki na systemie Windows zawierającej podpowiedzi (przez Clink)
* Zintegrowany zaszyfrowany kontener na klucze SSH i jego konfigurację
* Klient SSH, SFTP oraz Telnet dostępny jako [aplikacja webowa](https://tabby.sh/app) (również jako [własna instacja](https://github.com/Eugeny/tabby-web)).
# Spis treści <!-- omit in toc -->
- [Czym jest, a czym nie jest Tabby](#what-tabby-is-and-isnt)
- [Funkcje konsoli](#terminal-features)
- [Klient SSH](#ssh-client)
- [Konsola szeregowa](#serial-terminal)
- [Wersja przenośna](#portable)
- [Wtyczki](#plugins)
- [Motywy i palety kolorów](#themes)
- [Współtworzenie](#contributing)
<a name="about"></a>
# Czym jest, a czym nie jest Tabby
* **Tabby jest** alternatywą dla standardowej konsoli Windows (conhost), PowerShell ISE, PuTTY, Terminal.app oraz iTerm z macOS
* **Tabby nie jest** nową powłoką lub zamiennikiem dla MinGW czy Cygwin. Nie jest również zatrważająco szybki - jeśli ważne jest dla Ciebie użycie pamięci RAM, rozważ użycie [Conemu](https://conemu.github.io) lub [Alacritty](https://github.com/jwilm/alacritty)
<a name="terminal"></a>
# Funkcje konsoli
![](docs/readme-terminal.png)
* Konsola V220 + wiele rozszerzeń
* Wiele nakładających się podzielonych okien
* Okna na każdej stronie ekranu
* Opcjonalne dokowanie okna za pomocą skrótu ("Quake console")
* Wykrywanie postępu (Pasek)
* Powiadomienia przy ukończeniu procesu podczas postępu
* Wklejanie z nawiasami, ostrzeżenie przy wielu liniach
* Wsparcie różnych czcionek
* Niestandardowe profile powłoki
* Opcjonalne wklejanie PPM oraz kopiowanie na zaznaczeniu (Styl PuTTY)
<a name="ssh"></a>
# Klient SSH
![](docs/readme-ssh.png)
* Klient SSH2 z zarządzaniem połączeń
* X11 oraz przekierowywanie portów
* Automatyczne przejście między hostami
* Przekierowanie agenta (Pageant oraz Windowsowy natywny "OpenSSH Agent")
* Skrypty logowania
<a name="serial"></a>
# Konsola Szeregowa
* Zapisane połączenia
* Wczytywanie danych wejścia linii
* Opcjonalna konwersja danych wejścia i wyjścia na szesnastkowe "byte-by-byte"
* Konwersja na nową linię
* Automatyczne połączenie po rozłączeniu
<a name="portable"></a>
# Wersja przenośna
Tabby będzie uruchamiał się jako aplikacja przenośna, tylko wtedy, kiedy utworzysz folder `data` w tej samej lokacji, w której znajduje się `Tabby.exe`.
<a name="plugins"></a>
# Wtyczki
Wtyczki (jak i motywy) mogą być instalowane bezpośrednio z widoku ustawień w środku aplikacji Tabby.
* [docker](https://github.com/Eugeny/tabby-docker) - połączenie z kontenerami Docker
* [title-control](https://github.com/kbjr/terminus-title-control) - pozwala na zmienianie tytułu konsoli jako prefiks, sufiks lub/albo tekst do usunięcia
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - szybko wysyłaj komendy z jednej konsoli do wielu
* [save-output](https://github.com/Eugeny/tabby-save-output) - zapisuj dane wyjściowe do pliku
* [sync-config](https://github.com/starxg/terminus-sync-config) - synchronizuj konfigurację przez Gista lub Gitee
* [clippy](https://github.com/Eugeny/tabby-clippy) - przykładowa wtyczka, która zwyczajnie denerwuje
* [workspace-manager](https://github.com/composer404/tabby-workspace-manager) - pozwala na utworzenie niestandardowego profilu pracy w aplikacji odpowiednio do konfiguracji
* [search-in-browser](https://github.com/composer404/tabby-search-in-browser) - otwiera domyślną przeglądarkę z zaznaczonym tekstem w oknie Tabby
* [sftp-tab](https://github.com/wljince007/tabby-sftp-tab) - otwiera okno z połączeniem SFTP dla połączeń SSH jak SecureCRT
* [background](https://github.com/moemoechu/tabby-background) - zmień tło Tabby oraz wiele więcej
* [highlight](https://github.com/moemoechu/tabby-highlight) - Tabby terminal keyword highlight plugin
* [web-auth-handler](https://github.com/Jazzmoon/tabby-web-auth-handler) - okienka autoryzacji wewnątrz konsoli (Zbudowany głównie pod autoryzację projektu Warpgate w przeglądarce)
<a name="themes"></a>
# Motywy i palety kolorów
* [hype](https://github.com/Eugeny/tabby-theme-hype) - Motyw zainspirowany konsolą "Hyper"
* [relaxed](https://github.com/Relaxed-Theme/relaxed-terminal-themes#terminus) - Motyw "pełnej relaksacji"
* [gruvbox](https://github.com/porkloin/terminus-theme-gruvbox) - Motyw zainspirowany konsolą "Hyper" (kolejny)
* [windows10](https://www.npmjs.com/package/terminus-theme-windows10) - Motyw zainspirowany Microsoftem
* [altair](https://github.com/yxuko/terminus-altair) - Motwy autorstwa Yacine Kanzari
* [catppuccin](https://github.com/catppuccin/tabby) - Paleta pastelowa dla Tabby
* [noctis](https://github.com/aaronhuggins/tabby-colors-noctis) - Paleta kolorów zainspirowana motywem Noctis z VS Code
# Sponsorzy <!-- omit in toc -->
[![](https://assets-production.packagecloud.io/assets/packagecloud-logo-light-scaled-26ce8e96060fddf74afbd4445e63ba35590d4aaa56edc98495bb390ef3cae0ae.png)](https://packagecloud.io)
[**packagecloud**](https://packagecloud.io) zapewnia darmowe utrzymanie repozytorium Debian/RPM
[![](https://user-images.githubusercontent.com/161476/200423885-7aba2202-fea7-4409-95b9-3a062ce902c7.png)](https://keygen.sh/?via=eugene)
[**keygen**](https://keygen.sh/?via=eugene) zapewnia darmowe wydawanie oraz automatycznie utrzymywanie strony
<a name="contributing"></a>
# Współtworzenie
Pull requesty and dodawanie nowych wtyczek jest mile widziane!
Zobacz plik [HAKOWANIE.md](https://github.com/Eugeny/tabby/blob/master/HACKING.md) oraz [Dokumentację API](https://docs.tabby.sh/), aby poznać, jak projekt jest prowadzony wraz ze wstępnym poradnikiem jak tworzyć wtyczki.
---
<a name="contributors"></a>
Dziękujemy wszystkim osobom współtworzącym ten projekt ([emotki są specjalizacją](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://www.russellmyers.com"><img src="https://avatars2.githubusercontent.com/u/184085?v=4?s=100" width="100px;" alt="Russell Myers"/><br /><sub><b>Russell Myers</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mezner" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.morwire.com"><img src="https://avatars1.githubusercontent.com/u/3991658?v=4?s=100" width="100px;" alt="Austin Warren"/><br /><sub><b>Austin Warren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ehwarren" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Drachenkaetzchen"><img src="https://avatars1.githubusercontent.com/u/162974?v=4?s=100" width="100px;" alt="Felicia Hummel"/><br /><sub><b>Felicia Hummel</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Drachenkaetzchen" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mikemaccana"><img src="https://avatars2.githubusercontent.com/u/172594?v=4?s=100" width="100px;" alt="Mike MacCana"/><br /><sub><b>Mike MacCana</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mikemaccana" title="Tests">⚠️</a> <a href="#design-mikemaccana" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yxuko"><img src="https://avatars1.githubusercontent.com/u/1786317?v=4?s=100" width="100px;" alt="Yacine Kanzari"/><br /><sub><b>Yacine Kanzari</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=yxuko" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BBJip"><img src="https://avatars2.githubusercontent.com/u/32908927?v=4?s=100" width="100px;" alt="BBJip"/><br /><sub><b>BBJip</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=BBJip" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Futagirl"><img src="https://avatars2.githubusercontent.com/u/33533958?v=4?s=100" width="100px;" alt="Futagirl"/><br /><sub><b>Futagirl</b></sub></a><br /><a href="#design-Futagirl" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://www.levrik.io"><img src="https://avatars3.githubusercontent.com/u/9491603?v=4?s=100" width="100px;" alt="Levin Rickert"/><br /><sub><b>Levin Rickert</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=levrik" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://kwonoj.github.io"><img src="https://avatars2.githubusercontent.com/u/1210596?v=4?s=100" width="100px;" alt="OJ Kwon"/><br /><sub><b>OJ Kwon</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kwonoj" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Domain"><img src="https://avatars2.githubusercontent.com/u/903197?v=4?s=100" width="100px;" alt="domain"/><br /><sub><b>domain</b></sub></a><br /><a href="#plugin-Domain" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/tabby/commits?author=Domain" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.jbrumond.me"><img src="https://avatars1.githubusercontent.com/u/195127?v=4?s=100" width="100px;" alt="James Brumond"/><br /><sub><b>James Brumond</b></sub></a><br /><a href="#plugin-kbjr" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.growingwiththeweb.com"><img src="https://avatars0.githubusercontent.com/u/2193314?v=4?s=100" width="100px;" alt="Daniel Imms"/><br /><sub><b>Daniel Imms</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Tyriar" title="Code">💻</a> <a href="#plugin-Tyriar" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/tabby/commits?author=Tyriar" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/baflo"><img src="https://avatars2.githubusercontent.com/u/834350?v=4?s=100" width="100px;" alt="Florian Bachmann"/><br /><sub><b>Florian Bachmann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=baflo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://michael-kuehnel.de"><img src="https://avatars2.githubusercontent.com/u/441011?v=4?s=100" width="100px;" alt="Michael Kühnel"/><br /><sub><b>Michael Kühnel</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mischah" title="Code">💻</a> <a href="#design-mischah" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NieLeben"><img src="https://avatars3.githubusercontent.com/u/47182955?v=4?s=100" width="100px;" alt="Tilmann Meyer"/><br /><sub><b>Tilmann Meyer</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=NieLeben" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.jubeat.net"><img src="https://avatars3.githubusercontent.com/u/11289158?v=4?s=100" width="100px;" alt="PM Extra"/><br /><sub><b>PM Extra</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/issues?q=author%3APMExtra" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jjuhas.keybase.pub//"><img src="https://avatars1.githubusercontent.com/u/6438760?v=4?s=100" width="100px;" alt="Jonathan"/><br /><sub><b>Jonathan</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=IgnusG" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hans-koch.me"><img src="https://avatars0.githubusercontent.com/u/1093709?v=4?s=100" width="100px;" alt="Hans Koch"/><br /><sub><b>Hans Koch</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=hammster" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://thepuzzlemaker.info"><img src="https://avatars3.githubusercontent.com/u/12666617?v=4?s=100" width="100px;" alt="Dak Smyth"/><br /><sub><b>Dak Smyth</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ThePuzzlemaker" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://yfwz100.github.io"><img src="https://avatars2.githubusercontent.com/u/983211?v=4?s=100" width="100px;" alt="Wang Zhi"/><br /><sub><b>Wang Zhi</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=yfwz100" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jack1142"><img src="https://avatars0.githubusercontent.com/u/6032823?v=4?s=100" width="100px;" alt="jack1142"/><br /><sub><b>jack1142</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=jack1142" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hdougie"><img src="https://avatars1.githubusercontent.com/u/450799?v=4?s=100" width="100px;" alt="Howie Douglas"/><br /><sub><b>Howie Douglas</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=hdougie" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://chriskaczor.com"><img src="https://avatars2.githubusercontent.com/u/180906?v=4?s=100" width="100px;" alt="Chris Kaczor"/><br /><sub><b>Chris Kaczor</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ckaczor" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.boxmein.net"><img src="https://avatars1.githubusercontent.com/u/358714?v=4?s=100" width="100px;" alt="Johannes Kadak"/><br /><sub><b>Johannes Kadak</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boxmein" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LeSeulArtichaut"><img src="https://avatars1.githubusercontent.com/u/38361244?v=4?s=100" width="100px;" alt="LeSeulArtichaut"/><br /><sub><b>LeSeulArtichaut</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=LeSeulArtichaut" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CyrilTaylor"><img src="https://avatars0.githubusercontent.com/u/12631466?v=4?s=100" width="100px;" alt="Cyril Taylor"/><br /><sub><b>Cyril Taylor</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=CyrilTaylor" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nstefanou"><img src="https://avatars3.githubusercontent.com/u/51129173?v=4?s=100" width="100px;" alt="nstefanou"/><br /><sub><b>nstefanou</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nstefanou" title="Code">💻</a> <a href="#plugin-nstefanou" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/orin220444"><img src="https://avatars3.githubusercontent.com/u/30747229?v=4?s=100" width="100px;" alt="orin220444"/><br /><sub><b>orin220444</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=orin220444" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Goobles"><img src="https://avatars3.githubusercontent.com/u/8776771?v=4?s=100" width="100px;" alt="Gobius Dolhain"/><br /><sub><b>Gobius Dolhain</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Goobles" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/3l0w"><img src="https://avatars2.githubusercontent.com/u/37798980?v=4?s=100" width="100px;" alt="Gwilherm Folliot"/><br /><sub><b>Gwilherm Folliot</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=3l0w" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Dimitory"><img src="https://avatars0.githubusercontent.com/u/475955?v=4?s=100" width="100px;" alt="Dmitry Pronin"/><br /><sub><b>Dmitry Pronin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=dimitory" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JonathanBeverley"><img src="https://avatars1.githubusercontent.com/u/20328966?v=4?s=100" width="100px;" alt="Jonathan Beverley"/><br /><sub><b>Jonathan Beverley</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=JonathanBeverley" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zend"><img src="https://avatars1.githubusercontent.com/u/25160?v=4?s=100" width="100px;" alt="Zenghai Liang"/><br /><sub><b>Zenghai Liang</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zend" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://about.me/matishadow"><img src="https://avatars0.githubusercontent.com/u/9083085?v=4?s=100" width="100px;" alt="Mateusz Tracz"/><br /><sub><b>Mateusz Tracz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=matishadow" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zergpool.com"><img src="https://avatars3.githubusercontent.com/u/36234677?v=4?s=100" width="100px;" alt="pinpin"/><br /><sub><b>pinpin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=pinpins" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TakuroOnoda"><img src="https://avatars0.githubusercontent.com/u/1407926?v=4?s=100" width="100px;" alt="Takuro Onoda"/><br /><sub><b>Takuro Onoda</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TakuroOnoda" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/frauhottelmann"><img src="https://avatars2.githubusercontent.com/u/902705?v=4?s=100" width="100px;" alt="frauhottelmann"/><br /><sub><b>frauhottelmann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=frauhottelmann" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://patalong.pl"><img src="https://avatars.githubusercontent.com/u/29167842?v=4?s=100" width="100px;" alt="Piotr Patalong"/><br /><sub><b>Piotr Patalong</b></sub></a><br /><a href="#design-VectorKappa" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/clarkwang"><img src="https://avatars.githubusercontent.com/u/157076?v=4?s=100" width="100px;" alt="Clark Wang"/><br /><sub><b>Clark Wang</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=clarkwang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/iamchating"><img src="https://avatars.githubusercontent.com/u/7088153?v=4?s=100" width="100px;" alt="iamchating"/><br /><sub><b>iamchating</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=iamchating" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starxg"><img src="https://avatars.githubusercontent.com/u/34997494?v=4?s=100" width="100px;" alt="starxg"/><br /><sub><b>starxg</b></sub></a><br /><a href="#plugin-starxg" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://hashnote.net/"><img src="https://avatars.githubusercontent.com/u/546312?v=4?s=100" width="100px;" alt="Alisue"/><br /><sub><b>Alisue</b></sub></a><br /><a href="#design-lambdalisue" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ydcool"><img src="https://avatars.githubusercontent.com/u/5668295?v=4?s=100" width="100px;" alt="Dominic Yin"/><br /><sub><b>Dominic Yin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ydcool" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bdr99"><img src="https://avatars.githubusercontent.com/u/2292715?v=4?s=100" width="100px;" alt="Brandon Rothweiler"/><br /><sub><b>Brandon Rothweiler</b></sub></a><br /><a href="#design-bdr99" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://git.io/JnP49"><img src="https://avatars.githubusercontent.com/u/63876444?v=4?s=100" width="100px;" alt="Logic Machine"/><br /><sub><b>Logic Machine</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=logicmachine123" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cypherbits"><img src="https://avatars.githubusercontent.com/u/10424900?v=4?s=100" width="100px;" alt="cypherbits"/><br /><sub><b>cypherbits</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cypherbits" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://modulolotus.net"><img src="https://avatars.githubusercontent.com/u/946421?v=4?s=100" width="100px;" alt="Matthew Davidson"/><br /><sub><b>Matthew Davidson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=KingMob" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/al-wi"><img src="https://avatars.githubusercontent.com/u/11092199?v=4?s=100" width="100px;" alt="Alexander Wiedemann"/><br /><sub><b>Alexander Wiedemann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=al-wi" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.notion.so/3d45c6bd2cbd4f938873a4bd12e23375"><img src="https://avatars.githubusercontent.com/u/59506394?v=4?s=100" width="100px;" alt="장보연"/><br /><sub><b>장보연</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=BoYeonJang" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Me1onRind"><img src="https://avatars.githubusercontent.com/u/19531270?v=4?s=100" width="100px;" alt="zZ"/><br /><sub><b>zZ</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Me1onRind" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tainoNZ"><img src="https://avatars.githubusercontent.com/u/49261322?v=4?s=100" width="100px;" alt="Aaron Davison"/><br /><sub><b>Aaron Davison</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=tainoNZ" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/composer404"><img src="https://avatars.githubusercontent.com/u/58251560?v=4?s=100" width="100px;" alt="Przemyslaw Kozik"/><br /><sub><b>Przemyslaw Kozik</b></sub></a><br /><a href="#design-composer404" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/highfredo"><img src="https://avatars.githubusercontent.com/u/5951524?v=4?s=100" width="100px;" alt="Alfredo Arellano de la Fuente"/><br /><sub><b>Alfredo Arellano de la Fuente</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=highfredo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NessunKim"><img src="https://avatars.githubusercontent.com/u/12974079?v=4?s=100" width="100px;" alt="MH Kim"/><br /><sub><b>MH Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=NessunKim" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://discord.gg/4c5EVTBhtp"><img src="https://avatars.githubusercontent.com/u/40345645?v=4?s=100" width="100px;" alt="Marmota"/><br /><sub><b>Marmota</b></sub></a><br /><a href="#design-jaimeadf" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://ares.zone"><img src="https://avatars.githubusercontent.com/u/40336192?v=4?s=100" width="100px;" alt="Ares Andrew"/><br /><sub><b>Ares Andrew</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TENX-S" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://usual.io/"><img src="https://avatars.githubusercontent.com/u/780052?v=4?s=100" width="100px;" alt="George Korsnick"/><br /><sub><b>George Korsnick</b></sub></a><br /><a href="#financial-gkor" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://about.me/ulu"><img src="https://avatars.githubusercontent.com/u/872764?v=4?s=100" width="100px;" alt="Artem Smirnov"/><br /><sub><b>Artem Smirnov</b></sub></a><br /><a href="#financial-uluhonolulu" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nevotheless"><img src="https://avatars.githubusercontent.com/u/779797?v=4?s=100" width="100px;" alt="Tim Kopplow"/><br /><sub><b>Tim Kopplow</b></sub></a><br /><a href="#financial-nevotheless" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mrthock"><img src="https://avatars.githubusercontent.com/u/88901709?v=4?s=100" width="100px;" alt="mrthock"/><br /><sub><b>mrthock</b></sub></a><br /><a href="#financial-mrthock" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lrottach"><img src="https://avatars.githubusercontent.com/u/50323692?v=4?s=100" width="100px;" alt="Lukas Rottach"/><br /><sub><b>Lukas Rottach</b></sub></a><br /><a href="#financial-lrottach" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boonkerz"><img src="https://avatars.githubusercontent.com/u/277321?v=4?s=100" width="100px;" alt="boonkerz"/><br /><sub><b>boonkerz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boonkerz" title="Code">💻</a> <a href="#translation-boonkerz" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/milotype"><img src="https://avatars.githubusercontent.com/u/43657314?v=4?s=100" width="100px;" alt="Milo Ivir"/><br /><sub><b>Milo Ivir</b></sub></a><br /><a href="#translation-milotype" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JasonCubic"><img src="https://avatars.githubusercontent.com/u/8921015?v=4?s=100" width="100px;" alt="JasonCubic"/><br /><sub><b>JasonCubic</b></sub></a><br /><a href="#design-JasonCubic" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MaxWaldorf"><img src="https://avatars.githubusercontent.com/u/15877853?v=4?s=100" width="100px;" alt="MaxWaldorf"/><br /><sub><b>MaxWaldorf</b></sub></a><br /><a href="#infra-MaxWaldorf" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://microhobby.com.br/blog"><img src="https://avatars.githubusercontent.com/u/2633321?v=4?s=100" width="100px;" alt="Matheus Castello"/><br /><sub><b>Matheus Castello</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=microhobby" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jai-JAP"><img src="https://avatars.githubusercontent.com/u/78354625?v=4?s=100" width="100px;" alt="Jai A P"/><br /><sub><b>Jai A P</b></sub></a><br /><a href="#platform-Jai-JAP" title="Packaging/porting to new platform">📦</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.ysc3839.com"><img src="https://avatars.githubusercontent.com/u/12028138?v=4?s=100" width="100px;" alt="Richard Yu"/><br /><sub><b>Richard Yu</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ysc3839" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/artu-ole"><img src="https://avatars.githubusercontent.com/u/15938416?v=4?s=100" width="100px;" alt="artu-ole"/><br /><sub><b>artu-ole</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=artu-ole" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://timagribanov.github.io/"><img src="https://avatars.githubusercontent.com/u/48593815?v=4?s=100" width="100px;" alt="Timofey Gribanov"/><br /><sub><b>Timofey Gribanov</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TimaGribanov" title="Documentation">📖</a> <a href="#translation-TimaGribanov" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://git.christianbingman.com"><img src="https://avatars.githubusercontent.com/u/42191425?v=4?s=100" width="100px;" alt="Christian Bingman"/><br /><sub><b>Christian Bingman</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ChristianBingman" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://zhangzhipeng2023.cn/"><img src="https://avatars.githubusercontent.com/u/5310853?v=4?s=100" width="100px;" alt="zhipeng"/><br /><sub><b>zhipeng</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Ox0400" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/woodmeal"><img src="https://avatars.githubusercontent.com/u/104011197?v=4?s=100" width="100px;" alt="woodmeal"/><br /><sub><b>woodmeal</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=woodmeal" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://magiclike.codeberg.page/"><img src="https://avatars.githubusercontent.com/u/82117109?v=4?s=100" width="100px;" alt="MagicLike"/><br /><sub><b>MagicLike</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=MagicLike" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hisamafahri"><img src="https://avatars.githubusercontent.com/u/65691613?v=4?s=100" width="100px;" alt="Hisam Fahri"/><br /><sub><b>Hisam Fahri</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=hisamafahri" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://liangchengj.com"><img src="https://avatars.githubusercontent.com/u/48881023?v=4?s=100" width="100px;" alt="Liangcheng Juves"/><br /><sub><b>Liangcheng Juves</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=LiangchengJ" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/attet"><img src="https://avatars.githubusercontent.com/u/1911416?v=4?s=100" width="100px;" alt="Atte Timonen"/><br /><sub><b>Atte Timonen</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=attet" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/joaolmpinto/"><img src="https://avatars.githubusercontent.com/u/1143125?v=4?s=100" width="100px;" alt="João Pinto"/><br /><sub><b>João Pinto</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=joaompinto" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Qiming-Liu"><img src="https://avatars.githubusercontent.com/u/68600416?v=4?s=100" width="100px;" alt="Alan"/><br /><sub><b>Alan</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Qiming-Liu" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://74th.tech/"><img src="https://avatars.githubusercontent.com/u/1060011?v=4?s=100" width="100px;" alt="Atsushi Morimoto"/><br /><sub><b>Atsushi Morimoto</b></sub></a><br /><a href="#financial-74th" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://arles.red/"><img src="https://avatars.githubusercontent.com/u/5369096?v=4?s=100" width="100px;" alt="Arles"/><br /><sub><b>Arles</b></sub></a><br /><a href="#financial-aarles" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://pentestbook.six2dez.com/"><img src="https://avatars.githubusercontent.com/u/24670991?v=4?s=100" width="100px;" alt="six2dez"/><br /><sub><b>six2dez</b></sub></a><br /><a href="#financial-six2dez" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CandiceJoy"><img src="https://avatars.githubusercontent.com/u/8854890?v=4?s=100" width="100px;" alt="Candice"/><br /><sub><b>Candice</b></sub></a><br /><a href="#financial-CandiceJoy" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kingrowen"><img src="https://avatars.githubusercontent.com/u/13178700?v=4?s=100" width="100px;" alt="Rowen Willabus"/><br /><sub><b>Rowen Willabus</b></sub></a><br /><a href="#financial-kingrowen" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hengy1.top/"><img src="https://avatars.githubusercontent.com/u/98681454?v=4?s=100" width="100px;" alt="HengY1Coding✨"/><br /><sub><b>HengY1Coding✨</b></sub></a><br /><a href="#financial-HengY1Sky" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FrancisHG"><img src="https://avatars.githubusercontent.com/u/1611626?v=4?s=100" width="100px;" alt="Francis Gelderloos"/><br /><sub><b>Francis Gelderloos</b></sub></a><br /><a href="#financial-FrancisHG" title="Financial">💵</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/astromasoud"><img src="https://avatars.githubusercontent.com/u/18737721?v=4?s=100" width="100px;" alt="astromasoud"/><br /><sub><b>astromasoud</b></sub></a><br /><a href="#financial-astromasoud" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://spirit55555.dk/"><img src="https://avatars.githubusercontent.com/u/2357565?v=4?s=100" width="100px;" alt="Anders G. Jørgensen"/><br /><sub><b>Anders G. Jørgensen</b></sub></a><br /><a href="#financial-Spirit55555" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/djradon"><img src="https://avatars.githubusercontent.com/u/5224156?v=4?s=100" width="100px;" alt="Dave Richardson"/><br /><sub><b>Dave Richardson</b></sub></a><br /><a href="#financial-djradon" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/tpberntsen"><img src="https://avatars.githubusercontent.com/u/922318?v=4?s=100" width="100px;" alt="Thomas Peter Berntsen"/><br /><sub><b>Thomas Peter Berntsen</b></sub></a><br /><a href="#financial-tpberntsen" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt="Ikko Ashimine"/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=eltociear" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/giejqf"><img src="https://avatars.githubusercontent.com/u/9211230?v=4?s=100" width="100px;" alt="giejqf"/><br /><sub><b>giejqf</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=giejqf" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LacazeThomas"><img src="https://avatars.githubusercontent.com/u/19855907?v=4?s=100" width="100px;" alt="Thomas LACAZE"/><br /><sub><b>Thomas LACAZE</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=LacazeThomas" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://pochen.me/"><img src="https://avatars.githubusercontent.com/u/1329716?v=4?s=100" width="100px;" alt="Po Chen"/><br /><sub><b>Po Chen</b></sub></a><br /><a href="#financial-princemaple" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://victorchandra.carrd.co/"><img src="https://avatars.githubusercontent.com/u/41635105?v=4?s=100" width="100px;" alt="Victor Chandra"/><br /><sub><b>Victor Chandra</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mzmznasipadang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/daniel347x"><img src="https://avatars.githubusercontent.com/u/309746?v=4?s=100" width="100px;" alt="Dan Nissenbaum"/><br /><sub><b>Dan Nissenbaum</b></sub></a><br /><a href="#financial-daniel347x" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DunklerPhoenix"><img src="https://avatars.githubusercontent.com/u/1261305?v=4?s=100" width="100px;" alt="RogueThorn"/><br /><sub><b>RogueThorn</b></sub></a><br /><a href="#financial-DunklerPhoenix" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://spenserblack.github.io"><img src="https://avatars.githubusercontent.com/u/8546709?v=4?s=100" width="100px;" alt="Spenser Black"/><br /><sub><b>Spenser Black</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=spenserblack" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zuedev"><img src="https://avatars.githubusercontent.com/u/24614929?v=4?s=100" width="100px;" alt="Alex"/><br /><sub><b>Alex</b></sub></a><br /><a href="#financial-zuedev" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hengy1.top/"><img src="https://avatars.githubusercontent.com/u/98681454?v=4?s=100" width="100px;" alt="HengY1Coding✨"/><br /><sub><b>HengY1Coding✨</b></sub></a><br /><a href="#financial-HengY1Cola" title="Financial">💵</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://www.stackscale.com/"><img src="https://avatars.githubusercontent.com/u/195768?v=4?s=100" width="100px;" alt="David Carrero"/><br /><sub><b>David Carrero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=dcarrero" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhoro"><img src="https://avatars.githubusercontent.com/u/1105687?v=4?s=100" width="100px;" alt="Andrii Zhovtiak"/><br /><sub><b>Andrii Zhovtiak</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zhoro" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JohnMasoner"><img src="https://avatars.githubusercontent.com/u/42313377?v=4?s=100" width="100px;" alt="Mason Ma"/><br /><sub><b>Mason Ma</b></sub></a><br /><a href="#financial-JohnMasoner" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ntimo"><img src="https://avatars.githubusercontent.com/u/6145026?v=4?s=100" width="100px;" alt="Timo"/><br /><sub><b>Timo</b></sub></a><br /><a href="#financial-ntimo" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/evinwatson/"><img src="https://avatars.githubusercontent.com/u/24227251?v=4?s=100" width="100px;" alt="Evin Watson"/><br /><sub><b>Evin Watson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=EvinRWatson" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://t.me/hendrjl"><img src="https://avatars.githubusercontent.com/u/15981200?v=4?s=100" width="100px;" alt="Hendra Juli"/><br /><sub><b>Hendra Juli</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=deulizealand" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wkricowski"><img src="https://avatars.githubusercontent.com/u/36803521?v=4?s=100" width="100px;" alt="Wellinton Kricowski"/><br /><sub><b>Wellinton Kricowski</b></sub></a><br /><a href="#financial-wkricowski" title="Financial">💵</a> <a href="https://github.com/Eugeny/tabby/commits?author=wkricowski" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/almzau"><img src="https://avatars.githubusercontent.com/u/29115846?v=4?s=100" width="100px;" alt="Allan"/><br /><sub><b>Allan</b></sub></a><br /><a href="#design-almzau" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://oidamo.de"><img src="https://avatars.githubusercontent.com/u/17959794?v=4?s=100" width="100px;" alt="Benjamin Brandmeier"/><br /><sub><b>Benjamin Brandmeier</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=BenjaminBrandmeier" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/patric1025"><img src="https://avatars.githubusercontent.com/u/65654040?v=4?s=100" width="100px;" alt="patric1025"/><br /><sub><b>patric1025</b></sub></a><br /><a href="#translation-patric1025" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hermitpopcorn"><img src="https://avatars.githubusercontent.com/u/16042129?v=4?s=100" width="100px;" alt="hermitpopcorn"/><br /><sub><b>hermitpopcorn</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=hermitpopcorn" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://joshuatz.com/"><img src="https://avatars.githubusercontent.com/u/17817563?v=4?s=100" width="100px;" alt="Joshua Tzucker"/><br /><sub><b>Joshua Tzucker</b></sub></a><br /><a href="#financial-joshuatz" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/luxifr"><img src="https://avatars.githubusercontent.com/u/665715?v=4?s=100" width="100px;" alt="luxifr"/><br /><sub><b>luxifr</b></sub></a><br /><a href="#financial-luxifr" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ukulanne"><img src="https://avatars.githubusercontent.com/u/28586666?v=4?s=100" width="100px;" alt="Anne Summers"/><br /><sub><b>Anne Summers</b></sub></a><br /><a href="#financial-ukulanne" title="Financial">💵</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Clem-Fern"><img src="https://avatars.githubusercontent.com/u/20025949?v=4?s=100" width="100px;" alt="Clem"/><br /><sub><b>Clem</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Clem-Fern" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/elizabeth-dev"><img src="https://avatars.githubusercontent.com/u/13015727?v=4?s=100" width="100px;" alt="Elizabeth Martín Campos"/><br /><sub><b>Elizabeth Martín Campos</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=elizabeth-dev" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/siccous"><img src="https://avatars.githubusercontent.com/u/7812885?v=4?s=100" width="100px;" alt="Tomáš Hruška"/><br /><sub><b>Tomáš Hruška</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siccous" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/karaketir16"><img src="https://avatars.githubusercontent.com/u/27349806?v=4?s=100" width="100px;" alt="Osman Karaketir"/><br /><sub><b>Osman Karaketir</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=karaketir16" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.gnomegarden.io/"><img src="https://avatars.githubusercontent.com/u/33667144?v=4?s=100" width="100px;" alt="Crypto Gnome"/><br /><sub><b>Crypto Gnome</b></sub></a><br /><a href="#financial-CryptoGnome" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rbukovansky"><img src="https://avatars.githubusercontent.com/u/1004491?v=4?s=100" width="100px;" alt="Richard Bukovansky"/><br /><sub><b>Richard Bukovansky</b></sub></a><br /><a href="#financial-rbukovansky" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pseudocc"><img src="https://avatars.githubusercontent.com/u/85104110?v=4?s=100" width="100px;" alt="catlas"/><br /><sub><b>catlas</b></sub></a><br /><a href="#financial-pseudocc" title="Financial">💵</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://kapocsi.ca"><img src="https://avatars.githubusercontent.com/u/84490604?v=4?s=100" width="100px;" alt="Thomas Kapocsi"/><br /><sub><b>Thomas Kapocsi</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Kapocsi" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://dylhack.dev/"><img src="https://avatars.githubusercontent.com/u/27179786?v=4?s=100" width="100px;" alt="Dylan Hackworth"/><br /><sub><b>Dylan Hackworth</b></sub></a><br /><a href="#financial-dylhack" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/echo304"><img src="https://avatars.githubusercontent.com/u/16456651?v=4?s=100" width="100px;" alt="Sangboak Lee"/><br /><sub><b>Sangboak Lee</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=echo304" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qyecst"><img src="https://avatars.githubusercontent.com/u/13901864?v=4?s=100" width="100px;" alt="qyecst"/><br /><sub><b>qyecst</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=qyecst" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DehanLUO"><img src="https://avatars.githubusercontent.com/u/53093688?v=4?s=100" width="100px;" alt="Han"/><br /><sub><b>Han</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=DehanLUO" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
Ten projekt podlega specyfikacji [dla współautorów](https://github.com/all-contributors/all-contributors). Wszelkiego rodzaju przyczynianie się do rozwoju jest tu mile widziane!

View File

@@ -21,7 +21,7 @@
<br/>
<p align="center">
Esse README também está disponível em: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a>
Esse README também está disponível em: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
@@ -246,7 +246,7 @@ Obrigado vai para essas pessoas maravilhosas ([emoji key](https://allcontributor
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -330,6 +330,15 @@ Obrigado vai para essas pessoas maravilhosas ([emoji key](https://allcontributor
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -21,7 +21,7 @@
<br/>
<p align="center">
Этот README также доступен на: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:br: Português</a>
Этот README также доступен на: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.zh-CN.md">:cn: 简体中文</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
@@ -238,7 +238,7 @@ Pull-запросы и плагины приветствуются!
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -322,6 +322,15 @@ Pull-запросы и плагины приветствуются!
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -21,7 +21,7 @@
<br/>
<p align="center">
本 README 还适用于以下语言: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:br: Português</a>
本 README 还适用于以下语言: <a href="./README.md">:gb: English</a> · <a href="./README.es-ES.md">:es: Spanish</a> · <a href="./README.ru-RU.md">:ru: Русский</a> · <a href="./README.ko-KR.md">:kr: 한국어</a> · <a href="./README.it-IT.md">:it: Italiano</a> · <a href="./README.de-DE.md">:de: Deutsch</a> · <a href="./README.ja-JP.md">:jp: 日本語</a> · <a href="./README.id-ID.md">:id: Bahasa Indonesia</a> · <a href="./README.pt-BR.md">:brazil: Português</a> · <a href="./README.pl-PL.md">:poland: Polski</a>
</p>
----
@@ -237,7 +237,7 @@
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt="Michael Wizner"/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mgrulich"><img src="https://avatars.githubusercontent.com/u/781036?v=4?s=100" width="100px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mgrulich" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piersandro"><img src="https://avatars.githubusercontent.com/u/19996309?v=4?s=100" width="100px;" alt="Piersandro Guerrera"/><br /><sub><b>Piersandro Guerrera</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=piersandro" title="Documentation">📖</a> <a href="#translation-piersandro" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://pingbase.cn"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="X-0x01"/><br /><sub><b>X-0x01</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=X-0x01" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0x973"><img src="https://avatars.githubusercontent.com/u/19320096?v=4?s=100" width="100px;" alt="0x973"/><br /><sub><b>0x973</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=0x973" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allenator"><img src="https://avatars.githubusercontent.com/u/11794943?v=4?s=100" width="100px;" alt="Allenator"/><br /><sub><b>Allenator</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Allenator" title="Documentation">📖</a></td>
</tr>
<tr>
@@ -321,6 +321,15 @@
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wljince007"><img src="https://avatars.githubusercontent.com/u/88243938?v=4?s=100" width="100px;" alt="wljince007"/><br /><sub><b>wljince007</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=wljince007" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FeroTheFox"><img src="https://avatars.githubusercontent.com/u/52982404?v=4?s=100" width="100px;" alt="fero"/><br /><sub><b>fero</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=FeroTheFox" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://siebsie23.nl/"><img src="https://avatars.githubusercontent.com/u/25083973?v=4?s=100" width="100px;" alt="Sibren"/><br /><sub><b>Sibren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=siebsie23" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.nathaniel-walser.com"><img src="https://avatars.githubusercontent.com/u/33339996?v=4?s=100" width="100px;" alt="Nathaniel Walser"/><br /><sub><b>Nathaniel Walser</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nwalser" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aaronhuggins"><img src="https://avatars.githubusercontent.com/u/16567111?v=4?s=100" width="100px;" alt="Aaron Huggins"/><br /><sub><b>Aaron Huggins</b></sub></a><br /><a href="#design-aaronhuggins" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zkxdex.github.io/"><img src="https://avatars.githubusercontent.com/u/66271780?v=4?s=100" width="100px;" alt="KDex"/><br /><sub><b>KDex</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zKXDEX" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kimbob13"><img src="https://avatars.githubusercontent.com/u/26755098?v=4?s=100" width="100px;" alt="ChangHwan Kim"/><br /><sub><b>ChangHwan Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kimbob13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashneilson"><img src="https://avatars.githubusercontent.com/u/35913512?v=4?s=100" width="100px;" alt="Ash Neilson"/><br /><sub><b>Ash Neilson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ashneilson" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cfs4819"><img src="https://avatars.githubusercontent.com/u/53071761?v=4?s=100" width="100px;" alt="Chen Fansong"/><br /><sub><b>Chen Fansong</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cfs4819" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -28,6 +28,16 @@ export function parseArgs (argv: string[], cwd: string): any {
.command('recent [index]', 'open a tab with a recent profile', {
profileNumber: { type: 'number' },
})
.command('quickConnect <providerId> <query>', 'open a tab for specified quick connect provider', yargs => {
return yargs.positional('providerId', {
describe: 'The name of a quick connect profile provider',
type: 'string',
choices: ['ssh', 'telnet'],
}).positional('query', {
describe: 'The quick connect query string',
type: 'string',
})
})
.version(app.getVersion())
.option('debug', {
alias: 'd',

View File

@@ -1,13 +1,14 @@
import * as fs from 'fs'
import * as path from 'path'
import * as yaml from 'js-yaml'
import { app } from 'electron'
import { writeFile } from 'atomically'
export const configPath = path.join(process.env.TABBY_CONFIG_DIRECTORY!, 'config.yaml')
const legacyConfigPath = path.join(process.env.TABBY_CONFIG_DIRECTORY!, '../terminus', 'config.yaml')
export function migrateConfig (): void {
const configPath = path.join(app.getPath('userData'), 'config.yaml')
const legacyConfigPath = path.join(app.getPath('userData'), '../terminus', 'config.yaml')
if (fs.existsSync(legacyConfigPath) && (
!fs.existsSync(configPath) ||
fs.statSync(configPath).mtime < fs.statSync(legacyConfigPath).mtime
@@ -19,7 +20,6 @@ export function migrateConfig (): void {
export function loadConfig (): any {
migrateConfig()
const configPath = path.join(app.getPath('userData'), 'config.yaml')
if (fs.existsSync(configPath)) {
return yaml.load(fs.readFileSync(configPath, 'utf8'))
} else {
@@ -27,8 +27,6 @@ export function loadConfig (): any {
}
}
const configPath = path.join(app.getPath('userData'), 'config.yaml')
export async function saveConfig (content: string): Promise<void> {
await writeFile(configPath, content, { encoding: 'utf8' })
await writeFile(configPath + '.backup', content, { encoding: 'utf8' })

View File

@@ -1,17 +1,23 @@
import 'v8-compile-cache'
import { app, ipcMain, Menu, dialog } from 'electron'
// set userData Path on portable version
import './portable'
// set defaults of environment variables
import 'dotenv/config'
process.env.TABBY_PLUGINS ??= ''
process.env.TABBY_CONFIG_DIRECTORY ??= app.getPath('userData')
import 'v8-compile-cache'
import 'source-map-support/register'
import './sentry'
import './lru'
import { app, ipcMain, Menu, dialog } from 'electron'
import { parseArgs } from './cli'
import { Application } from './app'
import electronDebug = require('electron-debug')
import { loadConfig } from './config'
if (!process.env.TABBY_PLUGINS) {
process.env.TABBY_PLUGINS = ''
}
const argv = parseArgs(process.argv, process.cwd())

View File

@@ -26,7 +26,7 @@ abstract class GlasstronWindow extends BrowserWindow {
abstract setBlur (_: boolean)
}
const macOSVibrancyType = process.platform === 'darwin' ? compareVersions(macOSRelease().version || '0.0', '10.14', '>=') ? 'under-window' : 'dark' : null
const macOSVibrancyType: any = process.platform === 'darwin' ? compareVersions(macOSRelease().version || '0.0', '10.14', '>=') ? 'under-window' : 'dark' : null
const activityIcon = nativeImage.createFromPath(`${app.getAppPath()}/assets/activity.png`)

View File

@@ -64,6 +64,7 @@
},
"resolutions": {
"*/node-abi": "^2.20.0",
"node-gyp": "^10.0.0",
"nan": "github:jkleinsc/nan#remove_accessor_signature"
}
}

View File

@@ -16,6 +16,18 @@
update-notifier "^2.2.0"
yargs "^8.0.2"
"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==
dependencies:
string-width "^5.1.2"
string-width-cjs "npm:string-width@^4.2.0"
strip-ansi "^7.0.1"
strip-ansi-cjs "npm:strip-ansi@^6.0.1"
wrap-ansi "^8.1.0"
wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
"@ngx-translate/core@^14.0.0":
version "14.0.0"
resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-14.0.0.tgz#af421d0e1a28376843f0fed375cd2fae7630a5ff"
@@ -23,6 +35,29 @@
dependencies:
tslib "^2.3.0"
"@npmcli/agent@^2.0.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-2.2.0.tgz#e81f00fdb2a670750ff7731bbefb47ecbf0ccf44"
integrity sha512-2yThA1Es98orMkpSLVqlDZAMPK3jHJhifP2gnNUdk1754uZ8yI5c+ulCoVG+WlntQA6MzhrURMXjSd9Z7dJ2/Q==
dependencies:
agent-base "^7.1.0"
http-proxy-agent "^7.0.0"
https-proxy-agent "^7.0.1"
lru-cache "^10.0.1"
socks-proxy-agent "^8.0.1"
"@npmcli/fs@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e"
integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==
dependencies:
semver "^7.3.5"
"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@serialport/binding-abstract@^9.0.2":
version "9.2.3"
resolved "https://registry.yarnpkg.com/@serialport/binding-abstract/-/binding-abstract-9.2.3.tgz#e7dd273357b6a698af7ad58db6f57f62443a0acb"
@@ -185,6 +220,11 @@ abbrev@1, abbrev@~1.1.1:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
abbrev@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf"
integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==
agent-base@4, agent-base@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
@@ -192,6 +232,13 @@ agent-base@4, agent-base@^4.3.0:
dependencies:
es6-promisify "^5.0.0"
agent-base@^7.0.2, agent-base@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434"
integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==
dependencies:
debug "^4.3.4"
agent-base@~4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
@@ -206,6 +253,14 @@ agentkeepalive@^3.4.1:
dependencies:
humanize-ms "^1.2.1"
aggregate-error@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
dependencies:
clean-stack "^2.0.0"
indent-string "^4.0.0"
ajv@^6.12.3:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz"
@@ -248,6 +303,11 @@ ansi-regex@^5.0.1:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-regex@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -262,6 +322,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
ansi-styles@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
ansicolors@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz"
@@ -409,6 +474,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@@ -473,6 +545,24 @@ cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.3:
unique-filename "^1.1.1"
y18n "^4.0.0"
cacache@^18.0.0:
version "18.0.0"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.0.tgz#17a9ecd6e1be2564ebe6cdca5f7cfed2bfeb6ddc"
integrity sha512-I7mVOPl3PUCeRub1U8YoGz2Lqv9WOBpobZ8RyWFXmReuILz+3OAyTa5oH3QPdtKZD7N0Yk00aLfzn0qvp8dZ1w==
dependencies:
"@npmcli/fs" "^3.1.0"
fs-minipass "^3.0.0"
glob "^10.2.2"
lru-cache "^10.0.1"
minipass "^7.0.3"
minipass-collect "^1.0.2"
minipass-flush "^1.0.5"
minipass-pipeline "^1.2.4"
p-map "^4.0.0"
ssri "^10.0.0"
tar "^6.1.11"
unique-filename "^3.0.0"
call-bind@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce"
@@ -528,6 +618,11 @@ chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4:
resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
chownr@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
ci-info@^1.5.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
@@ -545,6 +640,11 @@ cidr-regex@^2.0.10:
dependencies:
ip-regex "^2.1.0"
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
cli-boxes@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
@@ -752,6 +852,15 @@ cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^7.0.0:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
crypto-random-string@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
@@ -776,7 +885,7 @@ debug@3.1.0:
dependencies:
ms "2.0.0"
debug@4.3.4, debug@^4.0.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -891,6 +1000,11 @@ duplexify@^3.4.2, duplexify@^3.6.0:
readable-stream "^2.0.0"
stream-shift "^1.0.0"
eastasianwidth@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz"
@@ -974,7 +1088,12 @@ emoji-regex@^8.0.0:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
encoding@^0.1.11:
emoji-regex@^9.2.2:
version "9.2.2"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
encoding@^0.1.11, encoding@^0.1.13:
version "0.1.13"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==
@@ -1003,6 +1122,11 @@ err-code@^1.0.0:
resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz"
integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=
err-code@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==
errno@~0.1.7:
version "0.1.8"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
@@ -1084,6 +1208,11 @@ expand-template@^2.0.3:
resolved "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz"
integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
exponential-backoff@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6"
integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz"
@@ -1162,6 +1291,14 @@ fontmanager-redux@1.1.0:
dependencies:
node-addon-api "^3.0.2"
foreground-child@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d"
integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==
dependencies:
cross-spawn "^7.0.0"
signal-exit "^4.0.1"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz"
@@ -1222,6 +1359,20 @@ fs-minipass@^1.2.7:
dependencies:
minipass "^2.6.0"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
dependencies:
minipass "^3.0.0"
fs-minipass@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54"
integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==
dependencies:
minipass "^7.0.3"
fs-vacuum@^1.2.10, fs-vacuum@~1.2.10:
version "1.2.10"
resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36"
@@ -1338,6 +1489,17 @@ glasstron@0.1.1:
node-addon-api "^4.0.0"
x11 "^2.3.0"
glob@^10.2.2, glob@^10.3.10:
version "10.3.10"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b"
integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==
dependencies:
foreground-child "^3.1.0"
jackspeak "^2.3.5"
minimatch "^9.0.1"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-scurry "^1.10.1"
glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.1.6"
resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz"
@@ -1374,7 +1536,7 @@ got@^6.7.1:
unzip-response "^2.0.1"
url-parse-lax "^1.0.0"
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.2, graceful-fs@^4.2.4:
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.4:
version "4.2.4"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
@@ -1384,6 +1546,11 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
graceful-fs@^4.2.6:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz"
@@ -1434,6 +1601,11 @@ http-cache-semantics@^3.8.1:
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==
http-cache-semantics@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
http-proxy-agent@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
@@ -1442,6 +1614,14 @@ http-proxy-agent@^2.1.0:
agent-base "4"
debug "3.1.0"
http-proxy-agent@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673"
integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==
dependencies:
agent-base "^7.1.0"
debug "^4.3.4"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz"
@@ -1459,6 +1639,14 @@ https-proxy-agent@^2.2.3:
agent-base "^4.3.0"
debug "^3.1.0"
https-proxy-agent@^7.0.1:
version "7.0.2"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b"
integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==
dependencies:
agent-base "^7.0.2"
debug "4"
humanize-ms@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz"
@@ -1505,6 +1693,11 @@ imurmurhash@^0.1.4:
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
indent-string@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
infer-owner@^1.0.3, infer-owner@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz"
@@ -1557,6 +1750,11 @@ ip@1.1.5:
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
ip@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
@@ -1635,6 +1833,11 @@ is-installed-globally@^0.1.0:
global-dirs "^0.1.0"
is-path-inside "^1.0.0"
is-lambda@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5"
integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==
is-negative-zero@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
@@ -1718,11 +1921,25 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
isexe@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d"
integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
jackspeak@^2.3.5:
version "2.3.6"
resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8"
integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==
dependencies:
"@isaacs/cliui" "^8.0.2"
optionalDependencies:
"@pkgjs/parseargs" "^0.11.0"
js-yaml@4.1.0, js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
@@ -2069,6 +2286,13 @@ lowercase-keys@^1.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
lru-cache@^10.0.1, "lru-cache@^9.1.1 || ^10.0.0":
version "10.0.2"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.2.tgz#34504678cc3266b09b8dfd6fab4e1515258271b7"
integrity sha512-Yj9mA8fPiVgOUpByoTZO5pNrcl5Yk37FcSHsUINpAsaBIEZIuqcCclDZJCVxqQShDsmYX8QG63svJiTbOATZwg==
dependencies:
semver "^7.3.5"
lru-cache@^4.0.1:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
@@ -2105,6 +2329,23 @@ make-dir@^1.0.0:
dependencies:
pify "^3.0.0"
make-fetch-happen@^13.0.0:
version "13.0.0"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz#705d6f6cbd7faecb8eac2432f551e49475bfedf0"
integrity sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==
dependencies:
"@npmcli/agent" "^2.0.0"
cacache "^18.0.0"
http-cache-semantics "^4.1.1"
is-lambda "^1.0.1"
minipass "^7.0.2"
minipass-fetch "^3.0.0"
minipass-flush "^1.0.5"
minipass-pipeline "^1.2.4"
negotiator "^0.6.3"
promise-retry "^2.0.1"
ssri "^10.0.0"
make-fetch-happen@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd"
@@ -2171,11 +2412,57 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
minimatch@^9.0.1:
version "9.0.3"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825"
integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==
dependencies:
brace-expansion "^2.0.1"
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
version "1.2.7"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
minipass-collect@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617"
integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==
dependencies:
minipass "^3.0.0"
minipass-fetch@^3.0.0:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7"
integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==
dependencies:
minipass "^7.0.3"
minipass-sized "^1.0.3"
minizlib "^2.1.2"
optionalDependencies:
encoding "^0.1.13"
minipass-flush@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373"
integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==
dependencies:
minipass "^3.0.0"
minipass-pipeline@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c"
integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==
dependencies:
minipass "^3.0.0"
minipass-sized@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70"
integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==
dependencies:
minipass "^3.0.0"
minipass@^2.3.5, minipass@^2.6.0, minipass@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
@@ -2184,6 +2471,23 @@ minipass@^2.3.5, minipass@^2.6.0, minipass@^2.9.0:
safe-buffer "^5.1.2"
yallist "^3.0.0"
minipass@^3.0.0:
version "3.3.6"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a"
integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==
dependencies:
yallist "^4.0.0"
minipass@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.2, minipass@^7.0.3:
version "7.0.4"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c"
integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==
minizlib@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
@@ -2191,6 +2495,14 @@ minizlib@^1.3.3:
dependencies:
minipass "^2.9.0"
minizlib@^2.1.1, minizlib@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
dependencies:
minipass "^3.0.0"
yallist "^4.0.0"
mississippi@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
@@ -2219,6 +2531,11 @@ mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.0:
dependencies:
minimist "^1.2.5"
mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -2276,6 +2593,11 @@ native-process-working-directory@^1.0.2:
dependencies:
node-addon-api "^3.1.0"
negotiator@^0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
ngx-filesize@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/ngx-filesize/-/ngx-filesize-3.0.2.tgz#aab5ce9ce6eaa421f0393447d9c01653f3839a2c"
@@ -2331,22 +2653,21 @@ node-gyp-build@4.6.0:
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055"
integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==
node-gyp@^5.0.2, node-gyp@^5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e"
integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==
node-gyp@^10.0.0, node-gyp@^5.0.2, node-gyp@^5.1.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-10.0.1.tgz#205514fc19e5830fa991e4a689f9e81af377a966"
integrity sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg==
dependencies:
env-paths "^2.2.0"
glob "^7.1.4"
graceful-fs "^4.2.2"
mkdirp "^0.5.1"
nopt "^4.0.1"
npmlog "^4.1.2"
request "^2.88.0"
rimraf "^2.6.3"
semver "^5.7.1"
tar "^4.4.12"
which "^1.3.1"
exponential-backoff "^3.1.1"
glob "^10.3.10"
graceful-fs "^4.2.6"
make-fetch-happen "^13.0.0"
nopt "^7.0.0"
proc-log "^3.0.0"
semver "^7.3.5"
tar "^6.1.2"
which "^4.0.0"
node-pty@^1.0:
version "1.0.0"
@@ -2355,7 +2676,7 @@ node-pty@^1.0:
dependencies:
nan "^2.17.0"
nopt@^4.0.1, nopt@^4.0.3:
nopt@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
@@ -2363,6 +2684,13 @@ nopt@^4.0.1, nopt@^4.0.3:
abbrev "1"
osenv "^0.1.4"
nopt@^7.0.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7"
integrity sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==
dependencies:
abbrev "^2.0.0"
normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@@ -2751,6 +3079,13 @@ p-locate@^3.0.0:
dependencies:
p-limit "^2.0.0"
p-map@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b"
integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==
dependencies:
aggregate-error "^3.0.0"
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz"
@@ -2863,11 +3198,24 @@ path-key@^2.0.0, path-key@^2.0.1:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-parse@^1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-scurry@^1.10.1:
version "1.10.1"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698"
integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==
dependencies:
lru-cache "^9.1.1 || ^10.0.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-type@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
@@ -2926,6 +3274,11 @@ prepend-http@^1.0.1:
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
proc-log@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8"
integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
@@ -2944,6 +3297,14 @@ promise-retry@^1.1.1:
err-code "^1.0.0"
retry "^0.10.0"
promise-retry@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22"
integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==
dependencies:
err-code "^2.0.2"
retry "^0.12.0"
promzard@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz"
@@ -3341,16 +3702,33 @@ shebang-command@^1.2.0:
dependencies:
shebang-regex "^1.0.0"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
shebang-regex "^3.0.0"
shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
shebang-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
signal-exit@^4.0.1:
version "4.1.0"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
simple-concat@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz"
@@ -3380,6 +3758,11 @@ smart-buffer@^4.1.0:
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz"
integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==
smart-buffer@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
socks-proxy-agent@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386"
@@ -3388,6 +3771,23 @@ socks-proxy-agent@^4.0.0:
agent-base "~4.2.1"
socks "~2.3.2"
socks-proxy-agent@^8.0.1:
version "8.0.2"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad"
integrity sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==
dependencies:
agent-base "^7.0.2"
debug "^4.3.4"
socks "^2.7.1"
socks@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55"
integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==
dependencies:
ip "^2.0.0"
smart-buffer "^4.2.0"
socks@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3"
@@ -3468,6 +3868,13 @@ sshpk@^1.7.0:
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
ssri@^10.0.0:
version "10.0.5"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c"
integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==
dependencies:
minipass "^7.0.3"
ssri@^6.0.0, ssri@^6.0.1:
version "6.0.2"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
@@ -3501,6 +3908,15 @@ strict-uri-encode@^2.0.0:
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY=
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz"
@@ -3527,14 +3943,14 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
eastasianwidth "^0.2.0"
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"
string.prototype.trimend@^1.0.1:
version "1.0.3"
@@ -3569,6 +3985,13 @@ stringify-package@^1.0.0, stringify-package@^1.0.1:
resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85"
integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz"
@@ -3597,12 +4020,12 @@ strip-ansi@^6.0.0:
dependencies:
ansi-regex "^5.0.0"
strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
dependencies:
ansi-regex "^5.0.1"
ansi-regex "^6.0.1"
strip-bom@^3.0.0:
version "3.0.0"
@@ -3659,7 +4082,7 @@ tar-stream@^2.1.4:
inherits "^2.0.3"
readable-stream "^3.1.1"
tar@^4.4.10, tar@^4.4.12, tar@^4.4.13:
tar@^4.4.10, tar@^4.4.13:
version "4.4.19"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==
@@ -3672,6 +4095,18 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13:
safe-buffer "^5.2.1"
yallist "^3.1.1"
tar@^6.1.11, tar@^6.1.2:
version "6.2.0"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73"
integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
minipass "^5.0.0"
minizlib "^2.1.1"
mkdirp "^1.0.3"
yallist "^4.0.0"
term-size@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
@@ -3794,6 +4229,13 @@ unique-filename@^1.1.1:
dependencies:
unique-slug "^2.0.0"
unique-filename@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea"
integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==
dependencies:
unique-slug "^4.0.0"
unique-slug@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz"
@@ -3801,6 +4243,13 @@ unique-slug@^2.0.0:
dependencies:
imurmurhash "^0.1.4"
unique-slug@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3"
integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==
dependencies:
imurmurhash "^0.1.4"
unique-string@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a"
@@ -3933,6 +4382,20 @@ which@^1.2.9, which@^1.3.0, which@^1.3.1:
dependencies:
isexe "^2.0.0"
which@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
which@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/which/-/which-4.0.0.tgz#cd60b5e74503a3fbcfbf6cd6b4138a8bae644c1a"
integrity sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==
dependencies:
isexe "^3.1.1"
wide-align@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz"
@@ -3968,6 +4431,15 @@ worker-farm@^1.6.0, worker-farm@^1.7.0:
dependencies:
errno "~0.1.7"
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
@@ -3985,14 +4457,14 @@ wrap-ansi@^5.1.0:
string-width "^3.0.0"
strip-ansi "^5.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
ansi-styles "^6.1.0"
string-width "^5.0.1"
strip-ansi "^7.0.1"
wrappy@1:
version "1.0.2"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -39,8 +39,8 @@
"cross-env": "7.0.3",
"css-loader": "^6.7.3",
"deep-equal": "2.0.5",
"electron": "^25.3.0",
"electron-builder": "^24.0.0-alpha.1",
"electron": "^27.0.4",
"electron-builder": "^24.6.4",
"electron-download": "^4.1.1",
"electron-installer-snap": "^5.1.0",
"electron-rebuild": "^3.2.9",
@@ -55,7 +55,7 @@
"lru-cache": "^6.0.0",
"macos-release": "^3.1.0",
"ngx-toastr": "^16.0.2",
"node-abi": "^3.45.0",
"node-abi": "^3.51.0",
"npmlog": "6.0.2",
"npx": "^10.2.2",
"patch-package": "^6.4.7",
@@ -96,7 +96,6 @@
"resolutions": {
"*/pug": "^3",
"lzma-native": "^8.0.6",
"*/node-abi": "^3.33.0",
"**/graceful-fs": "^4.2.4",
"nan": "2.17.0"
},
@@ -115,5 +114,8 @@
"i18n:push": "crowdin push"
},
"type": "module",
"private": true
"private": true,
"dependencies": {
"dotenv": "^16.3.1"
}
}

View File

@@ -13,6 +13,7 @@ builder({
armv7l: process.env.ARCH === 'armv7l',
arm64: process.env.ARCH === 'arm64',
config: {
npmRebuild: false,
extraMetadata: {
version: vars.version,
},

View File

@@ -18,7 +18,7 @@ process.env.APPLE_APP_SPECIFIC_PASSWORD ??= process.env.APPSTORE_PASSWORD
builder({
dir: true,
mac: ['pkg', 'zip'],
mac: ['dmg', 'zip'],
x64: process.env.ARCH === 'x86_64',
arm64: process.env.ARCH === 'arm64',
config: {

View File

@@ -1,3 +1,4 @@
import slugify from 'slugify'
import { BaseTabComponent } from '../components/baseTab.component'
import { MenuItemOptions } from './menu'
import { ToolbarButton } from './toolbarButtonProvider'
@@ -6,34 +7,33 @@ export enum CommandLocation {
LeftToolbar = 'left-toolbar',
RightToolbar = 'right-toolbar',
StartPage = 'start-page',
TabHeaderMenu = 'tab-header-menu',
TabBodyMenu = 'tab-body-menu',
}
export class Command {
id?: string
id: string
label: string
sublabel?: string
locations?: CommandLocation[]
run: () => Promise<void>
fullLabel?: string
locations: CommandLocation[]
run?: () => Promise<any>
/**
* Raw SVG icon code
*/
icon?: string
/**
* Optional Touch Bar icon ID
*/
touchBarNSImage?: string
/**
* Optional Touch Bar button label
*/
touchBarTitle?: string
weight?: number
parent?: string
group?: string
checked?: boolean
static fromToolbarButton (button: ToolbarButton): Command {
const command = new Command()
command.id = `legacy:${slugify(button.title)}`
command.label = button.title
command.run = async () => button.click?.()
command.icon = button.icon
@@ -44,18 +44,29 @@ export class Command {
if ((button.weight ?? 0) > 0) {
command.locations.push(CommandLocation.RightToolbar)
}
command.touchBarNSImage = button.touchBarNSImage
command.touchBarTitle = button.touchBarTitle
command.weight = button.weight
return command
}
static fromMenuItem (item: MenuItemOptions): Command {
const command = new Command()
command.label = item.commandLabel ?? item.label ?? ''
command.sublabel = item.sublabel
command.run = async () => item.click?.()
return command
static fromMenuItem (item: MenuItemOptions): Command[] {
if (item.type === 'separator') {
return []
}
const commands: Command[] = [{
id: `legacy:${slugify(item.commandLabel ?? item.label).toLowerCase()}`,
label: item.commandLabel ?? item.label,
run: async () => item.click?.(),
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
checked: item.checked,
}]
for (const submenu of item.submenu ?? []) {
commands.push(...Command.fromMenuItem(submenu).map(x => ({
...x,
id: `${commands[0].id}:${slugify(x.label).toLowerCase()}`,
parent: commands[0].id,
})))
}
return commands
}
}

View File

@@ -37,6 +37,7 @@ export { UpdaterService } from '../services/updater.service'
export { VaultService, Vault, VaultSecret, VaultFileSecret, VAULT_SECRET_TYPE_FILE, StoredVault, VaultSecretKey } from '../services/vault.service'
export { FileProvidersService } from '../services/fileProviders.service'
export { LocaleService } from '../services/locale.service'
export { CommandService } from '../services/commands.service'
export { TranslateService } from '@ngx-translate/core'
export * from '../utils'
export { UTF8Splitter } from '../utfSplitter'

View File

@@ -1,6 +1,4 @@
export interface MenuItemOptions {
type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio'
label?: string
export type MenuItemOptions = {
sublabel?: string
enabled?: boolean
checked?: boolean
@@ -9,4 +7,10 @@ export interface MenuItemOptions {
/** @hidden */
commandLabel?: string
}
} & ({
type: 'separator',
label?: string,
} | {
type?: 'normal' | 'submenu' | 'checkbox' | 'radio',
label: string,
})

View File

@@ -9,16 +9,6 @@ export interface ToolbarButton {
title: string
/**
* Optional Touch Bar icon ID
*/
touchBarNSImage?: string
/**
* Optional Touch Bar button label
*/
touchBarTitle?: string
weight?: number
click?: () => void

View File

@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core'
import { HostAppService } from './api/hostApp'
import { CLIHandler, CLIEvent } from './api/cli'
import { HostWindowService } from './api/hostWindow'
import { QuickConnectProfileProvider } from './api/profileProvider'
import { ProfilesService } from './services/profiles.service'
@Injectable()
@@ -27,6 +28,10 @@ export class ProfileCLIHandler extends CLIHandler {
this.handleOpenRecentProfile(event.argv.profileNumber)
return true
}
if (op === 'quickConnect') {
this.handleOpenQuickConnect(event.argv.providerId, event.argv.query)
return true
}
return false
}
@@ -48,6 +53,21 @@ export class ProfileCLIHandler extends CLIHandler {
this.profiles.openNewTabForProfile(profiles[profileNumber])
this.hostWindow.bringToFront()
}
private async handleOpenQuickConnect (providerId: string, query: string) {
const provider = this.profiles.getProviders().find(x => x.id === providerId)
if(!provider || !(provider instanceof QuickConnectProfileProvider)) {
console.error(`Requested provider "${providerId}" not found`)
return
}
const profile = provider.quickConnect(query)
if(!profile) {
console.error(`Could not parse quick connect query "${query}"`)
return
}
this.profiles.openNewTabForProfile(profile)
this.hostWindow.bringToFront()
}
}
@Injectable()

View File

@@ -1,10 +1,20 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { HostAppService, Platform } from './api/hostApp'
import { ProfilesService } from './services/profiles.service'
import { CommandProvider, Command, CommandLocation } from './api/commands'
import { AppService } from './services/app.service'
import { CommandProvider, Command, CommandLocation, CommandContext } from './api/commands'
import { SplitDirection, SplitTabComponent } from './components/splitTab.component'
import { BaseTabComponent } from './components/baseTab.component'
import { PromptModalComponent } from './components/promptModal.component'
import { HotkeysService } from './services/hotkeys.service'
import { TabsService } from './services/tabs.service'
import { SplitLayoutProfilesService } from './profiles'
import { TAB_COLORS } from './utils'
import { Subscription } from 'rxjs'
/** @hidden */
@Injectable({ providedIn: 'root' })
@@ -13,38 +23,327 @@ export class CoreCommandProvider extends CommandProvider {
private hostApp: HostAppService,
private profilesService: ProfilesService,
private translate: TranslateService,
private app: AppService,
private splitLayoutProfilesService: SplitLayoutProfilesService,
private ngbModal: NgbModal,
private tabsService: TabsService,
hotkeys: HotkeysService,
) {
super()
hotkeys.hotkey$.subscribe(hotkey => {
if (hotkey === 'switch-profile') {
let tab = this.app.activeTab
if (tab instanceof SplitTabComponent) {
tab = tab.getFocusedTab()
if (tab) {
this.switchTabProfile(tab)
}
}
}
})
}
async activate () {
async switchTabProfile (tab: BaseTabComponent) {
const profile = await this.profilesService.showProfileSelector().catch(() => null)
if (!profile) {
return
}
const params = await this.profilesService.newTabParametersForProfile(profile)
if (!params) {
return
}
if (!await tab.canClose()) {
return
}
const newTab = this.tabsService.create(params)
;(tab.parent as SplitTabComponent).replaceTab(tab, newTab)
tab.destroy()
}
async showProfileSelector () {
const profile = await this.profilesService.showProfileSelector().catch(() => null)
if (profile) {
this.profilesService.launchProfile(profile)
}
}
async provide (): Promise<Command[]> {
return [
async provide (context: CommandContext): Promise<Command[]> {
const commands: Command[] = [
{
id: 'core:profile-selector',
locations: [CommandLocation.LeftToolbar, CommandLocation.StartPage],
label: this.translate.instant('Profiles & connections'),
weight: 12,
icon: this.hostApp.platform === Platform.Web
? require('./icons/plus.svg')
: require('./icons/profiles.svg'),
run: async () => this.activate(),
run: async () => this.showProfileSelector(),
},
...this.profilesService.getRecentProfiles().map((profile, index) => ({
id: `core:recent-profile-${index}`,
label: profile.name,
locations: [CommandLocation.StartPage],
icon: require('./icons/history.svg'),
weight: 20,
run: async () => {
const p = (await this.profilesService.getProfiles()).find(x => x.id === profile.id) ?? profile
this.profilesService.launchProfile(p)
},
})),
]
if (context.tab) {
const tab = context.tab
commands.push({
id: `core:close-tab`,
label: this.translate.instant('Close tab'),
locations: [CommandLocation.TabHeaderMenu],
weight: -35,
group: 'core:close',
run: async () => {
if (this.app.tabs.includes(tab)) {
this.app.closeTab(tab, true)
} else {
tab.destroy()
}
},
})
commands.push({
id: `core:close`,
label: this.translate.instant('Close'),
locations: [CommandLocation.TabBodyMenu],
weight: 99,
group: 'core:close',
run: async () => {
tab.destroy()
},
})
if (!context.tab.parent) {
commands.push(...[{
id: 'core:close-other-tabs',
label: this.translate.instant('Close other tabs'),
locations: [CommandLocation.TabHeaderMenu],
weight: -34,
group: 'core:close',
run: async () => {
for (const t of this.app.tabs.filter(x => x !== tab)) {
this.app.closeTab(t, true)
}
},
},
{
id: 'core:close-tabs-to-the-right',
label: this.translate.instant('Close tabs to the right'),
locations: [CommandLocation.TabHeaderMenu],
weight: -33,
group: 'core:close',
run: async () => {
for (const t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) {
this.app.closeTab(t, true)
}
},
},
{
id: 'core:close-tabs-to-the-left',
label: this.translate.instant('Close tabs to the left'),
locations: [CommandLocation.TabHeaderMenu],
weight: -32,
group: 'core:close',
run: async () => {
for (const t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) {
this.app.closeTab(t, true)
}
},
}])
}
commands.push({
id: 'core:rename-tab',
label: this.translate.instant('Rename tab'),
locations: [CommandLocation.TabHeaderMenu],
group: 'core:common',
weight: -13,
run: async () => this.app.renameTab(tab),
})
commands.push({
id: 'core:duplicate-tab',
label: this.translate.instant('Duplicate tab'),
locations: [CommandLocation.TabHeaderMenu],
group: 'core:common',
weight: -12,
run: async () => this.app.duplicateTab(tab),
})
commands.push({
id: 'core:tab-color',
label: this.translate.instant('Color'),
group: 'core:common',
locations: [CommandLocation.TabHeaderMenu],
weight: -11,
})
for (const color of TAB_COLORS) {
commands.push({
id: `core:tab-color-${color.name.toLowerCase()}`,
parent: 'core:tab-color',
label: this.translate.instant(color.name) ?? color.name,
fullLabel: this.translate.instant('Set tab color to {color}', { color: this.translate.instant(color.name) }),
checked: tab.color === color.value,
locations: [CommandLocation.TabHeaderMenu],
run: async () => {
tab.color = color.value
},
})
}
if (tab.parent instanceof SplitTabComponent) {
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
commands.push({
id: 'core:split',
label: this.translate.instant('Split'),
group: 'core:panes',
locations: [CommandLocation.TabBodyMenu],
})
for (const dir of directions) {
commands.push({
id: `core:split-${dir}`,
label: {
r: this.translate.instant('Right'),
b: this.translate.instant('Down'),
l: this.translate.instant('Left'),
t: this.translate.instant('Up'),
}[dir],
fullLabel: {
r: this.translate.instant('Split to the right'),
b: this.translate.instant('Split to the down'),
l: this.translate.instant('Split to the left'),
t: this.translate.instant('Split to the up'),
}[dir],
locations: [CommandLocation.TabBodyMenu],
parent: 'core:split',
run: async () => {
(tab.parent as SplitTabComponent).splitTab(tab, dir)
},
})
}
commands.push({
id: 'core:switch-profile',
label: this.translate.instant('Switch profile'),
group: 'core:common',
locations: [CommandLocation.TabBodyMenu],
run: async () => this.switchTabProfile(tab),
})
}
if (tab instanceof SplitTabComponent && tab.getAllTabs().length > 1) {
commands.push({
id: 'core:save-split-tab-as-profile',
label: this.translate.instant('Save layout as profile'),
group: 'core:common',
locations: [CommandLocation.TabHeaderMenu],
run: async () => {
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = this.translate.instant('Profile name')
const name = (await modal.result.catch(() => null))?.value
if (!name) {
return
}
this.splitLayoutProfilesService.createProfile(tab, name)
},
})
}
}
return commands
}
}
/** @hidden */
@Injectable({ providedIn: 'root' })
export class TaskCompletionCommandProvider extends CommandProvider {
constructor (
private app: AppService,
private translate: TranslateService,
) {
super()
}
async provide (context: CommandContext): Promise<Command[]> {
if (!context.tab) {
return []
}
const process = await context.tab.getCurrentProcess()
const items: Command[] = []
const extTab: (BaseTabComponent & { __completionNotificationEnabled?: boolean, __outputNotificationSubscription?: Subscription|null }) = context.tab
if (process) {
items.push({
id: 'core:process-name',
label: this.translate.instant('Current process: {name}', process),
group: 'core:process',
weight: -1,
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
})
items.push({
id: 'core:notify-when-done',
label: this.translate.instant('Notify when done'),
group: 'core:process',
weight: 0,
checked: extTab.__completionNotificationEnabled,
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
run: async () => {
extTab.__completionNotificationEnabled = !extTab.__completionNotificationEnabled
if (extTab.__completionNotificationEnabled) {
this.app.observeTabCompletion(extTab).subscribe(() => {
new Notification(this.translate.instant('Process completed'), {
body: process.name,
}).addEventListener('click', () => {
this.app.selectTab(extTab)
})
extTab.__completionNotificationEnabled = false
})
} else {
this.app.stopObservingTabCompletion(extTab)
}
},
})
}
items.push({
id: 'core:notify-on-activity',
label: this.translate.instant('Notify on activity'),
group: 'core:process',
checked: !!extTab.__outputNotificationSubscription,
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
run: async () => {
extTab.clearActivity()
if (extTab.__outputNotificationSubscription) {
extTab.__outputNotificationSubscription.unsubscribe()
extTab.__outputNotificationSubscription = null
} else {
extTab.__outputNotificationSubscription = extTab.activity$.subscribe(active => {
if (extTab.__outputNotificationSubscription && active) {
extTab.__outputNotificationSubscription.unsubscribe()
extTab.__outputNotificationSubscription = null
new Notification(this.translate.instant('Tab activity'), {
body: extTab.title,
}).addEventListener('click', () => {
this.app.selectTab(extTab)
})
}
})
}
},
})
return items
}
}

View File

@@ -1,21 +1,21 @@
title-bar(
*ngIf='ready && !hostWindow.isFullscreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
(dblclick)='hostWindow.toggleMaximize()',
*ngIf='ready && !hostWindow.isFullscreen && config.store.appearance.dock == "off" && isTitleBarNeeded()',
(dblclick)='toggleMaximize()',
[hideControls]='hostApp.platform !== Platform.Linux && !hostWindow.isFullscreen',
[class.inset]='hostApp.platform == Platform.macOS && !hostWindow.isFullscreen'
)
.content(
*ngIf='ready',
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left"',
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left" || config.store.appearance.tabsLocation == "right"',
[class.tabs-on-left]='hasVerticalTabs() && config.store.appearance.tabsLocation == "left"',
[class.tabs-titlebar-enabled]='config.store.appearance.frame == "full"',
[class.tabs-titlebar-enabled]='isTitleBarNeeded()',
[class.tabs-on-right]='hasVerticalTabs() && config.store.appearance.tabsLocation == "right"',
)
.tab-bar(
*ngIf='!hostWindow.isFullscreen || config.store.appearance.tabsInFullscreen',
[class.tab-bar-no-controls-overlay]='hostApp.platform == Platform.macOS',
(dblclick)='hostWindow.toggleMaximize()'
(dblclick)='!isTitleBarNeeded() && toggleMaximize()'
)
.inset.background(*ngIf='hostApp.platform == Platform.macOS \
&& !hostWindow.isFullscreen \
@@ -35,7 +35,7 @@ title-bar(
[@animateTab]='{value: "in", params: {size: targetTabSize}}',
[@.disabled]='hasVerticalTabs() || !config.store.accessibility.animations',
(click)='app.selectTab(tab)',
[class.fully-draggable]='hostApp.platform != Platform.macOS'
[class.fully-draggable]='hostApp.platform !== Platform.macOS'
)
.btn-group.background
@@ -64,7 +64,11 @@ title-bar(
(transfersChange)='onTransfersChange()'
)
.drag-space.background([class.persistent]='config.store.appearance.frame == "thin"')
.btn-space.background(
[class.persistent]='config.store.appearance.frame == "thin"',
[class.drag]='config.store.appearance.frame == "thin" \
&& ((config.store.appearance.tabsLocation !== "left" && config.store.appearance.tabsLocation !== "right") || hostApp.platform !== Platform.macOS)'
)
.btn-group.background
.d-flex(
@@ -84,7 +88,9 @@ title-bar(
window-controls.background(
*ngIf='config.store.appearance.frame == "thin" \
&& (hostApp.platform == Platform.Linux)',
&& config.store.appearance.tabsLocation !== "left" \
&& config.store.appearance.tabsLocation !== "right" \
&& hostApp.platform == Platform.Linux',
)
div.window-controls-spacer(

View File

@@ -62,7 +62,7 @@ $tab-border-radius: 4px;
}
}
.drag-space {
.btn-space {
flex: auto;
}
@@ -126,15 +126,18 @@ $tab-border-radius: 4px;
min-width: 0;
}
&>.drag-space {
&>.btn-space {
min-width: 1px;
flex: 1 0 1%;
-webkit-app-region: drag;
.tabs-on-top & {
margin-top: 2px; // for window resizing
}
&.drag {
-webkit-app-region: drag;
}
&.persistent {
// min-width: 72px; // 2 x 36 px height, ie 2 squares
// Given WCO on Windows, the min-width of the window buttons is about 138px.

View File

@@ -238,6 +238,21 @@ export class AppRootComponent {
private async getToolbarButtons (aboveZero: boolean): Promise<Command[]> {
return (await this.commands.getCommands({ tab: this.app.activeTab ?? undefined }))
.filter(x => x.locations?.includes(aboveZero ? CommandLocation.RightToolbar : CommandLocation.LeftToolbar))
.filter(x => x.locations.includes(aboveZero ? CommandLocation.RightToolbar : CommandLocation.LeftToolbar))
}
toggleMaximize (): void {
this.hostWindow.toggleMaximize()
}
protected isTitleBarNeeded (): boolean {
return (
this.config.store.appearance.frame === 'full'
||
this.hostApp.platform !== Platform.macOS
&& this.config.store.appearance.frame === 'thin'
&& this.config.store.appearance.tabsLocation !== 'top'
&& this.config.store.appearance.tabsLocation !== 'bottom'
)
}
}

View File

@@ -128,7 +128,7 @@ export abstract class BaseTabComponent extends BaseComponent {
}
/**
* Shows the acticity marker on the tab header
* Shows the activity marker on the tab header
*/
displayActivity (): void {
if (!this.hasActivity) {
@@ -138,7 +138,7 @@ export abstract class BaseTabComponent extends BaseComponent {
}
/**
* Removes the acticity marker from the tab header
* Removes the activity marker from the tab header
*/
clearActivity (): void {
if (this.hasActivity) {

View File

@@ -18,17 +18,18 @@ export class SelectorModalComponent<T> {
@Input() selectedIndex = 0
hasGroups = false
@ViewChildren('item') itemChildren: QueryList<ElementRef>
private preventEdit: boolean
constructor (
public modalInstance: NgbActiveModal,
) { }
constructor (public modalInstance: NgbActiveModal) {
this.preventEdit = false
}
ngOnInit (): void {
this.onFilterChange()
this.hasGroups = this.options.some(x => x.group)
}
@HostListener('keydown', ['$event']) onKeyUp (event: KeyboardEvent): void {
@HostListener('keydown', ['$event']) onKeyDown (event: KeyboardEvent): void {
if (event.key === 'Escape') {
this.close()
} else if (this.filteredOptions.length > 0) {
@@ -46,10 +47,14 @@ export class SelectorModalComponent<T> {
event.preventDefault()
} else if (event.key === 'Enter') {
this.selectOption(this.filteredOptions[this.selectedIndex])
} else if (event.key === 'Backspace' && this.canEditSelected()) {
event.preventDefault()
this.filter = this.filteredOptions[this.selectedIndex].freeInputEquivalent!
this.onFilterChange()
} else if (event.key === 'Backspace' && !this.preventEdit) {
if (this.canEditSelected()) {
event.preventDefault()
this.filter = this.filteredOptions[this.selectedIndex].freeInputEquivalent!
this.onFilterChange()
} else {
this.preventEdit = true
}
}
this.selectedIndex = (this.selectedIndex + this.filteredOptions.length) % this.filteredOptions.length
@@ -61,6 +66,12 @@ export class SelectorModalComponent<T> {
}
}
@HostListener('keyup', ['$event']) onKeyUp (event: KeyboardEvent): void {
if (event.key === 'Backspace' && this.preventEdit) {
this.preventEdit = false
}
}
onFilterChange (): void {
const f = this.filter.trim().toLowerCase()
if (!f) {

View File

@@ -350,7 +350,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
}
break
case 'close-pane':
this.removeTab(this.focusedTab)
this.focusedTab.destroy()
break
case 'pane-increase-vertical':
this.resizePane('v')
@@ -475,7 +475,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
let target = relative ? this.getParentOf(relative) : null
if (!target) {
// Rewrap the root container just in case the orientation isn't compatibile
// Rewrap the root container just in case the orientation isn't compatible
target = new SplitContainer()
target.orientation = ['l', 'r'].includes(side) ? 'h' : 'v'
target.children = [this.root]

View File

@@ -1,5 +1,6 @@
import { Component } from '@angular/core'
import { DomSanitizer } from '@angular/platform-browser'
import { firstBy } from 'thenby'
import { HomeBaseService } from '../services/homeBase.service'
import { CommandService } from '../services/commands.service'
import { Command, CommandLocation } from '../api/commands'
@@ -20,7 +21,8 @@ export class StartPageComponent {
commands: CommandService,
) {
commands.getCommands({}).then(c => {
this.commands = c.filter(x => x.locations?.includes(CommandLocation.StartPage))
this.commands = c.filter(x => x.locations.includes(CommandLocation.StartPage))
this.commands.sort(firstBy(x => x.weight ?? 0))
})
}

View File

@@ -1,16 +1,19 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Component, Input, Optional, Inject, HostBinding, HostListener, NgZone } from '@angular/core'
import { Component, Input, HostBinding, HostListener, NgZone } from '@angular/core'
import { auditTime } from 'rxjs'
import { TabContextMenuItemProvider } from '../api/tabContextMenuProvider'
import { BaseTabComponent } from './baseTab.component'
import { SplitTabComponent } from './splitTab.component'
import { HotkeysService } from '../services/hotkeys.service'
import { AppService } from '../services/app.service'
import { HostAppService, Platform } from '../api/hostApp'
import { ConfigService } from '../services/config.service'
import { BaseComponent } from './base.component'
import { CommandService } from '../services/commands.service'
import { MenuItemOptions } from '../api/menu'
import { PlatformService } from '../api/platform'
import { CommandContext, CommandLocation } from '../api/commands'
import { BaseComponent } from './base.component'
import { SplitTabComponent } from './splitTab.component'
/** @hidden */
@Component({
@@ -31,8 +34,8 @@ export class TabHeaderComponent extends BaseComponent {
public hostApp: HostAppService,
private hotkeys: HotkeysService,
private platform: PlatformService,
private commands: CommandService,
private zone: NgZone,
@Optional() @Inject(TabContextMenuItemProvider) protected contextMenuProviders: TabContextMenuItemProvider[],
) {
super()
this.subscribeUntilDestroyed(this.hotkeys.hotkey$, (hotkey) => {
@@ -42,7 +45,6 @@ export class TabHeaderComponent extends BaseComponent {
}
}
})
this.contextMenuProviders.sort((a, b) => a.weight - b.weight)
}
ngOnInit () {
@@ -56,26 +58,17 @@ export class TabHeaderComponent extends BaseComponent {
}
async buildContextMenu (): Promise<MenuItemOptions[]> {
let items: MenuItemOptions[] = []
const contexts: CommandContext[] = [{ tab: this.tab }]
// Top-level tab menu
for (const section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(this.tab, true)))) {
items.push({ type: 'separator' })
items = items.concat(section)
}
if (this.tab instanceof SplitTabComponent) {
const tab = this.tab.getFocusedTab()
if (tab) {
for (let section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(tab, true)))) {
// eslint-disable-next-line @typescript-eslint/no-loop-func
section = section.filter(item => !items.some(ex => ex.label === item.label))
if (section.length) {
items.push({ type: 'separator' })
items = items.concat(section)
}
}
contexts.push({ tab })
}
}
return items.slice(1)
return this.commands.buildContextMenu(contexts, CommandLocation.TabHeaderMenu)
}
onTabDragStart (tab: BaseTabComponent) {

View File

@@ -37,7 +37,7 @@ import { FastHtmlBindDirective } from './directives/fastHtmlBind.directive'
import { DropZoneDirective } from './directives/dropZone.directive'
import { CdkAutoDropGroup } from './directives/cdkAutoDropGroup.directive'
import { Theme, CLIHandler, TabContextMenuItemProvider, TabRecoveryProvider, HotkeyProvider, ConfigProvider, PlatformService, FileProvider, ProfilesService, ProfileProvider, QuickConnectProfileProvider, SelectorOption, Profile, SelectorService, CommandProvider } from './api'
import { Theme, CLIHandler, TabRecoveryProvider, HotkeyProvider, ConfigProvider, PlatformService, FileProvider, ProfilesService, ProfileProvider, QuickConnectProfileProvider, SelectorOption, Profile, SelectorService, CommandProvider } from './api'
import { AppService } from './services/app.service'
import { ConfigService } from './services/config.service'
@@ -49,10 +49,9 @@ import { CommandService } from './services/commands.service'
import { StandardTheme, StandardCompactTheme, PaperTheme, NewTheme } from './theme'
import { CoreConfigProvider } from './config'
import { AppHotkeyProvider } from './hotkeys'
import { TaskCompletionContextMenu, CommonOptionsContextMenu, TabManagementContextMenu, ProfilesContextMenu } from './tabContextMenu'
import { LastCLIHandler, ProfileCLIHandler } from './cli'
import { SplitLayoutProfilesService } from './profiles'
import { CoreCommandProvider } from './commands'
import { CoreCommandProvider, TaskCompletionCommandProvider } from './commands'
export function TranslateMessageFormatCompilerFactory (): TranslateMessageFormatCompiler {
return new TranslateMessageFormatCompiler()
@@ -65,16 +64,13 @@ const PROVIDERS = [
{ provide: Theme, useClass: PaperTheme, multi: true },
{ provide: Theme, useClass: NewTheme, multi: true },
{ provide: ConfigProvider, useClass: CoreConfigProvider, multi: true },
{ provide: TabContextMenuItemProvider, useClass: CommonOptionsContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: TabManagementContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: TaskCompletionContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: ProfilesContextMenu, multi: true },
{ provide: TabRecoveryProvider, useExisting: SplitTabRecoveryProvider, multi: true },
{ provide: CLIHandler, useClass: ProfileCLIHandler, multi: true },
{ provide: CLIHandler, useClass: LastCLIHandler, multi: true },
{ provide: FileProvider, useClass: VaultFileProvider, multi: true },
{ provide: ProfileProvider, useExisting: SplitLayoutProfilesService, multi: true },
{ provide: CommandProvider, useExisting: CoreCommandProvider, multi: true },
{ provide: CommandProvider, useExisting: TaskCompletionCommandProvider, multi: true },
{
provide: LOCALE_ID,
deps: [LocaleService],

View File

@@ -1,6 +1,10 @@
import { Inject, Injectable, Optional } from '@angular/core'
import { AppService, Command, CommandContext, CommandProvider, ConfigService, MenuItemOptions, SplitTabComponent, TabContextMenuItemProvider, ToolbarButton, ToolbarButtonProvider, TranslateService } from '../api'
import { TranslateService } from '@ngx-translate/core'
import { Command, CommandContext, CommandLocation, CommandProvider, MenuItemOptions, SplitTabComponent, TabContextMenuItemProvider, ToolbarButton, ToolbarButtonProvider } from '../api'
import { AppService } from './app.service'
import { ConfigService } from './config.service'
import { SelectorService } from './selector.service'
import { firstBy } from 'thenby'
@Injectable({ providedIn: 'root' })
export class CommandService {
@@ -11,11 +15,11 @@ export class CommandService {
private config: ConfigService,
private app: AppService,
private translate: TranslateService,
@Optional() @Inject(TabContextMenuItemProvider) protected contextMenuProviders: TabContextMenuItemProvider[],
@Optional() @Inject(TabContextMenuItemProvider) protected contextMenuProviders: TabContextMenuItemProvider[]|null,
@Optional() @Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
@Inject(CommandProvider) private commandProviders: CommandProvider[],
) {
this.contextMenuProviders.sort((a, b) => a.weight - b.weight)
this.contextMenuProviders?.sort((a, b) => a.weight - b.weight)
}
async getCommands (context: CommandContext): Promise<Command[]> {
@@ -29,8 +33,8 @@ export class CommandService {
let items: MenuItemOptions[] = []
if (context.tab) {
for (const tabHeader of [false, true]) {
// Top-level tab menu
for (let section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(context.tab!, tabHeader)))) {
// Top-level tab menu
for (let section of await Promise.all(this.contextMenuProviders?.map(x => x.getItems(context.tab!, tabHeader)) ?? [])) {
// eslint-disable-next-line @typescript-eslint/no-loop-func
section = section.filter(item => !items.some(ex => ex.label === item.label))
items = items.concat(section)
@@ -38,7 +42,7 @@ export class CommandService {
if (context.tab instanceof SplitTabComponent) {
const tab = context.tab.getFocusedTab()
if (tab) {
for (let section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(tab, tabHeader)))) {
for (let section of await Promise.all(this.contextMenuProviders?.map(x => x.getItems(tab, tabHeader)) ?? [])) {
// eslint-disable-next-line @typescript-eslint/no-loop-func
section = section.filter(item => !items.some(ex => ex.label === item.label))
items = items.concat(section)
@@ -50,21 +54,10 @@ export class CommandService {
items = items.filter(x => (x.enabled ?? true) && x.type !== 'separator')
const flatItems: MenuItemOptions[] = []
function flattenItem (item: MenuItemOptions, prefix?: string): void {
if (item.submenu) {
item.submenu.forEach(x => flattenItem(x, (prefix ? `${prefix} > ` : '') + (item.commandLabel ?? item.label)))
} else {
flatItems.push({
...item,
label: (prefix ? `${prefix} > ` : '') + (item.commandLabel ?? item.label),
})
}
}
items.forEach(x => flattenItem(x))
const commands = buttons.map(x => Command.fromToolbarButton(x))
commands.push(...flatItems.map(x => Command.fromMenuItem(x)))
const commands = [
...buttons.map(x => Command.fromToolbarButton(x)),
...items.map(x => Command.fromMenuItem(x)).flat(),
]
for (const provider of this.config.enabledServices(this.commandProviders)) {
commands.push(...await provider.provide(context))
@@ -74,20 +67,36 @@ export class CommandService {
.filter(c => !this.config.store.commandBlacklist.includes(c.id))
.sort((a, b) => (a.weight ?? 0) - (b.weight ?? 0))
.map(command => {
const run = command.run
command.run = async () => {
// Serialize execution
this.lastCommand = this.lastCommand.finally(run)
await this.lastCommand
if (command.run) {
const run = command.run
command.run = async () => {
// Serialize execution
this.lastCommand = this.lastCommand.finally(run)
await this.lastCommand
}
}
return command
})
}
async getCommandsWithContexts (context: CommandContext[]): Promise<Command[]> {
let commands: Command[] = []
for (const commandSet of await Promise.all(context.map(x => this.getCommands(x)))) {
for (const command of commandSet) {
// eslint-disable-next-line @typescript-eslint/no-loop-func
commands = commands.filter(x => x.id !== command.id)
commands.push(command)
}
}
return commands
}
async run (id: string, context: CommandContext): Promise<void> {
const commands = await this.getCommands(context)
const command = commands.find(x => x.id === id)
await command?.run()
await command?.run?.()
}
async showSelector (): Promise<void> {
@@ -95,20 +104,80 @@ export class CommandService {
return
}
const context: CommandContext = {}
const tab = this.app.activeTab
if (tab instanceof SplitTabComponent) {
context.tab = tab.getFocusedTab() ?? undefined
const contexts: CommandContext[] = [{}]
if (this.app.activeTab) {
contexts.push({ tab: this.app.activeTab })
}
const commands = await this.getCommands(context)
if (this.app.activeTab instanceof SplitTabComponent) {
const tab = this.app.activeTab.getFocusedTab()
if (tab) {
contexts.push({ tab })
}
}
const commands = (await this.getCommandsWithContexts(contexts))
.filter(x => x.run)
.sort(firstBy(x => x.weight ?? 0))
return this.selector.show(
this.translate.instant('Commands'),
commands.map(c => ({
name: c.label,
name: c.fullLabel ?? c.label,
callback: c.run,
description: c.sublabel,
icon: c.icon,
})),
)
}
/** @hidden */
async buildContextMenu (contexts: CommandContext[], location: CommandLocation): Promise<MenuItemOptions[]> {
let commands = await this.getCommandsWithContexts(contexts)
commands = commands.filter(x => x.locations.includes(location))
commands.sort(firstBy(x => x.weight ?? 0))
interface Group {
id?: string
weight: number
commands: Command[]
}
const groups: Group[] = []
for (const command of commands.filter(x => !x.parent)) {
let group = groups.find(x => x.id === command.group)
if (!group) {
group = {
id: command.group,
weight: 0,
commands: [],
}
groups.push(group)
}
group.weight += command.weight ?? 0
group.commands.push(command)
}
groups.sort(firstBy(x => x.weight / x.commands.length))
function mapCommand (command: Command): MenuItemOptions {
const submenu = command.id ? commands.filter(x => x.parent === command.id).map(mapCommand) : []
return {
label: command.label,
submenu: submenu.length ? submenu : undefined,
checked: command.checked,
enabled: !!command.run || !!submenu.length,
type: command.checked ? 'checkbox' : undefined,
click: () => command.run?.(),
}
}
const items: MenuItemOptions[] = []
for (const group of groups) {
items.push({ type: 'separator' })
items.push(...group.commands.map(mapCommand))
}
return items.slice(1)
}
}

View File

@@ -406,6 +406,14 @@ export class ConfigService {
}
config.version = 6
}
if (config.version < 7) {
if (!config.configSync?.host || config.configSync?.host === 'https://api.tabby.sh') {
config.configSync ??= {}
delete config.configSync.host
delete config.configSync.token
}
config.version = 7
}
}
private async maybeDecryptConfig (store) {

View File

@@ -40,7 +40,7 @@ export class ProfilesService {
) { }
/*
* Methods used to interract with ProfileProvider
* Methods used to interact with ProfileProvider
*/
getProviders (): ProfileProvider<Profile>[] {
@@ -58,7 +58,7 @@ export class ProfilesService {
}
/*
* Methods used to interract with Profile
* Methods used to interact with Profile
*/
/*
@@ -115,10 +115,11 @@ export class ProfilesService {
async writeProfile (profile: PartialProfile<Profile>): Promise<void> {
const cProfile = this.config.store.profiles.find(p => p.id === profile.id)
if (cProfile) {
if (!profile.group) {
delete cProfile.group
// Fully replace the config
for (const k in cProfile) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete cProfile[k]
}
Object.assign(cProfile, profile)
}
}
@@ -205,7 +206,7 @@ export class ProfilesService {
}
/*
* Methods used to interract with Profile Selector
* Methods used to interact with Profile Selector
*/
selectorOptionForProfile <P extends Profile, T> (profile: PartialProfile<P>): SelectorOption<T> {
@@ -331,7 +332,7 @@ export class ProfilesService {
}
/*
* Methods used to interract with Profile/ProfileGroup/Global defaults
* Methods used to interact with Profile/ProfileGroup/Global defaults
*/
/**
@@ -369,7 +370,7 @@ export class ProfilesService {
}
/*
* Methods used to interract with ProfileGroup
* Methods used to interact with ProfileGroup
*/
/**

View File

@@ -1,298 +0,0 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { TranslateService } from '@ngx-translate/core'
import { Subscription } from 'rxjs'
import { AppService } from './services/app.service'
import { BaseTabComponent } from './components/baseTab.component'
import { SplitTabComponent, SplitDirection } from './components/splitTab.component'
import { TabContextMenuItemProvider } from './api/tabContextMenuProvider'
import { MenuItemOptions } from './api/menu'
import { ProfilesService } from './services/profiles.service'
import { TabsService } from './services/tabs.service'
import { HotkeysService } from './services/hotkeys.service'
import { PromptModalComponent } from './components/promptModal.component'
import { SplitLayoutProfilesService } from './profiles'
import { TAB_COLORS } from './utils'
/** @hidden */
@Injectable()
export class TabManagementContextMenu extends TabContextMenuItemProvider {
weight = 99
constructor (
private app: AppService,
private translate: TranslateService,
) {
super()
}
async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
let items: MenuItemOptions[] = [
{
label: this.translate.instant('Close'),
commandLabel: this.translate.instant('Close tab'),
click: () => {
if (this.app.tabs.includes(tab)) {
this.app.closeTab(tab, true)
} else {
tab.destroy()
}
},
},
]
if (!tab.parent) {
items = [
...items,
{
label: this.translate.instant('Close other tabs'),
click: () => {
for (const t of this.app.tabs.filter(x => x !== tab)) {
this.app.closeTab(t, true)
}
},
},
{
label: this.translate.instant('Close tabs to the right'),
click: () => {
for (const t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) {
this.app.closeTab(t, true)
}
},
},
{
label: this.translate.instant('Close tabs to the left'),
click: () => {
for (const t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) {
this.app.closeTab(t, true)
}
},
},
]
} else if (tab.parent instanceof SplitTabComponent) {
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
items.push({
label: this.translate.instant('Split'),
submenu: directions.map(dir => ({
label: {
r: this.translate.instant('Right'),
b: this.translate.instant('Down'),
l: this.translate.instant('Left'),
t: this.translate.instant('Up'),
}[dir],
commandLabel: {
r: this.translate.instant('Split to the right'),
b: this.translate.instant('Split to the down'),
l: this.translate.instant('Split to the left'),
t: this.translate.instant('Split to the up'),
}[dir],
click: () => {
(tab.parent as SplitTabComponent).splitTab(tab, dir)
},
})) as MenuItemOptions[],
})
}
return items
}
}
/** @hidden */
@Injectable()
export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
weight = -1
constructor (
private app: AppService,
private ngbModal: NgbModal,
private splitLayoutProfilesService: SplitLayoutProfilesService,
private translate: TranslateService,
) {
super()
}
async getItems (tab: BaseTabComponent, tabHeader?: boolean): Promise<MenuItemOptions[]> {
let items: MenuItemOptions[] = []
if (tabHeader) {
const currentColor = TAB_COLORS.find(x => x.value === tab.color)?.name
items = [
...items,
{
label: this.translate.instant('Rename'),
commandLabel: this.translate.instant('Rename tab'),
click: () => {
this.app.renameTab(tab)
},
},
{
label: this.translate.instant('Duplicate'),
commandLabel: this.translate.instant('Duplicate tab'),
click: () => this.app.duplicateTab(tab),
},
{
label: this.translate.instant('Color'),
commandLabel: this.translate.instant('Change tab color'),
sublabel: currentColor ? this.translate.instant(currentColor) : undefined,
submenu: TAB_COLORS.map(color => ({
label: this.translate.instant(color.name) ?? color.name,
type: 'radio',
checked: tab.color === color.value,
click: () => {
tab.color = color.value
},
})) as MenuItemOptions[],
},
]
if (tab instanceof SplitTabComponent && tab.getAllTabs().length > 1) {
items.push({
label: this.translate.instant('Save layout as profile'),
click: async () => {
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = this.translate.instant('Profile name')
const name = (await modal.result.catch(() => null))?.value
if (!name) {
return
}
this.splitLayoutProfilesService.createProfile(tab, name)
},
})
}
}
return items
}
}
/** @hidden */
@Injectable()
export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
constructor (
private app: AppService,
private translate: TranslateService,
) {
super()
}
async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
const process = await tab.getCurrentProcess()
const items: MenuItemOptions[] = []
const extTab: (BaseTabComponent & { __completionNotificationEnabled?: boolean, __outputNotificationSubscription?: Subscription|null }) = tab
if (process) {
items.push({
enabled: false,
label: this.translate.instant('Current process: {name}', process),
})
items.push({
label: this.translate.instant('Notify when done'),
type: 'checkbox',
checked: extTab.__completionNotificationEnabled,
click: () => {
extTab.__completionNotificationEnabled = !extTab.__completionNotificationEnabled
if (extTab.__completionNotificationEnabled) {
this.app.observeTabCompletion(tab).subscribe(() => {
new Notification(this.translate.instant('Process completed'), {
body: process.name,
}).addEventListener('click', () => {
this.app.selectTab(tab)
})
extTab.__completionNotificationEnabled = false
})
} else {
this.app.stopObservingTabCompletion(tab)
}
},
})
}
items.push({
label: this.translate.instant('Notify on activity'),
type: 'checkbox',
checked: !!extTab.__outputNotificationSubscription,
click: () => {
tab.clearActivity()
if (extTab.__outputNotificationSubscription) {
extTab.__outputNotificationSubscription.unsubscribe()
extTab.__outputNotificationSubscription = null
} else {
extTab.__outputNotificationSubscription = tab.activity$.subscribe(active => {
if (extTab.__outputNotificationSubscription && active) {
extTab.__outputNotificationSubscription.unsubscribe()
extTab.__outputNotificationSubscription = null
new Notification(this.translate.instant('Tab activity'), {
body: tab.title,
}).addEventListener('click', () => {
this.app.selectTab(tab)
})
}
})
}
},
})
return items
}
}
/** @hidden */
@Injectable()
export class ProfilesContextMenu extends TabContextMenuItemProvider {
weight = 10
constructor (
private profilesService: ProfilesService,
private tabsService: TabsService,
private app: AppService,
private translate: TranslateService,
hotkeys: HotkeysService,
) {
super()
hotkeys.hotkey$.subscribe(hotkey => {
if (hotkey === 'switch-profile') {
let tab = this.app.activeTab
if (tab instanceof SplitTabComponent) {
tab = tab.getFocusedTab()
if (tab) {
this.switchTabProfile(tab)
}
}
}
})
}
async switchTabProfile (tab: BaseTabComponent) {
const profile = await this.profilesService.showProfileSelector().catch(() => null)
if (!profile) {
return
}
const params = await this.profilesService.newTabParametersForProfile(profile)
if (!params) {
return
}
if (!await tab.canClose()) {
return
}
const newTab = this.tabsService.create(params)
;(tab.parent as SplitTabComponent).replaceTab(tab, newTab)
tab.destroy()
}
async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
if (tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
return [
{
label: this.translate.instant('Switch profile'),
click: () => this.switchTabProfile(tab),
},
]
}
return []
}
}

View File

@@ -11,6 +11,7 @@ import { ElectronHostWindow } from './hostWindow.service'
import { ShellIntegrationService } from './shellIntegration.service'
import { ElectronHostAppService } from './hostApp.service'
import { PlatformTheme } from '../../../tabby-core/src/api/platform'
import { configPath } from '../../../app/lib/config'
const fontManager = require('fontmanager-redux') // eslint-disable-line
/* eslint-disable block-scoped-var */
@@ -36,7 +37,7 @@ export class ElectronPlatformService extends PlatformService {
private translate: TranslateService,
) {
super()
this.configPath = path.join(electron.app.getPath('userData'), 'config.yaml')
this.configPath = configPath
electron.ipcRenderer.on('host:display-metrics-changed', () => {
this.zone.run(() => this.displayMetricsChanged.next())

View File

@@ -25,7 +25,7 @@ export class ElectronUpdaterService extends UpdaterService {
super()
this.logger = log.create('updater')
if (process.platform === 'linux') {
if (process.platform === 'linux' || process.env.PORTABLE_EXECUTABLE_FILE) {
this.electronUpdaterAvailable = false
return
}

View File

@@ -1,28 +0,0 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable } from '@angular/core'
import { ToolbarButtonProvider, ToolbarButton, TranslateService } from 'tabby-core'
import { TerminalService } from './services/terminal.service'
/** @hidden */
@Injectable()
export class ButtonProvider extends ToolbarButtonProvider {
constructor (
private terminal: TerminalService,
private translate: TranslateService,
) {
super()
}
provide (): ToolbarButton[] {
return [
{
icon: require('./icons/plus.svg'),
title: this.translate.instant('New terminal'),
touchBarNSImage: 'NSTouchBarAddDetailTemplate',
click: () => {
this.terminal.openTab()
},
},
]
}
}

123
tabby-local/src/commands.ts Normal file
View File

@@ -0,0 +1,123 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Inject, Injectable, Optional } from '@angular/core'
import { CommandProvider, Command, CommandLocation, TranslateService, CommandContext, ProfilesService } from 'tabby-core'
import { TerminalTabComponent } from './components/terminalTab.component'
import { TerminalService } from './services/terminal.service'
import { LocalProfile, UACService } from './api'
/** @hidden */
@Injectable({ providedIn: 'root' })
export class LocalCommandProvider extends CommandProvider {
constructor (
private terminal: TerminalService,
private profilesService: ProfilesService,
private translate: TranslateService,
@Optional() @Inject(UACService) private uac: UACService|undefined,
) {
super()
}
async provide (context: CommandContext): Promise<Command[]> {
const profiles = (await this.profilesService.getProfiles()).filter(x => x.type === 'local') as LocalProfile[]
const commands: Command[] = [
{
id: 'local:new-tab',
group: 'local:new-tab',
label: this.translate.instant('New terminal'),
locations: [CommandLocation.LeftToolbar, CommandLocation.StartPage, CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
weight: 11,
icon: require('./icons/plus.svg'),
run: async () => this.runOpenTab(context),
},
]
commands.push({
id: 'local:new-tab-with-profile',
group: 'local:new-tab',
label: this.translate.instant('New with profile'),
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
weight: 12,
})
for (const profile of profiles) {
commands.push({
id: `local:new-tab-with-profile:${profile.id}`,
group: 'local:new-tab',
parent: 'local:new-tab-with-profile',
label: profile.name,
fullLabel: this.translate.instant('New terminal with profile: {profile}', { profile: profile.name }),
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
// eslint-disable-next-line @typescript-eslint/no-loop-func
run: async () => {
let workingDirectory = profile.options.cwd
if (!workingDirectory && context.tab instanceof TerminalTabComponent) {
workingDirectory = await context.tab.session?.getWorkingDirectory() ?? undefined
}
await this.terminal.openTab(profile, workingDirectory)
},
})
}
if (this.uac?.isAvailable) {
commands.push({
id: 'local:new-tab-as-administrator-with-profile',
group: 'local:new-tab',
label: this.translate.instant('New admin tab'),
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
weight: 13,
})
for (const profile of profiles) {
commands.push({
id: `local:new-tab-as-administrator-with-profile:${profile.id}`,
group: 'local:new-tab',
label: profile.name,
fullLabel: this.translate.instant('New admin tab with profile: {profile}', { profile: profile.name }),
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
run: async () => {
this.profilesService.openNewTabForProfile({
...profile,
options: {
...profile.options,
runAsAdministrator: true,
},
})
},
})
}
if (context.tab && context.tab instanceof TerminalTabComponent) {
const terminalTab = context.tab
commands.push({
id: 'local:duplicate-tab-as-administrator',
group: 'local:new-tab',
label: this.translate.instant('Duplicate as administrator'),
locations: [CommandLocation.TabHeaderMenu],
weight: 14,
run: async () => {
this.profilesService.openNewTabForProfile({
...terminalTab.profile,
options: {
...terminalTab.profile.options,
runAsAdministrator: true,
},
})
},
})
}
}
return commands
}
runOpenTab (context: CommandContext) {
if (context.tab && context.tab instanceof TerminalTabComponent) {
this.profilesService.openNewTabForProfile(context.tab.profile)
} else {
this.terminal.openTab()
}
}
}

View File

@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { ToastrModule } from 'ngx-toastr'
import TabbyCorePlugin, { HostAppService, ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysService, HotkeyProvider, TabContextMenuItemProvider, CLIHandler, ProfileProvider } from 'tabby-core'
import TabbyCorePlugin, { HostAppService, TabRecoveryProvider, ConfigProvider, HotkeysService, HotkeyProvider, CLIHandler, ProfileProvider, CommandProvider } from 'tabby-core'
import TabbyTerminalModule from 'tabby-terminal'
import { SettingsTabProvider } from 'tabby-settings'
@@ -16,15 +16,14 @@ import { CommandLineEditorComponent } from './components/commandLineEditor.compo
import { TerminalService } from './services/terminal.service'
import { ButtonProvider } from './buttonProvider'
import { RecoveryProvider } from './recoveryProvider'
import { ShellSettingsTabProvider } from './settings'
import { TerminalConfigProvider } from './config'
import { LocalTerminalHotkeyProvider } from './hotkeys'
import { NewTabContextMenu } from './tabContextMenu'
import { AutoOpenTabCLIHandler, OpenPathCLIHandler, TerminalCLIHandler } from './cli'
import { LocalProfilesService } from './profiles'
import { LocalCommandProvider } from './commands'
/** @hidden */
@NgModule({
@@ -39,15 +38,13 @@ import { LocalProfilesService } from './profiles'
providers: [
{ provide: SettingsTabProvider, useClass: ShellSettingsTabProvider, multi: true },
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
{ provide: CommandProvider, useExisting: LocalCommandProvider, multi: true },
{ provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true },
{ provide: ConfigProvider, useClass: TerminalConfigProvider, multi: true },
{ provide: HotkeyProvider, useClass: LocalTerminalHotkeyProvider, multi: true },
{ provide: ProfileProvider, useClass: LocalProfilesService, multi: true },
{ provide: TabContextMenuItemProvider, useClass: NewTabContextMenu, multi: true },
{ provide: CLIHandler, useClass: TerminalCLIHandler, multi: true },
{ provide: CLIHandler, useClass: OpenPathCLIHandler, multi: true },
{ provide: CLIHandler, useClass: AutoOpenTabCLIHandler, multi: true },

View File

@@ -1,87 +0,0 @@
import { Inject, Injectable, Optional } from '@angular/core'
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, MenuItemOptions, ProfilesService, TranslateService } from 'tabby-core'
import { TerminalTabComponent } from './components/terminalTab.component'
import { TerminalService } from './services/terminal.service'
import { LocalProfile, UACService } from './api'
/** @hidden */
@Injectable()
export class NewTabContextMenu extends TabContextMenuItemProvider {
weight = 10
constructor (
public config: ConfigService,
private profilesService: ProfilesService,
private terminalService: TerminalService,
@Optional() @Inject(UACService) private uac: UACService|undefined,
private translate: TranslateService,
) {
super()
}
async getItems (tab: BaseTabComponent, tabHeader?: boolean): Promise<MenuItemOptions[]> {
const profiles = (await this.profilesService.getProfiles()).filter(x => x.type === 'local') as LocalProfile[]
const items: MenuItemOptions[] = [
{
label: this.translate.instant('New terminal'),
click: () => {
if (tab instanceof TerminalTabComponent) {
this.profilesService.openNewTabForProfile(tab.profile)
} else {
this.terminalService.openTab()
}
},
},
{
label: this.translate.instant('New with profile'),
submenu: profiles.map(profile => ({
label: profile.name,
click: async () => {
let workingDirectory = profile.options.cwd
if (!workingDirectory && tab instanceof TerminalTabComponent) {
workingDirectory = await tab.session?.getWorkingDirectory() ?? undefined
}
await this.terminalService.openTab(profile, workingDirectory)
},
})),
},
]
if (this.uac?.isAvailable) {
items.push({
label: this.translate.instant('New admin tab'),
submenu: profiles.map(profile => ({
label: profile.name,
click: () => {
this.profilesService.openNewTabForProfile({
...profile,
options: {
...profile.options,
runAsAdministrator: true,
},
})
},
})),
})
}
if (tab instanceof TerminalTabComponent && tabHeader && this.uac?.isAvailable) {
const terminalTab = tab
items.push({
label: this.translate.instant('Duplicate as administrator'),
click: () => {
this.profilesService.openNewTabForProfile({
...terminalTab.profile,
options: {
...terminalTab.profile.options,
runAsAdministrator: true,
},
})
},
})
}
return items
}
}

View File

@@ -87,6 +87,11 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.description(translate) Sends data one byte at a time
toggle([(ngModel)]='profile.options.slowSend')
li(ngbNavItem)
a(ngbNavLink, translate) Colors
ng-template(ngbNavContent)
color-scheme-selector([(model)]='profile.terminalColorScheme')
li(ngbNavItem)
a(ngbNavLink, translate) Login scripts
ng-template(ngbNavContent)

View File

@@ -1,11 +1,11 @@
import { Injectable } from '@angular/core'
import { ToolbarButtonProvider, ToolbarButton, AppService, HostAppService, HotkeysService, TranslateService } from 'tabby-core'
import { CommandProvider, AppService, HostAppService, HotkeysService, TranslateService, Command, CommandLocation } from 'tabby-core'
import { SettingsTabComponent } from './components/settingsTab.component'
/** @hidden */
@Injectable()
export class ButtonProvider extends ToolbarButtonProvider {
@Injectable({ providedIn: 'root' })
export class SettingsCommandProvider extends CommandProvider {
constructor (
hostApp: HostAppService,
hotkeys: HotkeysService,
@@ -22,13 +22,14 @@ export class ButtonProvider extends ToolbarButtonProvider {
})
}
provide (): ToolbarButton[] {
async provide (): Promise<Command[]> {
return [{
id: 'settings:open',
icon: require('./icons/cog.svg'),
title: this.translate.instant('Settings'),
touchBarNSImage: 'NSTouchBarComposeTemplate',
weight: 10,
click: (): void => this.open(),
label: this.translate.instant('Settings'),
weight: 99,
locations: [CommandLocation.RightToolbar, CommandLocation.StartPage],
run: async () => this.open(),
}]
}

View File

@@ -20,7 +20,7 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
)
i.fas.fa-external-link-alt
.form-line
.form-line(*ngIf='config.store.configSync.host')
.header
.title(translate) Secret sync token
.description(translate) Get it from the Tabby Web settings window
@@ -36,6 +36,11 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
i.fas.fa-fw.fa-check.text-success(*ngIf='connectionSuccessful')
i.fas.fa-fw.fa-exclamation-triangle.text-danger(*ngIf='connectionSuccessful === false')
.alert.alert-info.d-flex.align-items-center
.me-auto
span(translate) Config sync requires an instance of the Tabby Web service.
a.ml-1((click)='openTabbyWebInfo()', href='#', translate) Learn more
ng-container(*ngIf='config.store.configSync.token')
.alert.alert-danger(*ngIf='connectionSuccessful === false')
i.fas.fa-exclamation-triangle

View File

@@ -141,4 +141,8 @@ export class ConfigSyncSettingsTabComponent extends BaseComponent {
this.platform.openExternal(this.config.store.configSync.host)
}
}
openTabbyWebInfo () {
this.platform.openExternal('https://github.com/Eugeny/tabby-web')
}
}

View File

@@ -12,14 +12,16 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
[(ngModel)]='config.store.terminal.profile',
(ngModelChange)='config.save()',
)
option(
*ngFor='let profile of profiles',
[ngValue]='profile.id'
) {{profile.name}}
option(
*ngFor='let profile of builtinProfiles',
[ngValue]='profile.id'
) {{profile.name}}
optgroup([label]='"Custom Profiles"|translate', *ngIf='customProfiles?.length > 0')
option(
*ngFor='let profile of customProfiles',
[ngValue]='profile.id'
) {{profile.name}}
optgroup([label]='"Built-in Profiles"|translate')
option(
*ngFor='let profile of builtinProfiles',
[ngValue]='profile.id'
) {{profile.name}}
.d-flex.mb-3
.input-group

View File

@@ -20,7 +20,9 @@ interface CollapsableProfileGroup extends ProfileGroup {
})
export class ProfilesSettingsTabComponent extends BaseComponent {
builtinProfiles: PartialProfile<Profile>[] = []
profiles: PartialProfile<Profile>[] = []
templateProfiles: PartialProfile<Profile>[] = []
customProfiles: PartialProfile<Profile>[] = []
profileGroups: PartialProfileGroup<CollapsableProfileGroup>[]
filter = ''
Platform = Platform
@@ -40,12 +42,17 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
}
async ngOnInit (): Promise<void> {
this.refresh()
await this.refreshProfileGroups()
await this.refreshProfiles()
this.subscribeUntilDestroyed(this.config.changed$, () => this.refreshProfileGroups())
this.subscribeUntilDestroyed(this.config.changed$, () => this.refreshProfiles())
}
async refreshProfiles (): Promise<void> {
this.builtinProfiles = (await this.profilesService.getProfiles()).filter(x => x.isBuiltin)
this.customProfiles = (await this.profilesService.getProfiles()).filter(x => !x.isBuiltin)
this.templateProfiles = this.builtinProfiles.filter(x => x.isTemplate)
this.builtinProfiles = this.builtinProfiles.filter(x => !x.isTemplate)
this.refresh()
this.subscribeUntilDestroyed(this.config.changed$, () => this.refresh())
}
launchProfile (profile: PartialProfile<Profile>): void {
@@ -70,25 +77,24 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
return
}
}
const profile: PartialProfile<Profile> = deepClone(base)
delete profile.id
const baseProfile: PartialProfile<Profile> = deepClone(base)
delete baseProfile.id
if (base.isTemplate) {
profile.name = ''
baseProfile.name = ''
} else if (!base.isBuiltin) {
profile.name = this.translate.instant('{name} copy', base)
baseProfile.name = this.translate.instant('{name} copy', base)
}
profile.isBuiltin = false
profile.isTemplate = false
const result = await this.showProfileEditModal(profile)
baseProfile.isBuiltin = false
baseProfile.isTemplate = false
const result = await this.showProfileEditModal(baseProfile)
if (!result) {
return
}
Object.assign(profile, result)
if (!profile.name) {
const cfgProxy = this.profilesService.getConfigProxyForProfile(profile)
profile.name = this.profilesService.providerForProfile(profile)?.getSuggestedName(cfgProxy) ?? this.translate.instant('{name} copy', base)
if (!result.name) {
const cfgProxy = this.profilesService.getConfigProxyForProfile(result)
result.name = this.profilesService.providerForProfile(result)?.getSuggestedName(cfgProxy) ?? this.translate.instant('{name} copy', base)
}
await this.profilesService.newProfile(profile)
await this.profilesService.newProfile(result)
await this.config.save()
}
@@ -97,8 +103,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
if (!result) {
return
}
Object.assign(profile, result)
await this.profilesService.writeProfile(profile)
await this.profilesService.writeProfile(result)
await this.config.save()
}
@@ -119,12 +124,6 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
return null
}
// Fully replace the config
for (const k in profile) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete profile[k]
}
result.type = provider.id
return result
}
@@ -162,8 +161,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
if (!result) {
return
}
Object.assign(group, result)
await this.profilesService.writeProfileGroup(ProfilesSettingsTabComponent.collapsableIntoPartialProfileGroup(group))
await this.profilesService.writeProfileGroup(ProfilesSettingsTabComponent.collapsableIntoPartialProfileGroup(result))
await this.config.save()
}
@@ -249,7 +247,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
}
}
async refresh (): Promise<void> {
async refreshProfileGroups (): Promise<void> {
const profileGroupCollapsed = JSON.parse(window.localStorage.profileGroupCollapsed ?? '{}')
const groups = await this.profilesService.getProfileGroups({ includeNonUserGroup: true, includeProfiles: true })
groups.sort((a, b) => a.name.localeCompare(b.name))

View File

@@ -0,0 +1,15 @@
h4.modal-header.m-0.pb-0 {{title}}
.modal-body
.input-group.w-100
input.form-control(
type='text',
[(ngModel)]='secret.value',
disabled
)
button.btn.btn-secondary(
(click)='copySecret()'
)
i.fas.fa-copy
.modal-footer
button.btn.btn-primary((click)='close()', translate) Close

View File

@@ -0,0 +1,27 @@
import { Component, Input } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { NotificationsService, VaultFileSecret } from 'tabby-core'
/** @hidden */
@Component({
templateUrl: './showSecretModal.component.pug',
})
export class ShowSecretModalComponent {
@Input() title: string
@Input() secret: VaultFileSecret
constructor (
public modalInstance: NgbActiveModal,
private notifications: NotificationsService,
) { }
close (): void {
this.modalInstance.dismiss()
}
copySecret (): void {
navigator.clipboard.writeText(this.secret.value)
// Show a notification
this.notifications.info('Copied to clipboard')
}
}

View File

@@ -32,6 +32,9 @@ div(*ngIf='vault.isEnabled()')
button.btn.btn-link(ngbDropdownToggle)
i.fas.fa-ellipsis-v
div(ngbDropdownMenu)
button(ngbDropdownItem, (click)='showSecret(secret)')
i.fas.fa-fw.fa-eye
span(translate) Show
button(
ngbDropdownItem,
*ngIf='secret.type === VAULT_SECRET_TYPE_FILE',

View File

@@ -3,6 +3,7 @@ import { Component, HostBinding } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { BaseComponent, VaultService, VaultSecret, Vault, PlatformService, ConfigService, VAULT_SECRET_TYPE_FILE, PromptModalComponent, VaultFileSecret, TranslateService } from 'tabby-core'
import { SetVaultPassphraseModalComponent } from './setVaultPassphraseModal.component'
import { ShowSecretModalComponent } from './showSecretModal.component'
/** @hidden */
@@ -97,6 +98,16 @@ export class VaultSettingsTabComponent extends BaseComponent {
return this.translate.instant('Unknown secret of type {type} for {key}', { type: secret.type, key: JSON.stringify(secret.key) })
}
showSecret (secret: VaultSecret) {
if (!this.vaultContents) {
return
}
const modal = this.ngbModal.open(ShowSecretModalComponent)
modal.componentInstance.title = this.getSecretLabel(secret)
modal.componentInstance.secret = secret
}
removeSecret (secret: VaultSecret) {
if (!this.vaultContents) {
return

View File

@@ -4,8 +4,8 @@ import { ConfigProvider, Platform } from 'tabby-core'
export class SettingsConfigProvider extends ConfigProvider {
defaults = {
configSync: {
host: 'https://api.tabby.sh',
token: '',
host: null,
token: null,
configID: null,
auto: false,
parts: {

View File

@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { InfiniteScrollModule } from 'ngx-infinite-scroll'
import TabbyCorePlugin, { ToolbarButtonProvider, HotkeyProvider, ConfigProvider, HotkeysService, AppService } from 'tabby-core'
import TabbyCorePlugin, { HotkeyProvider, ConfigProvider, HotkeysService, AppService, CommandProvider } from 'tabby-core'
import { EditProfileModalComponent } from './components/editProfileModal.component'
import { EditProfileGroupModalComponent } from './components/editProfileGroupModal.component'
@@ -19,11 +19,12 @@ import { SetVaultPassphraseModalComponent } from './components/setVaultPassphras
import { ProfilesSettingsTabComponent } from './components/profilesSettingsTab.component'
import { ReleaseNotesComponent } from './components/releaseNotesTab.component'
import { ConfigSyncSettingsTabComponent } from './components/configSyncSettingsTab.component'
import { ShowSecretModalComponent } from './components/showSecretModal.component'
import { ConfigSyncService } from './services/configSync.service'
import { SettingsTabProvider } from './api'
import { ButtonProvider } from './buttonProvider'
import { SettingsCommandProvider } from './commands'
import { SettingsHotkeyProvider } from './hotkeys'
import { SettingsConfigProvider } from './config'
import { HotkeySettingsTabProvider, WindowSettingsTabProvider, VaultSettingsTabProvider, ProfilesSettingsTabProvider, ConfigSyncSettingsTabProvider } from './settings'
@@ -38,7 +39,7 @@ import { HotkeySettingsTabProvider, WindowSettingsTabProvider, VaultSettingsTabP
InfiniteScrollModule,
],
providers: [
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
{ provide: CommandProvider, useExisting: SettingsCommandProvider, multi: true },
{ provide: ConfigProvider, useClass: SettingsConfigProvider, multi: true },
{ provide: HotkeyProvider, useClass: SettingsHotkeyProvider, multi: true },
{ provide: SettingsTabProvider, useClass: HotkeySettingsTabProvider, multi: true },
@@ -61,6 +62,7 @@ import { HotkeySettingsTabProvider, WindowSettingsTabProvider, VaultSettingsTabP
WindowSettingsTabComponent,
ConfigSyncSettingsTabComponent,
ReleaseNotesComponent,
ShowSecretModalComponent,
],
})
export default class SettingsModule {

44
tabby-ssh/src/commands.ts Normal file
View File

@@ -0,0 +1,44 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable } from '@angular/core'
import { CommandProvider, Command, CommandLocation, TranslateService, CommandContext, Platform, HostAppService } from 'tabby-core'
import { SSHTabComponent } from './components/sshTab.component'
import { SSHService } from './services/ssh.service'
/** @hidden */
@Injectable({ providedIn: 'root' })
export class SSHCommandProvider extends CommandProvider {
constructor (
private hostApp: HostAppService,
private ssh: SSHService,
private translate: TranslateService,
) {
super()
}
async provide (context: CommandContext): Promise<Command[]> {
const tab = context.tab
if (!tab || !(tab instanceof SSHTabComponent)) {
return []
}
const commands: Command[] = [{
id: 'ssh:open-sftp-panel',
group: 'ssh:sftp',
label: this.translate.instant('Open SFTP panel'),
locations: [CommandLocation.TabHeaderMenu, CommandLocation.TabBodyMenu],
run: async () => tab.openSFTP(),
}]
if (this.hostApp.platform === Platform.Windows && this.ssh.getWinSCPPath()) {
commands.push({
id: 'ssh:open-winscp',
group: 'ssh:sftp',
label: this.translate.instant('Launch WinSCP'),
locations: [CommandLocation.TabHeaderMenu, CommandLocation.TabBodyMenu],
run: async () => this.ssh.launchWinSCP(tab.sshSession!),
})
}
return commands
}
}

View File

@@ -29,6 +29,12 @@
font-weight: bold;
}
.list-group-item-action {
&:hover {
background: rgba(white, .05);
}
}
.mode, .size, .date {
font-family: monospace;
opacity: .5;

View File

@@ -81,6 +81,45 @@ export class SFTPPanelComponent {
a.name.localeCompare(b.name))
}
getFileType (fileExtension: string): string {
const codeExtensions = ['js', 'ts', 'py', 'java', 'cpp', 'h', 'cs', 'html', 'css', 'rb', 'php', 'swift', 'go', 'kt', 'sh', 'json', 'cc', 'c', 'xml']
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp']
const pdfExtensions = ['pdf']
const archiveExtensions = ['zip', 'rar', 'tar', 'gz']
const wordExtensions = ['doc', 'docx']
const videoExtensions = ['mp4', 'avi', 'mkv', 'mov']
const powerpointExtensions = ['ppt', 'pptx']
const textExtensions = ['txt', 'log']
const audioExtensions = ['mp3', 'wav', 'flac']
const excelExtensions = ['xls', 'xlsx']
const lowerCaseExtension = fileExtension.toLowerCase()
if (codeExtensions.includes(lowerCaseExtension)) {
return 'code'
} else if (imageExtensions.includes(lowerCaseExtension)) {
return 'image'
} else if (pdfExtensions.includes(lowerCaseExtension)) {
return 'pdf'
} else if (archiveExtensions.includes(lowerCaseExtension)) {
return 'archive'
} else if (wordExtensions.includes(lowerCaseExtension)) {
return 'word'
} else if (videoExtensions.includes(lowerCaseExtension)) {
return 'video'
} else if (powerpointExtensions.includes(lowerCaseExtension)) {
return 'powerpoint'
} else if (textExtensions.includes(lowerCaseExtension)) {
return 'text'
} else if (audioExtensions.includes(lowerCaseExtension)) {
return 'audio'
} else if (excelExtensions.includes(lowerCaseExtension)) {
return 'excel'
} else {
return 'unknown'
}
}
getIcon (item: SFTPFile): string {
if (item.isDirectory) {
return 'fas fa-folder text-info'
@@ -88,6 +127,18 @@ export class SFTPPanelComponent {
if (item.isSymlink) {
return 'fas fa-link text-warning'
}
const fileMatch = /\.([^.]+)$/.exec(item.name)
const extension = fileMatch ? fileMatch[1] : null
if (extension !== null) {
const fileType = this.getFileType(extension)
switch (fileType) {
case 'unknown':
return 'fas fa-file'
default:
return `fa-solid fa-file-${fileType} `
}
}
return 'fas fa-file'
}

View File

@@ -160,10 +160,12 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
type='radio',
name='auth',
[(ngModel)]='profile.options.auth',
id='auth"keyboardInteractive"'
id='auth"keyboardInteractive"',
[value]='"keyboardInteractive"'
)
label.btn.btn-secondary(ngbButtonLabel)
label.btn.btn-secondary(
for='auth"keyboardInteractive"'
)
i.far.fa-keyboard
.m-0(translate) Interactive

View File

@@ -3,7 +3,7 @@ import { Component, ViewChild } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { firstBy } from 'thenby'
import { ConfigService, FileProvidersService, Platform, HostAppService, PromptModalComponent, PartialProfile } from 'tabby-core'
import { FileProvidersService, Platform, HostAppService, PromptModalComponent, PartialProfile, ProfilesService } from 'tabby-core'
import { LoginScriptsSettingsComponent } from 'tabby-terminal'
import { PasswordStorageService } from '../services/passwordStorage.service'
import { ForwardedPortConfig, SSHAlgorithmType, SSHProfile } from '../api'
@@ -27,14 +27,14 @@ export class SSHProfileSettingsComponent {
constructor (
public hostApp: HostAppService,
private config: ConfigService,
private profilesService: ProfilesService,
private passwordStorage: PasswordStorageService,
private ngbModal: NgbModal,
private fileProviders: FileProvidersService,
) { }
async ngOnInit () {
this.jumpHosts = this.config.store.profiles.filter(x => x.type === 'ssh' && x !== this.profile)
this.jumpHosts = (await this.profilesService.getProfiles({ includeBuiltin: false })).filter(x => x.type === 'ssh' && x !== this.profile)
this.jumpHosts.sort(firstBy(x => this.getJumpHostLabel(x)))
for (const k of Object.values(SSHAlgorithmType)) {
@@ -67,7 +67,7 @@ export class SSHProfileSettingsComponent {
}
getJumpHostLabel (p: PartialProfile<SSHProfile>) {
return p.group ? `${p.group} / ${p.name}` : p.name
return p.group ? `${this.profilesService.resolveProfileGroupName(p.group)} / ${p.name}` : p.name
}
async setPassword () {

View File

@@ -6,7 +6,7 @@ import { FormsModule } from '@angular/forms'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { ToastrModule } from 'ngx-toastr'
import { NgxFilesizeModule } from 'ngx-filesize'
import TabbyCoreModule, { ConfigProvider, TabRecoveryProvider, HotkeyProvider, TabContextMenuItemProvider, ProfileProvider } from 'tabby-core'
import TabbyCoreModule, { ConfigProvider, TabRecoveryProvider, HotkeyProvider, ProfileProvider, CommandProvider } from 'tabby-core'
import { SettingsTabProvider } from 'tabby-settings'
import TabbyTerminalModule from 'tabby-terminal'
@@ -24,11 +24,11 @@ import { SSHConfigProvider } from './config'
import { SSHSettingsTabProvider } from './settings'
import { RecoveryProvider } from './recoveryProvider'
import { SSHHotkeyProvider } from './hotkeys'
import { SFTPContextMenu } from './tabContextMenu'
import { SSHProfilesService } from './profiles'
import { SFTPContextMenuItemProvider } from './api/contextMenu'
import { CommonSFTPContextMenu } from './sftpContextMenu'
import { SFTPCreateDirectoryModalComponent } from './components/sftpCreateDirectoryModal.component'
import { SSHCommandProvider } from './commands'
/** @hidden */
@NgModule({
@@ -46,7 +46,7 @@ import { SFTPCreateDirectoryModalComponent } from './components/sftpCreateDirect
{ provide: SettingsTabProvider, useClass: SSHSettingsTabProvider, multi: true },
{ provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true },
{ provide: HotkeyProvider, useClass: SSHHotkeyProvider, multi: true },
{ provide: TabContextMenuItemProvider, useClass: SFTPContextMenu, multi: true },
{ provide: CommandProvider, useExisting: SSHCommandProvider, multi: true },
{ provide: ProfileProvider, useExisting: SSHProfilesService, multi: true },
{ provide: SFTPContextMenuItemProvider, useClass: CommonSFTPContextMenu, multi: true },
],

View File

@@ -37,7 +37,11 @@ export class SSHService {
if (password) {
uri += ':' + encodeURIComponent(password)
}
uri += `@${profile.options.host}:${profile.options.port}${cwd ?? '/'}`
if (profile.options.host.includes(':')) {
uri += `@[${profile.options.host}]:${profile.options.port}${cwd ?? '/'}`
}else {
uri += `@${profile.options.host}:${profile.options.port}${cwd ?? '/'}`
}
return uri
}

View File

@@ -1,40 +0,0 @@
import { Injectable } from '@angular/core'
import { BaseTabComponent, TabContextMenuItemProvider, HostAppService, Platform, MenuItemOptions, TranslateService } from 'tabby-core'
import { SSHTabComponent } from './components/sshTab.component'
import { SSHService } from './services/ssh.service'
/** @hidden */
@Injectable()
export class SFTPContextMenu extends TabContextMenuItemProvider {
weight = 10
constructor (
private hostApp: HostAppService,
private ssh: SSHService,
private translate: TranslateService,
) {
super()
}
async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
if (!(tab instanceof SSHTabComponent)) {
return []
}
const items = [{
label: this.translate.instant('Open SFTP panel'),
click: () => {
tab.openSFTP()
},
}]
if (this.hostApp.platform === Platform.Windows && this.ssh.getWinSCPPath()) {
items.push({
label: this.translate.instant('Launch WinSCP'),
click: (): void => {
this.ssh.launchWinSCP(tab.sshSession!)
},
})
}
return items
}
}

View File

@@ -28,15 +28,15 @@
"ngx-colors": "^3.4.0",
"patch-package": "^6.5.0",
"runes": "^0.4.2",
"xterm": "^5.2.0",
"xterm-addon-canvas": "^0.4.0",
"xterm-addon-fit": "^0.7.0",
"xterm-addon-image": "^0.4.1",
"xterm-addon-ligatures": "^0.6.0",
"xterm-addon-search": "^0.12.0",
"xterm-addon-serialize": "^0.10.0",
"xterm-addon-unicode11": "^0.5.0",
"xterm-addon-webgl": "^0.15.0",
"xterm": "^5.3.0",
"xterm-addon-canvas": "^0.5.0",
"xterm-addon-fit": "^0.8.0",
"xterm-addon-image": "^0.5.0",
"xterm-addon-ligatures": "^0.7.0",
"xterm-addon-search": "^0.13.0",
"xterm-addon-serialize": "^0.11.0",
"xterm-addon-unicode11": "^0.6.0",
"xterm-addon-webgl": "^0.16.0",
"zmodem.js": "^0.1.9"
},
"peerDependencies": {

View File

@@ -3,7 +3,7 @@ import { Spinner } from 'cli-spinner'
import colors from 'ansi-colors'
import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags, Component } from '@angular/core'
import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations'
import { AppService, ConfigService, BaseTabComponent, HostAppService, HotkeysService, NotificationsService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent, SubscriptionContainer, MenuItemOptions, PlatformService, HostWindowService, ResettableTimeout, TranslateService, ThemesService } from 'tabby-core'
import { AppService, ConfigService, BaseTabComponent, HostAppService, HotkeysService, NotificationsService, Platform, LogService, Logger, SplitTabComponent, SubscriptionContainer, MenuItemOptions, PlatformService, HostWindowService, ResettableTimeout, TranslateService, ThemesService, CommandContext, CommandLocation, CommandService } from 'tabby-core'
import { BaseSession } from '../session'
@@ -97,7 +97,7 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
profile: P
/**
* Enables normall passthrough from session output to terminal input
* Enables normal passthrough from session output to terminal input
*/
enablePassthrough = true
@@ -121,11 +121,11 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
protected notifications: NotificationsService
protected log: LogService
protected decorators: TerminalDecorator[] = []
protected contextMenuProviders: TabContextMenuItemProvider[]
protected hostWindow: HostWindowService
protected translate: TranslateService
protected multifocus: MultifocusService
protected themes: ThemesService
protected commands: CommandService
// Deps end
protected logger: Logger
@@ -200,11 +200,11 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
this.notifications = injector.get(NotificationsService)
this.log = injector.get(LogService)
this.decorators = injector.get<any>(TerminalDecorator, null, InjectFlags.Optional) as TerminalDecorator[]
this.contextMenuProviders = injector.get<any>(TabContextMenuItemProvider, null, InjectFlags.Optional) as TabContextMenuItemProvider[]
this.hostWindow = injector.get(HostWindowService)
this.translate = injector.get(TranslateService)
this.multifocus = injector.get(MultifocusService)
this.themes = injector.get(ThemesService)
this.commands = injector.get(CommandService)
this.logger = this.log.create('baseTerminalTab')
this.setTitle(this.translate.instant('Terminal'))
@@ -290,7 +290,7 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
break
case 'delete-previous-word':
this.forEachFocusedTerminalPane(tab => {
tab.sendInput('\x1b\x7f')
tab.sendInput('\u0017')
})
break
case 'delete-next-word':
@@ -323,8 +323,6 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
this.bellPlayer = document.createElement('audio')
this.bellPlayer.src = require<string>('../bell.ogg')
this.bellPlayer.load()
this.contextMenuProviders.sort((a, b) => a.weight - b.weight)
}
/** @hidden */
@@ -340,7 +338,26 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
this.configure()
})
const cls: new (..._) => Frontend = {
// Check if the the WebGL renderer is compatible with xterm.js:
// - https://github.com/Eugeny/tabby/issues/8884
// - https://github.com/microsoft/vscode/issues/190195
// - https://github.com/xtermjs/xterm.js/issues/4665
// - https://bugs.chromium.org/p/chromium/issues/detail?id=1476475
//
// Inspired by https://github.com/microsoft/vscode/pull/191795
let enable8884Workarround = false
const checkCanvas = document.createElement('canvas')
const checkGl = checkCanvas.getContext('webgl2')
const debugInfo = checkGl?.getExtension('WEBGL_debug_renderer_info')
if (checkGl && debugInfo) {
const renderer = checkGl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
if (renderer.startsWith('ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero)')) {
enable8884Workarround = true
}
}
const cls: new (..._) => Frontend = enable8884Workarround ? XTermFrontend : {
xterm: XTermFrontend,
'xterm-webgl': XTermWebGLFrontend,
}[this.config.store.terminal.frontend] ?? XTermFrontend
@@ -451,13 +468,14 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
}
async buildContextMenu (): Promise<MenuItemOptions[]> {
let items: MenuItemOptions[] = []
for (const section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(this)))) {
items = items.concat(section)
items.push({ type: 'separator' })
const contexts: CommandContext[] = [{ tab: this }]
// Top-level tab menu
if (this.parent) {
contexts.unshift({ tab: this.parent })
}
items.splice(items.length - 1, 1)
return items
return this.commands.buildContextMenu(contexts, CommandLocation.TabBodyMenu)
}
/**

View File

@@ -46,7 +46,9 @@ export abstract class ConnectableTerminalTabComponent<P extends ConnectableTermi
}
protected onFrontendReady (): void {
this.initializeSession()
this.initializeSession().then(() => {
this.clearServiceMessagesOnConnect()
})
super.onFrontendReady()
}
@@ -57,9 +59,6 @@ export abstract class ConnectableTerminalTabComponent<P extends ConnectableTermi
async initializeSession (): Promise<void> {
this.reconnectOffered = false
this.isDisconnectedByHand = false
if (this.profile.clearServiceMessagesOnConnect) {
this.frontend?.clear()
}
}
/**
@@ -119,7 +118,14 @@ export abstract class ConnectableTerminalTabComponent<P extends ConnectableTermi
async reconnect (): Promise<void> {
this.session?.destroy()
await this.initializeSession()
this.clearServiceMessagesOnConnect()
this.session?.releaseInitialDataBuffer()
}
private clearServiceMessagesOnConnect (): void {
if (this.profile.clearServiceMessagesOnConnect && this.session?.open) {
this.frontend?.clear()
}
}
}

View File

@@ -0,0 +1,180 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import slugify from 'slugify'
import { v4 as uuidv4 } from 'uuid'
import { CommandProvider, Command, CommandLocation, TranslateService, CommandContext, PromptModalComponent, PartialProfile, Profile, ConfigService, NotificationsService, SplitTabComponent } from 'tabby-core'
import { ConnectableTerminalTabComponent } from './api/connectableTerminalTab.component'
import { BaseTerminalTabComponent } from './api/baseTerminalTab.component'
import { MultifocusService } from './services/multifocus.service'
/** @hidden */
@Injectable({ providedIn: 'root' })
export class TerminalCommandProvider extends CommandProvider {
constructor (
private config: ConfigService,
private ngbModal: NgbModal,
private notifications: NotificationsService,
private translate: TranslateService,
private multifocus: MultifocusService,
) {
super()
}
async provide (context: CommandContext): Promise<Command[]> {
const commands: Command[] = []
const tab = context.tab
if (!tab) {
return []
}
if (tab instanceof BaseTerminalTabComponent && tab.enableToolbar && !tab.pinToolbar) {
commands.push({
id: 'terminal:show-toolbar',
group: 'terminal:misc',
label: this.translate.instant('Show toolbar'),
locations: [CommandLocation.TabHeaderMenu, CommandLocation.TabBodyMenu],
run: async () => {
tab.pinToolbar = true
},
})
}
if (tab instanceof BaseTerminalTabComponent && tab.session?.supportsWorkingDirectory()) {
commands.push({
id: 'terminal:copy-current-path',
group: 'terminal:misc',
label: this.translate.instant('Copy current path'),
locations: [CommandLocation.TabHeaderMenu, CommandLocation.TabBodyMenu],
run: async () => tab.copyCurrentPath(),
})
}
commands.push({
id: 'terminal:focus-all-tabs',
group: 'core:panes',
label: this.translate.instant('Focus all tabs'),
locations: [CommandLocation.TabHeaderMenu, CommandLocation.TabBodyMenu],
run: async () => {
this.multifocus.focusAllTabs()
},
})
let splitTab: SplitTabComponent|null = null
if (tab.parent instanceof SplitTabComponent) {
splitTab = tab.parent
}
if (tab instanceof SplitTabComponent) {
splitTab = tab
}
if (splitTab && splitTab.getAllTabs().length > 1) {
commands.push({
id: 'terminal:focus-all-panes',
group: 'terminal:misc',
label: this.translate.instant('Focus all panes'),
locations: [CommandLocation.TabHeaderMenu, CommandLocation.TabBodyMenu],
run: async () => {
this.multifocus.focusAllPanes()
},
})
}
if (tab instanceof BaseTerminalTabComponent) {
commands.push({
id: 'terminal:save-as-profile',
group: 'terminal:misc',
label: this.translate.instant('Save as profile'),
locations: [CommandLocation.TabBodyMenu, CommandLocation.TabHeaderMenu],
run: async () => {
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = this.translate.instant('New profile name')
modal.componentInstance.value = tab.profile.name
const name = (await modal.result.catch(() => null))?.value
if (!name) {
return
}
const options = {
...tab.profile.options,
}
const cwd = await tab.session?.getWorkingDirectory() ?? tab.profile.options.cwd
if (cwd) {
options.cwd = cwd
}
const profile: PartialProfile<Profile> = {
type: tab.profile.type,
name,
options,
}
profile.id = `${profile.type}:custom:${slugify(name)}:${uuidv4()}`
profile.group = tab.profile.group
profile.icon = tab.profile.icon
profile.color = tab.profile.color
profile.disableDynamicTitle = tab.profile.disableDynamicTitle
profile.behaviorOnSessionEnd = tab.profile.behaviorOnSessionEnd
this.config.store.profiles = [
...this.config.store.profiles,
profile,
]
this.config.save()
this.notifications.info(this.translate.instant('Saved'))
},
})
}
if (tab instanceof ConnectableTerminalTabComponent) {
commands.push({
id: 'terminal:disconnect',
label: this.translate.instant('Disconnect'),
group: 'terminal:connection',
locations: [CommandLocation.TabHeaderMenu, CommandLocation.TabBodyMenu],
run: async () => {
setTimeout(() => {
tab.disconnect()
this.notifications.notice(this.translate.instant('Disconnect'))
})
},
})
commands.push({
id: 'terminal:reconnect',
label: this.translate.instant('Reconnect'),
group: 'terminal:connection',
locations: [CommandLocation.TabHeaderMenu, CommandLocation.TabBodyMenu],
run: async () => {
setTimeout(() => {
tab.reconnect()
this.notifications.notice(this.translate.instant('Reconnect'))
})
},
})
}
if (tab instanceof BaseTerminalTabComponent) {
commands.push({
id: 'terminal:copy',
label: this.translate.instant('Copy'),
locations: [CommandLocation.TabBodyMenu],
weight: -2,
run: async () => {
setTimeout(() => {
tab.frontend?.copySelection()
this.notifications.notice(this.translate.instant('Copied'))
})
},
})
commands.push({
id: 'terminal:paste',
label: this.translate.instant('Paste'),
locations: [CommandLocation.TabBodyMenu],
weight: -1,
run: async () => tab.paste(),
})
}
return commands
}
}

View File

@@ -1,6 +1,6 @@
h3.mb-3(translate) Color schemes
.form-line
.form-line.mb-4
.header
.title(translate) Switch color scheme

View File

@@ -1,5 +1,5 @@
import { Component } from '@angular/core'
import { PlatformService } from 'tabby-core'
import { ConfigService, PlatformService } from 'tabby-core'
/** @hidden */
@Component({
@@ -10,6 +10,7 @@ export class ColorSchemeSettingsTabComponent {
constructor (
platform: PlatformService,
public config: ConfigService,
) {
this.defaultTab = platform.getTheme()
}

View File

@@ -53,6 +53,8 @@ export class StreamProcessingSettingsComponent {
{ key: 'cr', name: _('Force CR') },
{ key: 'lf', name: _('Force LF') },
{ key: 'crlf', name: _('Force CRLF') },
{ key: 'implicit_cr', name: _('Implicit CR in every LF') },
{ key: 'implicit_lf', name: _('Implicit LF in every CR') },
]
getInputModeName (key) {

View File

@@ -5,7 +5,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { ToastrModule } from 'ngx-toastr'
import { NgxColorsModule } from 'ngx-colors'
import TabbyCorePlugin, { ConfigProvider, HotkeyProvider, TabContextMenuItemProvider, CLIHandler } from 'tabby-core'
import TabbyCorePlugin, { ConfigProvider, HotkeyProvider, CLIHandler, CommandProvider } from 'tabby-core'
import { SettingsTabProvider } from 'tabby-settings'
import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component'
@@ -30,7 +30,7 @@ import { PathDropDecorator } from './features/pathDrop'
import { ZModemDecorator } from './features/zmodem'
import { TerminalConfigProvider } from './config'
import { TerminalHotkeyProvider } from './hotkeys'
import { CopyPasteContextMenu, MiscContextMenu, LegacyContextMenu, ReconnectContextMenu, SaveAsProfileContextMenu } from './tabContextMenu'
import { TerminalCommandProvider } from './commands'
import { Frontend } from './frontends/frontend'
import { XTermFrontend, XTermWebGLFrontend } from './frontends/xtermFrontend'
@@ -58,11 +58,7 @@ import { DefaultColorSchemes } from './colorSchemes'
{ provide: TerminalDecorator, useClass: ZModemDecorator, multi: true },
{ provide: TerminalDecorator, useClass: DebugDecorator, multi: true },
{ provide: TabContextMenuItemProvider, useClass: CopyPasteContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: MiscContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: LegacyContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: ReconnectContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: SaveAsProfileContextMenu, multi: true },
{ provide: CommandProvider, useExisting: TerminalCommandProvider, multi: true },
{ provide: CLIHandler, useClass: TerminalCLIHandler, multi: true },
{ provide: TerminalColorSchemeProvider, useClass: DefaultColorSchemes, multi: true },

View File

@@ -9,7 +9,7 @@ import { SessionMiddleware } from '../api/middleware'
export type InputMode = null | 'local-echo' | 'readline' | 'readline-hex'
export type OutputMode = null | 'hex'
export type NewlineMode = null | 'cr' | 'lf' | 'crlf'
export type NewlineMode = null | 'cr' | 'lf' | 'crlf' | 'implicit_cr' | 'implicit_lf'
export interface StreamProcessingOptions {
inputMode?: InputMode
@@ -133,7 +133,12 @@ export class TerminalStreamProcessor extends SessionMiddleware {
private replaceNewlines (data: Buffer, mode?: NewlineMode): Buffer {
if (!mode) {
return data
} else if (mode === 'implicit_cr') {
return bufferReplace(data, '\n', '\r\n')
} else if (mode === 'implicit_lf') {
return bufferReplace(data, '\r', '\r\n')
}
data = bufferReplace(data, '\r\n', '\n')
data = bufferReplace(data, '\r', '\n')
const replacement = {

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