Compare commits
1541 Commits
a5b53b0e75
...
img-swipe-
Author | SHA1 | Date | |
---|---|---|---|
|
20ab6193ab | ||
|
d42a81f97c | ||
|
46b9bb7854 | ||
|
fff1dd59c3 | ||
|
f88e95d9be | ||
|
248132dd89 | ||
|
ead37defeb | ||
|
f18cb91ef9 | ||
|
892fe7bd34 | ||
|
0126e5e5a3 | ||
|
b8afa96de5 | ||
|
9c42391706 | ||
|
d8c8bfa8a4 | ||
|
1041d2ae9d | ||
|
a1586694b6 | ||
|
a7aa1ff79d | ||
|
0c7d5c76e2 | ||
|
aa94774963 | ||
|
628fc810c7 | ||
|
fb9b0569b6 | ||
|
dc4612a0e2 | ||
|
e57396040d | ||
|
bafb2cba95 | ||
|
f607c3bc0d | ||
|
0017358f8b | ||
|
0d2bf00810 | ||
|
f362f94c2d | ||
|
c9e716d42f | ||
|
bef466a5a1 | ||
|
f180d22680 | ||
|
18fa33d816 | ||
|
e60796548b | ||
|
0f5f8e163d | ||
|
95e60b0f79 | ||
|
669cd49574 | ||
|
9917be0233 | ||
|
7537192c9a | ||
|
eaa7b91f1d | ||
|
ea989df6a1 | ||
|
166b404ea7 | ||
|
25792b53f2 | ||
|
aad4b449ee | ||
|
5743972a26 | ||
|
be37b6ff8f | ||
|
cd0ca0363e | ||
|
fdcff7a7f0 | ||
|
d9c868b2fe | ||
|
15dbadbfe0 | ||
|
707efac5b9 | ||
|
972eea1efd | ||
|
a77f4045f8 | ||
|
cc3e08ddaa | ||
|
eb17e37002 | ||
|
ecaee2dbbf | ||
|
84e7ddbf74 | ||
|
4f7695b0ce | ||
|
5f726d2b25 | ||
|
e43b9a3d2c | ||
|
34363e6875 | ||
|
79a8080b7d | ||
|
92dacdb386 | ||
|
4fdc28afbc | ||
|
874affb2f2 | ||
|
37819df542 | ||
|
160f7431d6 | ||
|
12824bb680 | ||
|
6af3f2ee7e | ||
|
d7085b119d | ||
|
1b817cd897 | ||
|
e65b72ea41 | ||
|
c9c5dfa8c0 | ||
|
f11ebb032b | ||
|
58e714fce4 | ||
|
ddb77732f2 | ||
|
01ef823da9 | ||
|
1b02426df1 | ||
|
c4021525ac | ||
|
e7189a1260 | ||
|
843bd1cf3c | ||
|
fc151284e4 | ||
|
f6f87f6d5b | ||
|
7543a24ca7 | ||
|
89ab138882 | ||
|
0237b6a872 | ||
|
c22ad7c2e8 | ||
|
26c4d231a8 | ||
|
1026e1f8e9 | ||
|
d6dcededc9 | ||
|
ebe30dceac | ||
|
370bd9a3a8 | ||
|
137927bb43 | ||
|
90cfdebff8 | ||
|
0cde7e7a7f | ||
|
cf63b70997 | ||
|
ad225138b4 | ||
|
68b5be063f | ||
|
bdbe043259 | ||
|
57a229d5fd | ||
|
e23f3a6314 | ||
|
c722d251ff | ||
|
a104de38b6 | ||
|
26093c1ae4 | ||
|
c8fbd51554 | ||
|
bf75e88931 | ||
|
13a3f4772e | ||
|
a3b2cc456f | ||
|
1e6f8c6637 | ||
|
594cba30ca | ||
|
e3bcc79bb7 | ||
|
73230272f3 | ||
|
71a3aefe86 | ||
|
6024b29ea7 | ||
|
ee13cef37f | ||
|
67d013e40a | ||
|
64206d6f47 | ||
|
fc1c767280 | ||
|
d4f6373bbc | ||
|
fa03443fe7 | ||
|
0f8a17b652 | ||
|
070de9df2d | ||
|
34b2ef0fd7 | ||
|
eef9c3ef62 | ||
|
6f0f32d83d | ||
|
7845994315 | ||
|
d94c301b10 | ||
|
67699d9cfa | ||
|
a392593e53 | ||
|
cabd6de85b | ||
|
c03da65821 | ||
|
5d74507e50 | ||
|
19b7deaed0 | ||
|
6aaa533410 | ||
|
96d79ac4e9 | ||
|
b52b11d7bb | ||
|
1cb9287684 | ||
|
0ea64050ff | ||
|
d0068ecbab | ||
|
ca14352972 | ||
|
50a0f41736 | ||
|
7e3946c152 | ||
|
edabd1128b | ||
|
f38898e03f | ||
|
98f92f6270 | ||
|
5d275998ed | ||
|
c3b5382882 | ||
|
de0e65fe13 | ||
|
ff5835278b | ||
|
980ed76cc3 | ||
|
91fe2841e3 | ||
|
b813bcad8a | ||
|
0423cb7ad3 | ||
|
5ff4c457c0 | ||
|
c593c9fe2a | ||
|
e476063f32 | ||
|
95e0be7e9e | ||
|
a9c2af19e3 | ||
|
1a52314812 | ||
|
7de516e5e7 | ||
|
381956652b | ||
|
7fd0f3e2bf | ||
|
bcb2096020 | ||
|
fa699956e6 | ||
|
c9277cec28 | ||
|
e9cf606c70 | ||
|
50f1e3f0f2 | ||
|
4d81dfb085 | ||
|
8161690ce6 | ||
|
02a8c8c460 | ||
|
8565df13e4 | ||
|
35b72cc6e6 | ||
|
6b821409e0 | ||
|
fc94ed64c1 | ||
|
c36607be6f | ||
|
3b9fcfae60 | ||
|
2d2bf48d3d | ||
|
c167890d26 | ||
|
a09b9fa746 | ||
|
fb5f3e0f97 | ||
|
3cb24507a7 | ||
|
5398684ea2 | ||
|
d3263b0e0f | ||
|
06beaccdae | ||
|
17d2771a75 | ||
|
858b750346 | ||
|
f1b50caf1a | ||
|
782d866fcf | ||
|
49db89fef0 | ||
|
507ce78c27 | ||
|
28bad6479c | ||
|
13cfe1650f | ||
|
5d69189f8f | ||
|
c48ecc67b2 | ||
|
3d813e4ef6 | ||
|
8d608bcd72 | ||
|
73d4922d70 | ||
|
383806325a | ||
|
70f762c006 | ||
|
bdbddd4ed3 | ||
|
d14b5e51a9 | ||
|
28fc498ee6 | ||
|
5d255d758e | ||
|
7be6e0d5af | ||
|
7d568dd4e0 | ||
|
0088333ebf | ||
|
c9ebea1d0a | ||
|
59ee2e1302 | ||
|
074f54d995 | ||
|
155956f45b | ||
|
5ecfbf3933 | ||
|
b1acfec825 | ||
|
6e6d1b24eb | ||
|
6e15e4875d | ||
|
0a89d9ca6f | ||
|
810d954d12 | ||
|
64e1fd5f71 | ||
|
590ad6235b | ||
|
696a999238 | ||
|
7522fa2e79 | ||
|
ede9f242af | ||
|
3a2d29b5cb | ||
|
f1f7a14349 | ||
|
108d9fd74f | ||
|
4c242fefe8 | ||
|
55a295f827 | ||
|
a161118308 | ||
|
947a307b25 | ||
|
61132dd7b9 | ||
|
1d995fb92d | ||
|
8aa7ed8635 | ||
|
68db63b629 | ||
|
743f07167c | ||
|
b95dd04fbe | ||
|
afdf56ce68 | ||
|
0bedb6e0ff | ||
|
ccd6a1631a | ||
|
661b84033f | ||
|
45d8cac5a9 | ||
|
8271bf36c7 | ||
|
d788c2fbb5 | ||
|
8a750c6341 | ||
|
868e97804a | ||
|
63b95ef504 | ||
|
385ef46a2b | ||
|
7e8471f28f | ||
|
8fded75069 | ||
|
969156d819 | ||
|
639c0235f9 | ||
|
284bac9b49 | ||
|
af5e9aa518 | ||
|
e91387c60b | ||
|
b3eb6e071f | ||
|
40720971c5 | ||
|
abe55ec905 | ||
|
ea59dcc30e | ||
|
4f224550f6 | ||
|
12335f4860 | ||
|
b2ce76c84c | ||
|
b6af55134a | ||
|
1aae08be5b | ||
|
2461913f85 | ||
|
5555b3e7db | ||
|
76e45abfc6 | ||
|
50e49cd67b | ||
|
16b62d9fb3 | ||
|
14aec43064 | ||
|
76cb34fd06 | ||
|
83e75439ab | ||
|
f33464527b | ||
|
2df140a6a9 | ||
|
eac0d04fd3 | ||
|
73035c1d1c | ||
|
7c72c1d9f3 | ||
|
60e8ffbf90 | ||
|
50ad31f8e8 | ||
|
978b2cdb21 | ||
|
58fe54954a | ||
|
d286fff42c | ||
|
5c146bdd67 | ||
|
9c4bffc487 | ||
|
20b5c962db | ||
|
a8f05c92ae | ||
|
549fae4015 | ||
|
0bc4396427 | ||
|
ea643cce6e | ||
|
f11a834895 | ||
|
f43b42544b | ||
|
b98556855d | ||
|
94441c54ae | ||
|
c6a2b4e429 | ||
|
08e184de26 | ||
|
60448f4ce8 | ||
|
d5056a5563 | ||
|
ae51c39c09 | ||
|
6905fcd0a4 | ||
|
d3006cc720 | ||
|
73786610a6 | ||
|
aaf066699b | ||
|
e312ae6b3b | ||
|
d613e1ee77 | ||
|
c60af6659c | ||
|
02ab882e63 | ||
|
7c7de3d965 | ||
|
02cdec5a10 | ||
|
813ec537cd | ||
|
a20928b02c | ||
|
1ef04ffc4d | ||
|
68eecc77bb | ||
|
b64273ab94 | ||
|
e7fcd0072b | ||
|
6c0538854d | ||
|
cf14b75091 | ||
|
eab4e8aebc | ||
|
2a65688148 | ||
|
22d551be3a | ||
|
4e1cb1eba4 | ||
|
6947ca7433 | ||
|
12ef33bca4 | ||
|
2cfaa034fb | ||
|
e98172bb0e | ||
|
90be2eee71 | ||
|
4aa8672925 | ||
|
acd8b817f4 | ||
|
6541dcbc66 | ||
|
0274d800f9 | ||
|
cf792c8195 | ||
|
5af4217fda | ||
|
fec0e248c5 | ||
|
582b710d3c | ||
|
0776f65193 | ||
|
4edb069bd8 | ||
|
861c502e44 | ||
|
11d56a407d | ||
|
7b55d91d35 | ||
|
8b135f9ca3 | ||
|
422517ec93 | ||
|
5545a425ea | ||
|
eceaa9cacc | ||
|
7def85a174 | ||
|
5955327f7b | ||
|
d28f39d77a | ||
|
8bdc00e0b9 | ||
|
4ab54016ad | ||
|
f0c7ea062b | ||
|
7064ce81c7 | ||
|
20a982491a | ||
|
5f024823a9 | ||
|
092ef26144 | ||
|
19fba66d2c | ||
|
f2e47d9276 | ||
|
b8ebed0f4c | ||
|
db148d5142 | ||
|
c855cd2bf0 | ||
|
82b74628c6 | ||
|
68234cdcef | ||
|
e71427953b | ||
|
5dc8450559 | ||
|
01b0a84b70 | ||
|
e0d1b21006 | ||
|
d2df04550a | ||
|
10a72b8c80 | ||
|
7eff895e88 | ||
|
296037d1c8 | ||
|
ae666c9012 | ||
|
7fc26c1d53 | ||
|
7a54b0cad7 | ||
|
919df98c6e | ||
|
2faaabbf5f | ||
|
26c9c7e56b | ||
|
7249d4470a | ||
|
810bca46a0 | ||
|
e27e045054 | ||
|
76fa90ed9e | ||
|
5a22e64466 | ||
|
6df2dc11f7 | ||
|
8aadada0e2 | ||
|
7f9960fa7a | ||
|
e0f3a22b80 | ||
|
49d1a16a18 | ||
|
ac8c2799b8 | ||
|
ee6202c379 | ||
|
2194bdfd56 | ||
|
bb03c60c39 | ||
|
8f38298f90 | ||
|
9e7f485b65 | ||
|
4a9503c056 | ||
|
f37541d629 | ||
|
caf3a64a0f | ||
|
8bd4fd76ae | ||
|
252ae9f534 | ||
|
a73dfa7586 | ||
|
fb06e7afa1 | ||
|
3cf4be8e85 | ||
|
f2cac8e7f7 | ||
|
4802e4bed2 | ||
|
1a1afd00a1 | ||
|
e7d38d95d0 | ||
|
15769a7643 | ||
|
9b631ed048 | ||
|
7188060ac8 | ||
|
3e26b93971 | ||
|
159852233f | ||
|
a2ecb81378 | ||
|
b12cd9fe05 | ||
|
d21b0f1b5e | ||
|
42f850239f | ||
|
db988411fd | ||
|
3a25550f5b | ||
|
5c79c8e162 | ||
|
30f97e0e64 | ||
|
938c8a9a36 | ||
|
13f76c974e | ||
|
afbe21b6b4 | ||
|
d32adb8d1d | ||
|
6e5db5c41a | ||
|
a7d7b6fb0f | ||
|
1adde74f38 | ||
|
1ad3f3d6c7 | ||
|
0cc0d6763e | ||
|
e8cdad0bf2 | ||
|
b0a2f241d2 | ||
|
29c71fe8f1 | ||
|
f755c3d4cb | ||
|
9c3e8c935b | ||
|
bfc609c2a8 | ||
|
4c7ede67f3 | ||
|
b17fdcbfd9 | ||
|
db500188d8 | ||
|
aadae85a2a | ||
|
cb6adc30ce | ||
|
bdbcf8623e | ||
|
e35217e7e3 | ||
|
aca1cb7f99 | ||
|
07160e0e60 | ||
|
179153ae67 | ||
|
94f53835f4 | ||
|
ab4d296b22 | ||
|
8ad7b5dcc5 | ||
|
00bb36f764 | ||
|
73784642d2 | ||
|
2b28065c9f | ||
|
eb31d7baa2 | ||
|
3f03936125 | ||
|
3f5b63bba0 | ||
|
7571552fef | ||
|
f6fe5fea77 | ||
|
3574527780 | ||
|
2834681a4b | ||
|
7ea2c5f8cf | ||
|
19e2a2f7d2 | ||
|
a58e026a40 | ||
|
a40f568409 | ||
|
bad806312d | ||
|
3bb8b887e1 | ||
|
135bf8a55b | ||
|
3d8a897c19 | ||
|
bd6da695c8 | ||
|
531999dc04 | ||
|
58bbfc0d4e | ||
|
380bd4ef4b | ||
|
bb64e9b5c5 | ||
|
1ef5154770 | ||
|
57aa820dc3 | ||
|
c12f26441e | ||
|
e4269f5d1d | ||
|
947d4f215e | ||
|
826e4f6d16 | ||
|
0f46128980 | ||
|
1a4bcbb794 | ||
|
441e5c6f7e | ||
|
da3b620f74 | ||
|
fa4a75215b | ||
|
0cdc389794 | ||
|
434bdab585 | ||
|
ce67f3a658 | ||
|
277fc00f38 | ||
|
36a3a7d615 | ||
|
d15d49b295 | ||
|
87afb1633b | ||
|
e5e2c9fe49 | ||
|
580856064e | ||
|
1a5b1f77d7 | ||
|
f5d68f1cd9 | ||
|
2e77171137 | ||
|
ab27b29819 | ||
|
231068f729 | ||
|
7b65427236 | ||
|
9f21f7771c | ||
|
1c0ca414b9 | ||
|
4f0921856f | ||
|
994d69508b | ||
|
1ad3a2b968 | ||
|
cd2d6e85e0 | ||
|
058c86f3c1 | ||
|
a771dd5478 | ||
|
baa4632071 | ||
|
ebe877e6b6 | ||
|
1156b648eb | ||
|
ec49b19aff | ||
|
75aec77271 | ||
|
7348e0274d | ||
|
362470da18 | ||
|
4d323ec76f | ||
|
0039b48d1b | ||
|
050e65861c | ||
|
a434d217cc | ||
|
890d10d811 | ||
|
1723ce0f22 | ||
|
b3688087d5 | ||
|
bcea4248c4 | ||
|
9590127bae | ||
|
eb6a158781 | ||
|
cc369d25c5 | ||
|
59928d37ff | ||
|
1f41124844 | ||
|
3d492523e2 | ||
|
fc488bd4fe | ||
|
fd38ca503a | ||
|
9a15890745 | ||
|
37d9d4c253 | ||
|
bae02a44ed | ||
|
23f0b6ed09 | ||
|
c87e203b4a | ||
|
dd50f49176 | ||
|
c37c9051a6 | ||
|
8a4cf86b65 | ||
|
a2a15b9978 | ||
|
96d6a6df07 | ||
|
dbbf069e85 | ||
|
d276d23310 | ||
|
c98d241f3c | ||
|
961a71877b | ||
|
13e38c7c86 | ||
|
61e056004a | ||
|
b029ae98dc | ||
|
f5bfbce0ad | ||
|
a4c124dff0 | ||
|
2445b6d9dc | ||
|
ad8f0f564f | ||
|
c47d997a2d | ||
|
dd55b2770a | ||
|
83f74a5d22 | ||
|
09aaa9181c | ||
|
5477586ce4 | ||
|
76becb43ae | ||
|
b033b98532 | ||
|
412d638e9e | ||
|
6e0ed8552f | ||
|
dd7391caaf | ||
|
f101dd571f | ||
|
1a52d3c293 | ||
|
d6bf3439b4 | ||
|
54a9e0afee | ||
|
5de2f8ea2d | ||
|
93f3334ad0 | ||
|
25a2582d15 | ||
|
d076a210a1 | ||
|
b5fc7d6d4d | ||
|
a204325136 | ||
|
0decd4d1b6 | ||
|
34db46d84b | ||
|
c2377f0c13 | ||
|
829888bda7 | ||
|
43f524bb5f | ||
|
34d17a4fcb | ||
|
340c03cedf | ||
|
5085f6cdc9 | ||
|
798f8d92a3 | ||
|
d4061cc139 | ||
|
93b6612c75 | ||
|
48dfee39ae | ||
|
6c0ea67d3d | ||
|
58b8e7908d | ||
|
4e94e83540 | ||
|
d1018a824c | ||
|
4c8ae0afd3 | ||
|
d9b2311e17 | ||
|
21af0243d6 | ||
|
63e3816e92 | ||
|
d60609716b | ||
|
76bd2547e1 | ||
|
ee101353d8 | ||
|
d5bdf1cb90 | ||
|
c8b103a9e8 | ||
|
c3dd3e246e | ||
|
47b06b4978 | ||
|
ad845b5fbf | ||
|
c7958a4bb8 | ||
|
aee8441fc4 | ||
|
703e876f4a | ||
|
d4e77280fc | ||
|
31f19d0d8a | ||
|
32ec475ca2 | ||
|
e8d8cebd8e | ||
|
d48db9aded | ||
|
33fa5aaab8 | ||
|
c501673241 | ||
|
0792c17f55 | ||
|
9697322f1e | ||
|
d8eeab0c00 | ||
|
b2bd73fa78 | ||
|
6e4a51b37f | ||
|
8b4414b799 | ||
|
a2cfcd4ca6 | ||
|
0bf18e7413 | ||
|
5e540f4f97 | ||
|
f83dccda39 | ||
|
98ea463e0e | ||
|
d5959a4681 | ||
|
c886de5deb | ||
|
c8e05a34d6 | ||
|
d94ac48b65 | ||
|
5886bb6b3a | ||
|
8387431534 | ||
|
754a14ff3e | ||
|
ca7d2aeec3 | ||
|
28ba262087 | ||
|
23d2c40e05 | ||
|
4094887624 | ||
|
4492828b9f | ||
|
a2aef5ea4a | ||
|
cc401b2c9d | ||
|
95a31cdd98 | ||
|
d1ec9eb8ab | ||
|
0bcf8b5d21 | ||
|
f32938981c | ||
|
25d1db3852 | ||
|
9d3ad0d69d | ||
|
3ec3d71c5f | ||
|
79b8229b1b | ||
|
06303bb62f | ||
|
1acee3d4c9 | ||
|
b6d6727135 | ||
|
92a83ed01b | ||
|
f85e464ffd | ||
|
852ec86e26 | ||
|
72ae3aa33d | ||
|
d35bd3b073 | ||
|
b074f9fa89 | ||
|
ed46b96ba2 | ||
|
acf71fd702 | ||
|
5f564343ec | ||
|
dfb062af41 | ||
|
d9bb5e6b1f | ||
|
363d8a4121 | ||
|
d9fc76f336 | ||
|
e2c3af2114 | ||
|
7aa9b857c2 | ||
|
327f4b1074 | ||
|
4a58948b27 | ||
|
1f206c3a36 | ||
|
c9144cd824 | ||
|
dd2154c19b | ||
|
dade4eafa5 | ||
|
4f63b471d1 | ||
|
16bb9b3679 | ||
|
6ececb2ceb | ||
|
6edbb23903 | ||
|
50baaaae81 | ||
|
da531f12c2 | ||
|
ba0e852f20 | ||
|
d0ebac37c1 | ||
|
3f9af45493 | ||
|
fd3c427f07 | ||
|
524ecf8acd | ||
|
c4be4d7d61 | ||
|
89a16f2030 | ||
|
1dfc09e4d2 | ||
|
bfd57b66ef | ||
|
71e1fc91f1 | ||
|
14703846a7 | ||
|
5494e89fdb | ||
|
4ca55d3b9b | ||
|
5aa82eda2b | ||
|
d9f2ee0d48 | ||
|
ff83ae975d | ||
|
02130b848c | ||
|
900c0caffa | ||
|
4e74fd0467 | ||
|
6fe26f7f77 | ||
|
fb83a3ca3f | ||
|
14c3dae180 | ||
|
50869757d3 | ||
|
aecbc48d43 | ||
|
0c8a11e28b | ||
|
ffeb6b45aa | ||
|
76d1661768 | ||
|
a14e3b0657 | ||
|
2d335e27ff | ||
|
8fb95f9a84 | ||
|
a5399b6614 | ||
|
199be15f4b | ||
|
055a6527fc | ||
|
842b59605b | ||
|
3818290e4d | ||
|
c5dad20fc4 | ||
|
e5e931356b | ||
|
e7c799ae2a | ||
|
6deaa31d41 | ||
|
1f0aa29307 | ||
|
eeaec2697b | ||
|
630c7980d3 | ||
|
890c0c4723 | ||
|
9c31c21d79 | ||
|
1ea2134936 | ||
|
b35a746470 | ||
|
d26f99b496 | ||
|
a1abe14e02 | ||
|
ae9296f989 | ||
|
ea1d9e1d1a | ||
|
b8821acb95 | ||
|
c11e64a782 | ||
|
cc7355358d | ||
|
d2cc8b36b8 | ||
|
3fe3430006 | ||
|
fb2ee756dd | ||
|
25ffc4ac4a | ||
|
5c30244627 | ||
|
72e1dcb3f9 | ||
|
a2a6afb731 | ||
|
e59114c1c5 | ||
|
6180210170 | ||
|
2b98e96784 | ||
|
364078ce27 | ||
|
fda64ffb1f | ||
|
5257a45bde | ||
|
9a03aac224 | ||
|
f155cc7e92 | ||
|
cee7170763 | ||
|
a969d34c03 | ||
|
515a5f6943 | ||
|
47bb7ad6a1 | ||
|
7d937b36da | ||
|
9243a68b18 | ||
|
371208c24d | ||
|
26030f6ee4 | ||
|
5bd3d9a518 | ||
|
9710d88a88 | ||
|
a83e7318b0 | ||
|
ae376b4195 | ||
|
f7eab66026 | ||
|
9de142b9ad | ||
|
67a4d10b75 | ||
|
56c9b21a28 | ||
|
94af9fc1a3 | ||
|
4bf3bd8343 | ||
|
753a99faf9 | ||
|
9ecf261a76 | ||
|
dfc2eb32c8 | ||
|
2a904c4aea | ||
|
2a322faa6a | ||
|
e4dda3c488 | ||
|
07ef5122bb | ||
|
578c3dda73 | ||
|
0c121ee95a | ||
|
3a6d5faa8a | ||
|
44343e8ec9 | ||
|
198fbe1a1f | ||
|
2318df8b74 | ||
|
198d10e759 | ||
|
73393a5d5e | ||
|
cbeb7ddcec | ||
|
3d817352ec | ||
|
1df209c284 | ||
|
f9324c74cd | ||
|
80b29ed5cb | ||
|
4b2575f301 | ||
|
4e7326b61b | ||
|
e3f0a8d35b | ||
|
e5db40cf2d | ||
|
a1cacbe904 | ||
|
c32e0bdde7 | ||
|
7bc8087d02 | ||
|
91b2dc57fa | ||
|
7fc0ddb60c | ||
|
d0abba23dc | ||
|
15a3cfcb8a | ||
|
ee57675c12 | ||
|
249e2555d0 | ||
|
a6a7810be2 | ||
|
9e8fd3f5a0 | ||
|
cd05650164 | ||
|
d5f6ecf3c3 | ||
|
7f321c9cf6 | ||
|
4f456b2b80 | ||
|
6dde068e71 | ||
|
2aa1dd41f5 | ||
|
26feb448a3 | ||
|
0c9676e7fc | ||
|
bab8a09a80 | ||
|
b0e80137da | ||
|
2344d98e20 | ||
|
35e8561bff | ||
|
6081b9f0ce | ||
|
552a418bae | ||
|
0c9b301a57 | ||
|
3a8a329b0f | ||
|
63e7acb87b | ||
|
145136059e | ||
|
283ceb6bbf | ||
|
6348d1f19a | ||
|
d316d51c0b | ||
|
d616dfef38 | ||
|
84a8a2bc2b | ||
|
0fb9884ab8 | ||
|
0a413d63aa | ||
|
7063af7363 | ||
|
6fc342d446 | ||
|
3d6f48786d | ||
|
65ad79adce | ||
|
fad4e4e75e | ||
|
3b8fd6f62f | ||
|
abe240397d | ||
|
8b5e0df2d7 | ||
|
2b919d0cf2 | ||
|
a03193b2f7 | ||
|
a5a8f6057b | ||
|
fd1fdc6466 | ||
|
ef127df623 | ||
|
3282c9426c | ||
|
5c34c93a84 | ||
|
239c3f1db7 | ||
|
913509f887 | ||
|
1f116d9afe | ||
|
2cfb9e8dab | ||
|
8448d6c6e6 | ||
|
9f54adbeb4 | ||
|
6d43eea1bd | ||
|
312969462e | ||
|
999da4945a | ||
|
bf294aa684 | ||
|
a58476d079 | ||
|
adede8b6be | ||
|
65e32f720d | ||
|
35ab677ff1 | ||
|
bfedf20db5 | ||
|
a7516937f7 | ||
|
a42337ad0a | ||
|
c9ab987658 | ||
|
eb798fa4f1 | ||
|
17d4175b47 | ||
|
45d4d1bb3e | ||
|
8fc880b69b | ||
|
30426d21e7 | ||
|
9aac5a22f1 | ||
|
96143177ce | ||
|
a072951102 | ||
|
c9a1a3eb94 | ||
|
44ade6ad64 | ||
|
44ad69ceca | ||
|
f78bf5e46f | ||
|
94ed548353 | ||
|
6099ffece1 | ||
|
347a515c25 | ||
|
9e54070c1d | ||
|
9a79c6b1a4 | ||
|
3fc4207cdb | ||
|
ef73ab43da | ||
|
2ff1957ca8 | ||
|
0141a60eb8 | ||
|
2253990898 | ||
|
076e5e3186 | ||
|
2d8da60ffc | ||
|
5ff402aabf | ||
|
e07faea874 | ||
|
a5dc505e61 | ||
|
538d66191e | ||
|
928487985d | ||
|
e1bf781b10 | ||
|
608e1c195b | ||
|
9d73189133 | ||
|
536d4218c2 | ||
|
e3885c2b5c | ||
|
9250be348d | ||
|
7c12a286c3 | ||
|
7454532641 | ||
|
8d35ca90e1 | ||
|
24c16f622f | ||
|
9a2968d1eb | ||
|
0937f44f39 | ||
|
91dabeff53 | ||
|
7c9b347116 | ||
|
075368b5ae | ||
|
a611a3ac59 | ||
|
90459116e3 | ||
|
d4672b3517 | ||
|
bbf28c74f7 | ||
|
bbd85fc823 | ||
|
291a5f42cd | ||
|
1dd73e74ab | ||
|
03c98fb55a | ||
|
7f9b139ae0 | ||
|
6aaeb754ef | ||
|
144277bdcc | ||
|
823b9db6f6 | ||
|
adad1fde19 | ||
|
8b2d97b946 | ||
|
515f78619f | ||
|
71be63dbb1 | ||
|
a503f58d0c | ||
|
afae8d02be | ||
|
6fef696268 | ||
|
e4290140bc | ||
|
7c93acedc3 | ||
|
ae29f06e44 | ||
|
a2f71d387f | ||
|
8f18d35109 | ||
|
f1923c5364 | ||
|
636c8cb165 | ||
|
513ea97769 | ||
|
93b18e6440 | ||
|
11882827c7 | ||
|
9f1d431c99 | ||
|
d45e9a0c30 | ||
|
2b00cdce7b | ||
|
636e79c438 | ||
|
1641b1f91f | ||
|
7877e6601d | ||
|
08b6ee0297 | ||
|
d7bb92be54 | ||
|
cc010643ad | ||
|
d87b925488 | ||
|
5e396e2a91 | ||
|
4fdff9fce2 | ||
|
4d18ddba6d | ||
|
a53ebe7572 | ||
|
df28c2c676 | ||
|
b5a6199784 | ||
|
75f36b992d | ||
|
6e2b5d5dc8 | ||
|
f98d27f187 | ||
|
af987143b7 | ||
|
2723d3b73b | ||
|
0441a8725f | ||
|
ac455ebb45 | ||
|
8acba00655 | ||
|
94d69b764a | ||
|
e7bcac0171 | ||
|
1f9fa74786 | ||
|
a06270fc85 | ||
|
c1535f1b34 | ||
|
6b494af146 | ||
|
beced225a3 | ||
|
776dedea82 | ||
|
08a4cee48f | ||
|
78e67080c9 | ||
|
bb0c662713 | ||
|
fb15480f6b | ||
|
f8c6a62c23 | ||
|
eee45281ea | ||
|
3770410bed | ||
|
15cc825f43 | ||
|
5734722c5d | ||
|
aaeb26e2b7 | ||
|
3674c9d020 | ||
|
5120b8fbf5 | ||
|
255e75c6cf | ||
|
74fc259c9c | ||
|
0773a86922 | ||
|
749c5df29a | ||
|
82422b4500 | ||
|
4322197aba | ||
|
4ebff0ffcc | ||
|
7e691143d0 | ||
|
f840d63bdb | ||
|
e38cd31ca7 | ||
|
218f198ec6 | ||
|
d78c8b7cc8 | ||
|
977e7a40bc | ||
|
d769798ba3 | ||
|
867a9950d5 | ||
|
6ab79ae689 | ||
|
40d29bd453 | ||
|
1f66bc7756 | ||
|
b177affd81 | ||
|
89c984830b | ||
|
1d5cf8d25c | ||
|
1dccb08cd6 | ||
|
f462436450 | ||
|
fc5debc660 | ||
|
b89d41a701 | ||
|
3455da404a | ||
|
0f45ebda03 | ||
|
4c1c62a56b | ||
|
7f5ce54b1f | ||
|
1528e2afed | ||
|
a66f9bf494 | ||
|
faaa4ba6bc | ||
|
aa10dd98c9 | ||
|
a62fa3b073 | ||
|
9f98bee362 | ||
|
f372e1a69d | ||
|
5b5b9a91aa | ||
|
b43ac187ec | ||
|
adc5940d15 | ||
|
e33c3771f5 | ||
|
d78577c46d | ||
|
2ab59f5a7a | ||
|
1807af355b | ||
|
efeedc1274 | ||
|
f869b26664 | ||
|
7a2276c176 | ||
|
b604588638 | ||
|
a585f3abcc | ||
|
0a03793d7b | ||
|
667ab77651 | ||
|
9be04fd69f | ||
|
ba73d278ae | ||
|
a8b5f8a95f | ||
|
45e7edc9b8 | ||
|
874127a4f9 | ||
|
d177314676 | ||
|
bab4f21056 | ||
|
188a043967 | ||
|
5e881e5944 | ||
|
23779fe565 | ||
|
d1f1299d43 | ||
|
126e4fa698 | ||
|
2b3e44cca3 | ||
|
5ea8309a30 | ||
|
1557dec2bc | ||
|
de8ecc6903 | ||
|
5b37d22e2d | ||
|
7b5baad5cd | ||
|
d791b54528 | ||
|
49fb2f4d79 | ||
|
41a0d6919f | ||
|
68d8d322a9 | ||
|
d7b3a56c3d | ||
|
81841ca2a6 | ||
|
5af7852465 | ||
|
57d6938d6c | ||
|
d4f23de003 | ||
|
c22ed52c72 | ||
|
6029b51f7e | ||
|
8bc515c6a1 | ||
|
f91e1b3d2f | ||
|
b66c4d7206 | ||
|
9062b6bc4d | ||
|
0f03dcfc0f | ||
|
2103e6238c | ||
|
b6e7f4f493 | ||
|
d13ec29158 | ||
|
96cd683d0e | ||
|
c7cbeed9bb | ||
|
9264008766 | ||
|
9db9c5c9ca | ||
|
efa80267f6 | ||
|
989f5a8692 | ||
|
8623d1198d | ||
|
e75d03fea9 | ||
|
48be0ceb16 | ||
|
0e3ff1699a | ||
|
7f5dc72161 | ||
|
5a617f60f5 | ||
|
18243fe879 | ||
|
446a9adcf1 | ||
|
7fdeeb0fae | ||
|
6552038712 | ||
|
0bda86c352 | ||
|
8514ac29fc | ||
|
c2caad3904 | ||
|
fae11fc04a | ||
|
81cb3430bb | ||
|
0a8fae06c2 | ||
|
77bee453ab | ||
|
590e52442c | ||
|
dd273a7727 | ||
|
02900520c9 | ||
|
eff4da42c5 | ||
|
dea4a63022 | ||
|
2f5f9a437d | ||
|
68437ed81c | ||
|
8ed2721ddd | ||
|
97f6dcace0 | ||
|
fc4fecf0fd | ||
|
40b05bb6b1 | ||
|
2d4bae17cc | ||
|
d0e1c3287a | ||
|
b7a96b3143 | ||
|
612fda4cfc | ||
|
beb4328714 | ||
|
5db7a9cf1e | ||
|
e99f918454 | ||
|
102d170752 | ||
|
6768264514 | ||
|
a867b2f85a | ||
|
f246bc5ac6 | ||
|
2c5cffe6be | ||
|
f9e3666d23 | ||
|
72e0f8ccc5 | ||
|
ee6eb5572d | ||
|
dec4a7d31e | ||
|
e45d2252aa | ||
|
1d22cd7592 | ||
|
ac4a0e8af5 | ||
|
8a321a7450 | ||
|
092d11bbe6 | ||
|
cf8bb8817b | ||
|
d956e0ebdc | ||
|
9e6db659d9 | ||
|
7c879a3abc | ||
|
e9c9dda3fb | ||
|
569f9a2091 | ||
|
8508c4bf9b | ||
|
4698b41d26 | ||
|
f47c98f85d | ||
|
48e5c11f9b | ||
|
8a55cd776f | ||
|
f43f057b07 | ||
|
6d0f58c862 | ||
|
b4c275f9e4 | ||
|
170378e615 | ||
|
97dc041777 | ||
|
ca62db2fbd | ||
|
5b4adbacba | ||
|
56da6eb39d | ||
|
75485f2d7d | ||
|
b4e5cfe797 | ||
|
9ad9877d3e | ||
|
227201a5fc | ||
|
d58f471cc3 | ||
|
d46a551d78 | ||
|
93e0efa241 | ||
|
6432adaf3c | ||
|
8bf78ce9cb | ||
|
2109a7bda1 | ||
|
fba02d69fa | ||
|
7896e81986 | ||
|
6b587c1160 | ||
|
e5989e0118 | ||
|
e34d777e11 | ||
|
71fc73ce37 | ||
|
245b9384bc | ||
|
4ee0375120 | ||
|
d463677328 | ||
|
de6c8c1501 | ||
|
e0af5ff353 | ||
|
8447c7e637 | ||
|
f416b6cd54 | ||
|
e9260e8809 | ||
|
e92d49377f | ||
|
f27b3361e5 | ||
|
f67abf9e03 | ||
|
ca9d5c2fd8 | ||
|
a2355ab2ef | ||
|
7c40834eb7 | ||
|
b834b71c69 | ||
|
b4aadff649 | ||
|
7baf7da90d | ||
|
8a80b43c52 | ||
|
8454583131 | ||
|
5da312356a | ||
|
cfa4bcc1b8 | ||
|
421402615a | ||
|
7db2042b7b | ||
|
3a29756109 | ||
|
ec0f57a8eb | ||
|
ad19a800ce | ||
|
e1b6eab9eb | ||
|
2ca70090aa | ||
|
69f8d02c53 | ||
|
44833b665e | ||
|
e37a4b982a | ||
|
cdb31699d4 | ||
|
c9db7a1574 | ||
|
0ded442bd3 | ||
|
4c7d160d41 | ||
|
662f0e9c73 | ||
|
7744be3319 | ||
|
07cff878e5 | ||
|
dd6dcf1c5b | ||
|
0382afc488 | ||
|
19eae8cb49 | ||
|
1a1ab1d18a | ||
|
c3ad87cea1 | ||
|
d8b738d73e | ||
|
7edc6b4123 | ||
|
af21c92bd6 | ||
|
3596ba6d38 | ||
|
e7d3351c1d | ||
|
7a7d6a500d | ||
|
35913e2dfb | ||
|
57a7d549c0 | ||
|
149de7d257 | ||
|
6a76ebe747 | ||
|
aaf0f24d60 | ||
|
c4f119ebf9 | ||
|
39cfb35c1a | ||
|
77f5f00151 | ||
|
08baa1f9ae | ||
|
59772bfd27 | ||
|
a82c05a8ac | ||
|
6286eb5827 | ||
|
7885739a55 | ||
|
bba36e2145 | ||
|
90ff4c7308 | ||
|
29acc2e2db | ||
|
0d8977d688 | ||
|
d14f2f3c77 | ||
|
77414045d9 | ||
|
4fa8e0a89c | ||
|
c42a7739d6 | ||
|
b5eb2b5150 | ||
|
27f8768141 | ||
|
844d8bdee7 | ||
|
f92f8f4a84 | ||
|
4a4e02450c | ||
|
ae79616c73 | ||
|
9c0993908a | ||
|
647b89f8ad | ||
|
591a61a61c | ||
|
4a8b47a6ff | ||
|
1689baa2a4 | ||
|
ca283c0da6 | ||
|
0d79bb6f6d | ||
|
e33e0b1e64 | ||
|
9e049f44e2 | ||
|
0bc0569932 | ||
|
e861b18992 | ||
|
26c0b620f8 | ||
|
324eb695f5 | ||
|
b5139e3ff9 | ||
|
38b1c26396 | ||
|
418a2564b2 | ||
|
8d0261bab3 | ||
|
dc3b18de94 | ||
|
b0cb982978 | ||
|
7f2cf6f7e6 | ||
|
0cb82b3288 | ||
|
28c7dbbe1b | ||
|
c89804677a | ||
|
0b43717931 | ||
|
540d93592b | ||
|
7adc6d38e2 | ||
|
09dd9762f7 | ||
|
7490357d9e | ||
|
1a16957519 | ||
|
83e677d6cb | ||
|
8394b97600 | ||
|
c4a92c95e6 | ||
|
650853eabb | ||
|
71050ef1d2 | ||
|
d166ccf455 | ||
|
5eff49f442 | ||
|
616fc34826 | ||
|
404a217622 | ||
|
7f94cb4bee | ||
|
f0b124221c | ||
|
3f7b91a4eb | ||
|
17df259afd | ||
|
964437ed13 | ||
|
6044aebe1f | ||
|
1ebaf18210 | ||
|
352a8e9a61 | ||
|
0f93caa427 | ||
|
e6107ad447 | ||
|
c3a12cc1a2 | ||
|
7bb37f129d | ||
|
78a1397a3c | ||
|
713443d234 | ||
|
d9101ce679 | ||
|
5739efc59b | ||
|
71d2530329 | ||
|
2c0895bd7d | ||
|
6033c38b19 | ||
|
107e2e0ed0 | ||
|
2796d5dcde | ||
|
ba7e34c195 | ||
|
c51e27fb69 | ||
|
f056e6a89c | ||
|
f794b7621f | ||
|
21ee072677 | ||
|
d07ee76784 | ||
|
252043ae11 | ||
|
85ce522270 | ||
|
2fbe689605 | ||
|
1f22b9c6bc | ||
|
222edd5c36 | ||
|
f649e4698b | ||
|
d27d750cb2 | ||
|
f1bc217e79 | ||
|
73614f2f8d | ||
|
d7328af4c8 | ||
|
94de9411b6 | ||
|
4232f6c5f4 | ||
|
1dd97c139e | ||
|
7e7b3e30c4 | ||
|
e83182c03b | ||
|
f3c12fb926 | ||
|
d5ed0f6cdf | ||
|
503c3ad22b | ||
|
6193eb14da | ||
|
372ac26080 | ||
|
00363cc206 | ||
|
dbc78c1c42 | ||
|
8753ae34be | ||
|
a6f37880e2 | ||
|
7eacdac665 | ||
|
0819588e7a | ||
|
0180e01c25 | ||
|
b094a355c0 | ||
|
2ef9f5d748 | ||
|
247a23bda9 | ||
|
0ea4494dea | ||
|
d8b1fd3b0b | ||
|
3f253f42f2 | ||
|
0e3b4335eb | ||
|
ce536201e6 | ||
|
12cc607754 | ||
|
266b181d49 | ||
|
2d66b7204a | ||
|
e49301308c | ||
|
4c3b987ee4 | ||
|
d16f5a24f4 | ||
|
43feffdfae | ||
|
9ea8fc92e4 | ||
|
9cab0618b6 | ||
|
58213d0ab0 | ||
|
954ed6c2b2 | ||
|
df5f69dc66 | ||
|
e762405cba | ||
|
6fce056b8c | ||
|
b8fc9f2194 | ||
|
713c05f808 | ||
|
e960ae64c5 | ||
|
8811010c73 | ||
|
e15e6dc3bd | ||
|
756f88b5aa | ||
|
5c1a9a3003 | ||
|
a7e8d00145 | ||
|
103251070f | ||
|
1ef25d6176 | ||
|
0e5100180b | ||
|
cd0b834291 | ||
|
f9eb720f2a | ||
|
6f4350b3a7 | ||
|
294b15976c | ||
|
3167019faf | ||
|
d1932f4cb5 | ||
|
e7b53dcb46 | ||
|
205f1d7adb | ||
|
47dea8159e | ||
|
79e3dda1df | ||
|
fa62326eeb | ||
|
10835de6e2 | ||
|
5c82ccf435 | ||
|
b94ed54283 | ||
|
f05ad26969 | ||
|
cf1b98e25d | ||
|
c4c9f43a60 | ||
|
67cb89f634 | ||
|
a64c8ade9d | ||
|
0090d68559 | ||
|
d9e0df0884 | ||
|
7b0d854fe6 | ||
|
9e8277882c | ||
|
5f8989437e | ||
|
f677b914f7 | ||
|
c05265d1a1 | ||
|
363c36da9c | ||
|
3698f40709 | ||
|
16c2183fd0 | ||
|
3be17e2ed8 | ||
|
00006aa072 | ||
|
62be0939d0 | ||
|
bc94ff7800 | ||
|
84bc14dfe5 | ||
|
0e81fb6a4a | ||
|
4bf58ca2d5 | ||
|
003d17b2c5 | ||
|
58ac746442 | ||
|
19c18d54f5 | ||
|
9c08f20e06 | ||
|
e773678f2d | ||
|
01dec6466c | ||
|
bcfb07de5e | ||
|
df8e0ba923 | ||
|
5a01eb8eb1 | ||
|
f5088b398f | ||
|
3c82d961bd | ||
|
c5b3ce0d5c | ||
|
050f485a5b | ||
|
2922f19a2a | ||
|
cc73a45d1f | ||
|
bcbfcb87b5 | ||
|
66f02f59c0 | ||
|
323b9407df | ||
|
3ed5d892f7 | ||
|
d2a39f7de8 | ||
|
b500406c2f | ||
|
099744b298 | ||
|
024213a8e4 | ||
|
c268713d84 | ||
|
1d0664a197 | ||
|
ece0cc9080 | ||
|
5166720f07 | ||
|
60caa67667 | ||
|
d9ee8aa3dc | ||
|
7a463708bd | ||
|
f98f83471a | ||
|
c842c6f238 | ||
|
9a13128398 | ||
|
210fac321b | ||
|
7098e17d22 | ||
|
e21931b6eb | ||
|
12db782a30 | ||
|
1d3abf54a5 | ||
|
1ecc65f5fe | ||
|
87535c6ec8 | ||
|
0638953a20 | ||
|
126616d539 | ||
|
83965fb611 | ||
|
c33649753b | ||
|
abe51682c8 | ||
|
84d2530c52 | ||
|
bea991b665 | ||
|
3849908fe1 | ||
|
bf4357774d | ||
|
54ca9477dd | ||
|
8574a5dd27 | ||
|
f6b9cd970d | ||
|
add108b821 | ||
|
a1115ab4ff | ||
|
b8a9a55246 | ||
|
51f89aaf7b | ||
|
0849cfca98 | ||
|
485e9e2eaa | ||
|
3ae858113b | ||
|
192a1f4014 | ||
|
0da4590597 | ||
|
3ed095bb0e | ||
|
22ea5f3c3c | ||
|
c78cb3b463 | ||
|
1a8e37d3a5 | ||
|
d5221760a3 | ||
|
dce63f52c0 | ||
|
d6f34f7b2c | ||
|
073b76a693 | ||
|
9c43999e4b | ||
|
8663c88ae8 | ||
|
7b732edf61 | ||
|
77841dbc21 | ||
|
3502bfcaa0 | ||
|
f5f60e269e | ||
|
7dfba69fc1 | ||
|
4cf5d1535e | ||
|
7f9766c918 | ||
|
e55748fe92 | ||
|
a137c23116 | ||
|
63f9f33e20 | ||
|
3dd1e25a3b | ||
|
23a10fdc22 | ||
|
373a0ad321 | ||
|
960db2d59b | ||
|
3d8f8d90c3 | ||
|
41a3035a2a | ||
|
a702dab68b | ||
|
efe25ddc04 | ||
|
a7c8b93652 | ||
|
23e59a1189 | ||
|
e9fc488661 | ||
|
2ef095c273 | ||
|
e6be28acea | ||
|
fb1f890974 | ||
|
8ef49b40b2 | ||
|
79700fd983 | ||
|
8de1d26eaa | ||
|
69da293fb9 | ||
|
cb21162558 | ||
|
bab9d3c74b | ||
|
9960db0ae2 | ||
|
4466da63bc | ||
|
7ce2841588 | ||
|
c3f988f246 | ||
|
80c8e83f09 | ||
|
86b4247767 | ||
|
36051fa5db | ||
|
980ebb2fbc | ||
|
1c803972cd | ||
|
82dff4f204 | ||
|
af582f43a6 | ||
|
b08cdffc64 | ||
|
ce34f14f19 | ||
|
ade6980037 | ||
|
de3f340a55 | ||
|
39c3924b3f | ||
|
8e94589f83 | ||
|
66a862f797 | ||
|
c930a66d81 | ||
|
89ec8fd23a | ||
|
d1a654f41f | ||
|
a86735d743 | ||
|
56c99000c4 | ||
|
4a7a11dfd5 | ||
|
8e20ebb534 | ||
|
04b68d2cce | ||
|
c3c16ea0d6 | ||
|
8b7a14f895 | ||
|
2f7bc7ca8d | ||
|
a444a782e2 | ||
|
0bebf02c97 | ||
|
7fbff41329 | ||
|
53514b5e1a | ||
|
c0b37631bc | ||
|
e124a22ffd | ||
|
095d19cda7 | ||
|
176ef77624 | ||
|
2384031d09 | ||
|
710a4ee867 | ||
|
3a1a955164 | ||
|
e8004b5b56 | ||
|
c873362d01 | ||
|
52606616c4 | ||
|
768b3e48f7 | ||
|
afccb8517a | ||
|
b5c2ecdfcc | ||
|
afb4acc19b | ||
|
f630c8892a | ||
|
4f24f8078d | ||
|
8bfb695536 | ||
|
ef35adb9e4 | ||
|
76c2789587 | ||
|
f4ef9697e9 | ||
|
309157dd89 | ||
|
1395c0b8c6 | ||
|
8d67bdee84 | ||
|
78c55558af | ||
|
dd4a1bf072 | ||
|
16ba8331b5 | ||
|
8dbd78f560 | ||
|
f730e2179b | ||
|
faf80d1b62 | ||
|
e02f57b7b0 | ||
|
4988f22e94 | ||
|
e56faaaed5 | ||
|
e1d6a47048 | ||
|
9382845dee | ||
|
d1cac298c6 | ||
|
e2c083ba31 | ||
|
2661881bc4 | ||
|
eb29f03ab0 |
@@ -12,3 +12,4 @@ access.log
|
||||
/data
|
||||
/cache
|
||||
.DS_Store
|
||||
/public/scripts/extensions/third-party
|
||||
|
@@ -54,6 +54,7 @@ module.exports = {
|
||||
},
|
||||
// These scripts are loaded in HTML; tell ESLint not to complain about them being undefined
|
||||
globals: {
|
||||
globalThis: 'readonly',
|
||||
ePub: 'readonly',
|
||||
pdfjsLib: 'readonly',
|
||||
toastr: 'readonly',
|
||||
@@ -74,6 +75,7 @@ module.exports = {
|
||||
'plugins/**',
|
||||
'**/*.min.js',
|
||||
'public/scripts/extensions/quick-reply/lib/**',
|
||||
'public/scripts/extensions/tts/lib/**',
|
||||
],
|
||||
rules: {
|
||||
'no-unused-vars': ['error', { args: 'none' }],
|
||||
@@ -90,6 +92,8 @@ module.exports = {
|
||||
'space-infix-ops': 'error',
|
||||
'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
|
||||
'no-cond-assign': 'error',
|
||||
'no-unneeded-ternary': 'error',
|
||||
'no-irregular-whitespace': ['error', { skipStrings: true, skipTemplates: true }],
|
||||
|
||||
// These rules should eventually be enabled.
|
||||
'no-async-promise-executor': 'off',
|
||||
|
3
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -1,4 +1,5 @@
|
||||
name: Bug Report 🐛
|
||||
type: Bug
|
||||
description: Report something that's not working the intended way. Support requests for external programs (reverse proxies, 3rd party servers, other peoples' forks) will be refused! Please use English only.
|
||||
title: '[BUG] <title>'
|
||||
labels: ['🐛 Bug']
|
||||
@@ -80,6 +81,8 @@ body:
|
||||
required: true
|
||||
- label: I have checked the [docs](https://docs.sillytavern.app/) 
|
||||
required: true
|
||||
- label: I confirm that my issue is not related to third-party content, unofficial extension or patch. If in doubt, check with a new [user account](https://docs.sillytavern.app/administration/multi-user/) and with extensions disabled
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
3
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -1,4 +1,5 @@
|
||||
name: Feature Request ✨
|
||||
type: Feature
|
||||
description: Suggest an idea for future development of this project. Please use English only.
|
||||
title: '[FEATURE_REQUEST] <title>'
|
||||
labels: ['🦄 Feature Request']
|
||||
@@ -32,7 +33,7 @@ body:
|
||||
id: solution
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
placeholder: An outline of how you would like this to be implemented, include as much details as possible
|
||||
placeholder: An outline of how you would like this to be implemented, include as much details as possible
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
2
.github/close-label.yml
vendored
@@ -1,2 +0,0 @@
|
||||
🐛 Bug: ✅ Fixed
|
||||
🦄 Feature Request: ✅ Implemented
|
62
.github/issue-auto-comments.yml
vendored
@@ -1,62 +0,0 @@
|
||||
comment:
|
||||
footer: |
|
||||
---
|
||||
> I am a bot, and this is an automated message 🤖
|
||||
labels:
|
||||
- name: ✖️ Invalid
|
||||
labeled:
|
||||
issue:
|
||||
action: close
|
||||
body: >
|
||||
Hello @{{ issue.user.login }} your ticket has been marked as invalid.
|
||||
Please ensure you follow the issue template, provide all requested info,
|
||||
and be sure to check the docs + previous issues prior to raising tickets.
|
||||
pr:
|
||||
body: Thank you @{{ pull_request.user.login }} for suggesting this. Please follow the pull request templates.
|
||||
action: close
|
||||
|
||||
- name: 👩💻 Good First Issue
|
||||
labeled:
|
||||
issue:
|
||||
body: >
|
||||
This issue has been marked as a good first issue for first-time contributors to implement!
|
||||
This is a great way to support the project, while also improving your skills, you'll also be credited as a contributor once your PR is merged.
|
||||
If you're new to SillyTavern [here are a collection of resources](https://docs.sillytavern.app/)
|
||||
If you need any support at all, feel free to reach out via [Discord](https://discord.gg/sillytavern).
|
||||
|
||||
- name: ❌ wontfix
|
||||
labeled:
|
||||
issue:
|
||||
action: close
|
||||
body: >
|
||||
This ticked has been marked as 'wontfix', which usually means it is out-of-scope, or not feasible at this time.
|
||||
You can still fork the project and make the changes yourself.
|
||||
|
||||
- name: ✅ Fixed
|
||||
labeled:
|
||||
issue:
|
||||
body: >
|
||||
Hello @{{ issue.user.login }}! It looks like all or part of this issue has now been implemented.
|
||||
|
||||
|
||||
- name: ‼️ High Priority
|
||||
labeled:
|
||||
issue:
|
||||
body: >
|
||||
This ticket has been marked as high priority, and has been bumped to the top of the priority list.
|
||||
You should expect an implementation to be pushed out soon. Thank you for your patience.
|
||||
|
||||
- name: 💀 Spam
|
||||
labeled:
|
||||
issue:
|
||||
action: close
|
||||
locking: lock
|
||||
lock_reason: spam
|
||||
body: >
|
||||
This issue has been identified as spam, and is now locked.
|
||||
Users who repeatedly raise spam issues may be blocked or reported.
|
||||
|
||||
- name: ⛔ Don't Merge
|
||||
labeled:
|
||||
pr:
|
||||
body: This PR has been temporarily blocked from merging.
|
69
.github/issues-auto-comments.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
labels:
|
||||
- name: ✖️ Invalid
|
||||
labeled:
|
||||
issue:
|
||||
action: close
|
||||
body: >
|
||||
Hey @{{ issue.user.login }}, this issue has been marked as invalid.
|
||||
|
||||
Please double-check that you've followed the issue template, included all necessary details, and reviewed the docs & previous issues before submitting.
|
||||
If provided, follow the instructions given by maintainers.
|
||||
|
||||
- name: 👩💻 Good First Issue
|
||||
labeled:
|
||||
issue:
|
||||
body: >
|
||||
🏆 This issue has been marked as a good first issue for contributors to implement!
|
||||
This is a great way to support the project. While also improving your skills, you'll also be credited as a contributor once your PR is merged.
|
||||
|
||||
If you're new to SillyTavern [here is the official documentation](https://docs.sillytavern.app/). The official contribution guide can be found [here](https://github.com/SillyTavern/SillyTavern/blob/release/CONTRIBUTING.md).
|
||||
If you need any support, feel free to reach out via [Discord](https://discord.gg/sillytavern), or let us know in this issue or via [discussions](https://github.com/SillyTavern/SillyTavern/discussions).
|
||||
|
||||
- name: ❌ wontfix
|
||||
labeled:
|
||||
issue:
|
||||
action: close
|
||||
body: >
|
||||
❌ This issue has been marked as 'wontfix', which usually means it is out-of-scope, not feasible at this time or will not be implemented for various reasons.
|
||||
If you have any questions about this, feel free to reach out.
|
||||
|
||||
- name: 🛑 Out of Scope
|
||||
labeled:
|
||||
issue:
|
||||
action: close
|
||||
body: >
|
||||
🛑 This issue has been marked as 'out of scope', as this can't or won't be implemented.
|
||||
If you have any questions about this, feel free to reach out.
|
||||
|
||||
- name: ✅ Done (staging)
|
||||
labeled:
|
||||
issue:
|
||||
body: >
|
||||
✅ It looks like all or part of this issue has now been implemented as part of the `staging` branch.
|
||||
If you currently are on the `release` branch, you can switch to `staging` to test this right away.
|
||||
|
||||
Note that `staging` is considered less stable than the official releases. To switch, follow existing instructions,
|
||||
or simply enter the following command: `git switch staging`
|
||||
|
||||
- name: ✅ Done
|
||||
labeled:
|
||||
issue:
|
||||
body: >
|
||||
✅ It looks like all or part of this issue has now been implemented as part of the latest release.
|
||||
|
||||
- name: ‼️ High Priority
|
||||
labeled:
|
||||
issue:
|
||||
body: >
|
||||
🚨 This issue has been marked high priority, meaning it's important to the maintainers or community.
|
||||
While we can't promise immediate changes, it is on our radar and will be addressed whenever possible. Thanks for your patience!
|
||||
|
||||
- name: 💀 Spam
|
||||
labeled:
|
||||
issue:
|
||||
action: close
|
||||
locking: lock
|
||||
lock_reason: spam
|
||||
body: >
|
||||
💀 This issue has been flagged as spam and is now locked.
|
||||
Please avoid posting spam - it disrupts the community and wastes everyone's time.
|
@@ -1,7 +1,3 @@
|
||||
# Add/remove 'critical' label if issue contains the words 'urgent' or 'critical'
|
||||
#critical:
|
||||
# - '(critical|urgent)'
|
||||
|
||||
🪟 Windows:
|
||||
- '(🪟 Windows)'
|
||||
|
||||
@@ -15,4 +11,10 @@
|
||||
- '(📱 Termux)'
|
||||
|
||||
🐧 Linux:
|
||||
- '(🐧 Linux)'
|
||||
- '(🐧 Linux)'
|
||||
|
||||
🦊 Firefox:
|
||||
- '(firefox|mozilla)'
|
||||
|
||||
📱 Mobile:
|
||||
- '(iphone|ios|android|📱 Termux)'
|
51
.github/pr-auto-comments.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
labels:
|
||||
- name: ✖️ Invalid
|
||||
labeled:
|
||||
pr:
|
||||
action: close
|
||||
body: >
|
||||
Hey @{{ pull_request.user.login }}, thanks for your contribution!
|
||||
Unfortunately, this PR has been marked as invalid.
|
||||
|
||||
Please check that you've followed the PR template, included all relevant details, and are targeting the correct branch (`staging` for regular contributions, `release` only for hotfixes).
|
||||
|
||||
If you need help, feel free to ask!
|
||||
|
||||
- name: ⛔ Don't Merge
|
||||
labeled:
|
||||
pr:
|
||||
body: >
|
||||
🚨 This PR has been temporarily blocked from merging.
|
||||
|
||||
- name: 💥💣 Breaking Changes
|
||||
labeled:
|
||||
pr:
|
||||
body: >
|
||||
⚠️ Heads up! This PR introduces breaking changes.
|
||||
|
||||
Make sure these changes are well-documented and that users will be properly informed when this is released.
|
||||
|
||||
- name: ⛔ Waiting For External/Upstream
|
||||
labeled:
|
||||
pr:
|
||||
body: >
|
||||
⛔ This PR is awaiting external or upstream changes or approval.
|
||||
It can only be merged once those changes have been implemented and approved.
|
||||
|
||||
Please inform us of any progress on the upstream changes or approval.
|
||||
|
||||
- name: 🔬 Needs Testing
|
||||
labeled:
|
||||
pr:
|
||||
body: >
|
||||
🔬 This PR needs testing!
|
||||
Any contributor can test and leave reviews, so feel free to help us out!
|
||||
|
||||
- name: 🟥 ⬤⬤⬤⬤⬤
|
||||
labeled:
|
||||
pr:
|
||||
body: >
|
||||
⚠️ This PR is over 1000 lines, which is larger than recommended.
|
||||
|
||||
Please make sure that it only addresses a single issue - PRs this large are hard to test and may be rejected.
|
||||
|
77
.github/pr-auto-labels-by-branch.yml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
####################################
|
||||
# Label PRs against 'release' #
|
||||
####################################
|
||||
❗ Against Release Branch:
|
||||
- base-branch: 'release'
|
||||
|
||||
####################################
|
||||
# Labels based on PR branch name #
|
||||
####################################
|
||||
🦋 Bug Fix:
|
||||
- head-branch: ['^fix[/-]', '\bfixes\b']
|
||||
|
||||
🚑 Hot Fix:
|
||||
- head-branch: ['^hotfix[/-]']
|
||||
|
||||
✨ New Feature:
|
||||
- head-branch: ['^feat(ure)?[/-].*?\badd', '^add-']
|
||||
|
||||
✨ Feature Changes:
|
||||
- head-branch: ['^feat(ure)?[/-](?!.*\badd\b)', '\bchanges?\b']
|
||||
|
||||
🤖 API / Model:
|
||||
- head-branch: ['\bapi\b', '\bmodels?\b']
|
||||
|
||||
🏭 Backend Changes:
|
||||
- head-branch: ['\bbackend\b', '\bendpoints?\b']
|
||||
|
||||
🐋 Docker:
|
||||
- head-branch: ['\bdocker\b']
|
||||
|
||||
➕ Extension:
|
||||
- head-branch: ['\bextension\b', '\bext\b']
|
||||
|
||||
🦊 Firefox:
|
||||
- head-branch: ['\bfirefox\b']
|
||||
|
||||
🖼️ Image Gen:
|
||||
- head-branch: ['\bimage-gen\b']
|
||||
|
||||
🌐 Language:
|
||||
- head-branch: ['\btranslations?\b', '\blanguages?\b']
|
||||
|
||||
🐧 Linux:
|
||||
- head-branch: ['\blinux\b']
|
||||
|
||||
🧩 Macros:
|
||||
- head-branch: ['\bmacros?\b']
|
||||
|
||||
📱 Mobile:
|
||||
- head-branch: ['\bmobile\b', '\bios\b', '\bandroid\b']
|
||||
|
||||
🚄 Performance:
|
||||
- head-branch: ['\bperformance\b']
|
||||
|
||||
⚙️ Preset:
|
||||
- head-branch: ['\bpresets?\b']
|
||||
|
||||
📜 Prompt:
|
||||
- head-branch: ['\bprompt\b']
|
||||
|
||||
🚚 Refactor:
|
||||
- head-branch: ['\brefactor(s|ed)?\b']
|
||||
|
||||
📜 STscript:
|
||||
- head-branch: ['\bstscript\b', '\bslash-commands\b']
|
||||
|
||||
🏷️ Tags / Folders:
|
||||
- head-branch: ['\btags\b']
|
||||
|
||||
🎙️ TTS / Voice:
|
||||
- head-branch: ['\btts\b', '\bvoice\b']
|
||||
|
||||
🌟 UX:
|
||||
- head-branch: ['\bux\b']
|
||||
|
||||
🗺️ World Info:
|
||||
- head-branch: ['\bworld-info\b', '\bwi\b']
|
46
.github/pr-auto-labels-by-files.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
####################################
|
||||
# Labels based on changed files #
|
||||
####################################
|
||||
🏭 Backend Changes:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "src/**"
|
||||
- "default/config.yaml"
|
||||
- "server.js"
|
||||
- "plugins.js"
|
||||
- "recover.js"
|
||||
- "webpack.config.js"
|
||||
- "Start.bat"
|
||||
- "start.sh"
|
||||
- "UpdateAndStart.bat"
|
||||
- "UpdateForkAndStart.bat"
|
||||
|
||||
⚙️ config.yaml:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "default/config.yaml"
|
||||
|
||||
🛠️ Build Changes:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ".github/workflows/**"
|
||||
- "docker/**"
|
||||
- ".dockerignore"
|
||||
- "Dockerfile"
|
||||
- "webpack.config.js"
|
||||
|
||||
🌐 Language:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "public/locales/**"
|
||||
|
||||
📥 Dependencies:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "public/lib/**" # Every frontend lib counts as a dependency as well
|
||||
- "package.json"
|
||||
- "package-lock.json"
|
||||
- "tests/package.json"
|
||||
- "tests/package-lock.json"
|
||||
- "src/electron/package.json"
|
||||
- "src/electron/package-lock.json"
|
2
.github/readme-de_de.md
vendored
@@ -8,7 +8,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[English](readme.md) | German | [中文](readme-zh_cn.md) | [日本語](readme-ja_jp.md) | [Русский](readme-ru_ru.md)
|
||||
[English](readme.md) | German | [中文](readme-zh_cn.md) | [繁體中文](readme-zh_tw.md) | [日本語](readme-ja_jp.md) | [Русский](readme-ru_ru.md) | [한국어](readme-ko_kr.md)
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/stargazers)
|
||||
[](https://github.com/SillyTavern/SillyTavern/network)
|
||||
|
2
.github/readme-ja_jp.md
vendored
@@ -5,7 +5,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[English](readme.md) | [German](readme-de_de.md) | [中文](readme-zh_cn.md) | 日本語 | [Русский](readme-ru_ru.md)
|
||||
[English](readme.md) | [German](readme-de_de.md) | [中文](readme-zh_cn.md) | [繁體中文](readme-zh_tw.md) | 日本語 | [Русский](readme-ru_ru.md) | [한국어](readme-ko_kr.md)
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/stargazers)
|
||||
[](https://github.com/SillyTavern/SillyTavern/network)
|
||||
|
394
.github/readme-ko_kr.md
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
> [!IMPORTANT]
|
||||
> 이곳에 게재된 정보는 오래되거나 불완전할 수 있습니다. 최신 정보는 영어 버전을 이용하십시오.
|
||||
|
||||
<a name="readme-top"></a>
|
||||
|
||||
![][cover]
|
||||
|
||||
<div align="center">
|
||||
|
||||
[English](readme.md) | [German](readme-de_de.md) | [中文](readme-zh_cn.md) | [繁體中文](readme-zh_tw.md) | [日本語](readme-ja_jp.md) | [Русский](readme-ru_ru.md) | 한국어
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/stargazers)
|
||||
[](https://github.com/SillyTavern/SillyTavern/network)
|
||||
[](https://github.com/SillyTavern/SillyTavern/issues)
|
||||
[](https://github.com/SillyTavern/SillyTavern/pulls)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
SillyTavern은 많은 LLM API(KoboldAI/CPP, Horde, NovelAI, Ooba, Tabby, OpenAI, OpenRouter, Claude, Mistral 등)에 대한 단일 통합 인터페이스, 모바일 친화적 레이아웃, 비주얼 노벨 모드, Automatic1111 & ComfyUI API 이미지 생성 통합, TTS, 월드 인포 (로어북), 커스텀 가능한 UI, 자동 번역, 필요 이상의 프롬프트 옵션, 그리고 서드파티 확장을 통한 무궁무진한 성장 가능성을 제공합니다.
|
||||
|
||||
또한, 자주 묻는 질문에 대한 답변과, 시작하는 데 도움을 주기 위한 [문서 웹사이트](https://docs.sillytavern.app/)가 있습니다.
|
||||
|
||||
## SillyTavern이 무엇인가요?
|
||||
|
||||
SillyTavern(짧게는 ST)은 텍스트 생성 LLM, 이미지 생성 엔진, TTS 음성 모델 등과 상호작할 수 있는 로컬 설치형 UI 입니다.
|
||||
|
||||
2023년 2월, TavernAI 1.2.8의 포크로 시작한 SillyTavern은 현재 100명이 넘는 기여자를 보유하고 있으며, 2년간의 독자적인 개발을 거쳐 숙련된 AI 애호가들을 위한 선도적인 소프트웨어로 자리매김하고 있습니다.
|
||||
|
||||
|
||||
## 우리의 비전
|
||||
|
||||
1. 저희는 사용자가 LLM 프롬프트에 대한 최대한의 유용성과 제어 능력을 갖도록 하는 것을 목표로 합니다. 빠르게 배우는 것 역시 재미의 일부입니다!
|
||||
2. 저희는 어떠한 온라인 및 호스팅 서브시도 제공하지 않으며, 프로그래밍으로 사용자의 데이터를 추적하지 않습니다.
|
||||
3. SillyTavern은 헌신적인 LLM 커뮤니티가 여러분에게 제공하는 열정적인 프로젝트이며, 언제나 무료이며 오픈소스로 제공될 것입니다.
|
||||
|
||||
## 브랜치
|
||||
|
||||
SillyTavern은 모든 사용자가 원활한 경험을 할 수 있도록 두 개의 브랜치를 활용하여 개발되고 있습니다.
|
||||
|
||||
|
||||
* `release` -🌟 **대부분의 사용자에게 추천됨.** 가장 안정적이고 권장되는 브랜치이며, 주요 릴리스가 배포될 때만 업데이트됩니다. 대부분의 사용자에게 적합합니다. 일반적으로 한달에 한번 업데이트됩니다.
|
||||
* `staging` - ⚠️ **일반적인 사용에 추천되지 않음.** 최신 기능을 가지고 있지만, 언제든지 문제가 발생할 수 있습니다. 고급 사용자 및 숙련자 전용입니다. 하루에 여러번 업데이트됩니다.
|
||||
|
||||
만약 git CLI 사용에 익숙하지 않거나 브랜치가 무엇인지 모르겠다면 release 브랜치가 더 나은 선택입니다.
|
||||
|
||||
## SillyTavern 외에 무엇이 필요한가요?
|
||||
|
||||
SillyTavern은 인터페이스 역할만 하기 때문에, 실제로 채팅하려면 LLM 백엔드에 대한 액세스 권한이 필요합니다. 즉시 사용 가능한 채팅을 위해 AI Horde를 사용할 수 있습니다. 그 외에도 OpenAI 호환 API, KoboldAI, Tabby 등 많은 로컬 및 클라우드 기반 LLM 백엔드를 지원합니다. 지원되는 API에 대한 자세한 내용은 [FAQ](https://docs.sillytavern.app/usage/api-connections/)에서 확인할 수 있습니다.
|
||||
|
||||
### SillyTavern을 위해서 좋은 성능의 PC가 필요한가요?
|
||||
|
||||
하드웨어 요구 사항은 거의 없습니다: NodeJS 18 이상을 실행할 수 있는 모든 환경에서 작동합니다. 다만 로컬 LLM 모델을 사용할 경우, 최소 6GB VRAM 이상의 3000번대 NVIDIA 그래픽 카드를 권장합니다. 자세한 내용은 백엔드 문서를 참고하세요.
|
||||
|
||||
### 추천되는 백엔드 (제휴 없음)
|
||||
|
||||
* [AI Horde](https://aihorde.net/) - 자원 봉사자들이 호스팅하는 모델을 사용합니다. 추가 설정이 필요하지 않습니다.
|
||||
* [KoboldCpp](https://github.com/LostRuins/koboldcpp) - 로컬에서 GGUF 모델을 실행하기 위한 커뮤니티에서 선호하는 옵션입니다.
|
||||
* [tabbyAPI](https://github.com/theroyallab/tabbyAPI) - 인기 있는 경량 로컬 exl2 추론 API입니다.
|
||||
* [OpenRouter](https://openrouter.ai) - OpenAI, Claude, Meta Llama 등 다양한 클라우드 제공업체와 인기 있는 커뮤니티 모델을 위한 단일 API입니다.
|
||||
|
||||
## 질문이나 제안이 있으신가요?
|
||||
|
||||
### 디스코드 서버
|
||||
|
||||
| [![][discord-shield-badge]][discord-link] | [저희의 디스코드에 참여하세요!](https://discord.gg/sillytavern) 지원을 받고, 좋아하는 캐릭터와 프롬프트를 공유하세요. |
|
||||
| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------- |
|
||||
|
||||
혹은 저희의 개발자들과 직접 연락할 수 있습니다:
|
||||
|
||||
* 디스코드: cohee, rossascends, wolfsblvt
|
||||
* 레딧: [/u/RossAscends](https://www.reddit.com/user/RossAscends/), [/u/sillylossy](https://www.reddit.com/user/sillylossy/), [u/Wolfsblvt](https://www.reddit.com/user/Wolfsblvt/)
|
||||
* [GitHub issue를 작성하세요](https://github.com/SillyTavern/SillyTavern/issues)
|
||||
|
||||
### 이 프로젝트가 마음에 들어요! 어떻게 기여할 수 있을까요?
|
||||
|
||||
1. PULL REQUEST를 생성하세요. 기여 방법에 대해서는 [CONTRIBUTING.md](../CONTRIBUTING.md)를 참고하세요.
|
||||
2. 제공된 탬플릿에 따라 기능 제안이나 이슈 리포트를 생성하세요.
|
||||
3. 중복된 이슈를 생성하지 않도록 이 README 파일 전체를 읽고 문서 웹사이트를 먼저 확인하세요.
|
||||
|
||||
## 스크린샷
|
||||
|
||||
<img width="500" alt="image" src="https://github.com/user-attachments/assets/9b5f32f0-c3b3-4102-b3f5-0e9213c0f50f">
|
||||
<img width="500" alt="image" src="https://github.com/user-attachments/assets/913fdbaa-7d33-42f1-ae2c-89dca41c53d1">
|
||||
|
||||
|
||||
## 캐릭터 카드
|
||||
|
||||
SillyTavern은 "캐릭터 카드"라는 개념을 중심으로 구축되었습니다. 캐릭터 카드는 LLM의 동작을 설정하는 프롬프트 모음이며, SillyTavern에서 지속적인 대화를 하려면 필수적입니다. 이는 ChatGPT의 GPT 또는 Poe의 봇과 유사하게 작동합니다. 캐릭터 카드의 내용은 추상적인 시나리오, 특정 작업에 맞춰진 도우미, 유명 인사 또는 가상 인물 등 무엇이든 될 수 있습니다.
|
||||
|
||||
이름 필드는 유일한 필수 캐릭터 카드 입력 항목입니다. 언어 모델과 중립적인 대화를 시작하려면 "도우미"라고 간단히 이름 지은 새 카드를 만들고 나머지 상자는 비워 두세요. 더 주제가 있는 채팅을 원한다면 언어 모델에 다양한 배경 정보, 행동 및 작문 패턴, 그리고 채팅을 바로 시작할 시나리오를 제공할 수 있습니다.
|
||||
|
||||
캐릭터 카드를 선택하지 않고 빠른 대화를 하거나 LLM 연결을 테스트하려면 SillyTavern을 연 후 시작 화면의 입력 창에 프롬프트 입력을 입력하기만 하면 됩니다. 이러한 채팅은 임시적이며 저장되지 않습니다.
|
||||
|
||||
캐릭터 카드를 정의하는 방법에 대한 일반적인 아이디어를 얻으려면 기본 캐릭터(Seraphina)를 보거나 "확장 프로그램 및 에셋 다운로드" 메뉴에서 선택된 커뮤니티 제작 카드를 다운로드하세요.
|
||||
|
||||
|
||||
## 핵심 기능
|
||||
|
||||
* 고급 텍스트 생성 설정과 다양한 커뮤니티 제작 프리셋
|
||||
* 월드 인포 지원: 풍부한 설정을 만들거나 캐릭터 카드에 토큰 저장
|
||||
* 그룹 채팅: 캐릭터가 사용자 혹은 다른 캐릭터와 대화할 수 있는 방
|
||||
* 다양한 UI 커스텀 옵션: 테마 색, 뱌경 이미지, 커스텀 CSS 등
|
||||
* 유저 페르소나: AI에게 사용자에 대한 정보를 주어 더욱 몰입감을 높임
|
||||
* 내장 RAG 지원: AI가 참조할 수 있도록 채팅에 문서를 추가
|
||||
* 광범위한 채팅 명령어 시스템 및 자체 [스크립트](https://docs.sillytavern.app/usage/st-script/)
|
||||
|
||||
## 확장
|
||||
|
||||
SillyTavern은 확장(익스텐션)을 지원합니다.
|
||||
|
||||
* 캐릭터 감정 표현 (스프라이트)
|
||||
* 채팅 기록 자동 요약
|
||||
* 자동 UI 및 채팅 번역
|
||||
* Stable Diffusion/FLUX/DALL-E 이미지 생성
|
||||
* AI 응답 메시지 텍스트 음성 변환 (ElevenLabs, Silero 또는 OS 시스템 TTS 사용)
|
||||
* 프롬프트에 추가적인 현실 세계 맥락을 추가하기 위한 웹 검색 기능
|
||||
* "확장 프로그램 및 에셋 다운로드" 메뉴에서 더 많은 기능을 다운로드할 수 있습니다.
|
||||
|
||||
|
||||
사용 방법에 대한 튜토리얼은 [Docs](https://docs.sillytavern.app/)에서 확인할 수 있습니다.
|
||||
|
||||
# ⌛ Installation
|
||||
|
||||
> \[!WARNING]
|
||||
>
|
||||
> * **윈도우 제어 폴더에는 설치하지 마십시오 (Program Files, System32 등).**
|
||||
> * **권리자 권한으로 START.BAT을 실행하지 마십시오.**
|
||||
> * **Windows 7에서는 NodeJS 18.16을 실행할 수 없으므로 설치가 불가능합니다.**
|
||||
|
||||
## 🪟 Windows
|
||||
|
||||
### Git을 통해 설치하기
|
||||
|
||||
1. [NodeJS](https://nodejs.org/ko) 설치 (최신 LTS 버전 권장)
|
||||
2. [Git for Windows](https://gitforwindows.org/) 설치
|
||||
3. 파일 탐색기 열기 (`Win+E`)
|
||||
4. Windows에서 제어하거나 모니터하지 않는 폴더를 찾거나 만드세요. (ex: C:\MySpecialFolder\)
|
||||
5. 상단의 주소 표시줄을 클릭하고 `cmd`를 입력한 후 Enter 키를 눌러 해당 폴더 내에서 명령 프롬프트를 여세요.
|
||||
6. 검은색 창(명령 프롬프트)이 나타나면 다음 중 하나를 입력하고 Enter 키를 누르세요.
|
||||
|
||||
* Release 브랜치: `git clone https://github.com/SillyTavern/SillyTavern -b release`
|
||||
* Staging 브랜치: `git clone https://github.com/SillyTavern/SillyTavern -b staging`
|
||||
|
||||
7. clone이 완료되면, `Start.bat`을 더블 클릭하여 NodeJS가 필요한 구성요소를 설치하도록 하세요.
|
||||
8. 그러면 서버가 시작하고, SillyTavern이 브라우저에 나타납니다.
|
||||
|
||||
### GitHub Desktop을 통해 설치하기
|
||||
|
||||
(이 방법은 **오직** GitHub Desktop에서만 git 사용이 가능합니다. 명령 프롬프트에서 git을 사용하려면 [Git for Windows](https://gitforwindows.org/)를 설치해야 합니다.)
|
||||
|
||||
|
||||
|
||||
1. [NodeJS](https://nodejs.org/ko) 설치 (최신 LTS 버전 권장)
|
||||
2. [GitHub Desktop](https://central.github.com/deployments/desktop/desktop/latest/win32) 설치
|
||||
3. GitHub Desktop을 설치했으면, `Clone a repository from the internet....`를 클릭하세요. (참고: 이 과정에서는 Github 계정이 **필요하지 않습니다**.)
|
||||
4. 메뉴에서 URL 탭을 클릭하고, 다음 URL을 입력한 후 복제를 클릭합니다: `https://github.com/SillyTavern/SillyTavern` 리포지토리가 다운로드될 위치를 변경하려면 로컬 경로를 변경할 수 있습니다.
|
||||
5. SillyTavern을 열려면 파일 탐색기를 사용하여 리포지토리를 복제한 폴더로 이동합니다. 기본적으로 리포지토리는 다음 위치에 복제됩니다: `C:\Users\[사용자 Windows 사용자 이름]\Documents\GitHub\SillyTavern`
|
||||
6. `start.bat` 파일을 더블 클릭 하세요. (참고: `.bat` 확장자 명은 OS 설정에 따라 보이지 않을 수 있습니다, 그럴 때는 파일 이름이 "`Start`" 처럼 보일 수 있습니다. 이 파일을 더블 클릭해 SillyTavern을 실행하세요.)
|
||||
7. 더블 클릭하면, 검고 큰 명령 프롬프트 창이 열리고 SillyTavern이 작동하는데 필요한 항목을 설치하기 시작합니다.
|
||||
8. 설치 과정이 끝나고 모든 것이 잘 작동한다면, 브라우저에 SillyTavern 탭이 열려 있어야 하고, 명령 프롬프트 창에 다음과 같이 표시되어야 합니다:
|
||||
9. Connect to any of the [supported APIs](https://docs.sillytavern.app/usage/api-connections/) and start chatting!
|
||||
|
||||
## 🐧 Linux & 🍎 MacOS
|
||||
|
||||
MacOS / Linux 에서는 이 모든 작업이 터미널에서 수행됩니다.
|
||||
|
||||
1. git과 nodeJS 설치 (이 작업은 OS에 따라 달라집니다.)
|
||||
2. 리포지토리 clone하기
|
||||
|
||||
* Release 브랜치: `git clone https://github.com/SillyTavern/SillyTavern -b release`
|
||||
* Staging 브랜치: `git clone https://github.com/SillyTavern/SillyTavern -b staging`
|
||||
|
||||
3. `cd SillyTavern` 를 입력해 설치 폴더로 이동하기
|
||||
4. `start.sh` 스크립트를 아래의 명령어 중 하나로 실행하기:
|
||||
|
||||
* `./start.sh`
|
||||
* `bash start.sh`
|
||||
|
||||
## ⚡ SillyTavern Launcher를 통해 설치하기
|
||||
|
||||
SillyTavern 런처는 로컬 LLM 사용을 위한 백엔드 설치를 포함하여 다양한 설정을 도와주는 설치 마법사입니다.
|
||||
|
||||
|
||||
### Windows 사용자
|
||||
|
||||
1. 키보드에서 **`WINDOWS + R`** 키를 눌러 실행 창을 여세요. 그리고 아래의 명령어를 입력해 git을 설치하세요.
|
||||
|
||||
```shell
|
||||
cmd /c winget install -e --id Git.Git
|
||||
```
|
||||
|
||||
2. 키보드에서 **`WINDOWS + E`** 키를 눌러 파일 탐색기를 열고 런처를 설치할 폴더로 이동합니다. 원하는 폴더에 도착하면 주소 표시줄에 `cmd`를 입력하고 Enter 키를 누릅니다. 그 후 아래의 명령어를 입력합니다.
|
||||
|
||||
|
||||
```shell
|
||||
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher && start installer.bat
|
||||
```
|
||||
|
||||
### Linux 사용자
|
||||
|
||||
1. 선호하는 터미널을 열고 git을 설치하세요.
|
||||
2. SillyTavern-Launcher를 clone 하세요:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher
|
||||
```
|
||||
|
||||
3. installer.sh를 실행하세요:
|
||||
|
||||
```shell
|
||||
chmod +x install.sh && ./install.sh
|
||||
```
|
||||
|
||||
4. 설치가 끝나면 launcher.sh를 실행하세요:
|
||||
|
||||
```shell
|
||||
chmod +x launcher.sh && ./launcher.sh
|
||||
```
|
||||
|
||||
### Mac 사용자
|
||||
|
||||
1. 터미널을 열고 Brew를 설치하세요:
|
||||
|
||||
```shell
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
|
||||
2. git을 설치하세요:
|
||||
|
||||
```shell
|
||||
brew install git
|
||||
```
|
||||
|
||||
3. SillyTavern-Launcher를 clone 하세요:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher
|
||||
```
|
||||
|
||||
4. installer.sh를 실행하세요:
|
||||
|
||||
```shell
|
||||
chmod +x install.sh && ./install.sh
|
||||
```
|
||||
|
||||
5. 설치가 끝나면 launcher.sh를 실행하세요:
|
||||
|
||||
```shell
|
||||
chmod +x launcher.sh && ./launcher.sh
|
||||
```
|
||||
|
||||
## 🐋 Docker를 통해 설치하기
|
||||
|
||||
이 방법은 Docker가 설치되어 있고, Docker 설치를 위해 커맨드 라인에 접근할 수 있으며, Docker의 일반적인 작동 방식에 익숙하다고 가정합니다.
|
||||
|
||||
### 이미지 직접 빌드하기
|
||||
|
||||
SillyTavern을 Docker에서 사용하는 방법에 대한 포괄적인 가이드는 [여기서](http://docs.sillytavern.app/installation/docker/) 확인할 수 있습니다. 이 가이드는 Windows, macOS 및 Linux에서의 설치를 다룹니다! 직접 이미지를 빌드하려면 이 가이드를 읽어보세요.
|
||||
|
||||
### GitHub Container Registry 사용하기 (가장 쉬움)
|
||||
|
||||
SillyTavern이 작동하려면 두 개의 필수 디렉터리 매핑과 하나의 포트 매핑이 필요합니다. 명령에서 다음 위치의 선택 항목을 바꿔주세요.
|
||||
|
||||
|
||||
#### Container Variables
|
||||
|
||||
##### Volume Mappings
|
||||
|
||||
* [config] - SillyTavern 구성 파일이 호스트 컴퓨터에 저장될 디렉터리
|
||||
* [data] - 캐릭터를 포함한 SillyTavern 사용자 데이터가 호스트 컴퓨터에 저장될 디렉터리
|
||||
* [plugins] - (선택 사항) SillyTavern 서버 플러그인이 호스트 컴퓨터에 저장될 디렉터리
|
||||
|
||||
##### Port Mappings
|
||||
|
||||
* [PublicPort] - 트래픽을 노출할 포트입니다. 가상 머신 컨테이너 외부에서 인스턴스에 접근하므로 필수 사항입니다. 보안을 위한 별도의 서비스를 구현하지 않고는 인터넷에 노출하지 마십시오.
|
||||
|
||||
|
||||
##### Additional Settings
|
||||
|
||||
* [DockerNet] - 컨테이너가 연결되어 생성되어야 하는 Docker 네트워크입니다. 해당 내용을 모르는 경우 [공식 Docker 문서](https://docs.docker.com/reference/cli/docker/network/)를 참조하세요.
|
||||
* [version] - 이 GitHub 페이지의 오른쪽에서 "Packages"를 선택하면 "sillytavern" 패키지를 볼 수 있습니다. "latest" 이미지 태그는 현재 릴리스와 함께 최신 상태를 유지합니다. 각 브랜치의 야간 이미지를 가리키는 "staging" 및 "release" 태그를 사용할 수도 있지만, 업데이트에 시간이 걸릴 수 있고 중단될 수 있는 확장 프로그램을 사용하는 경우에는 적합하지 않을 수 있습니다.
|
||||
|
||||
|
||||
#### 설치 명령어
|
||||
|
||||
1. 커맨드 라인 열기
|
||||
2. 아래의 명령어 실행
|
||||
|
||||
`docker create --name='sillytavern' --net='[DockerNet]' -p '8000:8000/tcp' -v '[plugins]':'/home/node/app/plugins':'rw' -v '[config]':'/home/node/app/config':'rw' -v '[data]':'/home/node/app/data':'rw' 'ghcr.io/sillytavern/sillytavern:[version]'`
|
||||
|
||||
> 8000은 기본 리스닝 포트입니다. 구성에서 포트를 변경한 경우 적절한 포트를 사용하는 것을 잊지 마세요.
|
||||
## 📱 Termux를 통해 Android OS에 설치하기
|
||||
|
||||
> \[!NOTE]
|
||||
> **SillyTavern은 Termux를 사용하여 Android 기기에서 기본적으로 실행할 수 있지만, 이러한 사용 사례에 대한 공식적인 지원은 제공하지 않습니다.**
|
||||
>
|
||||
> **ArroganceComplex#2659의 가이드를 참조하세요:**
|
||||
>
|
||||
> * <https://rentry.org/STAI-Termux>
|
||||
|
||||
**지원되지 않는 플랫폼: android arm LEtime-web.** 32비트 Android는 npm으로 설치할 수 없는 외부 종속성이 필요합니다. 다음 명령어를 사용하여 설치하세요: pkg install esbuild. 그런 다음 일반적인 설치 단계를 진행하세요.
|
||||
|
||||
|
||||
## API 키 관리
|
||||
|
||||
SillyTavern은 API 키를 사용자 데이터 디렉터리의 `secrets.json` 파일에 저장합니다 (`/data/default-user/secrets.json`이 기본 경로입니다).
|
||||
|
||||
|
||||
|
||||
기본적으로 API 키는 저장하고 페이지를 새로 고침한 후에는 인터페이스에서 보이지 않습니다.
|
||||
|
||||
키 보기 기능을 활성화하려면 다음 단계를 따르세요:
|
||||
|
||||
1. `config.yaml` 파일에서 `allowKeysExposure` 값을 `true로` 설정합니다.
|
||||
2. SillyTavern 서버를 다시 시작합니다.
|
||||
3. API 연결 패널 오른쪽 하단에 있는 '숨겨진 API 키 보기' 링크를 클릭합니다.
|
||||
|
||||
## 커맨드 라인 인수
|
||||
|
||||
`config.yaml`의 일부 설정을 덮어쓰기 위해 SillyTavern 서버 시작 시 커맨드 라인 인수를 전달할 수 있습니다.
|
||||
|
||||
|
||||
### 예시
|
||||
|
||||
```shell
|
||||
node server.js --port 8000 --listen false
|
||||
# 혹은
|
||||
npm run start -- --port 8000 --listen false
|
||||
# 혹은 (Windows 전용)
|
||||
Start.bat --port 8000 --listen false
|
||||
```
|
||||
|
||||
### 지원되는 인수
|
||||
|
||||
| 옵션 | 설명 | 타입 |
|
||||
|-------------------------|------------------------------------------------------------------------------------------------------|----------|
|
||||
| `--version` | 버전 표시 | boolean |
|
||||
| `--enableIPv6` | IPv6 활성화 | boolean |
|
||||
| `--enableIPv4` | IPv4 활성화 | boolean |
|
||||
| `--port` | SillyTavern이 실행될 포트를 설정합니다. 설정되지 않은 경우 yaml config 'port'를 불러옵니다. | number |
|
||||
| `--dnsPreferIPv6` | DNS에 IPv6를 우선으로 할당합니다. 설정되지 않은 경우 yaml config를 불러옵니다. | boolean |
|
||||
| `--autorun` | 브라우저에서 SillyTavern을 자동으로 실행합니다. 설정되지 않은 경우 yaml config 'autorun'를 불러옵니다. | boolean |
|
||||
| `--autorunHostname` | 자동 실행 호스트 이름, 'auto'가 최적의 설정일 것입니다. | string |
|
||||
| `--autorunPortOverride` | 자동 실행 포트 덮어쓰기 | string |
|
||||
| `--listen` | SillyTavern이 모든 네트워크 인터페이스에서 수신 대기합니다. 설정되지 않은 경우 yaml 구성 'listen'을 불러옵니다. | boolean |
|
||||
| `--corsProxy` | CORS 프록시 활성화. 설정되지 않은 경우 yaml 구성 'enableCorsProxy'을 불러옵니다. | boolean |
|
||||
| `--disableCsrf` | CSRF 보호 비활성화 | boolean |
|
||||
| `--ssl` | SSL 활성화 | boolean |
|
||||
| `--certPath` | 인증서 파일 경로 | string |
|
||||
| `--keyPath` | 프라이빗 키 파일 경로 | string |
|
||||
| `--whitelist` | 화이트리스트 모드 활성화 | boolean |
|
||||
| `--dataRoot` | 데이터 스토리지의 루트 디렉토리 | string |
|
||||
| `--avoidLocalhost` | 자동 모드에서 자동 실행 시 'localhost' 사용 방지 | boolean |
|
||||
| `--basicAuthMode` | 기본 인증 활성화 | boolean |
|
||||
| `--requestProxyEnabled` | 외부 리퀘스트 프록시 활성화 | boolean |
|
||||
| `--requestProxyUrl` | 프록시 URL 리퀘스트 (HTTP 혹은 SOCKS 프로토콜) | string |
|
||||
| `--requestProxyBypass` | 프록시 바이패스 리스트 리퀘스트 (공백으로 구분된 호스트 목록) | array |
|
||||
|
||||
## 원격 연결
|
||||
|
||||
대부분의 경우 이는 PC에서 ST 서버를 실행하는 동안 모바일 장치에서 SillyTavern을 사용하려는 사람들을 위한 것입니다. 그러나 원격 연결을 다른 곳에서도 허용하도록 사용할 수 있습니다.
|
||||
|
||||
원격 연결 설정 방법에 대한 자세한 가이드는 [Docs](https://docs.sillytavern.app/usage/remoteconnections/)에서 확인할 수 있습니다.
|
||||
|
||||
또한 암호 보호 기능이 포함된 SillyTavern 사용자 프로필을 구성할 수 있습니다 (선택 사항): [Users](https://docs.sillytavern.app/installation/st-1.12.0-migration-guide/#users).
|
||||
|
||||
## 성능 이슈가 발생하나요?
|
||||
|
||||
1. 사용자 설정 패널(UI 테마 전환 카테고리)에서 흐림 효과를 비활성화하고 동작 줄이기를 활성화합니다.
|
||||
2. 응답 스트리밍을 사용하는 경우 스트리밍 FPS를 더 낮은 값(10-15 FPS 권장)으로 설정합니다.
|
||||
3. 브라우저에서 렌더링에 GPU 가속을 사용하도록 설정되어 있는지 확인합니다.
|
||||
|
||||
## 라이센스 및 크레딧
|
||||
|
||||
**이 프로그램은 유용할 것이라는 희망으로 배포되지만, 어떠한 보증도 제공하지 않습니다. 상품성 또는 특정 목적에의 적합성에 대한 묵시적인 보증조차도 제공하지 않습니다. 자세한 내용은 GNU Affero 일반 공중 사용 허가서를 참조하십시오.**
|
||||
|
||||
* Humi의 [TavernAI](https://github.com/TavernAI/TavernAI) 1.2.8: MIT 라이선스
|
||||
* CncAnon의 TavernAITurbo 모드의 일부는 허가를 받아 사용됨
|
||||
* PepperTaco의 작업(<https://github.com/peppertaco/Tavern/>)에 영감을 받은 비주얼 노벨 모드
|
||||
* Noto Sans Font by Google (OFL 라이선스)
|
||||
* Font Awesome의 아이콘 테마 <https://fontawesome.com> (아이콘: CC BY 4.0, 폰트: SIL OFL 1.1, 코드: MIT 라이선스)
|
||||
* 기본 콘텐츠는 @OtisAlejandro (Seraphina 캐릭터 및 로어북)와 @kallmeflocc (10K 디스코드 사용자 축전 배경화면)가 제공함
|
||||
* [@mrguymiah](https://github.com/mrguymiah)와 [@Bronya-Rand](https://github.com/Bronya-Rand)의 Docker 가이드
|
||||
|
||||
## 상위 기여자
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/graphs/contributors)
|
||||
|
||||
<!-- LINK GROUP -->
|
||||
[cover]: https://github.com/user-attachments/assets/01a6ae9a-16aa-45f2-8bff-32b5dc587e44
|
||||
[discord-link]: https://discord.gg/sillytavern
|
||||
[discord-shield-badge]: https://img.shields.io/discord/1100685673633153084?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=for-the-badge
|
40
.github/readme-ru_ru.md
vendored
@@ -7,7 +7,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[English](readme.md) | [German](readme-de_de.md) | [中文](readme-zh_cn.md) | [日本語](readme-ja_jp.md) | Русский
|
||||
[English](readme.md) | [German](readme-de_de.md) | [中文](readme-zh_cn.md) | [繁體中文](readme-zh_tw.md) | [日本語](readme-ja_jp.md) | Русский | [한국어](readme-ko_kr.md)
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/stargazers)
|
||||
[](https://github.com/SillyTavern/SillyTavern/network)
|
||||
@@ -209,6 +209,44 @@ SillyTavern поддерживает расширения.
|
||||
5. Запустите лаунчер установки: `chmod +x install.sh && ./install.sh` and choose what you wanna install
|
||||
6. После завершения установки, запустите лаунчер следующей командой: `chmod +x launcher.sh && ./launcher.sh`
|
||||
|
||||
## 🐋 Установка с помощью Docker
|
||||
|
||||
Предполагается, что вы уже установили Docker, имеете доступ к командной строке для установки контейнеров и знакомы с их базовым управлением.
|
||||
|
||||
### Сборка образа самостоятельно
|
||||
|
||||
У нас есть подробное руководство по использованию SillyTavern в Docker [здесь](http://docs.sillytavern.app/installation/docker/), которое охватывает установку на Windows, macOS и Linux! Ознакомьтесь с ним, если хотите создать образ самостоятельно.
|
||||
|
||||
### Использование реестра контейнеров GitHub (самый простой способ)
|
||||
|
||||
Для работы SillyTavern вам понадобятся две обязательные настройки каталогов и одна настройка порта. В команде замените указанные значения на свои:
|
||||
|
||||
#### Переменные контейнера
|
||||
|
||||
##### Маппинг томов
|
||||
|
||||
* [config] - директория, где на вашем хосте будут храниться файлы конфигурации SillyTavern.
|
||||
* [data] - директория, где на вашем хосте будут храниться пользовательские данные SillyTavern (включая персонажей).
|
||||
* [plugins] - (необязательно) директория, где на вашем хосте будут храниться плагины сервера SillyTavern.
|
||||
|
||||
##### Маппинг портов
|
||||
|
||||
* [PublicPort] - Порт, через который будет передаваться трафик. Это обязательно, так как вы будете обращаться к контейнеру извне его виртуальной машины. НЕ ОТКРЫВАЙТЕ этот порт в интернет без реализации дополнительного уровня безопасности.
|
||||
|
||||
##### Дополнительные настройки
|
||||
|
||||
* [DockerNet] - Docker сеть, к которой контейнер должен быть подключен. Если вы не знаете, что это, обратитесь к [официальной документации Docker](https://docs.docker.com/reference/cli/docker/network/).
|
||||
* [version] - на правой части этой страницы GitHub вы найдете раздел "Packages". Выберите пакет "sillytavern", чтобы увидеть версии образов. Тег "latest" позволит вам обновляться до текущего релиза. Также доступны теги "staging" и "release", которые соответствуют ночным сборкам соответствующих веток. Однако это может быть нецелесообразно, если вы используете расширения, которые могут ломаться и требуют времени для обновления.
|
||||
|
||||
#### Команда установки
|
||||
|
||||
1. Откройте командную строку
|
||||
2. Выполните следующую команду
|
||||
|
||||
`docker create --name='sillytavern' --net='[DockerNet]' -p '8000:8000/tcp' -v '[plugins]':'/home/node/app/plugins':'rw' -v '[config]':'/home/node/app/config':'rw' -v '[data]':'/home/node/app/data':'rw' 'ghcr.io/sillytavern/sillytavern:[version]'`
|
||||
|
||||
> Заметьте, что 8000 является портом по умолчанию. Не забудьте использовать соответствующий порт, если вы измените его в конфиге.
|
||||
|
||||
## 📱 Мобильные устройства - Установка при помощи termux
|
||||
|
||||
> **ОБРАТИТЕ ВНИМАНИЕ!**
|
||||
|
2
.github/readme-zh_cn.md
vendored
@@ -5,7 +5,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[English](readme.md) | [German](readme-de_de.md) | 中文 | [日本語](readme-ja_jp.md) | [Русский](readme-ru_ru.md)
|
||||
[English](readme.md) | [German](readme-de_de.md) | 中文 | [繁體中文](readme-zh_tw.md) | [日本語](readme-ja_jp.md) | [Русский](readme-ru_ru.md) | [한국어](readme-ko_kr.md)
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/stargazers)
|
||||
[](https://github.com/SillyTavern/SillyTavern/network)
|
||||
|
381
.github/readme-zh_tw.md
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
> [!IMPORTANT]
|
||||
> 此處資訊可能已經過時或不完整,僅供您參考。請使用英文版本以取得最新資訊。
|
||||
|
||||
<a name="readme-top"></a>
|
||||
|
||||
![][cover]
|
||||
|
||||
<div align="center">
|
||||
|
||||
[English](readme.md) | [German](readme-de_de.md) | [中文](readme-zh_cn.md) | 繁體中文 | [日本語](readme-ja_jp.md) | [Русский](readme-ru_ru.md) | [한국어](readme-ko_kr.md)
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/stargazers)
|
||||
[](https://github.com/SillyTavern/SillyTavern/network)
|
||||
[](https://github.com/SillyTavern/SillyTavern/issues)
|
||||
[](https://github.com/SillyTavern/SillyTavern/pulls)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
SillyTavern 提供一個統一的前端介面,整合多種大型語言模型的 API(包括:KoboldAI/CPP、Horde、NovelAI、Ooba、Tabby、OpenAI、OpenRouter、Claude、Mistral 等)。同時具備對行動裝置友善的佈局、視覺小說模式(Visual Novel Mode)、Automatic1111 與 ComfyUI 的影像生成 API 整合、TTS(語音合成)、世界資訊(Lorebook)、可自訂 UI、自動翻譯功能,以及強大的提示詞(prompt)設定選項和無限的第三方擴充潛力。
|
||||
|
||||
我們擁有一個 [官方文件網站](https://docs.sillytavern.app/) 可以幫助解答絕大多數的使用問題,並幫助您順利入門。
|
||||
|
||||
## SillyTavern 是什麼?
|
||||
|
||||
SillyTavern(簡稱 ST)是一款本地安裝的使用者介面,讓您能與大型語言模型(LLM)、影像生成引擎以及語音合成模型互動的前端。
|
||||
|
||||
SillyTavern 起源於 2023 年 2 月,作為 TavernAI 1.2.8 的分支版本發展至今。目前已有超過 100 位貢獻者,並擁有超過兩年的獨立開發歷史。如今,它已成為 AI 愛好者中備受推崇的軟體之一。
|
||||
|
||||
## 我們的願景
|
||||
|
||||
1. 我們致力於賦予使用者對 LLM 提示詞的最大控制權與實用性,並認為學習過程中的挑戰是樂趣的一部分。
|
||||
2. 我們不提供任何線上或託管服務,也不會程式化追蹤任何使用者數據。
|
||||
3. SillyTavern 是由一群熱衷於 LLM 的開發者社群所打造的專案,並將永遠保持免費與開源。
|
||||
|
||||
## 分支介紹
|
||||
|
||||
SillyTavern 採用雙分支開發模式,確保為所有使用者提供流暢的體驗。
|
||||
|
||||
* `release`(穩定版):🌟 **推薦給大部分的使用者使用。** 此分支最為穩定,僅在主要版本發布時更新。適合大多數人,通常每月更新一次。
|
||||
* `staging`(開發版):⚠️ **不建議普通使用者使用。** 此分支包含最新功能,但可能隨時出現問題。適合進階使用者與愛好者,每日多次更新。
|
||||
|
||||
如果您不熟悉 git CLI 或對分支概念不清楚,請放心,對您來說,`release`(穩定版)分支永遠是首選。
|
||||
|
||||
## 使用 SillyTavern 需要什麼?
|
||||
|
||||
由於 SillyTavern 僅是一個介面,您需要一個 LLM 後端來提供推理能力。您可以使用 AI Horde 以立即開始聊天。此外,我們支持許多其他本地和雲端 LLM 後端,例如 OpenAI 兼容 API、KoboldAI、Tabby 等。更多支持的 API 資訊,請參閱 [常見問題](https://docs.sillytavern.app/usage/api-connections/)。
|
||||
|
||||
### 我需要高效能電腦才能運行 SillyTavern 嗎?
|
||||
|
||||
SillyTavern 的硬體需求相當低。任何能夠運行 NodeJS 18 或更高版本的設備都可以執行。若您打算在本地機器上進行 LLM 推理,我們建議使用擁有至少 6GB VRAM 的 3000 系列 NVIDIA 顯示卡。更多詳細資訊,請參考您使用的後端文檔。
|
||||
|
||||
### 推薦後端(僅為推薦,非官方合作和隸屬關係)
|
||||
|
||||
* [AI Horde](https://aihorde.net/):使用志願者託管的模型,無需進一步設定
|
||||
* [KoboldCpp](https://github.com/LostRuins/koboldcpp):社群推崇的選擇,可在本地運行 GGUF 模型
|
||||
* [tabbyAPI](https://github.com/theroyallab/tabbyAPI):一個流行且輕量的本地託管 exl2 推理 API
|
||||
* [OpenRouter](https://openrouter.ai):提供多個雲端 LLM 提供商(如 OpenAI、Claude、Meta Llama 等)及熱門社群模型的單一 API
|
||||
|
||||
## 有任何問題或建議?
|
||||
|
||||
### 歡迎加入我們的 Discord 伺服器
|
||||
|
||||
| [![][discord-shield-badge]][discord-link] | [加入我們的 Disocrd 伺服器](https://discord.gg/sillytavern) 以獲得技術支援、分享您喜愛的角色與提示詞。 |
|
||||
| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------- |
|
||||
|
||||
或直接聯繫開發者:
|
||||
|
||||
* Discord: cohee, rossascends, wolfsblvt
|
||||
* Reddit: [/u/RossAscends](https://www.reddit.com/user/RossAscends/), [/u/sillylossy](https://www.reddit.com/user/sillylossy/), [u/Wolfsblvt](https://www.reddit.com/user/Wolfsblvt/)
|
||||
* [提交 GitHub 問題](https://github.com/SillyTavern/SillyTavern/issues)
|
||||
|
||||
### 我喜歡這個專案,我該如何貢獻呢?
|
||||
|
||||
1. **提交拉取要求(Pull Request)**:想了解如何貢獻,請參閱 [CONTRIBUTING.md](../CONTRIBUTING.md)。
|
||||
2. **提供功能建議與問題報告**:使用本專案所提供的模板提交建議或問題報告。
|
||||
3. **仔細閱讀此 README 文件及相關文檔**:請避免提出重複問題或建議。
|
||||
|
||||
## 螢幕截圖
|
||||
|
||||
<img width="500" alt="image" src="https://github.com/user-attachments/assets/9b5f32f0-c3b3-4102-b3f5-0e9213c0f50f">
|
||||
<img width="500" alt="image" src="https://github.com/user-attachments/assets/913fdbaa-7d33-42f1-ae2c-89dca41c53d1">
|
||||
|
||||
## 角色卡
|
||||
|
||||
SillyTavern 的核心概念是「角色卡」(Character Cards)。角色卡是一組設定 LLM 行為的提示詞,用於 SillyTavern 中進行持續性對話。功能類似於 ChatGPT 的 GPT 或 Poe 的聊天機器人。角色卡的內容可以是任何形式:抽象場景、針對特定任務設計的助手、知名人物,或者虛構角色。
|
||||
|
||||
角色卡中唯一必填的項目是名稱欄位。若想與語言模型開始一般對話,您只需創建一個名稱為「Assistant」的新卡片,其餘欄位皆可保持空白。若希望進行更具主題性的對話,則可以提供語言模型背景資訊、行為模式、寫作風格以及特定情境來啟動聊天。
|
||||
|
||||
如果僅想進行快速對話而不選擇角色卡片,或想測試 LLM 的連線,則可在開啟 SillyTavern 後,於歡迎頁面的輸入欄位中直接輸入您的提示內容。請注意,這類對話是暫時的,不會被永久保存。
|
||||
|
||||
若想了解如何設定角色卡,可參考預設角色(如 Seraphina)或從「下載擴充功能 & 資源」(Download Extensions & Assets)選單中下載社群製作的角色卡。
|
||||
|
||||
## 核心功能
|
||||
|
||||
* 進階文本生成設定:內含許多社群製作的預設設定
|
||||
* 支援世界資訊(World Info):創建豐富的背景故事,或節省角色卡中的 Token(符元)使用
|
||||
* 群組聊天:多角色聊天室,可讓角色與您或彼此對話
|
||||
* 豐富的 UI 自定義選項:主題顏色、背景圖片、自定義 CSS 等
|
||||
* 使用者設定:讓 AI 更了解您並提升沉浸感
|
||||
* 內建 RAG 支持:可將文檔加入對話,供 AI 參考
|
||||
* 強大的聊天指令子系統:內含 [腳本引擎(Scripting Engine)](https://docs.sillytavern.app/usage/st-script/)
|
||||
|
||||
## 擴充功能
|
||||
|
||||
SillyTavern 支持多種擴充功能。
|
||||
|
||||
* 角色情感表達:使用視覺圖片(立繪)呈現情緒表達
|
||||
* 聊天記錄自動摘要
|
||||
* 自動化介面與聊天翻譯
|
||||
* 穩定擴散(Stable Diffusion)、FLUX 和 DALL-E 的影像生成整合
|
||||
* 語音合成:AI 回應的訊息可使用 ElevenLabs、Silero 或系統 TTS 語音合成
|
||||
* 網頁搜尋功能:為提示詞添加真實世界的上下文資訊
|
||||
* 更多擴展:可從「下載擴充功能 & 資源」(Download Extensions & Assets)選單中下載
|
||||
|
||||
想了解如何使用這些擴充功能,請參考:[官方說明文件](https://docs.sillytavern.app/)
|
||||
|
||||
# ⌛ 安裝指南
|
||||
|
||||
> \[!WARNING]
|
||||
>
|
||||
> * 請勿將程式安裝到 Windows 的系統控制資料夾(如 Program Files、System32 等)
|
||||
> * 請勿以管理員權限執行 Start.bat
|
||||
> * 無法在 Windows 7 系統上安裝,因為它無法執行 NodeJS 18.16
|
||||
|
||||
## 🪟 Windows
|
||||
|
||||
### 使用 Git 安裝
|
||||
|
||||
1. 安裝 [NodeJS](https://nodejs.org/en)(建議使用最新的 LTS 版本)
|
||||
2. 安裝 [Git for Windows](https://gitforwindows.org/)
|
||||
3. 打開 Windows 檔案總管(`Win+E`)
|
||||
4. 創建/使用一個不受 Windows 系統控制或監控的資料夾(例如:C:\MySpecialFolder\)
|
||||
5. 在該資料夾內開啟命令提示字元(Command Prompt):點擊地址欄,輸入 `cmd` 並按下 Enter
|
||||
6. 當命令提示字元黑框彈出時,輸入以下其中一條指令後,按下 Enter:
|
||||
|
||||
* 安裝 Release(穩定版)分支:`git clone https://github.com/SillyTavern/SillyTavern -b release`
|
||||
* 安裝 Staging(開發板)分支:`git clone https://github.com/SillyTavern/SillyTavern -b staging`
|
||||
|
||||
7. 當程式碼下載完成後,雙擊 `Start.bat`,NodeJS 將自動安裝所需的依賴項
|
||||
8. 本地伺服器啟動後,SillyTavern 將自動在您的瀏覽器中打開
|
||||
|
||||
### 使用 GitHub Desktop 安裝
|
||||
|
||||
(此方式僅允許通過 GitHub Desktop 使用 git。如果您也希望在命令列中使用 `git`,則需額外安裝 [Git for Windows](https://gitforwindows.org/))
|
||||
|
||||
1. 安裝 [NodeJS](https://nodejs.org/en)(建議使用最新的 LTS 版本)
|
||||
2. 安裝 [GitHub Desktop](https://central.github.com/deployments/desktop/desktop/latest/win32)
|
||||
3. 安裝完成後,打開 GitHub Desktop,點擊 `Clone a repository from the internet....` (注意:此步驟 **無需創建 GitHub 帳號**。)
|
||||
4. 在彈出選單中,點擊「URL」選項,輸入此網址:`https://github.com/SillyTavern/SillyTavern`,然後點擊「Clone」。您可以更改「Local path」來選擇 SillyTavern 的下載位置
|
||||
6. 若想開啟 SillyTavern,需使用 Windows 檔案總管以進入您複製儲存庫的資料夾。預設位置為:`C:\Users\[您的 Windows 使用者名稱]\Documents\GitHub\SillyTavern`
|
||||
7. 雙擊 `start.bat` 文件。(請注意:若您的作業系統隱藏了 `.bat` 副檔名,該文件可能顯示為「`Start`」。這就是您需要雙擊運行的文件。)
|
||||
8. 雙擊後,將會彈出一個大型黑色的命令提示字元視窗,SillyTavern 會開始安裝其運行所需的文件與依賴
|
||||
9. 安裝完成後,若一切正常,命令提示字元視窗應顯示運行中的訊息,且您的瀏覽器會自動打開 SillyTavern 頁籤
|
||||
10. 連接到任何 SillyTavern [支援的 APIs](https://docs.sillytavern.app/usage/api-connections/) 並開始聊天吧!
|
||||
|
||||
## 🐧 Linux & 🍎 MacOS
|
||||
|
||||
對於 MacOS 和 Linux 系統,所有操作都將在終端機(Terminal)中完成。
|
||||
|
||||
1. 安裝 git 和 NodeJS(具體方法因操作系統而異)
|
||||
2. 複製儲存庫(Clone the repo):
|
||||
|
||||
* 安裝 Release(穩定版)分支:`git clone https://github.com/SillyTavern/SillyTavern -b release`
|
||||
* 安裝 Staging(開發板)分支:`git clone https://github.com/SillyTavern/SillyTavern -b staging`
|
||||
|
||||
3. 使用命令 `cd SillyTavern` 以進入安裝資料夾
|
||||
4. 使用以下其中一條命令,以執行 `start.sh` 腳本:
|
||||
|
||||
* `./start.sh`
|
||||
* `bash start.sh`
|
||||
|
||||
## ⚡ 使用 SillyTavern Launcher 安裝
|
||||
|
||||
SillyTavern Launcher 是一個安裝嚮導,協助您設定多種選項,包括安裝本地推理(inference)的後端。
|
||||
|
||||
### 對於 Windows 使用者
|
||||
|
||||
1. 在鍵盤上按下 **`WINDOWS + R`** 打開「執行」對話框,然後輸入以下指令以安裝 git:
|
||||
|
||||
```shell
|
||||
cmd /c winget install -e --id Git.Git
|
||||
```
|
||||
|
||||
2. 在鍵盤上按下 **`WINDOWS + E`** 打開檔案總管,導航至您想要安裝 Launcher 的資料夾。在目標資料夾的地址欄輸入 `cmd` 並按下 Enter。接著執行以下命令:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher && start installer.bat
|
||||
```
|
||||
|
||||
### 對於 Linux 使用者
|
||||
|
||||
1. 打開您喜歡的終端機(Terminal),安裝 git
|
||||
2. 使用以下指令以複製 Sillytavern-Launcher:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher
|
||||
```
|
||||
|
||||
3. 執行安裝腳本(installer.sh):
|
||||
|
||||
```shell
|
||||
chmod +x install.sh && ./install.sh
|
||||
```
|
||||
|
||||
4. 安裝完成後,執行啟動腳本(launcher.sh):
|
||||
|
||||
```shell
|
||||
chmod +x launcher.sh && ./launcher.sh
|
||||
```
|
||||
|
||||
### 對於 Mac 使用者
|
||||
|
||||
1. 打開終端機(Terminal),並使用以下指令安裝 Homebrew:
|
||||
|
||||
```shell
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
|
||||
2. 使用 Homebrew 以安裝 git:
|
||||
|
||||
```shell
|
||||
brew install git
|
||||
```
|
||||
|
||||
3. 使用以下指令以複製 Sillytavern-Launcher:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher
|
||||
```
|
||||
|
||||
4. 執行安裝腳本(installer.sh):
|
||||
|
||||
```shell
|
||||
chmod +x install.sh && ./install.sh
|
||||
```
|
||||
|
||||
5. 安裝完成後,執行啟動腳本(launcher.sh):
|
||||
|
||||
```shell
|
||||
chmod +x launcher.sh && ./launcher.sh
|
||||
```
|
||||
|
||||
## 🐋 使用 Docker 安裝
|
||||
|
||||
以下指南已假設您安裝 Docker,能夠訪問命令列進行容器安裝,並熟悉 Docker 的基本使用。
|
||||
|
||||
### 自行構建映像
|
||||
|
||||
我們提供了一份完整的 [SillyTavern Docker 使用指南](http://docs.sillytavern.app/installation/docker/)。該指南涵蓋了 Windows、macOS 和 Linux 的安裝過程。若您希望自行構建映像,建議先閱讀該文檔。
|
||||
|
||||
### 使用 GitHub 容器註冊表(最簡易的方式)
|
||||
|
||||
您需要設定兩個必要的目錄映射(directory mappings)和一個端口映射(port mapping)來使 SillyTavern 正常運行。在執行指令時,請將以下佔位符替換為您的實際配置:
|
||||
|
||||
#### 容器變數
|
||||
|
||||
##### 目錄映射(Volume Mappings)
|
||||
|
||||
* [config]:用於存放 SillyTavern 設定文件的本地資料夾
|
||||
* [data]:用於存放 SillyTavern 使用者數據(包括角色)的本地資料夾
|
||||
* [plugins](可選):用於存放 SillyTavern 擴充功能的本地資料夾
|
||||
|
||||
##### 端口映射(Port Mappings)
|
||||
|
||||
* [PublicPort]:對外流量的訪問端口。這是必需的,因為您將從虛擬機容器外部訪問實例。除非實施了額外的安全服務,否則請勿將此端口暴露於網路
|
||||
|
||||
##### 其他設定(Additional Settings)
|
||||
|
||||
* [DockerNet]:容器應連接的 Docker 網路。如果您不熟悉此概念,請參閱 [Docker 官方說明文件](https://docs.docker.com/reference/cli/docker/network/)
|
||||
* [version]:在 GitHub 頁面的右側,您可以找到「Packages」。選擇「sillytavern」包,然後查看映像版本。「latest」標籤會使您保持與當前版本同步。您也可以選擇「staging」或「release」標籤,但這可能不適用於依賴擴充功能的使用者,因為擴充功能可能需要時間進行更新
|
||||
|
||||
#### 安裝命令
|
||||
|
||||
1. 打開命令列(Command Line)
|
||||
2. 執行以下指令:
|
||||
|
||||
`docker create --name='sillytavern' --net='[DockerNet]' -p '8000:8000/tcp' -v '[plugins]':'/home/node/app/plugins':'rw' -v '[config]':'/home/node/app/config':'rw' -v '[data]':'/home/node/app/data':'rw' 'ghcr.io/sillytavern/sillytavern:[version]'`
|
||||
|
||||
> 請注意:默認的監聽端口為 8000。如果您在設定文件中更改了此端口,請務必使用適當的端口號
|
||||
|
||||
## 📱 於 Android 系統中使用 Termux 安裝
|
||||
|
||||
> \[!NOTE]
|
||||
> **雖然您可以在 Android 設備上使用 Termux 直接運行 SillyTavern,但這不在我們的官方支持範圍內。**
|
||||
>
|
||||
> **請參閱 ArroganceComplex#2659 所提供的指南:**
|
||||
>
|
||||
> * <https://rentry.org/STAI-Termux>
|
||||
|
||||
**不支援:Android ARM LEtime-web。** 32 位 Android 系統需要額外的依賴項,這無法通過 npm 安裝。請使用以下命令安裝:`pkg install esbuild`。完成後,請按照普通的安裝步驟進行操作
|
||||
|
||||
## API 金鑰管理
|
||||
|
||||
SillyTavern 將您的 API 金鑰(Keys)保存在使用者數據目錄中的 `secrets.json` 文件內(默認路徑為`/data/default-user/secrets.json`)
|
||||
|
||||
默認情況下,API 金鑰在您保存並重新載入頁面後,將不會自介面中顯示
|
||||
|
||||
如需啟用查看金鑰功能:
|
||||
|
||||
1. 在 `config.yaml` 文件中,將 `allowKeysExposure` 的「值」設為 `true`
|
||||
2. 重新啟動 SillyTavern 伺服器
|
||||
3. 點擊 API 連線頁面右下角的「查看隱藏的 API 金鑰(View hidden API keys)」超連結
|
||||
|
||||
## 命令列參數(Command-line Arguments)
|
||||
|
||||
您可以在啟動 SillyTavern 伺服器時傳遞命令列參數,以覆蓋 `config.yaml` 文件中的某些設定。
|
||||
|
||||
### 範例
|
||||
|
||||
```shell
|
||||
node server.js --port 8000 --listen false
|
||||
# or
|
||||
npm run start -- --port 8000 --listen false
|
||||
# or(僅適用於 Windows)
|
||||
Start.bat --port 8000 --listen false
|
||||
```
|
||||
|
||||
### Supported arguments
|
||||
|
||||
| Option | Description | Type |
|
||||
|-------------------------|------------------------------------------------------------------------------------------------------|----------|
|
||||
| `--version` | 顯示版本序號 | boolean |
|
||||
| `--enableIPv6` | 啟用 IPv6 | boolean |
|
||||
| `--enableIPv4` | 啟用 IPv4 | boolean |
|
||||
| `--port` | 設定 SillyTavern 運行的端口。若未提供,則預設使用 `config.yaml` 中的 'port' | number
|
||||
| `--dnsPreferIPv6` | 偏好使用 IPv6 解析 DNS。未提供則默認使用 `config.yaml` 中的 'preferIPv6' | boolean |
|
||||
| `--autorun` | 自動在瀏覽器中啟動 SillyTavern。未提供則默認使用 `config.yaml` 中的 'autorun' | boolean |
|
||||
| `--autorunHostname` | 自動啟動時的主機名稱,通常建議保持為 'auto' | string |
|
||||
| `--autorunPortOverride` | 覆蓋自動啟動的端口設定 | string |
|
||||
| `--listen` | SillyTavern 是否可監聽所有網路接口。若未提供,則默認使用 `config.yaml` 中的 'listen' | boolean |
|
||||
| `--corsProxy` | 啟用 CORS 代理。若未提供,則默認使用 `config.yaml` 中的 'enableCorsProxy' | boolean |
|
||||
| `--disableCsrf` | 停用 CSRF 保護 | boolean |
|
||||
| `--ssl` | 啟用 SSL | boolean |
|
||||
| `--certPath` | 設定您證書文件的路徑 | string |
|
||||
| `--keyPath` | 設定您私人金鑰文件的路徑 | string |
|
||||
| `--whitelist` | 啟用白名單模式 | boolean |
|
||||
| `--dataRoot` | 設定數據儲存的根目錄 | string |
|
||||
| `--avoidLocalhost` | 在自動模式下避免使用 'localhost' | boolean |
|
||||
| `--basicAuthMode` | 啟用基本身份驗證模式 | boolean |
|
||||
| `--requestProxyEnabled` | 啟用代理以處理外部請求 | boolean |
|
||||
| `--requestProxyUrl` | 設定請求代理的 URL(支持 HTTP 或 SOCKS 協議) | string |
|
||||
| `--requestProxyBypass` | 請求代理的例外主機清單(主機列表需以空格分隔) | array |
|
||||
|
||||
## 遠端連線
|
||||
|
||||
遠端連線功能最常用於希望在手機上使用 SillyTavern 的使用者。此時伺服器將由同一 Wi-Fi 網路上的 PC 運行。不過,您也可以設定來自其他網路的遠端連線。
|
||||
|
||||
詳細設定指南請參閱 [官方說明文件](https://docs.sillytavern.app/usage/remoteconnections/)。
|
||||
|
||||
您還可以選擇設定 SillyTavern 的使用者檔案,並開啟密碼保護(可選):[使用者設定指南](https://docs.sillytavern.app/installation/st-1.12.0-migration-guide/#users)。
|
||||
|
||||
## 遇到任何效能問題?
|
||||
|
||||
1. 在「使用者設定」選單(設定介面主題)中,禁用模糊效果(Blur Effect),並開啟「減少動畫效果」(Reduced Motion)
|
||||
2. 若使用響應串流傳輸,請將串流的 FPS 設定為較低的值(建議設定為 10-15 FPS)
|
||||
3. 確保瀏覽器已啟用 GPU 加速以進行渲染
|
||||
|
||||
## 授權與致謝
|
||||
|
||||
**本程式(SillyTavern)的發布是基於其可能對使用者有所幫助的期許,但不提供任何形式的保證;包括但不限於對可銷售性(marketability)或特定用途適用性的隱含保證。如需更多詳情,請參閱 GNU Affero 通用公共許可證。**
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
* [TavernAI](https://github.com/TavernAI/TavernAI) 1.2.8 由 Humi 提供:MIT 許可
|
||||
* 經授權使用部分來自 CncAnon 的 TavernAITurbo 模組
|
||||
* 視覺小說模式(Visual Novel Mode)的靈感,來源於 PepperTaco 的貢獻(<https://github.com/peppertaco/Tavern/>)
|
||||
* Noto Sans 字體由 Google 提供(OFL 許可)
|
||||
* 主題圖示由 Font Awesome <https://fontawesome.com> 提供(圖示:CC BY 4.0,字體:SIL OFL 1.1,程式碼:MIT 許可)
|
||||
* 預設資源來源於 @OtisAlejandro(包含角色 Seraphina 與知識書)與 @kallmeflocc(SillyTavern 官方 Discord 伺服器成員突破 10K 的慶祝背景)
|
||||
* Docker 安裝指南由 [@mrguymiah](https://github.com/mrguymiah) 和 [@Bronya-Rand](https://github.com/Bronya-Rand) 編寫
|
||||
|
||||
## 主要貢獻者
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/graphs/contributors)
|
||||
|
||||
<!-- LINK GROUP -->
|
||||
[cover]: https://github.com/user-attachments/assets/01a6ae9a-16aa-45f2-8bff-32b5dc587e44
|
||||
[discord-link]: https://discord.gg/sillytavern
|
||||
[discord-shield-badge]: https://img.shields.io/discord/1100685673633153084?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=for-the-badge
|
176
.github/readme.md
vendored
@@ -4,7 +4,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
English | [German](readme-de_de.md) | [中文](readme-zh_cn.md) | [日本語](readme-ja_jp.md) | [Русский](readme-ru_ru.md)
|
||||
English | [German](readme-de_de.md) | [中文](readme-zh_cn.md) | [繁體中文](readme-zh_tw.md) | [日本語](readme-ja_jp.md) | [Русский](readme-ru_ru.md) | [한국어](readme-ko_kr.md)
|
||||
|
||||
[](https://github.com/SillyTavern/SillyTavern/stargazers)
|
||||
[](https://github.com/SillyTavern/SillyTavern/network)
|
||||
@@ -23,7 +23,7 @@ We have a [Documentation website](https://docs.sillytavern.app/) to answer most
|
||||
|
||||
SillyTavern (or ST for short) is a locally installed user interface that allows you to interact with text generation LLMs, image generation engines, and TTS voice models.
|
||||
|
||||
Beginning in February 2023 as a fork of TavernAI 1.2.8, SillyTavern now has over 100 contributors and 2 years of independent development under its belt, and continues to serve as a leading software for savvy AI hobbyists.
|
||||
Beginning in February 2023 as a fork of TavernAI 1.2.8, SillyTavern now has over 200 contributors and 2 years of independent development under its belt, and continues to serve as a leading software for savvy AI hobbyists.
|
||||
|
||||
## Our Vision
|
||||
|
||||
@@ -113,7 +113,9 @@ SillyTavern has extensibility support.
|
||||
|
||||
Tutorials on how to use them can be found in the [Docs](https://docs.sillytavern.app/).
|
||||
|
||||
# ⌛ Installation
|
||||
## ⌛ Installation
|
||||
|
||||
### 🪟 Windows
|
||||
|
||||
> \[!WARNING]
|
||||
>
|
||||
@@ -121,9 +123,7 @@ Tutorials on how to use them can be found in the [Docs](https://docs.sillytavern
|
||||
> * DO NOT RUN START.BAT WITH ADMIN PERMISSIONS
|
||||
> * INSTALLATION ON WINDOWS 7 IS IMPOSSIBLE AS IT CAN NOT RUN NODEJS 18.16
|
||||
|
||||
## 🪟 Windows
|
||||
|
||||
### Installing via Git
|
||||
#### Installing via Git (recommended)
|
||||
|
||||
1. Install [NodeJS](https://nodejs.org/en) (latest LTS version is recommended)
|
||||
2. Install [Git for Windows](https://gitforwindows.org/)
|
||||
@@ -138,7 +138,7 @@ Tutorials on how to use them can be found in the [Docs](https://docs.sillytavern
|
||||
7. Once everything is cloned, double-click `Start.bat` to make NodeJS install its requirements.
|
||||
8. The server will then start, and SillyTavern will pop up in your browser.
|
||||
|
||||
### Installing via GitHub Desktop
|
||||
#### Installing via GitHub Desktop
|
||||
|
||||
(This allows git usage **only** in GitHub Desktop, if you want to use `git` on the command line too, you also need to install [Git for Windows](https://gitforwindows.org/))
|
||||
|
||||
@@ -152,7 +152,7 @@ Tutorials on how to use them can be found in the [Docs](https://docs.sillytavern
|
||||
9. After the installation process, if everything is working, the command console window should look like this and a SillyTavern tab should be open in your browser:
|
||||
10. Connect to any of the [supported APIs](https://docs.sillytavern.app/usage/api-connections/) and start chatting!
|
||||
|
||||
## 🐧 Linux & 🍎 MacOS
|
||||
### 🐧 Linux & 🍎 MacOS
|
||||
|
||||
For MacOS / Linux all of these will be done in a Terminal.
|
||||
|
||||
@@ -168,6 +168,57 @@ For MacOS / Linux all of these will be done in a Terminal.
|
||||
* `./start.sh`
|
||||
* `bash start.sh`
|
||||
|
||||
## 🐋 Installing via Docker
|
||||
|
||||
These instructions assume you have installed Docker, are able to access your command line for the installation of containers, and familiar with their general operation.
|
||||
|
||||
### Using the GitHub Container Registry
|
||||
|
||||
#### Docker Compose (easiest)
|
||||
|
||||
Grab the `docker-compose.yml` file from the [GitHub Repository](https://github.com/SillyTavern/SillyTavern/blob/release/docker/docker-compose.yml) and run the following command in the directory where the file is located. This will pull the latest release image from the GitHub Container Registry and start the container, automatically creating the necessary volumes.
|
||||
|
||||
```shell
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
Customize the `docker-compose.yml` file to your needs. The default port is 8000. If you want to adjust the server configuration using environment variables, read the documentation [here](https://docs.sillytavern.app/administration/config-yaml/#environment-variables).
|
||||
|
||||
#### Docker CLI (advanced)
|
||||
|
||||
You will need two mandatory directory mappings and a port mapping to allow SillyTavern to function. In the command, replace your selections in the following places:
|
||||
|
||||
#### Container Variables
|
||||
|
||||
##### Volume Mappings
|
||||
|
||||
* [config] - The directory where SillyTavern configuration files will be stored on your host machine
|
||||
* [data] - The directory where SillyTavern user data (including characters) will be stored on your host machine
|
||||
* [plugins] - (optional) The directory where SillyTavern server plugins will be stored on your host machine
|
||||
* [extensions] - (optional) The directory where global UI extensions will be stored on your host machine
|
||||
|
||||
##### Port Mappings
|
||||
|
||||
* [PublicPort] - The port to expose the traffic on. This is mandatory, as you will be accessing the instance from outside of its virtual machine container. DO NOT expose this to the internet without implementing a separate service for security.
|
||||
|
||||
##### Additional Settings
|
||||
|
||||
* [DockerNet] - The docker network that the container should be created with a connection to. If you don't know what it is, see the [official Docker documentation](https://docs.docker.com/reference/cli/docker/network/).
|
||||
* [version] - On the right-hand side of this GitHub page, you'll see "Packages". Select the "sillytavern" package and you'll see the image versions. The image tag "latest" will keep you up-to-date with the current release. You can also utilize "staging" and "release" tags that point to the nightly images of the respective branches, but this may not be appropriate, if you are utilizing extensions that could be broken, and may need time to update.
|
||||
|
||||
#### Install command
|
||||
|
||||
1. Open your Command Line
|
||||
2. Run the following command
|
||||
|
||||
`docker run --name='sillytavern' --net='[DockerNet]' -p '8000:8000/tcp' -v '[plugins]':'/home/node/app/plugins':'rw' -v '[config]':'/home/node/app/config':'rw' -v '[data]':'/home/node/app/data':'rw' -v '[extensions]':'/home/node/app/public/scripts/extensions/third-party':'rw' 'ghcr.io/sillytavern/sillytavern:[version]'`
|
||||
|
||||
> Note that 8000 is a default listening port. Don't forget to use an appropriate port if you change it in the config.
|
||||
|
||||
### Building the image yourself
|
||||
|
||||
We have a comprehensive guide on using SillyTavern in Docker [here](http://docs.sillytavern.app/installation/docker/) which covers installations on Windows, macOS and Linux! Give it a read if you wish to build the image yourself.
|
||||
|
||||
## ⚡ Installing via SillyTavern Launcher
|
||||
|
||||
SillyTavern Launcher is an installation wizard that will help you get setup with many options, including installing a backend for local inference.
|
||||
@@ -239,44 +290,6 @@ chmod +x install.sh && ./install.sh
|
||||
chmod +x launcher.sh && ./launcher.sh
|
||||
```
|
||||
|
||||
## 🐋 Installing via Docker
|
||||
|
||||
These instructions assume you have installed Docker, are able to access your command line for the installation of containers, and familiar with their general operation.
|
||||
|
||||
### Building the image yourself
|
||||
|
||||
We have a comprehensive guide on using SillyTavern in Docker [here](http://docs.sillytavern.app/installation/docker/) which covers installations on Windows, macOS and Linux! Give it a read if you wish to build the image yourself.
|
||||
|
||||
### Using the GitHub Container Registry (easiest)
|
||||
|
||||
You will need two mandatory directory mappings and a port mapping to allow SillyTavern to function. In the command, replace your selections in the following places:
|
||||
|
||||
#### Container Variables
|
||||
|
||||
##### Volume Mappings
|
||||
|
||||
* [config] - The directory where SillyTavern configuration files will be stored on your host machine
|
||||
* [data] - The directory where SillyTavern user data (including characters) will be stored on your host machine
|
||||
* [plugins] - (optional) The directory where SillyTavern server plugins will be stored on your host machine
|
||||
|
||||
##### Port Mappings
|
||||
|
||||
* [PublicPort] - The port to expose the traffic on. This is mandatory, as you will be accessing the instance from outside of its virtual machine container. DO NOT expose this to the internet without implementing a separate service for security.
|
||||
|
||||
##### Additional Settings
|
||||
|
||||
* [DockerNet] - The docker network that the container should be created with a connection to. If you don't know what it is, see the [official Docker documentation](https://docs.docker.com/reference/cli/docker/network/).
|
||||
* [version] - On the right-hand side of this GitHub page, you'll see "Packages". Select the "sillytavern" package and you'll see the image versions. The image tag "latest" will keep you up-to-date with the current release. You can also utilize "staging" and "release" tags that point to the nightly images of the respective branches, but this may not be appropriate, if you are utilizing extensions that could be broken, and may need time to update.
|
||||
|
||||
#### Install command
|
||||
|
||||
1. Open your Command Line
|
||||
2. Run the following command
|
||||
|
||||
`docker create --name='sillytavern' --net='[DockerNet]' -p '8000:8000/tcp' -v '[plugins]':'/home/node/app/plugins':'rw' -v '[config]':'/home/node/app/config':'rw' -v '[data]':'/home/node/app/data':'rw' 'ghcr.io/sillytavern/sillytavern:[version]'`
|
||||
|
||||
> Note that 8000 is a default listening port. Don't forget to use an appropriate port if you change it in the config.
|
||||
|
||||
## 📱 Installing via Termux on Android OS
|
||||
|
||||
> \[!NOTE]
|
||||
@@ -316,29 +329,34 @@ Start.bat --port 8000 --listen false
|
||||
|
||||
### Supported arguments
|
||||
|
||||
| Option | Description | Type |
|
||||
|-------------------------|------------------------------------------------------------------------------------------------------|----------|
|
||||
| `--version` | Show version number | boolean |
|
||||
| `--enableIPv6` | Enables IPv6. | boolean |
|
||||
| `--enableIPv4` | Enables IPv4. | boolean |
|
||||
| `--port` | Sets the port under which SillyTavern will run. If not provided falls back to yaml config 'port'. | number |
|
||||
| `--dnsPreferIPv6` | Prefers IPv6 for dns. If not provided falls back to yaml config 'preferIPv6'. | boolean |
|
||||
| `--autorun` | Automatically launch SillyTavern in the browser. If not provided falls back to yaml config 'autorun'.| boolean |
|
||||
| `--autorunHostname` | The autorun hostname, probably best left on 'auto'. | string |
|
||||
| `--autorunPortOverride` | Overrides the port for autorun. | string |
|
||||
| `--listen` | SillyTavern is listening on all network interfaces. If not provided falls back to yaml config 'listen'.| boolean |
|
||||
| `--corsProxy` | Enables CORS proxy. If not provided falls back to yaml config 'enableCorsProxy'. | boolean |
|
||||
| `--disableCsrf` | Disables CSRF protection | boolean |
|
||||
| `--ssl` | Enables SSL | boolean |
|
||||
| `--certPath` | Path to your certificate file. | string |
|
||||
| `--keyPath` | Path to your private key file. | string |
|
||||
| `--whitelist` | Enables whitelist mode | boolean |
|
||||
| `--dataRoot` | Root directory for data storage | string |
|
||||
| `--avoidLocalhost` | Avoids using 'localhost' for autorun in auto mode. | boolean |
|
||||
| `--basicAuthMode` | Enables basic authentication | boolean |
|
||||
| `--requestProxyEnabled` | Enables a use of proxy for outgoing requests | boolean |
|
||||
| `--requestProxyUrl` | Request proxy URL (HTTP or SOCKS protocols) | string |
|
||||
| `--requestProxyBypass` | Request proxy bypass list (space separated list of hosts) | array |
|
||||
> \[!TIP]
|
||||
> None of the arguments are required. If you don't provide them, SillyTavern will use the settings in `config.yaml`.
|
||||
|
||||
| Option | Description | Type |
|
||||
|-------------------------|----------------------------------------------------------------------|----------|
|
||||
| `--version` | Show version number | boolean |
|
||||
| `--dataRoot` | Root directory for data storage | string |
|
||||
| `--port` | Sets the port under which SillyTavern will run | number |
|
||||
| `--listen` | SillyTavern will listen on all network interfaces | boolean |
|
||||
| `--whitelist` | Enables whitelist mode | boolean |
|
||||
| `--basicAuthMode` | Enables basic authentication | boolean |
|
||||
| `--enableIPv4` | Enables IPv4 protocol | boolean |
|
||||
| `--enableIPv6` | Enables IPv6 protocol | boolean |
|
||||
| `--listenAddressIPv4` | Specific IPv4 address to listen to | string |
|
||||
| `--listenAddressIPv6` | Specific IPv6 address to listen to | string |
|
||||
| `--dnsPreferIPv6` | Prefers IPv6 for DNS | boolean |
|
||||
| `--ssl` | Enables SSL | boolean |
|
||||
| `--certPath` | Path to your certificate file | string |
|
||||
| `--keyPath` | Path to your private key file | string |
|
||||
| `--autorun` | Automatically launch SillyTavern in the browser | boolean |
|
||||
| `--autorunHostname` | Autorun hostname | string |
|
||||
| `--autorunPortOverride` | Overrides the port for autorun | string |
|
||||
| `--avoidLocalhost` | Avoids using 'localhost' for autorun in auto mode | boolean |
|
||||
| `--corsProxy` | Enables CORS proxy | boolean |
|
||||
| `--requestProxyEnabled` | Enables a use of proxy for outgoing requests | boolean |
|
||||
| `--requestProxyUrl` | Request proxy URL (HTTP or SOCKS protocols) | string |
|
||||
| `--requestProxyBypass` | Request proxy bypass list (space separated list of hosts) | array |
|
||||
| `--disableCsrf` | Disables CSRF protection (NOT RECOMMENDED) | boolean |
|
||||
|
||||
## Remote connections
|
||||
|
||||
@@ -350,10 +368,29 @@ You may also want to configure SillyTavern user profiles with (optional) passwor
|
||||
|
||||
## Performance issues?
|
||||
|
||||
### General tips
|
||||
|
||||
1. Disable the Blur Effect and enable Reduced Motion on the User Settings panel (UI Theme toggles category).
|
||||
2. If using response streaming, set the streaming FPS to a lower value (10-15 FPS is recommended).
|
||||
3. Make sure the browser is enabled to use GPU acceleration for rendering.
|
||||
|
||||
### Input lag
|
||||
|
||||
Performance degradation, particularly input lag, is most commonly attributed to browser extensions. Known problematic extensions include:
|
||||
|
||||
* iCloud Password Manager
|
||||
* DeepL Translation
|
||||
* AI-based grammar correction tools
|
||||
* Various ad-blocking extensions
|
||||
|
||||
If you experience performance issues and cannot identify the cause, or suspect an issue with SillyTavern itself, please:
|
||||
|
||||
1. [Record a performance profile](https://developer.chrome.com/docs/devtools/performance/reference)
|
||||
2. Export the profile as a JSON file
|
||||
3. Submit it to the development team for analysis
|
||||
|
||||
We recommend first testing with all browser extensions and third-party SillyTavern extensions disabled to isolate the source of the performance degradation.
|
||||
|
||||
## License and credits
|
||||
|
||||
**This program is distributed in the hope that it will be useful,
|
||||
@@ -368,6 +405,7 @@ GNU Affero General Public License for more details.**
|
||||
* Icon theme by Font Awesome <https://fontawesome.com> (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
* Default content by @OtisAlejandro (Seraphina character and lorebook) and @kallmeflocc (10K Discord Users Celebratory Background)
|
||||
* Docker guide by [@mrguymiah](https://github.com/mrguymiah) and [@Bronya-Rand](https://github.com/Bronya-Rand)
|
||||
* kokoro-js library by [@hexgrad](https://github.com/hexgrad) (Apache-2.0 License)
|
||||
|
||||
## Top Contributors
|
||||
|
||||
|
28
.github/workflows/add-comment-from-tag.yml
vendored
@@ -1,28 +0,0 @@
|
||||
# Based on a label applied to an issue, the bot will add a comment with some additional info
|
||||
|
||||
name: 🎯 Auto-Reply to Labeled Tickets
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- labeled
|
||||
- unlabeled
|
||||
pull_request_target:
|
||||
types:
|
||||
- labeled
|
||||
- unlabeled
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Label Commenter
|
||||
uses: peaceiris/actions-label-commenter@v1
|
||||
with:
|
||||
config_file: .github/issue-auto-comments.yml
|
||||
github_token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
17
.github/workflows/check-merge-conflicts.yml
vendored
@@ -1,17 +0,0 @@
|
||||
# Detect and label pull requests that have merge conflicts
|
||||
name: 🏗️ Check Merge Conflicts
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- staging
|
||||
jobs:
|
||||
check-conflicts:
|
||||
if: github.repository == 'SillyTavern/SillyTavern'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: mschilde/auto-label-merge-conflicts@master
|
||||
with:
|
||||
CONFLICT_LABEL_NAME: "🚫 Merge Conflicts"
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
MAX_RETRIES: 5
|
||||
WAIT_MS: 5000
|
82
.github/workflows/close-stale-issues.yml
vendored
@@ -1,82 +0,0 @@
|
||||
# Closes any issues that no longer have user interaction
|
||||
name: 🎯 Close Stale Issues
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *' # Runs every day at midnight UTC
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Comment on, then close issues that haven't been updated for ages
|
||||
- name: Close Stale Issues
|
||||
uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 183
|
||||
days-before-close: 7
|
||||
operations-per-run: 30
|
||||
remove-stale-when-updated: true
|
||||
enable-statistics: true
|
||||
stale-issue-message: >
|
||||
This issue has gone 6 months without an update. To keep the ticket open, please indicate that it is still relevant in a comment below.
|
||||
Otherwise it will be closed in 7 days.
|
||||
stale-pr-message: >
|
||||
This PR is stale because it has been open 6 months with no activity. Either remove the stale label or comment below with a short update,
|
||||
otherwise this PR will be closed in 7 days.
|
||||
close-issue-message: >
|
||||
This issue was automatically closed because it has been stalled for over 6 months with no activity.
|
||||
close-pr-message: >
|
||||
This pull request was automatically closed because it has been stalled for over 6 months with no activity.
|
||||
stale-issue-label: '⚰️ Stale'
|
||||
close-issue-label: '🕸️ Inactive'
|
||||
stale-pr-label: '⚰️ Stale'
|
||||
close-pr-label: '🕸️ Inactive'
|
||||
exempt-issue-labels: '📌 Keep Open'
|
||||
exempt-pr-labels: '📌 Keep Open'
|
||||
labels-to-add-when-unstale: '📌 Keep Open'
|
||||
|
||||
# Comment on, then close issues that required a response from the user, but didn't get one
|
||||
- name: Close Issues without Response
|
||||
uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 7
|
||||
operations-per-run: 30
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-message: >
|
||||
Hi! Looks like additional info is required for this issue to be addressed.
|
||||
Don't forget to provide this within the next few days to keep your ticket open.
|
||||
close-issue-message: 'Issue closed due to no response from user.'
|
||||
only-labels: '🚏 Awaiting User Response'
|
||||
labels-to-remove-when-unstale: '🚏 Awaiting User Response, 🛑 No Response'
|
||||
stale-issue-label: '🛑 No Response'
|
||||
close-issue-label: '🕸️ Inactive'
|
||||
exempt-issue-labels: '📌 Keep Open'
|
||||
exempt-pr-labels: '📌 Keep Open'
|
||||
|
||||
# Comment on issues that we should have replied to
|
||||
- name: Notify Repo Owner to Respond
|
||||
uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 183
|
||||
operations-per-run: 30
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-message: Hey SillyTavern, - Don't forget to respond!
|
||||
stale-pr-message: Hey SillyTavern, - Don't forget to respond!
|
||||
only-labels: '👤 Awaiting Maintainer Response'
|
||||
labels-to-remove-when-unstale: '👤 Awaiting Maintainer Response'
|
||||
close-issue-message: 'Closed due to no response from repo author for over a year'
|
||||
close-pr-message: 'Closed due to no response from repo author for over a year'
|
||||
stale-issue-label: '👤 Awaiting Maintainer Response'
|
||||
stale-pr-label: '👤 Awaiting Maintainer Response'
|
||||
close-issue-label: '🕸️ Inactive'
|
||||
close-pr-label: '🕸️ Inactive'
|
||||
exempt-issue-labels: '📌 Keep Open'
|
||||
exempt-pr-labels: '📌 Keep Open'
|
39
.github/workflows/get-pr-size.yml
vendored
@@ -1,39 +0,0 @@
|
||||
# Adds a comment to new PRs, showing the compressed size and size difference of new code
|
||||
# And also labels the PR based on the number of lines changes
|
||||
|
||||
name: 🌈 Check PR Size
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
# Find and comment with compressed size
|
||||
- name: Get Compressed Size
|
||||
uses: preactjs/compressed-size-action@v2
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
pattern: './dist/**/*.{js,css,html}'
|
||||
strip-hash: '\\b\\w{8}\\.'
|
||||
exclude: '**/node_modules/**'
|
||||
minimum-change-threshold: 100
|
||||
# Check number of lines of code added
|
||||
- name: Label based on Lines of Code
|
||||
uses: codelytv/pr-size-labeler@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
xs_max_size: '10'
|
||||
s_max_size: '100'
|
||||
m_max_size: '500'
|
||||
l_max_size: '1000'
|
||||
s_label: '🟩 PR - Small'
|
||||
m_label: '🟨 PR - Medium'
|
||||
l_label: '🟧 PR - Large'
|
||||
xl_label: '🟥 PR - XL'
|
||||
fail_if_xl: 'false'
|
||||
message_if_xl: >
|
||||
It looks like this PR is very large (over 1000 lines).
|
||||
Try to avoid addressing multiple issues in a single PR, and
|
||||
in the future consider breaking large tasks down into smaller steps.
|
||||
This it to make reviewing, testing, reverting and general quality management easier.
|
116
.github/workflows/issues-auto-manager.yml
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
name: 🛠️ Issues Manager
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited, labeled, unlabeled]
|
||||
# Re also listen to comments, to remove stale labels right away
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
label-on-content:
|
||||
name: 🏷️ Label Issues by Content
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
# Checkout
|
||||
# https://github.com/marketplace/actions/checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Auto-Label Issues (Based on Issue Content)
|
||||
# only auto label based on issue content once, on open (to prevent re-labeling removed labels)
|
||||
if: github.event.action == 'opened'
|
||||
|
||||
# Issue Labeler
|
||||
# https://github.com/marketplace/actions/regex-issue-labeler
|
||||
uses: github/issue-labeler@v3.4
|
||||
with:
|
||||
configuration-path: .github/issues-auto-labels.yml
|
||||
enable-versioned-regex: 0
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
|
||||
label-on-labels:
|
||||
name: 🏷️ Label Issues by Labels
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: ✅ Add "👍 Approved" for relevant labels
|
||||
if: contains(fromJSON('["👩💻 Good First Issue", "🙏 Help Wanted", "🪲 Confirmed", "⚠️ High Priority", "❕ Medium Priority", "💤 Low Priority"]'), github.event.label.name)
|
||||
# 🤖 Issues Helper
|
||||
# https://github.com/marketplace/actions/issues-helper
|
||||
uses: actions-cool/issues-helper@v3.6.0
|
||||
with:
|
||||
actions: 'add-labels'
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
labels: '👍 Approved'
|
||||
|
||||
- name: ❌ Remove progress labels when issue is marked done or stale
|
||||
if: contains(fromJSON('["✅ Done", "✅ Done (staging)", "⚰️ Stale", "❌ wontfix"]'), github.event.label.name)
|
||||
# 🤖 Issues Helper
|
||||
# https://github.com/marketplace/actions/issues-helper
|
||||
uses: actions-cool/issues-helper@v3.6.0
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
labels: '🧑💻 In Progress,🤔 Unsure,🤔 Under Consideration'
|
||||
|
||||
- name: ❌ Remove temporary labels when confirmed labels are added
|
||||
if: contains(fromJSON('["❌ wontfix","👍 Approved","👩💻 Good First Issue"]'), github.event.label.name)
|
||||
# 🤖 Issues Helper
|
||||
# https://github.com/marketplace/actions/issues-helper
|
||||
uses: actions-cool/issues-helper@v3.6.0
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
labels: '🤔 Unsure,🤔 Under Consideration'
|
||||
|
||||
- name: ❌ Remove no bug labels when "🪲 Confirmed" is added
|
||||
if: github.event.label.name == '🪲 Confirmed'
|
||||
# 🤖 Issues Helper
|
||||
# https://github.com/marketplace/actions/issues-helper
|
||||
uses: actions-cool/issues-helper@v3.6.0
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
labels: '✖️ Not Reproducible,✖️ Not A Bug'
|
||||
|
||||
remove-stale-label:
|
||||
name: 🗑️ Remove Stale Label on Comment
|
||||
runs-on: ubuntu-latest
|
||||
# Only run this on new comments, to automatically remove the stale label
|
||||
if: github.event_name == 'issue_comment' && github.actor != 'github-actions[bot]'
|
||||
|
||||
steps:
|
||||
- name: Remove Stale Label
|
||||
# 🤖 Issues Helper
|
||||
# https://github.com/marketplace/actions/issues-helper
|
||||
uses: actions-cool/issues-helper@v3.6.0
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '⚰️ Stale,🕸️ Inactive,🚏 Awaiting User Response,🛑 No Response'
|
||||
|
||||
write-auto-comments:
|
||||
name: 💬 Post Issue Comments Based on Labels
|
||||
needs: [label-on-content, label-on-labels]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
# Checkout
|
||||
# https://github.com/marketplace/actions/checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Post Issue Comments Based on Labels
|
||||
# Label Commenter
|
||||
# https://github.com/marketplace/actions/label-commenter
|
||||
uses: peaceiris/actions-label-commenter@v1.10.0
|
||||
with:
|
||||
config_file: .github/issues-auto-comments.yml
|
||||
github_token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
45
.github/workflows/issues-updates-on-merge.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: 🔄 Update Issues on Push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- staging
|
||||
- release
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
# This runs commits to staging/release, reading the commit messages. Check `pr-auto-manager.yml`:`update-linked-issues` for PR-linked updates.
|
||||
update-linked-issues:
|
||||
name: 🔗 Mark Linked Issues Done on Push
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
# Checkout
|
||||
# https://github.com/marketplace/actions/checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Extract Linked Issues from Commit Message
|
||||
id: extract_issues
|
||||
run: |
|
||||
ISSUES=$(git log ${{ github.event.before }}..${{ github.event.after }} --pretty=%B | grep -oiE '(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) #([0-9]+)' | awk '{print $2}' | tr -d '#' | jq -R -s -c 'split("\n")[:-1]')
|
||||
echo "issues=$ISSUES" >> $GITHUB_ENV
|
||||
|
||||
- name: Label Linked Issues
|
||||
id: label_linked_issues
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
for ISSUE in $(echo $issues | jq -r '.[]'); do
|
||||
if [ "${{ github.ref }}" == "refs/heads/staging" ]; then
|
||||
LABEL="✅ Done (staging)"
|
||||
gh issue edit $ISSUE -R ${{ github.repository }} --add-label "$LABEL"
|
||||
elif [ "${{ github.ref }}" == "refs/heads/release" ]; then
|
||||
LABEL="✅ Done"
|
||||
gh issue edit $ISSUE -R ${{ github.repository }} --add-label "$LABEL"
|
||||
fi
|
||||
echo "Added label '$LABEL' to issue #$ISSUE"
|
||||
done
|
100
.github/workflows/job-close-stale.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
name: 🕒 Close Stale Issues/PRs Workflow
|
||||
|
||||
on:
|
||||
# Run the workflow every day
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *' # Runs every day at midnight UTC
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
mark-inactivity:
|
||||
name: ⏳ Mark Issues/PRs without Activity
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Mark Issues/PRs without Activity
|
||||
# Close Stale Issues and PRs
|
||||
# https://github.com/marketplace/actions/close-stale-issues
|
||||
uses: actions/stale@v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 183
|
||||
days-before-close: 7
|
||||
operations-per-run: 30
|
||||
remove-stale-when-updated: true
|
||||
enable-statistics: true
|
||||
stale-issue-message: >
|
||||
⏳ This issue has been inactive for 6 months. If it's still relevant, drop a comment below to keep it open.
|
||||
Otherwise, it will be auto-closed in 7 days.
|
||||
stale-pr-message: >
|
||||
⏳ This PR has been inactive for 6 months. If it's still relevant, update it or remove the stale label.
|
||||
Otherwise, it will be auto-closed in 7 days.
|
||||
close-issue-message: >
|
||||
🔒 This issue was auto-closed due to inactivity for over 6 months.
|
||||
close-pr-message: >
|
||||
🔒 This PR was auto-closed due to inactivity for over 6 months.
|
||||
stale-issue-label: '⚰️ Stale'
|
||||
close-issue-label: '🕸️ Inactive'
|
||||
stale-pr-label: '⚰️ Stale'
|
||||
close-pr-label: '🕸️ Inactive'
|
||||
exempt-issue-labels: '📌 Keep Open'
|
||||
exempt-pr-labels: '📌 Keep Open'
|
||||
|
||||
await-user-response:
|
||||
name: ⚠️ Mark Issues/PRs Awaiting User Response
|
||||
runs-on: ubuntu-latest
|
||||
needs: mark-inactivity
|
||||
|
||||
steps:
|
||||
- name: Mark Issues/PRs Awaiting User Response
|
||||
# Close Stale Issues and PRs
|
||||
# https://github.com/marketplace/actions/close-stale-issues
|
||||
uses: actions/stale@v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 7
|
||||
operations-per-run: 30
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-message: >
|
||||
⚠️ Hey! We need some more info to move forward with this issue.
|
||||
Please provide the requested details in the next few days to keep this ticket open.
|
||||
close-issue-message: >
|
||||
🔒 This issue was auto-closed due to no response from user.
|
||||
only-labels: '🚏 Awaiting User Response'
|
||||
labels-to-remove-when-unstale: '🚏 Awaiting User Response'
|
||||
stale-issue-label: '🛑 No Response'
|
||||
close-issue-label: '🕸️ Inactive'
|
||||
exempt-issue-labels: '🚧 Alternative Exists'
|
||||
|
||||
alternative-exists:
|
||||
name: 🔄 Mark Issues with Alternative Exists
|
||||
runs-on: ubuntu-latest
|
||||
needs: await-user-response
|
||||
|
||||
steps:
|
||||
- name: Mark Issues with Alternative Exists
|
||||
# Close Stale Issues and PRs
|
||||
# https://github.com/marketplace/actions/close-stale-issues
|
||||
uses: actions/stale@v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 7
|
||||
operations-per-run: 30
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-message: >
|
||||
🔄 An alternative solution has been provided for this issue.
|
||||
Did this solve your problem? If so, we'll go ahead and close it.
|
||||
If you still need help, drop a comment within the next 7 days to keep this open.
|
||||
close-issue-message: >
|
||||
✅ Closing this issue due to no confirmation on the alternative solution.
|
||||
only-labels: '🚧 Alternative Exists'
|
||||
stale-issue-label: '🚏 Awaiting User Response'
|
||||
close-issue-label: '🕸️ Inactive'
|
||||
exempt-issue-labels: '📌 Keep Open'
|
19
.github/workflows/labeler.yml
vendored
@@ -1,19 +0,0 @@
|
||||
name: "Issue Labeler"
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: github/issue-labeler@v3.4
|
||||
with:
|
||||
configuration-path: .github/labeler.yml
|
||||
# not-before: 2020-01-15T02:54:32Z # optional and will result in any issues prior to this timestamp to be ignored.
|
||||
enable-versioned-regex: 0
|
||||
repo-token: ${{ github.token }}
|
@@ -1,17 +0,0 @@
|
||||
# When a new comment is added to an issue, if it had the Stale or Awaiting User Response labels, then those labels will be removed
|
||||
|
||||
name: 🎯 Remove Pending Labels on Close
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
jobs:
|
||||
remove-labels:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Remove Labels when Closed
|
||||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: remove-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '🚏 Awaiting User Response,⚰️ Stale,👤 Awaiting Maintainer Response'
|
42
.github/workflows/manage-pending-labels.yml
vendored
@@ -1,42 +0,0 @@
|
||||
# When a new comment is added to an issue, if it had the Stale or Awaiting User Response labels, then those labels will be removed
|
||||
|
||||
name: 🎯 Add/ Remove Awaiting Response Labels
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
jobs:
|
||||
remove-stale:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.comment.author_association != 'COLLABORATOR' && github.event.comment.author_association != 'OWNER' }}
|
||||
steps:
|
||||
- name: Remove Stale labels when Updated
|
||||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: remove-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '🚏 Awaiting User Response,⚰️ Stale'
|
||||
|
||||
add-awaiting-author:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{!github.event.issue.pull_request && github.event.comment.author_association != 'COLLABORATOR' && github.event.comment.author_association != 'OWNER' && github.event.issue.state == 'open' }}
|
||||
steps:
|
||||
- name: Add Awaiting Author labels when Updated
|
||||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: add-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '👤 Awaiting Maintainer Response'
|
||||
|
||||
remove-awaiting-author:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.comment.author_association == 'OWNER' }}
|
||||
steps:
|
||||
- name: Remove Awaiting Author labels when Updated
|
||||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: remove-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '👤 Awaiting Maintainer Response'
|
28
.github/workflows/on-close-handler.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: 🚪 Issues/PRs On Close Handler
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
pull_request_target:
|
||||
types: [closed]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
remove-labels:
|
||||
name: 🗑️ Remove Pending Labels on Close
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Remove Pending Labels on Close
|
||||
# 🤖 Issues Helper
|
||||
# https://github.com/marketplace/actions/issues-helper
|
||||
uses: actions-cool/issues-helper@v3.6.0
|
||||
with:
|
||||
actions: remove-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number || github.event.pull_request.number }}
|
||||
labels: '🚏 Awaiting User Response,🧑💻 In Progress,📌 Keep Open,🚫 Merge Conflicts,🔬 Needs Testing,🔨 Needs Work,⚰️ Stale,⛔ Waiting For External/Upstream'
|
29
.github/workflows/on-open-handler.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: 📨 Issues/PRs Open Handler
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
label-maintainer:
|
||||
name: 🏷️ Label if Author is a Repo Maintainer
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(fromJson('["Cohee1207", "RossAscends", "Wolfsblvt"]'), github.actor)
|
||||
|
||||
steps:
|
||||
- name: Label if Author is a Repo Maintainer
|
||||
# 🤖 Issues Helper
|
||||
# https://github.com/marketplace/actions/issues-helper
|
||||
uses: actions-cool/issues-helper@v3.6.0
|
||||
with:
|
||||
actions: 'add-labels'
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number || github.event.pull_request.number }}
|
||||
labels: '👷 Maintainer'
|
202
.github/workflows/pr-auto-manager.yml
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
name: 🔀 Pull Request Manager
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened, edited, labeled, unlabeled, closed]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
label-by-size:
|
||||
name: 🏷️ Label PR by Size
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Label PR Size
|
||||
# Pull Request Size Labeler
|
||||
# https://github.com/marketplace/actions/pull-request-size-labeler
|
||||
uses: codelytv/pr-size-labeler@v1.10.2
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
xs_label: '🟩 ⬤○○○○'
|
||||
xs_max_size: '20'
|
||||
s_label: '🟩 ⬤⬤○○○'
|
||||
s_max_size: '100'
|
||||
m_label: '🟨 ⬤⬤⬤○○'
|
||||
m_max_size: '500'
|
||||
l_label: '🟧 ⬤⬤⬤⬤○'
|
||||
l_max_size: '1000'
|
||||
xl_label: '🟥 ⬤⬤⬤⬤⬤'
|
||||
fail_if_xl: 'false'
|
||||
github_api_url: 'https://api.github.com'
|
||||
files_to_ignore: |
|
||||
"package-lock.json"
|
||||
"public/lib/*"
|
||||
|
||||
label-by-branches:
|
||||
name: 🏷️ Label PR by Branches
|
||||
runs-on: ubuntu-latest
|
||||
# Only label once when PR is created or branches are changed, to allow manual label removal
|
||||
if: github.event.action == 'opened' || (github.event.action == 'synchronize' && (github.event.changes.base || github.event.changes.head))
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
# Checkout
|
||||
# https://github.com/marketplace/actions/checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Apply Labels Based on Branch Name and Target Branch
|
||||
# Pull Request Labeler
|
||||
# https://github.com/marketplace/actions/labeler
|
||||
uses: actions/labeler@v5.0.0
|
||||
with:
|
||||
configuration-path: .github/pr-auto-labels-by-branch.yml
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
|
||||
label-by-files:
|
||||
name: 🏷️ Label PR by Files
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
# Checkout
|
||||
# https://github.com/marketplace/actions/checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Apply Labels Based on Changed Files
|
||||
# Pull Request Labeler
|
||||
# https://github.com/marketplace/actions/labeler
|
||||
uses: actions/labeler@v5.0.0
|
||||
with:
|
||||
configuration-path: .github/pr-auto-labels-by-files.yml
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
|
||||
remove-stale-label:
|
||||
name: 🗑️ Remove Stale Label on Comment
|
||||
runs-on: ubuntu-latest
|
||||
# Only runs when this is not done by the github actions bot
|
||||
if: github.event_name == 'pull_request_review_comment' && github.actor != 'github-actions[bot]'
|
||||
|
||||
steps:
|
||||
- name: Remove Stale Label
|
||||
# 🤖 Issues Helper
|
||||
# https://github.com/marketplace/actions/issues-helper
|
||||
uses: actions-cool/issues-helper@v3.6.0
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
labels: '⚰️ Stale'
|
||||
|
||||
check-merge-blocking-labels:
|
||||
name: 🚫 Check Merge Blocking Labels
|
||||
needs: [label-by-branches, label-by-files]
|
||||
runs-on: ubuntu-latest
|
||||
# Run, even if the previous jobs were skipped/failed
|
||||
if: always()
|
||||
|
||||
# Override permissions, as this needs to write a check
|
||||
permissions:
|
||||
checks: write
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
steps:
|
||||
- name: Check Merge Blocking
|
||||
# GitHub Script
|
||||
# https://github.com/marketplace/actions/github-script
|
||||
id: label-check
|
||||
uses: actions/github-script@v7.0.1
|
||||
with:
|
||||
script: |
|
||||
const prLabels = context.payload.pull_request.labels.map(label => label.name);
|
||||
const blockingLabels = [
|
||||
"⛔ Don't Merge",
|
||||
"🔨 Needs Work",
|
||||
"🔬 Needs Testing",
|
||||
"⛔ Waiting For External/Upstream",
|
||||
"❗ Against Release Branch",
|
||||
"💥💣 Breaking Changes"
|
||||
];
|
||||
const hasBlockingLabel = prLabels.some(label => blockingLabels.includes(label));
|
||||
|
||||
if (hasBlockingLabel) {
|
||||
console.log("Blocking label detected. Setting warning status.");
|
||||
await github.rest.checks.create({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: "PR Label Warning",
|
||||
head_sha: context.payload.pull_request.head.sha,
|
||||
status: "completed",
|
||||
conclusion: "neutral",
|
||||
output: {
|
||||
title: "Potential Merge Issue",
|
||||
summary: "This PR has a merge-blocking label. Proceed with caution."
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log("No merge-blocking labels found.");
|
||||
}
|
||||
|
||||
write-auto-comments:
|
||||
name: 💬 Post PR Comments Based on Labels
|
||||
needs: [label-by-size, label-by-branches, label-by-files]
|
||||
runs-on: ubuntu-latest
|
||||
# Run, even if the previous jobs were skipped/failed
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
# Checkout
|
||||
# https://github.com/marketplace/actions/checkout
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Post PR Comments Based on Labels
|
||||
# Label Commenter for PRs
|
||||
# https://github.com/marketplace/actions/label-commenter
|
||||
uses: peaceiris/actions-label-commenter@v1.10.0
|
||||
with:
|
||||
config_file: .github/pr-auto-comments.yml
|
||||
github_token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
|
||||
# This runs on merged PRs to staging, reading the PR body and directly linked issues. Check `issues-updates-on-merge.yml`:`update-linked-issues` for commit-based updates.
|
||||
update-linked-issues:
|
||||
name: 🔗 Mark Linked Issues Done on Staging Merge
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'staging'
|
||||
|
||||
steps:
|
||||
- name: Extract Linked Issues From PR Description
|
||||
id: extract_issues
|
||||
run: |
|
||||
ISSUES=$(jq -r '.pull_request.body' "$GITHUB_EVENT_PATH" | grep -oiE '(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) #([0-9]+)' | awk '{print $2}' | tr -d '#' | jq -R -s -c 'split("\n")[:-1]')
|
||||
echo "issues=$ISSUES" >> $GITHUB_ENV
|
||||
|
||||
- name: Fetch Directly Linked Issues
|
||||
id: fetch_linked_issues
|
||||
run: |
|
||||
PR_NUMBER=${{ github.event.pull_request.number }}
|
||||
REPO=${{ github.repository }}
|
||||
API_URL="https://api.github.com/repos/$REPO/pulls/$PR_NUMBER/issues"
|
||||
ISSUES=$(curl -s -H "Authorization: token ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}" "$API_URL" | jq -r '.[].number' | jq -R -s -c 'split("\n")[:-1]')
|
||||
echo "linked_issues=$ISSUES" >> $GITHUB_ENV
|
||||
|
||||
- name: Merge Issue Lists
|
||||
id: merge_issues
|
||||
run: |
|
||||
ISSUES=$(jq -c -n --argjson a "$issues" --argjson b "$linked_issues" '$a + $b | unique')
|
||||
echo "final_issues=$ISSUES" >> $GITHUB_ENV
|
||||
|
||||
- name: Label Linked Issues
|
||||
id: label_linked_issues
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
for ISSUE in $(echo $final_issues | jq -r '.[]'); do
|
||||
gh issue edit $ISSUE -R ${{ github.repository }} --add-label "✅ Done (staging)"
|
||||
echo "Added label '✅ Done (staging)' to issue #$ISSUE"
|
||||
done
|
28
.github/workflows/pr-check-merge-conflicts.yaml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: ⚔️ Check Merge Conflicts
|
||||
|
||||
on:
|
||||
# So that PRs touching the same files as the push are updated
|
||||
push:
|
||||
# So that the `dirtyLabel` is removed if conflicts are resolved
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
check-merge-conflicts:
|
||||
name: ⚔️ Check Merge Conflicts
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check Merge Conflicts
|
||||
# Label Conflicting Pull Requests
|
||||
# https://github.com/marketplace/actions/label-conflicting-pull-requests
|
||||
uses: eps1lon/actions-label-merge-conflict@v3.0.3
|
||||
with:
|
||||
dirtyLabel: '🚫 Merge Conflicts'
|
||||
repoToken: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
commentOnDirty: >
|
||||
⚠️ This PR has conflicts that need to be resolved before it can be merged.
|
5
.gitignore
vendored
@@ -45,8 +45,13 @@ access.log
|
||||
/vectors/
|
||||
/cache/
|
||||
public/css/user.css
|
||||
public/error/
|
||||
/plugins/
|
||||
/data
|
||||
/default/scaffold
|
||||
public/scripts/extensions/third-party
|
||||
/certs
|
||||
.aider*
|
||||
.env
|
||||
/StartDev.bat
|
||||
|
||||
|
@@ -11,3 +11,4 @@ access.log
|
||||
.github
|
||||
.vscode
|
||||
.git
|
||||
/public/scripts/extensions/third-party
|
||||
|
16
Dockerfile
@@ -4,10 +4,7 @@ FROM node:lts-alpine3.19
|
||||
ARG APP_HOME=/home/node/app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apk add gcompat tini git
|
||||
|
||||
# Ensure proper handling of kernel signals
|
||||
ENTRYPOINT [ "tini", "--" ]
|
||||
RUN apk add --no-cache gcompat tini git
|
||||
|
||||
# Create app directory
|
||||
WORKDIR ${APP_HOME}
|
||||
@@ -30,6 +27,11 @@ RUN \
|
||||
ln -s "./config/config.yaml" "config.yaml" || true && \
|
||||
mkdir "config" || true
|
||||
|
||||
# Pre-compile public libraries
|
||||
RUN \
|
||||
echo "*** Run Webpack ***" && \
|
||||
node "./docker/build-lib.js"
|
||||
|
||||
# Cleanup unnecessary files
|
||||
RUN \
|
||||
echo "*** Cleanup ***" && \
|
||||
@@ -40,6 +42,10 @@ RUN \
|
||||
echo "*** Convert line endings to Unix format ***" && \
|
||||
dos2unix "./docker-entrypoint.sh"
|
||||
|
||||
# Fix extension repos permissions
|
||||
RUN git config --global --add safe.directory "*"
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD [ "./docker-entrypoint.sh" ]
|
||||
# Ensure proper handling of kernel signals
|
||||
ENTRYPOINT ["tini", "--", "./docker-entrypoint.sh"]
|
||||
|
13
default/!DO-NOT-EDIT-THESE-FILES.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
These are master copies of the default content files and are managed by SillyTavern.
|
||||
|
||||
Editing any of these files would not only have no effect, but will also cause merge conflicts during update pulls.
|
||||
|
||||
You should edit their respective copies instead, for example:
|
||||
|
||||
1. /default/config.yaml => /config.yaml
|
||||
2. /default/public/css/user.css => /public/css/user.css
|
||||
etc.
|
||||
|
||||
Any questions? You're always welcome at our official documentation website:
|
||||
|
||||
https://docs.sillytavern.app/
|
@@ -4,7 +4,13 @@ dataRoot: ./data
|
||||
# -- SERVER CONFIGURATION --
|
||||
# Listen for incoming connections
|
||||
listen: false
|
||||
# Listen on a specific address, supports IPv4 and IPv6
|
||||
listenAddress:
|
||||
ipv4: 0.0.0.0
|
||||
ipv6: '[::]'
|
||||
# Enables IPv6 and/or IPv4 protocols. Need to have at least one enabled!
|
||||
# - Use option "auto" to automatically detect support
|
||||
# - Use true or false (no qoutes) to enable or disable each protocol
|
||||
protocol:
|
||||
ipv4: true
|
||||
ipv6: false
|
||||
@@ -20,6 +26,11 @@ port: 8000
|
||||
# - Use -1 to use the server port.
|
||||
# - Specify a port to override the default.
|
||||
autorunPortOverride: -1
|
||||
# -- SSL options --
|
||||
ssl:
|
||||
enabled: false
|
||||
certPath: "./certs/cert.pem"
|
||||
keyPath: "./certs/privkey.pem"
|
||||
# -- SECURITY CONFIGURATION --
|
||||
# Toggle whitelist mode
|
||||
whitelistMode: true
|
||||
@@ -29,6 +40,8 @@ enableForwardedWhitelist: true
|
||||
whitelist:
|
||||
- ::1
|
||||
- 127.0.0.1
|
||||
# Automatically whitelist Docker host and gateway IPs
|
||||
whitelistDockerHosts: true
|
||||
# Toggle basic authentication for endpoints
|
||||
basicAuthMode: false
|
||||
# Basic authentication credentials
|
||||
@@ -68,36 +81,70 @@ perUserBasicAuth: false
|
||||
## Set to a positive number to expire session after a certain time of inactivity
|
||||
## Set to 0 to expire session when the browser is closed
|
||||
## Set to a negative number to disable session expiration
|
||||
sessionTimeout: 86400
|
||||
# Used to sign session cookies. Will be auto-generated if not set
|
||||
cookieSecret: ''
|
||||
sessionTimeout: -1
|
||||
# Disable CSRF protection - NOT RECOMMENDED
|
||||
disableCsrfProtection: false
|
||||
# Disable startup security checks - NOT RECOMMENDED
|
||||
securityOverride: false
|
||||
# -- LOGGING CONFIGURATION --
|
||||
logging:
|
||||
# Enable access logging to access.log file
|
||||
# Records new connections with timestamp, IP address and user agent
|
||||
enableAccessLog: true
|
||||
# Minimum log level to display in the terminal (DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3)
|
||||
minLogLevel: 0
|
||||
# -- RATE LIMITING CONFIGURATION --
|
||||
rateLimiting:
|
||||
# Use X-Real-IP header instead of socket IP for rate limiting
|
||||
# Only enable this if you are using a properly configured reverse proxy (like Nginx/traefik/Caddy)
|
||||
preferRealIpHeader: false
|
||||
# -- ADVANCED CONFIGURATION --
|
||||
# Open the browser automatically
|
||||
autorun: true
|
||||
# Avoids using 'localhost' for autorun in auto mode.
|
||||
# use if you don't have 'localhost' in your hosts file
|
||||
avoidLocalhost: false
|
||||
# Disable thumbnail generation
|
||||
disableThumbnails: false
|
||||
# Thumbnail quality (0-100)
|
||||
thumbnailsQuality: 95
|
||||
# Generate avatar thumbnails as PNG instead of JPG (preserves transparency but increases filesize by about 100%)
|
||||
# Changing this only affects new thumbnails. To recreate the old ones, clear out your ST/thumbnails/ folder.
|
||||
avatarThumbnailsPng: false
|
||||
|
||||
## BACKUP CONFIGURATION
|
||||
backups:
|
||||
# Common settings for all backup types
|
||||
common:
|
||||
# Number of backups to keep for each chat and settings file
|
||||
numberOfBackups: 50
|
||||
chat:
|
||||
# Enable automatic chat backups
|
||||
enabled: true
|
||||
# Maximum number of chat backups to keep per user (starting from the most recent). Set to -1 to keep all backups.
|
||||
maxTotalBackups: -1
|
||||
# Interval in milliseconds to throttle chat backups per user
|
||||
throttleInterval: 10000
|
||||
|
||||
# THUMBNAILING CONFIGURATION
|
||||
thumbnails:
|
||||
# Enable thumbnail generation
|
||||
enabled: true
|
||||
# Image format of avatar thumbnails:
|
||||
# * "jpg": best compression with adjustable quality, no transparency
|
||||
# * "png": preserves transparency but increases filesize by about 100%
|
||||
# Changing this only affects new thumbnails. To recreate the old ones, clear out /thumbnails folder in your user data.
|
||||
format: "jpg"
|
||||
# JPG thumbnail quality (0-100)
|
||||
quality: 95
|
||||
# Maximum thumbnail dimensions per type [width, height]
|
||||
dimensions: { 'bg': [160, 90], 'avatar': [96, 144] }
|
||||
|
||||
# PERFORMANCE-RELATED CONFIGURATION
|
||||
performance:
|
||||
# Enables lazy loading of character cards. Improves performances with large card libraries.
|
||||
# May have compatibility issues with some extensions.
|
||||
lazyLoadCharacters: false
|
||||
# The maximum amount of memory that parsed character cards can use. Set to 0 to disable memory caching.
|
||||
memoryCacheCapacity: '100mb'
|
||||
|
||||
# Allow secret keys exposure via API
|
||||
allowKeysExposure: false
|
||||
# Skip new default content checks
|
||||
skipContentCheck: false
|
||||
# Disable automatic chats backup
|
||||
disableChatBackup: false
|
||||
# Number of backups to keep for each chat and settings file
|
||||
numberOfBackups: 50
|
||||
# Interval in milliseconds to throttle chat backups per user
|
||||
chatBackupThrottleInterval: 10000
|
||||
# Allowed hosts for card downloads
|
||||
whitelistImportDomains:
|
||||
- localhost
|
||||
@@ -115,24 +162,26 @@ whitelistImportDomains:
|
||||
## headers:
|
||||
## User-Agent: "Googlebot/2.1 (+http://www.google.com/bot.html)"
|
||||
requestOverrides: []
|
||||
# -- EXTENSIONS CONFIGURATION --
|
||||
# Enable UI extensions
|
||||
enableExtensions: true
|
||||
# Automatically update extensions when a release version changes
|
||||
enableExtensionsAutoUpdate: true
|
||||
|
||||
# EXTENSIONS CONFIGURATION
|
||||
extensions:
|
||||
# Enable UI extensions
|
||||
enabled: true
|
||||
# Automatically update extensions when a release version changes
|
||||
autoUpdate: true
|
||||
models:
|
||||
# Enables automatic model download from HuggingFace
|
||||
autoDownload: true
|
||||
# Additional models for extensions. Expects model IDs from HuggingFace model hub in ONNX format
|
||||
classification: Cohee/distilbert-base-uncased-go-emotions-onnx
|
||||
captioning: Xenova/vit-gpt2-image-captioning
|
||||
embedding: Cohee/jina-embeddings-v2-base-en
|
||||
speechToText: Xenova/whisper-small
|
||||
textToSpeech: Xenova/speecht5_tts
|
||||
|
||||
# Additional model tokenizers can be downloaded on demand.
|
||||
# Disabling will fallback to another locally available tokenizer.
|
||||
enableDownloadableTokenizers: true
|
||||
# Extension settings
|
||||
extras:
|
||||
# Disables automatic model download from HuggingFace
|
||||
disableAutoDownload: false
|
||||
# Extra models for plugins. Expects model IDs from HuggingFace model hub in ONNX format
|
||||
classificationModel: Cohee/distilbert-base-uncased-go-emotions-onnx
|
||||
captioningModel: Xenova/vit-gpt2-image-captioning
|
||||
embeddingModel: Cohee/jina-embeddings-v2-base-en
|
||||
speechToTextModel: Xenova/whisper-small
|
||||
textToSpeechModel: Xenova/speecht5_tts
|
||||
# -- OPENAI CONFIGURATION --
|
||||
# A placeholder message to use in strict prompt post-processing mode when the prompt doesn't start with a user message
|
||||
promptPlaceholder: "[Start a new chat]"
|
||||
@@ -159,6 +208,10 @@ ollama:
|
||||
# * 0: Unload the model immediately after the request
|
||||
# * N (any positive number): Keep the model loaded for N seconds after the request.
|
||||
keepAlive: -1
|
||||
# Controls the "num_batch" (batch size) parameter of the generation request
|
||||
# * -1: Use the default value of the model
|
||||
# * N (positive number): Use the specified value. Must be a power of 2, e.g. 128, 256, 512, etc.
|
||||
batchSize: -1
|
||||
# -- ANTHROPIC CLAUDE API CONFIGURATION --
|
||||
claude:
|
||||
# Enables caching of the system prompt (if supported).
|
||||
@@ -178,3 +231,5 @@ claude:
|
||||
cachingAtDepth: -1
|
||||
# -- SERVER PLUGIN CONFIGURATION --
|
||||
enableServerPlugins: false
|
||||
# Attempt to automatically update server plugins on startup
|
||||
enableServerPluginsAutoUpdate: true
|
||||
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 8.1 KiB |
@@ -627,6 +627,14 @@
|
||||
"filename": "presets/instruct/Synthia.json",
|
||||
"type": "instruct"
|
||||
},
|
||||
{
|
||||
"filename": "presets/instruct/Tulu.json",
|
||||
"type": "instruct"
|
||||
},
|
||||
{
|
||||
"filename": "presets/context/Tulu.json",
|
||||
"type": "context"
|
||||
},
|
||||
{
|
||||
"filename": "presets/instruct/Vicuna 1.0.json",
|
||||
"type": "instruct"
|
||||
@@ -663,10 +671,6 @@
|
||||
"filename": "presets/moving-ui/Default.json",
|
||||
"type": "moving_ui"
|
||||
},
|
||||
{
|
||||
"filename": "presets/moving-ui/Black Magic Time.json",
|
||||
"type": "moving_ui"
|
||||
},
|
||||
{
|
||||
"filename": "presets/quick-replies/Default.json",
|
||||
"type": "quick_replies"
|
||||
@@ -774,5 +778,13 @@
|
||||
{
|
||||
"filename": "presets/context/Mistral V7.json",
|
||||
"type": "context"
|
||||
},
|
||||
{
|
||||
"filename": "presets/instruct/DeepSeek-V2.5.json",
|
||||
"type": "instruct"
|
||||
},
|
||||
{
|
||||
"filename": "presets/context/DeepSeek-V2.5.json",
|
||||
"type": "context"
|
||||
}
|
||||
]
|
||||
|
11
default/content/presets/context/DeepSeek-V2.5.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"story_string": "{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}\n",
|
||||
"example_separator": "",
|
||||
"chat_start": "",
|
||||
"use_stop_strings": false,
|
||||
"allow_jailbreak": false,
|
||||
"always_force_name2": true,
|
||||
"trim_sentences": false,
|
||||
"single_line": false,
|
||||
"name": "DeepSeek-V2.5"
|
||||
}
|
11
default/content/presets/context/Tulu.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"story_string": "<|system|>\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}\n",
|
||||
"example_separator": "",
|
||||
"chat_start": "",
|
||||
"use_stop_strings": false,
|
||||
"allow_jailbreak": false,
|
||||
"always_force_name2": true,
|
||||
"trim_sentences": false,
|
||||
"single_line": false,
|
||||
"name": "Tulu"
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"input_sequence": "<|im_start|>[{{name}}]",
|
||||
"output_sequence": "<|im_start|>[{{name}}]",
|
||||
"input_sequence": "<|im_start|>{{name}}",
|
||||
"output_sequence": "<|im_start|>{{name}}",
|
||||
"last_output_sequence": "",
|
||||
"system_sequence": "<|im_start|>system",
|
||||
"stop_sequence": "<|im_end|>",
|
||||
|
22
default/content/presets/instruct/DeepSeek-V2.5.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"input_sequence": "<|User|>",
|
||||
"output_sequence": "<|Assistant|>",
|
||||
"first_output_sequence": "",
|
||||
"last_output_sequence": "",
|
||||
"system_sequence_prefix": "",
|
||||
"system_sequence_suffix": "",
|
||||
"stop_sequence": "",
|
||||
"wrap": false,
|
||||
"macro": true,
|
||||
"names_behavior": "force",
|
||||
"activation_regex": "",
|
||||
"skip_examples": false,
|
||||
"output_suffix": "<|end▁of▁sentence|>",
|
||||
"input_suffix": "",
|
||||
"system_sequence": "",
|
||||
"system_suffix": "",
|
||||
"user_alignment_message": "",
|
||||
"last_system_sequence": "",
|
||||
"system_same_as_user": true,
|
||||
"name": "DeepSeek-V2.5"
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"input_sequence": "<|start_header_id|>[{{name}}]<|end_header_id|>\n\n",
|
||||
"output_sequence": "<|start_header_id|>[{{name}}]<|end_header_id|>\n\n",
|
||||
"input_sequence": "<|start_header_id|>{{name}}<|end_header_id|>\n\n",
|
||||
"output_sequence": "<|start_header_id|>{{name}}<|end_header_id|>\n\n",
|
||||
"last_output_sequence": "",
|
||||
"system_sequence": "<|start_header_id|>system<|end_header_id|>\n\n",
|
||||
"stop_sequence": "<|eot_id|>",
|
||||
|
22
default/content/presets/instruct/Tulu.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"input_sequence": "<|user|>\n",
|
||||
"output_sequence": "<|assistant|>\n",
|
||||
"first_output_sequence": "",
|
||||
"last_output_sequence": "",
|
||||
"system_sequence_prefix": "",
|
||||
"system_sequence_suffix": "",
|
||||
"stop_sequence": "<|end_of_text|>",
|
||||
"wrap": false,
|
||||
"macro": true,
|
||||
"names_behavior": "always",
|
||||
"activation_regex": "",
|
||||
"skip_examples": false,
|
||||
"output_suffix": "<|end_of_text|>\n",
|
||||
"input_suffix": "\n",
|
||||
"system_sequence": "<|system|>\n",
|
||||
"system_suffix": "\n",
|
||||
"user_alignment_message": "",
|
||||
"last_system_sequence": "",
|
||||
"system_same_as_user": false,
|
||||
"name": "Tulu"
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"name": "Black Magic Time",
|
||||
"movingUIState": {
|
||||
"sheld": {
|
||||
"top": 488,
|
||||
"left": 1407,
|
||||
"right": 1,
|
||||
"bottom": 4,
|
||||
"margin": "unset",
|
||||
"width": 471,
|
||||
"height": 439
|
||||
},
|
||||
"floatingPrompt": {
|
||||
"width": 369,
|
||||
"height": 441
|
||||
},
|
||||
"right-nav-panel": {
|
||||
"top": 0,
|
||||
"left": 1400,
|
||||
"right": 111,
|
||||
"bottom": 446,
|
||||
"margin": "unset",
|
||||
"width": 479,
|
||||
"height": 487
|
||||
},
|
||||
"WorldInfo": {
|
||||
"top": 41,
|
||||
"left": 369,
|
||||
"right": 642,
|
||||
"bottom": 51,
|
||||
"margin": "unset",
|
||||
"width": 1034,
|
||||
"height": 858
|
||||
},
|
||||
"left-nav-panel": {
|
||||
"top": 442,
|
||||
"left": 0,
|
||||
"right": 1546,
|
||||
"bottom": 25,
|
||||
"margin": "unset",
|
||||
"width": 368,
|
||||
"height": 483
|
||||
}
|
||||
}
|
||||
}
|
@@ -28,19 +28,18 @@
|
||||
"wrap_in_quotes": false,
|
||||
"names_behavior": 0,
|
||||
"send_if_empty": "",
|
||||
"jailbreak_system": false,
|
||||
"impersonation_prompt": "[Write your next reply from the point of view of {{user}}, using the chat history so far as a guideline for the writing style of {{user}}. Don't write as {{char}} or system. Don't describe actions of {{char}}.]",
|
||||
"new_chat_prompt": "[Start a new Chat]",
|
||||
"new_group_chat_prompt": "[Start a new group chat. Group members: {{group}}]",
|
||||
"new_example_chat_prompt": "[Example Chat]",
|
||||
"continue_nudge_prompt": "[Continue the following message. Do not include ANY parts of the original message. Use capitalization and punctuation as if your reply is a part of the original message: {{lastChatMessage}}]",
|
||||
"continue_nudge_prompt": "[Continue your last message without repeating its original content.]",
|
||||
"bias_preset_selected": "Default (none)",
|
||||
"reverse_proxy": "",
|
||||
"proxy_password": "",
|
||||
"max_context_unlocked": false,
|
||||
"wi_format": "{0}",
|
||||
"scenario_format": "[Circumstances and context of the dialogue: {{scenario}}]",
|
||||
"personality_format": "[{{char}}'s personality: {{personality}}]",
|
||||
"scenario_format": "{{scenario}}",
|
||||
"personality_format": "{{personality}}",
|
||||
"group_nudge_prompt": "[Write the next reply only as {{char}}.]",
|
||||
"stream_openai": true,
|
||||
"prompts": [
|
||||
@@ -230,7 +229,6 @@
|
||||
"show_external_models": false,
|
||||
"assistant_prefill": "",
|
||||
"assistant_impersonation": "",
|
||||
"human_sysprompt_message": "Let's get started. Please generate your response based on the information and instructions provided above.",
|
||||
"claude_use_sysprompt": false,
|
||||
"use_alt_scale": false,
|
||||
"squash_system_messages": false,
|
||||
|
@@ -593,24 +593,28 @@
|
||||
"new_chat_prompt": "[Start a new Chat]",
|
||||
"new_group_chat_prompt": "[Start a new group chat. Group members: {{group}}]",
|
||||
"new_example_chat_prompt": "[Example Chat]",
|
||||
"continue_nudge_prompt": "[Continue the following message. Do not include ANY parts of the original message. Use capitalization and punctuation as if your reply is a part of the original message: {{lastChatMessage}}]",
|
||||
"continue_nudge_prompt": "[Continue your last message without repeating its original content.]",
|
||||
"bias_preset_selected": "Default (none)",
|
||||
"bias_presets": {
|
||||
"Default (none)": [],
|
||||
"Anti-bond": [
|
||||
{
|
||||
"id": "22154f79-dd98-41bc-8e34-87015d6a0eaf",
|
||||
"text": " bond",
|
||||
"value": -50
|
||||
},
|
||||
{
|
||||
"id": "8ad2d5c4-d8ef-49e4-bc5e-13e7f4690e0f",
|
||||
"text": " future",
|
||||
"value": -50
|
||||
},
|
||||
{
|
||||
"id": "52a4b280-0956-4940-ac52-4111f83e4046",
|
||||
"text": " bonding",
|
||||
"value": -50
|
||||
},
|
||||
{
|
||||
"id": "e63037c7-c9d1-4724-ab2d-7756008b433b",
|
||||
"text": " connection",
|
||||
"value": -25
|
||||
}
|
||||
@@ -622,7 +626,6 @@
|
||||
"ai21_model": "jamba-1.5-large",
|
||||
"windowai_model": "",
|
||||
"openrouter_model": "OR_Website",
|
||||
"jailbreak_system": true,
|
||||
"reverse_proxy": "",
|
||||
"chat_completion_source": "openai",
|
||||
"max_context_unlocked": false,
|
||||
|
22
default/public/error/forbidden-by-whitelist.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Forbidden</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Forbidden</h1>
|
||||
<p>
|
||||
If you are the system administrator, add your IP address to the
|
||||
whitelist or disable whitelist mode by editing
|
||||
<code>config.yaml</code> in the root directory of your installation.
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
<em>Connection from {{ipDetails}} has been blocked. This attempt
|
||||
has been logged.</em>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
17
default/public/error/unauthorized.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Unauthorized</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Unauthorized</h1>
|
||||
<p>
|
||||
If you are the system administrator, you can configure the
|
||||
<code>basicAuthUser</code> credentials by editing
|
||||
<code>config.yaml</code> in the root directory of your installation.
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
15
default/public/error/url-not-found.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Not found</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Not found</h1>
|
||||
<p>
|
||||
The requested URL was not found on this server.
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
4
docker/build-lib.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import getWebpackServeMiddleware from '../src/middleware/webpack-serve.js';
|
||||
|
||||
const middleware = getWebpackServeMiddleware();
|
||||
await middleware.runWebpackCompiler({ forceDist: true });
|
@@ -1,14 +1,17 @@
|
||||
version: "3"
|
||||
services:
|
||||
sillytavern:
|
||||
build: ..
|
||||
container_name: sillytavern
|
||||
hostname: sillytavern
|
||||
image: ghcr.io/sillytavern/sillytavern:latest
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- FORCE_COLOR=1
|
||||
ports:
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
- "./config:/home/node/app/config"
|
||||
- "./data:/home/node/app/data"
|
||||
- "./plugins:/home/node/app/plugins"
|
||||
- "./extensions:/home/node/app/public/scripts/extensions/third-party"
|
||||
restart: unless-stopped
|
||||
|
@@ -5,5 +5,8 @@ if [ ! -e "config/config.yaml" ]; then
|
||||
cp -r "default/config.yaml" "config/config.yaml"
|
||||
fi
|
||||
|
||||
# Execute postinstall to auto-populate config.yaml with missing values
|
||||
npm run postinstall
|
||||
|
||||
# Start the server
|
||||
exec node server.js --listen
|
||||
exec node server.js --listen "$@"
|
||||
|
62
index.d.ts
vendored
@@ -1,6 +1,53 @@
|
||||
import { UserDirectoryList, User } from "./src/users";
|
||||
import { EventEmitter } from 'node:events';
|
||||
import { CsrfSyncedToken } from 'csrf-sync';
|
||||
import { UserDirectoryList, User } from './src/users.js';
|
||||
import { CommandLineArguments } from './src/command-line.js';
|
||||
import { EVENT_NAMES } from './src/server-events.js';
|
||||
|
||||
/**
|
||||
* Event payload for SERVER_STARTED event.
|
||||
*/
|
||||
export interface ServerStartedEvent {
|
||||
/**
|
||||
* The URL the server is listening on.
|
||||
*/
|
||||
url: URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of all server events to their payload types.
|
||||
*/
|
||||
export interface ServerEventMap {
|
||||
[EVENT_NAMES.SERVER_STARTED]: [ServerStartedEvent];
|
||||
}
|
||||
|
||||
declare global {
|
||||
declare namespace NodeJS {
|
||||
export interface Process {
|
||||
/**
|
||||
* A global instance of the server events emitter.
|
||||
*/
|
||||
serverEvents: EventEmitter<ServerEventMap>;
|
||||
}
|
||||
}
|
||||
|
||||
declare namespace CookieSessionInterfaces {
|
||||
export interface CookieSessionObject {
|
||||
/**
|
||||
* The CSRF token for the session.
|
||||
*/
|
||||
csrfToken: CsrfSyncedToken;
|
||||
/**
|
||||
* Authenticated user handle.
|
||||
*/
|
||||
handle: string;
|
||||
/**
|
||||
* Last time the session was extended.
|
||||
*/
|
||||
touch: number;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Express {
|
||||
export interface Request {
|
||||
user: {
|
||||
@@ -14,12 +61,9 @@ declare global {
|
||||
* The root directory for user data.
|
||||
*/
|
||||
var DATA_ROOT: string;
|
||||
}
|
||||
|
||||
declare module 'express-session' {
|
||||
export interface SessionData {
|
||||
handle: string;
|
||||
touch: number;
|
||||
// other properties...
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Parsed command line arguments.
|
||||
*/
|
||||
var COMMAND_LINE_ARGS: CommandLineArguments;
|
||||
}
|
||||
|
@@ -1,20 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"target": "ESNext",
|
||||
"target": "ES2023",
|
||||
"moduleResolution": "Node",
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"checkJs": true,
|
||||
"allowUmdGlobalAccess": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true
|
||||
"resolveJsonModule": true,
|
||||
"strictBindCallApply": true
|
||||
},
|
||||
"exclude": [
|
||||
"**/node_modules/**",
|
||||
"**/dist/**",
|
||||
"**/.git/**",
|
||||
"public/lib/**",
|
||||
"public/**",
|
||||
"backups/**",
|
||||
"data/**",
|
||||
"cache/**",
|
||||
|
1299
package-lock.json
generated
74
package.json
@@ -1,37 +1,41 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@adobe/css-tools": "^4.4.0",
|
||||
"@adobe/css-tools": "^4.4.2",
|
||||
"@agnai/sentencepiece-js": "^1.1.1",
|
||||
"@agnai/web-tokenizers": "^0.1.3",
|
||||
"@iconfu/svg-inject": "^1.2.3",
|
||||
"@mozilla/readability": "^0.5.0",
|
||||
"@mozilla/readability": "^0.6.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@zeldafan0225/ai_horde": "^5.1.0",
|
||||
"@zeldafan0225/ai_horde": "^5.2.0",
|
||||
"archiver": "^7.0.1",
|
||||
"bing-translate-api": "^2.9.1",
|
||||
"bing-translate-api": "^4.0.2",
|
||||
"body-parser": "^1.20.2",
|
||||
"bowser": "^2.11.0",
|
||||
"bytes": "^3.1.2",
|
||||
"chalk": "^5.4.1",
|
||||
"command-exists": "^1.2.9",
|
||||
"compression": "^1",
|
||||
"compression": "^1.8.0",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cookie-session": "^2.1.0",
|
||||
"cors": "^2.8.5",
|
||||
"csrf-csrf": "^2.2.3",
|
||||
"csrf-sync": "^4.0.3",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
"dompurify": "^3.1.7",
|
||||
"dompurify": "^3.2.4",
|
||||
"droll": "^0.2.1",
|
||||
"express": "^4.21.0",
|
||||
"form-data": "^4.0.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"form-data": "^4.0.2",
|
||||
"fuse.js": "^7.1.0",
|
||||
"google-translate-api-browser": "^3.0.1",
|
||||
"google-translate-api-x": "^10.7.1",
|
||||
"google-translate-api-x": "^10.7.2",
|
||||
"handlebars": "^4.7.8",
|
||||
"helmet": "^7.1.0",
|
||||
"highlight.js": "^11.10.0",
|
||||
"helmet": "^7.2.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"html-entities": "^2.5.2",
|
||||
"iconv-lite": "^0.6.3",
|
||||
"ip-matching": "^2.1.2",
|
||||
"ipaddr.js": "^2.0.1",
|
||||
"ip-regex": "^5.0.0",
|
||||
"ipaddr.js": "^2.2.0",
|
||||
"is-docker": "^3.0.0",
|
||||
"jimp": "^0.22.10",
|
||||
"localforage": "^1.10.0",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -40,27 +44,28 @@
|
||||
"morphdom": "^2.7.4",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"node-persist": "^4.0.1",
|
||||
"node-persist": "^4.0.4",
|
||||
"open": "^8.4.2",
|
||||
"png-chunk-text": "^1.0.0",
|
||||
"png-chunks-encode": "^1.0.0",
|
||||
"png-chunks-extract": "^1.0.0",
|
||||
"proxy-agent": "^6.4.0",
|
||||
"rate-limiter-flexible": "^5.0.0",
|
||||
"response-time": "^2.3.2",
|
||||
"proxy-agent": "^6.5.0",
|
||||
"rate-limiter-flexible": "^5.0.5",
|
||||
"response-time": "^2.3.3",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"seedrandom": "^3.0.5",
|
||||
"showdown": "^2.1.0",
|
||||
"sillytavern-transformers": "2.14.6",
|
||||
"simple-git": "^3.19.1",
|
||||
"tiktoken": "^1.0.16",
|
||||
"simple-git": "^3.27.0",
|
||||
"slidetoggle": "^4.0.0",
|
||||
"tiktoken": "^1.0.20",
|
||||
"url-join": "^5.0.0",
|
||||
"vectra": "^0.2.2",
|
||||
"wavefile": "^11.0.0",
|
||||
"webpack": "^5.95.0",
|
||||
"webpack-dev-middleware": "^7.4.2",
|
||||
"webpack": "^5.98.0",
|
||||
"write-file-atomic": "^5.0.1",
|
||||
"ws": "^8.17.1",
|
||||
"yaml": "^2.3.4",
|
||||
"ws": "^8.18.1",
|
||||
"yaml": "^2.7.0",
|
||||
"yargs": "^17.7.1",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
@@ -85,9 +90,11 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
||||
},
|
||||
"version": "1.12.7",
|
||||
"version": "1.12.13",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"debug": "node --inspect server.js",
|
||||
"start:electron": "cd ./src/electron && npm run start",
|
||||
"start:deno": "deno run --allow-run --allow-net --allow-read --allow-write --allow-sys --allow-env server.js",
|
||||
"start:bun": "bun server.js",
|
||||
"start:no-csrf": "node server.js --disableCsrf",
|
||||
@@ -106,28 +113,33 @@
|
||||
},
|
||||
"main": "server.js",
|
||||
"devDependencies": {
|
||||
"@types/archiver": "^6.0.2",
|
||||
"@types/archiver": "^6.0.3",
|
||||
"@types/bytes": "^3.1.5",
|
||||
"@types/command-exists": "^1.2.3",
|
||||
"@types/compression": "^1.7.5",
|
||||
"@types/cookie-parser": "^1.4.7",
|
||||
"@types/cookie-parser": "^1.4.8",
|
||||
"@types/cookie-session": "^2.0.49",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/deno": "^2.0.0",
|
||||
"@types/deno": "^2.2.0",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jquery": "^3.5.29",
|
||||
"@types/lodash": "^4.17.10",
|
||||
"@types/jquery": "^3.5.32",
|
||||
"@types/jquery-cropper": "^1.0.4",
|
||||
"@types/jquery.transit": "^0.9.33",
|
||||
"@types/jqueryui": "^1.12.24",
|
||||
"@types/lodash": "^4.17.16",
|
||||
"@types/mime-types": "^2.1.4",
|
||||
"@types/multer": "^1.4.12",
|
||||
"@types/node": "^18.19.55",
|
||||
"@types/node": "^18.19.80",
|
||||
"@types/node-persist": "^3.1.8",
|
||||
"@types/png-chunk-text": "^1.0.3",
|
||||
"@types/png-chunks-encode": "^1.0.2",
|
||||
"@types/png-chunks-extract": "^1.0.2",
|
||||
"@types/response-time": "^2.3.8",
|
||||
"@types/select2": "^4.0.63",
|
||||
"@types/toastr": "^2.1.43",
|
||||
"@types/write-file-atomic": "^4.0.3",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"@types/yauzl": "^2.10.3",
|
||||
"eslint": "^8.57.0"
|
||||
"eslint": "^8.57.1"
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { default as git } from 'simple-git';
|
||||
import { default as git, CheckRepoActions } from 'simple-git';
|
||||
import { color } from './src/util.js';
|
||||
|
||||
const __dirname = import.meta.dirname ?? path.dirname(fileURLToPath(import.meta.url));
|
||||
@@ -48,6 +48,13 @@ async function updatePlugins() {
|
||||
console.log(`Updating plugin ${color.green(directory)}...`);
|
||||
const pluginPath = path.join(pluginsPath, directory);
|
||||
const pluginRepo = git(pluginPath);
|
||||
|
||||
const isRepo = await pluginRepo.checkIsRepo(CheckRepoActions.IS_REPO_ROOT);
|
||||
if (!isRepo) {
|
||||
console.log(`Directory ${color.yellow(directory)} is not a Git repository`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await pluginRepo.fetch();
|
||||
const commitHash = await pluginRepo.revparse(['HEAD']);
|
||||
const trackingBranch = await pluginRepo.revparse(['--abbrev-ref', '@{u}']);
|
||||
|
209
post-install.js
@@ -7,26 +7,107 @@ import crypto from 'node:crypto';
|
||||
import process from 'node:process';
|
||||
import yaml from 'yaml';
|
||||
import _ from 'lodash';
|
||||
import chalk from 'chalk';
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
/**
|
||||
* Colorizes console output.
|
||||
*/
|
||||
const color = {
|
||||
byNum: (mess, fgNum) => {
|
||||
mess = mess || '';
|
||||
fgNum = fgNum === undefined ? 31 : fgNum;
|
||||
return '\u001b[' + fgNum + 'm' + mess + '\u001b[39m';
|
||||
const color = chalk;
|
||||
|
||||
const keyMigrationMap = [
|
||||
{
|
||||
oldKey: 'disableThumbnails',
|
||||
newKey: 'thumbnails.enabled',
|
||||
migrate: (value) => !value,
|
||||
},
|
||||
black: (mess) => color.byNum(mess, 30),
|
||||
red: (mess) => color.byNum(mess, 31),
|
||||
green: (mess) => color.byNum(mess, 32),
|
||||
yellow: (mess) => color.byNum(mess, 33),
|
||||
blue: (mess) => color.byNum(mess, 34),
|
||||
magenta: (mess) => color.byNum(mess, 35),
|
||||
cyan: (mess) => color.byNum(mess, 36),
|
||||
white: (mess) => color.byNum(mess, 37),
|
||||
};
|
||||
{
|
||||
oldKey: 'thumbnailsQuality',
|
||||
newKey: 'thumbnails.quality',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'avatarThumbnailsPng',
|
||||
newKey: 'thumbnails.format',
|
||||
migrate: (value) => (value ? 'png' : 'jpg'),
|
||||
},
|
||||
{
|
||||
oldKey: 'disableChatBackup',
|
||||
newKey: 'backups.chat.enabled',
|
||||
migrate: (value) => !value,
|
||||
},
|
||||
{
|
||||
oldKey: 'numberOfBackups',
|
||||
newKey: 'backups.common.numberOfBackups',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'maxTotalChatBackups',
|
||||
newKey: 'backups.chat.maxTotalBackups',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'chatBackupThrottleInterval',
|
||||
newKey: 'backups.chat.throttleInterval',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'enableExtensions',
|
||||
newKey: 'extensions.enabled',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'enableExtensionsAutoUpdate',
|
||||
newKey: 'extensions.autoUpdate',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'extras.disableAutoDownload',
|
||||
newKey: 'extensions.models.autoDownload',
|
||||
migrate: (value) => !value,
|
||||
},
|
||||
{
|
||||
oldKey: 'extras.classificationModel',
|
||||
newKey: 'extensions.models.classification',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'extras.captioningModel',
|
||||
newKey: 'extensions.models.captioning',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'extras.embeddingModel',
|
||||
newKey: 'extensions.models.embedding',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'extras.speechToTextModel',
|
||||
newKey: 'extensions.models.speechToText',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'extras.textToSpeechModel',
|
||||
newKey: 'extensions.models.textToSpeech',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'minLogLevel',
|
||||
newKey: 'logging.minLogLevel',
|
||||
migrate: (value) => value,
|
||||
},
|
||||
{
|
||||
oldKey: 'cardsCacheCapacity',
|
||||
newKey: 'performance.memoryCacheCapacity',
|
||||
migrate: (value) => `${value}mb`,
|
||||
},
|
||||
{
|
||||
oldKey: 'cookieSecret',
|
||||
newKey: 'cookieSecret',
|
||||
migrate: () => void 0,
|
||||
remove: true,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Gets all keys from an object recursively.
|
||||
@@ -35,7 +116,7 @@ const color = {
|
||||
* @returns {string[]} Array of all keys in the object
|
||||
*/
|
||||
function getAllKeys(obj, prefix = '') {
|
||||
if (typeof obj !== 'object' || Array.isArray(obj)) {
|
||||
if (typeof obj !== 'object' || Array.isArray(obj) || obj === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -83,6 +164,33 @@ function addMissingConfigValues() {
|
||||
const defaultConfig = yaml.parse(fs.readFileSync(path.join(process.cwd(), './default/config.yaml'), 'utf8'));
|
||||
let config = yaml.parse(fs.readFileSync(path.join(process.cwd(), './config.yaml'), 'utf8'));
|
||||
|
||||
// Migrate old keys to new keys
|
||||
const migratedKeys = [];
|
||||
for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) {
|
||||
if (_.has(config, oldKey)) {
|
||||
if (remove) {
|
||||
_.unset(config, oldKey);
|
||||
migratedKeys.push({
|
||||
oldKey,
|
||||
newValue: void 0,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const oldValue = _.get(config, oldKey);
|
||||
const newValue = migrate(oldValue);
|
||||
_.set(config, newKey, newValue);
|
||||
_.unset(config, oldKey);
|
||||
|
||||
migratedKeys.push({
|
||||
oldKey,
|
||||
newKey,
|
||||
oldValue,
|
||||
newValue,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get all keys from the original config
|
||||
const originalKeys = getAllKeys(config);
|
||||
|
||||
@@ -95,11 +203,18 @@ function addMissingConfigValues() {
|
||||
// Find the keys that were added
|
||||
const addedKeys = _.difference(updatedKeys, originalKeys);
|
||||
|
||||
if (addedKeys.length === 0) {
|
||||
if (addedKeys.length === 0 && migratedKeys.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Adding missing config values to config.yaml:', addedKeys);
|
||||
if (addedKeys.length > 0) {
|
||||
console.log('Adding missing config values to config.yaml:', addedKeys);
|
||||
}
|
||||
|
||||
if (migratedKeys.length > 0) {
|
||||
console.log('Migrating config values in config.yaml:', migratedKeys);
|
||||
}
|
||||
|
||||
fs.writeFileSync('./config.yaml', yaml.stringify(config));
|
||||
} catch (error) {
|
||||
console.error(color.red('FATAL: Could not add missing config values to config.yaml'), error);
|
||||
@@ -110,20 +225,60 @@ function addMissingConfigValues() {
|
||||
* Creates the default config files if they don't exist yet.
|
||||
*/
|
||||
function createDefaultFiles() {
|
||||
const files = {
|
||||
config: './config.yaml',
|
||||
user: './public/css/user.css',
|
||||
};
|
||||
/**
|
||||
* @typedef DefaultItem
|
||||
* @type {object}
|
||||
* @property {'file' | 'directory'} type - Whether the item should be copied as a single file or merged into a directory structure.
|
||||
* @property {string} defaultPath - The path to the default item (typically in `default/`).
|
||||
* @property {string} productionPath - The path to the copied item for production use.
|
||||
*/
|
||||
|
||||
for (const file of Object.values(files)) {
|
||||
/** @type {DefaultItem[]} */
|
||||
const defaultItems = [
|
||||
{
|
||||
type: 'file',
|
||||
defaultPath: './default/config.yaml',
|
||||
productionPath: './config.yaml',
|
||||
},
|
||||
{
|
||||
type: 'directory',
|
||||
defaultPath: './default/public/',
|
||||
productionPath: './public/',
|
||||
},
|
||||
];
|
||||
|
||||
for (const defaultItem of defaultItems) {
|
||||
try {
|
||||
if (!fs.existsSync(file)) {
|
||||
const defaultFilePath = path.join('./default', path.parse(file).base);
|
||||
fs.copyFileSync(defaultFilePath, file);
|
||||
console.log(color.green(`Created default file: ${file}`));
|
||||
if (defaultItem.type === 'file') {
|
||||
if (!fs.existsSync(defaultItem.productionPath)) {
|
||||
fs.copyFileSync(
|
||||
defaultItem.defaultPath,
|
||||
defaultItem.productionPath,
|
||||
);
|
||||
console.log(
|
||||
color.green(`Created default file: ${defaultItem.productionPath}`),
|
||||
);
|
||||
}
|
||||
} else if (defaultItem.type === 'directory') {
|
||||
fs.cpSync(defaultItem.defaultPath, defaultItem.productionPath, {
|
||||
force: false, // Don't overwrite existing files!
|
||||
recursive: true,
|
||||
});
|
||||
console.log(
|
||||
color.green(`Synchronized missing files: ${defaultItem.productionPath}`),
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
'FATAL: Unexpected default file format in `post-install.js#createDefaultFiles()`.',
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(color.red(`FATAL: Could not write default file: ${file}`), error);
|
||||
console.error(
|
||||
color.red(
|
||||
`FATAL: Could not write default ${defaultItem.type}: ${defaultItem.productionPath}`,
|
||||
),
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@ label[for="extensions_autoconnect"] {
|
||||
}
|
||||
|
||||
.extensions_info .extension_enabled {
|
||||
color: green;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.extensions_info .extension_disabled {
|
||||
@@ -76,13 +76,44 @@ label[for="extensions_autoconnect"] {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
input.extension_missing[type="checkbox"] {
|
||||
opacity: 0.5;
|
||||
.extensions_info .extension_modules {
|
||||
font-size: 0.8em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#extensions_list .disabled {
|
||||
text-decoration: line-through;
|
||||
color: lightgray;
|
||||
.extensions_info .extension_block {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid var(--SmartThemeBorderColor);
|
||||
border-radius: 10px;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.extensions_info .extension_name {
|
||||
font-size: 1.05em;
|
||||
}
|
||||
|
||||
.extensions_info .extension_version {
|
||||
opacity: 0.8;
|
||||
font-size: 0.8em;
|
||||
font-weight: normal;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.extensions_info .extension_block a {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
.extensions_info .extension_name.update_available {
|
||||
color: limegreen;
|
||||
}
|
||||
|
||||
input.extension_missing[type="checkbox"] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.update-button {
|
||||
@@ -105,3 +136,13 @@ input.extension_missing[type="checkbox"] {
|
||||
#extensionsMenu>div.extension_container:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.extensions_info .extension_text_block {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.extensions_info .extension_actions {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
@@ -42,3 +42,9 @@ body.login .userSelect .userHandle {
|
||||
body.login .userSelect:hover {
|
||||
background-color: var(--black30a);
|
||||
}
|
||||
|
||||
body.login #handleEntryBlock,
|
||||
body.login #passwordEntryBlock,
|
||||
body.login #passwordRecoveryBlock {
|
||||
margin: 2px;
|
||||
}
|
||||
|
@@ -216,8 +216,6 @@
|
||||
|
||||
}
|
||||
|
||||
#showRawPrompt,
|
||||
#copyPromptToClipboard,
|
||||
#groupCurrentMemberPopoutButton,
|
||||
#summaryExtensionPopoutButton {
|
||||
display: none;
|
||||
|
@@ -9,3 +9,11 @@ body.safari .popup .popup-body {
|
||||
max-height: 90vh;
|
||||
max-height: 90dvh;
|
||||
}
|
||||
|
||||
body.safari #select_chat_div {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
body.safari #select_chat_popup {
|
||||
height: max-content;
|
||||
}
|
||||
|
@@ -72,6 +72,10 @@ dialog {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.popup.left_aligned_dialogue_popup .popup-content {
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
/* Opening animation */
|
||||
.popup[opening] {
|
||||
animation: pop-in var(--popup-animation-speed) ease-in-out;
|
||||
|
@@ -28,6 +28,11 @@
|
||||
color: var(--white50a);
|
||||
}
|
||||
|
||||
#completion_prompt_manager #completion_prompt_manager_list .completion_prompt_manager_prompt .completion_prompt_manager_prompt_name .fa-solid[data-role] {
|
||||
vertical-align: unset;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
#completion_prompt_manager #completion_prompt_manager_list .completion_prompt_manager_prompt_invisible {
|
||||
display: none;
|
||||
}
|
||||
@@ -260,12 +265,30 @@
|
||||
}
|
||||
|
||||
#completion_prompt_manager #completion_prompt_manager_list .completion_prompt_manager_prompt .completion_prompt_manager_prompt_name .fa-solid.prompt-manager-overridden {
|
||||
margin-left: 5px;
|
||||
margin-left: 3px;
|
||||
color: var(--SmartThemeQuoteColor);
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
#completion_prompt_manager #completion_prompt_manager_list .completion_prompt_manager_prompt .drag-handle:not(.ui-sortable-handle) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#completion_prompt_manager #completion_prompt_manager_list .completion_prompt_manager_prompt:has(.drag-handle.ui-sortable-handle) {
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
#completion_prompt_manager #completion_prompt_manager_list .completion_prompt_manager_prompt .drag-handle {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
padding: 0 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#completion_prompt_manager_footer_append_prompt {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
.scrollable-buttons-container {
|
||||
max-height: 50vh; /* Use viewport height instead of fixed pixels */
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch; /* Momentum scrolling on iOS */
|
||||
margin-top: 1rem; /* m-t-1 is equivalent to margin-top: 1rem; */
|
||||
flex-shrink: 1;
|
||||
|
@@ -100,6 +100,13 @@
|
||||
border: 1px solid var(--SmartThemeBorderColor);
|
||||
}
|
||||
|
||||
.select2-container .select2-results .select2-results__option--disabled {
|
||||
color: inherit;
|
||||
background-color: inherit;
|
||||
cursor: not-allowed;
|
||||
filter: brightness(0.5);
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice,
|
||||
.select2-container .select2-selection--single .select2-selection__choice {
|
||||
border-radius: 5px;
|
||||
|
@@ -96,11 +96,6 @@ body.charListGrid #rm_print_characters_block .group_select .group_name_block,
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#user_avatar_block.gridView .avatar-container .avatar-buttons {
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .bogus_folder_select .character_select_container,
|
||||
body.charListGrid #rm_print_characters_block .character_select .character_select_container,
|
||||
body.charListGrid #rm_print_characters_block .group_select .group_select_container,
|
||||
@@ -231,10 +226,16 @@ body.big-avatars .avatars_inline_small .avatar img {
|
||||
body.big-avatars .avatars_inline {
|
||||
max-height: calc(var(--avatar-base-height) * var(--big-avatar-height-factor) + 2 * var(--avatar-base-border-radius));
|
||||
}
|
||||
body.big-avatars .avatars_inline.avatars_multiline {
|
||||
max-height: fit-content;
|
||||
}
|
||||
|
||||
body.big-avatars .avatars_inline.avatars_inline_small {
|
||||
height: calc(var(--avatar-base-height) * var(--big-avatar-height-factor) * var(--inline-avatar-small-factor) + 2 * var(--avatar-base-border-radius));
|
||||
}
|
||||
body.big-avatars .avatars_inline.avatars_inline_small.avatars_multiline {
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
body:not(.big-avatars) .avatars_inline_small .avatar_collage {
|
||||
min-width: calc(var(--avatar-base-width) * var(--inline-avatar-small-factor));
|
||||
@@ -472,6 +473,11 @@ label[for="trim_spaces"]:has(input:checked) i.warning {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label[for="trim_spaces"]:not(:has(input:checked)) small {
|
||||
color: var(--warning);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#claude_function_prefill_warning {
|
||||
display: none;
|
||||
color: red;
|
||||
@@ -488,3 +494,7 @@ label[for="trim_spaces"]:has(input:checked) i.warning {
|
||||
#mistralai_other_models:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#banned_tokens_block_ooba:not(:has(#send_banned_tokens_textgenerationwebui:checked)) #banned_tokens_controls_ooba {
|
||||
filter: brightness(0.5);
|
||||
}
|
||||
|
450
public/global.d.ts
vendored
@@ -1,17 +1,25 @@
|
||||
import libs from './lib';
|
||||
|
||||
// Global namespace modules
|
||||
declare var ai;
|
||||
declare var pdfjsLib;
|
||||
declare var ePub;
|
||||
|
||||
declare var SillyTavern: {
|
||||
getContext(): any;
|
||||
llm: any;
|
||||
libs: typeof libs;
|
||||
};
|
||||
import getContext from './scripts/st-context';
|
||||
import { power_user } from './scripts/power-user';
|
||||
|
||||
declare global {
|
||||
// Custom types
|
||||
declare type InstructSettings = typeof power_user.instruct;
|
||||
|
||||
// Global namespace modules
|
||||
interface Window {
|
||||
ai: any;
|
||||
}
|
||||
|
||||
declare var pdfjsLib;
|
||||
declare var ePub;
|
||||
|
||||
declare var SillyTavern: {
|
||||
getContext(): typeof getContext;
|
||||
llm: any;
|
||||
libs: typeof libs;
|
||||
};
|
||||
|
||||
// Jquery plugins
|
||||
interface JQuery {
|
||||
nanogallery2(options?: any): JQuery;
|
||||
@@ -19,400 +27,32 @@ declare global {
|
||||
pagination(method: 'getCurrentPageNum'): number;
|
||||
pagination(method: string, options?: any): JQuery;
|
||||
pagination(options?: any): JQuery;
|
||||
transition(options?: any, complete?: function): JQuery;
|
||||
autocomplete(options?: any): JQuery;
|
||||
autocomplete(method: string, options?: any): JQuery;
|
||||
slider(options?: any): JQuery;
|
||||
slider(method: string, func: string, options?: any): JQuery;
|
||||
cropper(options?: any): JQuery;
|
||||
izoomify(options?: any): JQuery;
|
||||
|
||||
//#region select2
|
||||
|
||||
/**
|
||||
* Initializes or modifies a select2 instance with provided options
|
||||
*
|
||||
* @param options - Configuration options for the select2 instance
|
||||
* @returns The jQuery object for chaining
|
||||
*/
|
||||
select2(options?: Select2Options): JQuery;
|
||||
|
||||
/**
|
||||
* Retrieves data currently selected in the select2 instance
|
||||
*
|
||||
* @param field - A string specifying the 'data' method
|
||||
* @returns An array of selected items
|
||||
*/
|
||||
select2(field: 'data'): any[];
|
||||
|
||||
/**
|
||||
* Calls the specified select2 method
|
||||
*
|
||||
* @param method - The name of the select2 method to invoke
|
||||
* @returns The jQuery object for chaining
|
||||
*/
|
||||
select2(method: 'open' | 'close' | 'destroy' | 'focus' | 'val', value?: any): JQuery;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region sortable
|
||||
|
||||
/**
|
||||
* Initializes or updates a sortable instance with the provided options
|
||||
*
|
||||
* @param options - Configuration options for the sortable instance
|
||||
* @returns The jQuery object for chaining
|
||||
*/
|
||||
sortable(options?: SortableOptions): JQuery;
|
||||
|
||||
/**
|
||||
* Calls a sortable method to perform actions on the instance
|
||||
*
|
||||
* @param method - The name of the sortable method to invoke
|
||||
* @returns The jQuery object for chaining
|
||||
*/
|
||||
sortable(method: 'destroy' | 'disable' | 'enable' | 'refresh' | 'toArray'): JQuery;
|
||||
|
||||
/**
|
||||
* Retrieves the sortable's instance object. If the element does not have an associated instance, undefined is returned.
|
||||
*
|
||||
* @returns The instance of the sortable object
|
||||
*/
|
||||
sortable(method: 'instance'): object;
|
||||
|
||||
/**
|
||||
* Retrieves the current option value for the specified option
|
||||
*
|
||||
* @param method - The string 'option' to retrieve an option value
|
||||
* @param optionName - The name of the option to retrieve
|
||||
* @returns The value of the specified option
|
||||
*/
|
||||
sortable(method: 'option', optionName: string): any;
|
||||
|
||||
/**
|
||||
* Sets the value of the specified option
|
||||
*
|
||||
* @param method - The string 'option' to set an option value
|
||||
* @param optionName - The name of the option to set
|
||||
* @param value - The value to assign to the option
|
||||
* @returns The jQuery object for chaining
|
||||
*/
|
||||
sortable(method: 'option', optionName: string, value: any): JQuery;
|
||||
|
||||
/**
|
||||
* Sets multiple options using an object
|
||||
*
|
||||
* @param method - The string 'option' to set options
|
||||
* @param options - An object containing multiple option key-value pairs
|
||||
* @returns The jQuery object for chaining
|
||||
*/
|
||||
sortable(method: 'option', options: SortableOptions): JQuery;
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
namespace Select2 {
|
||||
interface Options<Result = DataFormat | GroupedDataFormat, RemoteResult = any> {
|
||||
/**
|
||||
* Extends Select2 v4 plugin by adding an option to set a placeholder for the 'search' input field
|
||||
* [Custom Field]
|
||||
* @default ''
|
||||
*/
|
||||
searchInputPlaceholder?: string;
|
||||
|
||||
/**
|
||||
* Extends select2 plugin by adding a custom css class for the 'search' input field
|
||||
* [Custom Field]
|
||||
* @default ''
|
||||
*/
|
||||
searchInputCssClass?: string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a text to a target language using a translation provider.
|
||||
* @param text Text to translate
|
||||
* @param lang Target language
|
||||
* @param provider Translation provider
|
||||
*/
|
||||
async function translate(text: string, lang: string, provider: string = null): Promise<string>;
|
||||
}
|
||||
|
||||
//#region select2
|
||||
|
||||
/** Options for configuring a select2 instance */
|
||||
interface Select2Options {
|
||||
/**
|
||||
* Provides support for ajax data sources
|
||||
* @param params - Parameters including the search term
|
||||
* @param callback - A callback function to handle the results
|
||||
* @default null
|
||||
*/
|
||||
ajax?: {
|
||||
url: string;
|
||||
dataType?: string;
|
||||
delay?: number;
|
||||
data?: (params: any) => any;
|
||||
processResults?: (data: any, params: any) => any;
|
||||
} | { transport: (params, success, failure) => any };
|
||||
|
||||
/**
|
||||
* Provides support for clearable selections
|
||||
* @default false
|
||||
*/
|
||||
allowClear?: boolean;
|
||||
|
||||
/**
|
||||
* See Using Select2 with AMD or CommonJS loaders
|
||||
* @default './i18n/'
|
||||
*/
|
||||
amdLanguageBase?: string;
|
||||
|
||||
/**
|
||||
* Controls whether the dropdown is closed after a selection is made
|
||||
* @default true
|
||||
*/
|
||||
closeOnSelect?: boolean;
|
||||
|
||||
/**
|
||||
* Allows rendering dropdown options from an array
|
||||
* @default null
|
||||
*/
|
||||
data?: object[];
|
||||
|
||||
/**
|
||||
* Used to override the built-in DataAdapter
|
||||
* @default SelectAdapter
|
||||
*/
|
||||
dataAdapter?: SelectAdapter;
|
||||
|
||||
/**
|
||||
* Enable debugging messages in the browser console
|
||||
* @default false
|
||||
*/
|
||||
debug?: boolean;
|
||||
|
||||
/**
|
||||
* Sets the dir attribute on the selection and dropdown containers to indicate the direction of the text
|
||||
* @default 'ltr'
|
||||
*/
|
||||
dir?: string;
|
||||
|
||||
/**
|
||||
* When set to true, the select control will be disabled
|
||||
* @default false
|
||||
*/
|
||||
disabled?: boolean;
|
||||
|
||||
/**
|
||||
* Used to override the built-in DropdownAdapter
|
||||
* @default DropdownAdapter
|
||||
*/
|
||||
dropdownAdapter?: DropdownAdapter;
|
||||
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
dropdownAutoWidth?: boolean;
|
||||
|
||||
/**
|
||||
* Adds additional CSS classes to the dropdown container. The helper :all: can be used to add all CSS classes present on the original <select> element.
|
||||
* @default ''
|
||||
*/
|
||||
dropdownCssClass?: string;
|
||||
|
||||
/**
|
||||
* Allows you to customize placement of the dropdown
|
||||
* @default $(document.body)
|
||||
*/
|
||||
dropdownParent?: JQuery | HTMLElement;
|
||||
|
||||
/**
|
||||
* Handles automatic escaping of content rendered by custom templates
|
||||
* @default Utils.escapeMarkup
|
||||
*/
|
||||
escapeMarkup?: function;
|
||||
|
||||
/**
|
||||
* Specify the language used for Select2 messages
|
||||
* @default EnglishTranslation
|
||||
*/
|
||||
language?: string | object;
|
||||
|
||||
/**
|
||||
* Handles custom search matching
|
||||
* @default null
|
||||
*/
|
||||
matcher?: (searchParams: object, data: object) => boolean;
|
||||
|
||||
/**
|
||||
* Maximum number of characters that may be provided for a search term
|
||||
* @default 0
|
||||
*/
|
||||
maximumInputLength?: number;
|
||||
|
||||
/**
|
||||
* The maximum number of items that may be selected in a multi-select control. If the value of this option is less than 1, the number of selected items will not be limited.
|
||||
* @default 0
|
||||
*/
|
||||
maximumSelectionLength?: number;
|
||||
|
||||
/**
|
||||
* Minimum number of characters required to start a search
|
||||
* @default 0
|
||||
*/
|
||||
minimumInputLength?: number;
|
||||
|
||||
/**
|
||||
* The minimum number of results required to display the search box
|
||||
* @default 0
|
||||
*/
|
||||
minimumResultsForSearch?: number;
|
||||
|
||||
/**
|
||||
* This option enables multi-select (pillbox) mode. Select2 will automatically map the value of the multiple HTML attribute to this option during initialization.
|
||||
* @default false
|
||||
*/
|
||||
multiple?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies the placeholder for the control
|
||||
* @default null
|
||||
*/
|
||||
placeholder?: string;
|
||||
|
||||
/**
|
||||
* Used to override the built-in ResultsAdapter
|
||||
* @default ResultsAdapter
|
||||
*/
|
||||
resultsAdapter?: ResultsAdapter;
|
||||
|
||||
/**
|
||||
* Used to override the built-in SelectionAdapter
|
||||
* @default SingleSelection | MultipleSelection
|
||||
*/
|
||||
selectionAdapter?: SingleSelection | MultipleSelection;
|
||||
|
||||
/**
|
||||
* Adds additional CSS classes to the selection container. The helper :all: can be used to add all CSS classes present on the original <select> element
|
||||
* @default ''
|
||||
*/
|
||||
selectionCssClass?: string;
|
||||
|
||||
/**
|
||||
* Implements automatic selection when the dropdown is closed
|
||||
* @default false
|
||||
*/
|
||||
selectOnClose?: boolean;
|
||||
|
||||
sorter?: function;
|
||||
|
||||
/**
|
||||
* When set to `true`, allows the user to create new tags that aren't pre-populated
|
||||
* Used to enable free text responses
|
||||
* @default false
|
||||
*/
|
||||
tags?: boolean | object[];
|
||||
|
||||
/**
|
||||
* Customizes the way that search results are rendered
|
||||
* @param item - The item object to format
|
||||
* @returns The formatted representation
|
||||
* @default null
|
||||
*/
|
||||
templateResult?: (item: any) => JQuery | string;
|
||||
|
||||
/**
|
||||
* Customizes the way that selections are rendered
|
||||
* @param item - The selected item object to format
|
||||
* @returns The formatted representation
|
||||
* @default null
|
||||
*/
|
||||
templateSelection?: (item: any) => JQuery | string;
|
||||
|
||||
/**
|
||||
* Allows you to set the theme
|
||||
* @default 'default'
|
||||
*/
|
||||
theme?: string;
|
||||
|
||||
/**
|
||||
* A callback that handles automatic tokenization of free-text entry
|
||||
* @default null
|
||||
*/
|
||||
tokenizer?: (input: { _type: string, term: string }, selection: { options: object }, callback: (Select2Option) => any) => { term: string };
|
||||
|
||||
/**
|
||||
* The list of characters that should be used as token separators
|
||||
* @default null
|
||||
*/
|
||||
tokenSeparators?: string[];
|
||||
|
||||
/**
|
||||
* Supports customization of the container width
|
||||
* @default 'resolve'
|
||||
*/
|
||||
width?: string;
|
||||
|
||||
/**
|
||||
* If true, resolves issue for multiselects using closeOnSelect: false that caused the list of results to scroll to the first selection after each select/unselect
|
||||
* @default false
|
||||
*/
|
||||
scrollAfterSelect?: boolean;
|
||||
|
||||
/**
|
||||
* Extends Select2 v4 plugin by adding an option to set a placeholder for the 'search' input field
|
||||
* [Custom Field]
|
||||
* @default ''
|
||||
*/
|
||||
searchInputPlaceholder?: string;
|
||||
|
||||
/**
|
||||
* Extends select2 plugin by adding a custom css class for the 'searcH' input field
|
||||
* [Custom Field]
|
||||
* @default ''
|
||||
*/
|
||||
searchInputCssClass?: string;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region sortable
|
||||
|
||||
/** Options for configuring a sortable instance */
|
||||
interface SortableOptions {
|
||||
/**
|
||||
* When set, prevents the sortable items from being dragged unless clicked with a delay
|
||||
* @default 0
|
||||
*/
|
||||
delay?: number;
|
||||
|
||||
/**
|
||||
* Class name for elements to handle sorting. Elements with this class can be dragged to sort.
|
||||
* @default ''
|
||||
*/
|
||||
handle?: string;
|
||||
|
||||
/**
|
||||
* Whether to allow sorting between different connected lists
|
||||
* @default false
|
||||
*/
|
||||
connectWith?: string | boolean;
|
||||
|
||||
/**
|
||||
* Function called when sorting starts
|
||||
* @param event - The event object
|
||||
* @param ui - The UI object containing the helper and position information
|
||||
*/
|
||||
start?: (event: Event, ui: SortableUI) => void;
|
||||
|
||||
/**
|
||||
* Function called when sorting stops
|
||||
* @param event - The event object
|
||||
* @param ui - The UI object containing the helper and position information
|
||||
*/
|
||||
stop?: (event: Event, ui: SortableUI) => void;
|
||||
|
||||
/**
|
||||
* Function called when sorting updates
|
||||
* @param event - The event object
|
||||
* @param ui - The UI object containing the helper and position information
|
||||
*/
|
||||
update?: (event: Event, ui: SortableUI) => void;
|
||||
|
||||
/**
|
||||
* Specifies which items inside the element should be sortable
|
||||
* @default '> *'
|
||||
*/
|
||||
items?: string;
|
||||
}
|
||||
|
||||
/** UI object passed to sortable event handlers */
|
||||
interface SortableUI {
|
||||
/** jQuery object representing the helper element */
|
||||
helper: JQuery;
|
||||
/** The current position of the helper element */
|
||||
position: { top: number; left: number };
|
||||
/** Original position of the helper element */
|
||||
originalPosition: { top: number; left: number };
|
||||
/** jQuery object representing the item being sorted */
|
||||
item: JQuery;
|
||||
/** The placeholder element used during sorting */
|
||||
placeholder: JQuery;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
6
public/img/deepseek.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 128 128" version="1.1">
|
||||
<g id="surface1">
|
||||
<path d="M 126.65625 23.902344 C 125.300781 23.242188 124.714844 24.507812 123.925781 25.152344 C 123.652344 25.359375 123.425781 25.632812 123.195312 25.878906 C 121.210938 27.996094 118.894531 29.382812 115.871094 29.214844 C 111.449219 28.96875 107.675781 30.355469 104.335938 33.738281 C 103.625 29.566406 101.269531 27.082031 97.683594 25.484375 C 95.808594 24.652344 93.910156 23.824219 92.59375 22.015625 C 91.675781 20.730469 91.425781 19.296875 90.964844 17.886719 C 90.671875 17.035156 90.378906 16.164062 89.402344 16.019531 C 88.335938 15.855469 87.921875 16.746094 87.503906 17.492188 C 85.835938 20.542969 85.1875 23.902344 85.253906 27.308594 C 85.398438 34.964844 88.628906 41.066406 95.054688 45.402344 C 95.785156 45.898438 95.972656 46.398438 95.742188 47.125 C 95.308594 48.617188 94.785156 50.070312 94.324219 51.566406 C 94.03125 52.523438 93.59375 52.726562 92.570312 52.316406 C 89.109375 50.828125 85.96875 48.691406 83.3125 46.019531 C 78.742188 41.605469 74.613281 36.730469 69.460938 32.910156 C 68.269531 32.03125 67.042969 31.191406 65.785156 30.398438 C 60.535156 25.296875 66.480469 21.105469 67.855469 20.609375 C 69.296875 20.085938 68.351562 18.304688 63.703125 18.324219 C 59.050781 18.347656 54.792969 19.898438 49.371094 21.972656 C 48.566406 22.28125 47.734375 22.527344 46.890625 22.703125 C 41.820312 21.75 36.636719 21.566406 31.515625 22.160156 C 21.460938 23.28125 13.433594 28.039062 7.53125 36.148438 C 0.4375 45.898438 -1.230469 56.980469 0.8125 68.535156 C 2.960938 80.714844 9.179688 90.800781 18.730469 98.683594 C 28.640625 106.859375 40.046875 110.863281 53.066406 110.097656 C 60.96875 109.644531 69.777344 108.582031 79.703125 100.175781 C 82.207031 101.425781 84.832031 101.921875 89.195312 102.292969 C 92.554688 102.609375 95.785156 102.132812 98.289062 101.609375 C 102.207031 100.777344 101.9375 97.148438 100.523438 96.484375 C 89.03125 91.128906 91.550781 93.3125 89.253906 91.546875 C 95.097656 84.632812 103.898438 77.457031 107.34375 54.199219 C 107.609375 52.347656 107.382812 51.183594 107.34375 49.691406 C 107.324219 48.785156 107.53125 48.425781 108.570312 48.324219 C 111.457031 48.027344 114.253906 47.164062 116.8125 45.792969 C 124.257812 41.722656 127.265625 35.046875 127.972656 27.035156 C 128.078125 25.808594 127.953125 24.542969 126.65625 23.898438 Z M 61.765625 96 C 50.625 87.242188 45.222656 84.355469 42.992188 84.480469 C 40.902344 84.609375 41.28125 86.992188 41.738281 88.550781 C 42.21875 90.085938 42.84375 91.140625 43.71875 92.492188 C 44.324219 93.382812 44.742188 94.710938 43.113281 95.707031 C 39.523438 97.925781 33.289062 94.960938 32.996094 94.816406 C 25.738281 90.539062 19.664062 84.894531 15.390625 77.179688 C 11.265625 69.75 8.863281 61.78125 8.46875 53.273438 C 8.363281 51.214844 8.964844 50.492188 11.011719 50.117188 C 13.703125 49.601562 16.457031 49.53125 19.167969 49.910156 C 30.539062 51.574219 40.214844 56.65625 48.332031 64.703125 C 52.960938 69.289062 56.464844 74.769531 60.074219 80.121094 C 63.914062 85.808594 68.042969 91.226562 73.300781 95.664062 C 75.15625 97.222656 76.632812 98.40625 78.054688 99.273438 C 73.777344 99.753906 66.640625 99.863281 61.765625 96 Z M 67.097656 61.652344 C 67.097656 61.117188 67.359375 60.609375 67.800781 60.304688 C 68.246094 60 68.808594 59.929688 69.3125 60.121094 C 70.378906 62.097656 70.207031 62.515625 69.894531 62.824219 C 69.585938 63.132812 69.164062 63.300781 68.726562 63.296875 C 68.292969 63.296875 67.875 63.125 67.570312 62.816406 C 67.265625 62.507812 67.097656 62.085938 67.105469 61.652344 Z M 83.683594 70.164062 C 82.617188 70.597656 81.558594 70.96875 80.539062 71.019531 C 79.007812 71.070312 77.503906 70.59375 76.28125 69.664062 C 74.820312 68.4375 73.777344 67.753906 73.339844 65.621094 C 73.1875 64.578125 73.214844 63.519531 73.425781 62.484375 C 73.796875 60.742188 73.382812 59.621094 72.148438 58.609375 C 71.152344 57.777344 69.878906 57.546875 68.480469 57.546875 C 68 57.519531 67.535156 57.375 67.125 57.128906 C 66.539062 56.84375 66.058594 56.117188 66.515625 55.222656 C 66.667969 54.933594 67.371094 54.230469 67.542969 54.101562 C 69.441406 53.023438 71.632812 53.375 73.652344 54.1875 C 75.53125 54.953125 76.949219 56.363281 78.992188 58.355469 C 81.078125 60.761719 81.457031 61.429688 82.644531 63.230469 C 83.585938 64.644531 84.4375 66.097656 85.019531 67.753906 C 85.375 68.792969 84.917969 69.644531 83.683594 70.164062 Z M 83.683594 70.164062 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
15
public/img/generic.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="616.86328"
|
||||
height="616.86328"
|
||||
viewBox="0 0 77.10791 77.10791"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<path
|
||||
id="circle1"
|
||||
d="M 38.553955,0 A 38.554,38.554 0 0 0 0,38.553955 38.554,38.554 0 0 0 38.553955,77.107911 38.554,38.554 0 0 0 77.107911,38.553955 38.554,38.554 0 0 0 38.553955,0 Z m -3.125976,13.545898 h 6.251953 v 19.593751 l 16.968751,-9.796875 3.125974,5.414306 -16.968506,9.796875 16.968506,9.796877 -3.125974,5.414305 -16.968751,-9.796874 V 63.56201 H 35.427979 V 43.968263 l -16.968506,9.796874 -3.125977,-5.414305 16.96875,-9.796877 -16.96875,-9.796875 3.125977,-5.414306 16.968506,9.796875 z" />
|
||||
</svg>
|
After Width: | Height: | Size: 803 B |
1
public/img/vllm.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg version="1.0" width="565.752" height="586.537" viewBox="0 0 424.314 439.903" preserveAspectRatio="xMidYMid" xmlns="http://www.w3.org/2000/svg"><path d="M344.6 41.703c-43.4 23-79.3 42.4-79.7 43.2-.8 1.4-72.3 276.1-84.3 323.5-6.2 24.9-7.1 27.7-8 25.5-.4-.8-.5-77.7-.4-170.8l.3-169.2H86.3c-47.5 0-86.3.2-86.3.5 0 1 162.2 325 166.9 333.3 2.5 4.6 5 9.2 5.6 10.3.9 1.8 2.7 1.9 68.2 1.9 63.1 0 67.2-.1 67.7-1.8.3-.9 24.2-90.8 53-199.7 51-192.7 58.9-222.4 62-233.3.8-2.8 1.1-5.2.8-5.1-.4 0-36.2 18.8-79.6 41.7z"/></svg>
|
After Width: | Height: | Size: 516 B |
@@ -5,7 +5,8 @@
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"allowUmdGlobalAccess": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strictBindCallApply": true
|
||||
},
|
||||
"exclude": [
|
||||
"**/node_modules/**",
|
||||
@@ -13,7 +14,8 @@
|
||||
"**/.git/**",
|
||||
"lib/**",
|
||||
"**/*.min.js",
|
||||
"scripts/extensions/quick-reply/lib/**"
|
||||
"scripts/extensions/quick-reply/lib/**",
|
||||
"scripts/extensions/tts/lib/**"
|
||||
],
|
||||
"typeAcquisition": {
|
||||
"include": []
|
||||
|
@@ -19,6 +19,8 @@ import seedrandom from 'seedrandom';
|
||||
import * as Popper from '@popperjs/core';
|
||||
import droll from 'droll';
|
||||
import morphdom from 'morphdom';
|
||||
import { toggle as slideToggle } from 'slidetoggle';
|
||||
import chalk from 'chalk';
|
||||
|
||||
/**
|
||||
* Expose the libraries to the 'window' object.
|
||||
@@ -94,6 +96,8 @@ export default {
|
||||
Popper,
|
||||
droll,
|
||||
morphdom,
|
||||
slideToggle,
|
||||
chalk,
|
||||
};
|
||||
|
||||
export {
|
||||
@@ -115,4 +119,6 @@ export {
|
||||
Popper,
|
||||
droll,
|
||||
morphdom,
|
||||
slideToggle,
|
||||
chalk,
|
||||
};
|
||||
|
@@ -24,10 +24,22 @@ if (typeof Array.prototype.indexOf === 'function') {
|
||||
|
||||
|
||||
/* Polyfill EventEmitter. */
|
||||
var EventEmitter = function () {
|
||||
/**
|
||||
* Creates an event emitter.
|
||||
* @param {string[]} autoFireAfterEmit Auto-fire event names
|
||||
*/
|
||||
var EventEmitter = function (autoFireAfterEmit = []) {
|
||||
this.events = {};
|
||||
this.autoFireLastArgs = new Map();
|
||||
this.autoFireAfterEmit = new Set(autoFireAfterEmit);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a listener to an event.
|
||||
* @param {string} event Event name
|
||||
* @param {function} listener Event listener
|
||||
* @returns
|
||||
*/
|
||||
EventEmitter.prototype.on = function (event, listener) {
|
||||
// Unknown event used by external libraries?
|
||||
if (event === undefined) {
|
||||
@@ -40,6 +52,10 @@ EventEmitter.prototype.on = function (event, listener) {
|
||||
}
|
||||
|
||||
this.events[event].push(listener);
|
||||
|
||||
if (this.autoFireAfterEmit.has(event) && this.autoFireLastArgs.has(event)) {
|
||||
listener.apply(this, this.autoFireLastArgs.get(event));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -60,6 +76,10 @@ EventEmitter.prototype.makeLast = function (event, listener) {
|
||||
}
|
||||
|
||||
events.push(listener);
|
||||
|
||||
if (this.autoFireAfterEmit.has(event) && this.autoFireLastArgs.has(event)) {
|
||||
listener.apply(this, this.autoFireLastArgs.get(event));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,8 +100,17 @@ EventEmitter.prototype.makeFirst = function (event, listener) {
|
||||
}
|
||||
|
||||
events.unshift(listener);
|
||||
|
||||
if (this.autoFireAfterEmit.has(event) && this.autoFireLastArgs.has(event)) {
|
||||
listener.apply(this, this.autoFireLastArgs.get(event));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener from an event.
|
||||
* @param {string} event Event name
|
||||
* @param {function} listener Event listener
|
||||
*/
|
||||
EventEmitter.prototype.removeListener = function (event, listener) {
|
||||
var idx;
|
||||
|
||||
@@ -94,14 +123,19 @@ EventEmitter.prototype.removeListener = function (event, listener) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Emits an event with optional arguments.
|
||||
* @param {string} event Event name
|
||||
*/
|
||||
EventEmitter.prototype.emit = async function (event) {
|
||||
let args = [].slice.call(arguments, 1);
|
||||
if (localStorage.getItem('eventTracing') === 'true') {
|
||||
console.trace('Event emitted: ' + event, args);
|
||||
} else {
|
||||
console.debug('Event emitted: ' + event);
|
||||
}
|
||||
|
||||
var i, listeners, length, args = [].slice.call(arguments, 1);
|
||||
let i, listeners, length;
|
||||
|
||||
if (typeof this.events[event] === 'object') {
|
||||
listeners = this.events[event].slice();
|
||||
@@ -117,16 +151,21 @@ EventEmitter.prototype.emit = async function (event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.autoFireAfterEmit.has(event)) {
|
||||
this.autoFireLastArgs.set(event, args);
|
||||
}
|
||||
};
|
||||
|
||||
EventEmitter.prototype.emitAndWait = function (event) {
|
||||
let args = [].slice.call(arguments, 1);
|
||||
if (localStorage.getItem('eventTracing') === 'true') {
|
||||
console.trace('Event emitted: ' + event, args);
|
||||
} else {
|
||||
console.debug('Event emitted: ' + event);
|
||||
}
|
||||
|
||||
var i, listeners, length, args = [].slice.call(arguments, 1);
|
||||
let i, listeners, length;
|
||||
|
||||
if (typeof this.events[event] === 'object') {
|
||||
listeners = this.events[event].slice();
|
||||
@@ -142,10 +181,14 @@ EventEmitter.prototype.emitAndWait = function (event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.autoFireAfterEmit.has(event)) {
|
||||
this.autoFireLastArgs.set(event, args);
|
||||
}
|
||||
};
|
||||
|
||||
EventEmitter.prototype.once = function (event, listener) {
|
||||
this.on(event, function g () {
|
||||
this.on(event, function g() {
|
||||
this.removeListener(event, g);
|
||||
listener.apply(this, arguments);
|
||||
});
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "اكتمال النص",
|
||||
"Chat Completion": "إكمال الدردشة",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "جماعة KoboldAI",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "تجنب إرسال معلومات حساسة إلى الجماعة.",
|
||||
"Review the Privacy statement": "مراجعة بيان الخصوصية",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "فصل بفواصل دون مسافة بينها",
|
||||
"Custom Stopping Strings": "سلاسل توقف مخصصة",
|
||||
"JSON serialized array of strings": "مصفوفة سلسلة JSON متسلسلة",
|
||||
"Replace Macro in Custom Stopping Strings": "استبدال الماكرو في سلاسل التوقف المخصصة",
|
||||
"Replace Macro in Stop Strings": "استبدال الماكرو في سلاسل التوقف المخصصة",
|
||||
"Auto-Continue": "المتابعة التلقائية",
|
||||
"Allow for Chat Completion APIs": "السماح بواجهات برمجة التطبيقات لإكمال الدردشة",
|
||||
"Target length (tokens)": "الطول المستهدف (رموز)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "حذف موضوع",
|
||||
"Update a theme file": "تحديث ملف السمة",
|
||||
"Save as a new theme": "حفظ كسمة جديدة",
|
||||
"Avatar Style": "نمط الصورة الرمزية",
|
||||
"Avatar Style:": "نمط الصورة الرمزية",
|
||||
"Circle": "دائرة",
|
||||
"Square": "مربع",
|
||||
"Rectangle": "مستطيل",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "تفضيل التعليمات من بطاقة الشخصية",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "إذا تم التحقق وكانت بطاقة الشخصية تحتوي على تجاوز للكسر (تعليمات تاريخ المشاركة)، استخدم ذلك بدلاً من ذلك",
|
||||
"Prefer Character Card Jailbreak": "تفضيل كسر الحصار من بطاقة الشخصية",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "تجنب اقتصاص صور الأحرف المستوردة وتغيير حجمها. عند إيقاف التشغيل، قم بالقص/تغيير الحجم إلى 512 × 768.",
|
||||
"never_resize_avatars_tooltip": "تجنب اقتصاص صور الأحرف المستوردة وتغيير حجمها. عند إيقاف التشغيل، قم بالقص/تغيير الحجم إلى 512 × 768.",
|
||||
"Never resize avatars": "لا تغيير حجم الصور الرمزية أبدًا",
|
||||
"Show actual file names on the disk, in the characters list display only": "عرض الأسماء الفعلية للملفات على القرص، في عرض قائمة الشخصيات فقط",
|
||||
"Show avatar filenames": "عرض أسماء ملفات الصور الرمزية",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "السحب التلقائي",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "تمكين وظيفة السحب التلقائي. الإعدادات في هذا القسم تؤثر فقط عند تمكين السحب التلقائي",
|
||||
"Minimum generated message length": "الحد الأدنى لطول الرسالة المولدة",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "إذا كانت الرسالة المولدة أقصر من هذا، فتحريض السحب التلقائي",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "إذا كانت الرسالة المولدة أقصر من هذا، فتحريض السحب التلقائي",
|
||||
"Blacklisted words": "الكلمات الممنوعة",
|
||||
"words you dont want generated separated by comma ','": "الكلمات التي لا تريد توليدها مفصولة بفاصلة ','",
|
||||
"Blacklisted word count to swipe": "عدد الكلمات الممنوعة للسحب",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "لا",
|
||||
"popup-button-cancel": "يلغي",
|
||||
"popup-button-import": "يستورد",
|
||||
"Advanced Defininitions": "تعريفات متقدمة",
|
||||
"Advanced Definitions": "تعريفات متقدمة",
|
||||
"Prompt Overrides": "التجاوزات السريعة",
|
||||
"(For Chat Completion and Instruct Mode)": "(لاستكمال الدردشة ووضع التعليمات)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "أدخل {{original}} في أي مربع لتضمين التعليمات الافتراضية المعنية من إعدادات النظام.",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "قم بتشغيل تطبيق DrawThings مع تمكين مفتاح HTTP API في واجهة المستخدم! يجب أن يكون الخادم قابلاً للوصول من الجهاز المضيف SillyTavern.",
|
||||
"sd_vlad_url": "مثال: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "يجب أن يكون الخادم قابلاً للوصول من الجهاز المضيف SillyTavern.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "تلميح: احفظ مفتاح API في إعدادات Horde KoboldAI API لاستخدامه هنا.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "تلميح: احفظ مفتاح API في إعدادات AI Horde API لاستخدامه هنا.",
|
||||
"Allow NSFW images from Horde": "السماح بصور NSFW من Horde",
|
||||
"Sanitize prompts (recommended)": "مطالبات التعقيم (مستحسن)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "قم بضبط معلمات الإنشاء تلقائيًا لضمان إنشاء صور مجانية.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Chub Lorebook (رابط مباشر أو معرف)",
|
||||
"char_import_3": "حرف JanitorAI (رابط مباشر أو UUID)",
|
||||
"char_import_4": "حرف Pygmalion.chat (رابط مباشر أو UUID)",
|
||||
"char_import_5": "حرف AICharacterCard.com (رابط مباشر أو معرف)",
|
||||
"char_import_5": "حرف AICharacterCards.com (رابط مباشر أو معرف)",
|
||||
"char_import_6": "رابط PNG المباشر (راجع",
|
||||
"char_import_7": "للمضيفين المسموح بهم)",
|
||||
"char_import_8": "شخصية RisuRealm (رابط مباشر)",
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "Textvervollständigung",
|
||||
"Chat Completion": "Chat-Abschluss",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "KoboldAI Horde",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Vermeide das Senden sensibler Informationen an die Horde.",
|
||||
"Review the Privacy statement": "Überprüfe die Datenschutzerklärung",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "getrennt durch Kommas ohne Leerzeichen dazwischen",
|
||||
"Custom Stopping Strings": "Benutzerdefinierte Stoppzeichenfolgen",
|
||||
"JSON serialized array of strings": "JSON serialisierte Reihe von Zeichenfolgen",
|
||||
"Replace Macro in Custom Stopping Strings": "Makro in benutzerdefinierten Stoppzeichenfolgen ersetzen",
|
||||
"Replace Macro in Stop Strings": "Makro in benutzerdefinierten Stoppzeichenfolgen ersetzen",
|
||||
"Auto-Continue": "Automatisch fortsetzen",
|
||||
"Allow for Chat Completion APIs": "Erlaube Chat-Vervollständigungs-APIs",
|
||||
"Target length (tokens)": "Ziel-Länge (Tokens)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "Löschen eines Designs",
|
||||
"Update a theme file": "Ein Theme-Datei aktualisieren",
|
||||
"Save as a new theme": "Als neues Theme speichern",
|
||||
"Avatar Style": "Avatar-Stil",
|
||||
"Avatar Style:": "Avatar-Stil",
|
||||
"Circle": "Kreis",
|
||||
"Square": "Quadrat",
|
||||
"Rectangle": "Rechteck",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "Bevorzuge Charakterkarten-Prompt",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Wenn aktiviert und die Charakterkarte eine Jailbreak-Überschreibung enthält (Post-History-Instruction), verwende stattdessen diese",
|
||||
"Prefer Character Card Jailbreak": "Bevorzuge Charakterkarten-Jailbreak",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Vermeiden Sie das Zuschneiden und Ändern der Größe importierter Zeichenbilder. Wenn deaktiviert, wird die Größe auf 512 x 768 zugeschnitten/angepasst.",
|
||||
"never_resize_avatars_tooltip": "Vermeiden Sie das Zuschneiden und Ändern der Größe importierter Zeichenbilder. Wenn deaktiviert, wird die Größe auf 512 x 768 zugeschnitten/angepasst.",
|
||||
"Never resize avatars": "Avatare niemals verkleinern",
|
||||
"Show actual file names on the disk, in the characters list display only": "Zeige tatsächliche Dateinamen auf der Festplatte, nur in der Anzeige der Charakterliste",
|
||||
"Show avatar filenames": "Avatar-Dateinamen anzeigen",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "Automatisches Wischen",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Aktiviere die Auto-Wisch-Funktion. Einstellungen in diesem Abschnitt haben nur dann Auswirkungen, wenn das automatische Wischen aktiviert ist",
|
||||
"Minimum generated message length": "Minimale generierte Nachrichtenlänge",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Wenn die generierte Nachricht kürzer ist als diese, löse automatisches Wischen aus",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Wenn die generierte Nachricht kürzer ist als diese, löse automatisches Wischen aus",
|
||||
"Blacklisted words": "Verbotene Wörter",
|
||||
"words you dont want generated separated by comma ','": "Wörter, die du nicht generiert haben möchtest, durch Komma ',' getrennt",
|
||||
"Blacklisted word count to swipe": "Anzahl der verbotenen Wörter, um zu wischen",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "NEIN",
|
||||
"popup-button-cancel": "Stornieren",
|
||||
"popup-button-import": "Importieren",
|
||||
"Advanced Defininitions": "Erweiterte Definitionen",
|
||||
"Advanced Definitions": "Erweiterte Definitionen",
|
||||
"Prompt Overrides": "Eingabeaufforderungsüberschreibungen",
|
||||
"(For Chat Completion and Instruct Mode)": "(Für Chat-Abschluss und Anweisungsmodus)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Füge {{original}} in eines der Felder ein, um den jeweiligen Standardprompt aus den Systemeinstellungen einzuschließen.",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "Führen Sie die DrawThings-App mit aktiviertem HTTP-API-Schalter in der Benutzeroberfläche aus! Der Server muss vom SillyTavern-Hostcomputer aus zugänglich sein.",
|
||||
"sd_vlad_url": "Beispiel: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "Der Server muss vom SillyTavern-Hostcomputer aus zugänglich sein.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Tipp: Speichern Sie einen API-Schlüssel in den Horde KoboldAI API-Einstellungen, um ihn hier zu verwenden.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Tipp: Speichern Sie einen API-Schlüssel in den AI Horde API-Einstellungen, um ihn hier zu verwenden.",
|
||||
"Allow NSFW images from Horde": "NSFW-Bilder von Horde zulassen",
|
||||
"Sanitize prompts (recommended)": "Eingabeaufforderungen bereinigen (empfohlen)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Passen Sie die Generierungsparameter automatisch an, um eine freie Bildgenerierung zu gewährleisten.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Chub Lorebook (Direktlink oder ID)",
|
||||
"char_import_3": "JanitorAI-Charakter (Direktlink oder UUID)",
|
||||
"char_import_4": "Pygmalion.chat-Charakter (Direktlink oder UUID)",
|
||||
"char_import_5": "AICharacterCard.com-Charakter (Direktlink oder ID)",
|
||||
"char_import_5": "AICharacterCards.com-Charakter (Direktlink oder ID)",
|
||||
"char_import_6": "Direkter PNG-Link (siehe",
|
||||
"char_import_7": "für erlaubte Hosts)",
|
||||
"char_import_8": "RisuRealm-Charakter (Direktlink)",
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "Completar texto",
|
||||
"Chat Completion": "Finalización del chat",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "Horde de KoboldAI",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Evite enviar información sensible a Horde.",
|
||||
"Review the Privacy statement": "Revise la declaración de privacidad",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "separe con comas sin espacio entre ellas",
|
||||
"Custom Stopping Strings": "Cadenas de Detención Personalizadas",
|
||||
"JSON serialized array of strings": "Arreglo de cadenas serializado en JSON",
|
||||
"Replace Macro in Custom Stopping Strings": "Reemplazar macro en Cadenas de Detención Personalizadas",
|
||||
"Replace Macro in Stop Strings": "Reemplazar macro en Cadenas de Detención Personalizadas",
|
||||
"Auto-Continue": "Autocontinuar",
|
||||
"Allow for Chat Completion APIs": "Permitir para APIs de Completado de Chat",
|
||||
"Target length (tokens)": "Longitud objetivo (tokens)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "Eliminar un tema",
|
||||
"Update a theme file": "Actualizar un archivo de tema",
|
||||
"Save as a new theme": "Guardar como nuevo tema",
|
||||
"Avatar Style": "Estilo de Avatar",
|
||||
"Avatar Style:": "Estilo de Avatar",
|
||||
"Circle": "Círculo",
|
||||
"Square": "Cuadrado",
|
||||
"Rectangle": "Rectángulo",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "Preferir Indicaciones en Tarjeta de Personaje",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Si está marcado y la tarjeta de personaje contiene una anulación de jailbreak (Instrucciones Post Historial), usar eso en su lugar",
|
||||
"Prefer Character Card Jailbreak": "Preferir Jailbreak en Tarjeta de Personaje",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Evite recortar y cambiar el tamaño de las imágenes de personajes importados. Cuando esté desactivado, recorte/cambie el tamaño a 512x768.",
|
||||
"never_resize_avatars_tooltip": "Evite recortar y cambiar el tamaño de las imágenes de personajes importados. Cuando esté desactivado, recorte/cambie el tamaño a 512x768.",
|
||||
"Never resize avatars": "Nunca redimensionar avatares",
|
||||
"Show actual file names on the disk, in the characters list display only": "Mostrar nombres de archivo reales en el disco, solo en la visualización de la lista de personajes",
|
||||
"Show avatar filenames": "Mostrar nombres de archivo de avatares",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "Deslizamiento automático",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Habilitar la función de deslizamiento automático. La configuración en esta sección solo tiene efecto cuando el deslizamiento automático está habilitado",
|
||||
"Minimum generated message length": "Longitud mínima del mensaje generado",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Si el mensaje generado es más corto que esto, activar un deslizamiento automático",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Si el mensaje generado es más corto que esto, activar un deslizamiento automático",
|
||||
"Blacklisted words": "Palabras prohibidas",
|
||||
"words you dont want generated separated by comma ','": "palabras que no desea generar separadas por coma ','",
|
||||
"Blacklisted word count to swipe": "Número de palabras prohibidas para deslizar",
|
||||
@@ -874,12 +874,12 @@
|
||||
"Bulk_edit_characters": "Editar personajes masivamente",
|
||||
"Bulk select all characters": "Seleccionar de forma masiva todos los personajes",
|
||||
"Bulk delete characters": "Eliminar personajes masivamente",
|
||||
"popup-button-save": "Ahorrar",
|
||||
"popup-button-save": "Guardar",
|
||||
"popup-button-yes": "Sí",
|
||||
"popup-button-no": "No",
|
||||
"popup-button-cancel": "Cancelar",
|
||||
"popup-button-import": "Importar",
|
||||
"Advanced Defininitions": "Definiciones avanzadas",
|
||||
"Advanced Definitions": "Definiciones avanzadas",
|
||||
"Prompt Overrides": "Anulaciones rápidas",
|
||||
"(For Chat Completion and Instruct Mode)": "(Para completar el chat y el modo de instrucción)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Inserte {{original}} en cualquiera de las casillas para incluir las indicaciones predeterminadas respectivas de la configuración del sistema.",
|
||||
@@ -1019,7 +1019,7 @@
|
||||
"This prompt cannot be overridden by character cards, even if overrides are preferred.": "Este mensaje no puede ser anulado por tarjetas de personaje, incluso si se prefieren las anulaciones.",
|
||||
"prompt_manager_forbid_overrides": "Prohibir anulaciones",
|
||||
"reset": "reiniciar",
|
||||
"save": "ahorrar",
|
||||
"save": "guardar",
|
||||
"This message is invisible for the AI": "Este mensaje es invisible para la IA",
|
||||
"Message Actions": "Acciones de mensajes",
|
||||
"Translate message": "Traducir mensaje",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "¡Ejecute la aplicación DrawThings con el interruptor API HTTP habilitado en la interfaz de usuario! Se debe poder acceder al servidor desde la máquina host de SillyTavern.",
|
||||
"sd_vlad_url": "Ejemplo: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "Se debe poder acceder al servidor desde la máquina host de SillyTavern.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Sugerencia: guarde una clave API en la configuración de API de Horde KoboldAI para usarla aquí.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Sugerencia: guarde una clave API en la configuración de API de AI Horde para usarla aquí.",
|
||||
"Allow NSFW images from Horde": "Permitir imágenes NSFW de Horda",
|
||||
"Sanitize prompts (recommended)": "Indicaciones para desinfectar (recomendado)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Ajuste automáticamente los parámetros de generación para garantizar generaciones de imágenes gratuitas.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Chub Lorebook (enlace directo o ID)",
|
||||
"char_import_3": "Carácter de JanitorAI (enlace directo o UUID)",
|
||||
"char_import_4": "Carácter Pygmalion.chat (enlace directo o UUID)",
|
||||
"char_import_5": "Carácter AICharacterCard.com (enlace directo o ID)",
|
||||
"char_import_5": "Carácter AICharacterCards.com (enlace directo o ID)",
|
||||
"char_import_6": "Enlace PNG directo (consulte",
|
||||
"char_import_7": "para hosts permitidos)",
|
||||
"char_import_8": "Personaje RisuRealm (Enlace directo)",
|
||||
@@ -1439,5 +1439,112 @@
|
||||
"Still have questions?": "¿Todavía tienes preguntas?",
|
||||
"Join the SillyTavern Discord": "Únete al Discord de SillyTavern",
|
||||
"Post a GitHub issue": "Publicar un problema en GitHub",
|
||||
"Contact the developers": "Contactar a los desarrolladores"
|
||||
"Contact the developers": "Contactar a los desarrolladores",
|
||||
"Prome (Visual Novel Extension)": "Prome (Extensión de Modo Waifu/Novela Visual)",
|
||||
"Brought to you by": "Presentado por",
|
||||
"and Prometheus.": "y Prometheus.",
|
||||
"Enable Prome": "Iniciar Prome",
|
||||
"Toggles Prome, VN Mode and other Prome features.": "Activa Prome, el modo VN y otras funciones de Prome.",
|
||||
"Features marked with a": "Las funciones marcadas con un",
|
||||
"require Prome to be enabled.": "requieren que Prome esté iniciado.",
|
||||
"Sheld Configuration": "Configuración de interfaz (Sheld)",
|
||||
"Hide Sheld (Message Box)": "Ocultar Sheld (cuadro de mensajes)",
|
||||
"Hide the message box (sheld) in the ST UI.": "Ocultar el cuadro de mensajes (sheld) en la interfaz de usuario de SillyTavern.",
|
||||
"Enable Traditional VN Mode": "Modo VN tradicional*",
|
||||
"Only Show Last Message in Chat (Requires Prome to be enabled).": "Mostrar solo el último mensaje en el chat (Requiere que Prome esté iniciado).",
|
||||
"Letterbox Configuration*": "Configuración de la franja negra*",
|
||||
"Letterbox Mode": "Modo de franja negra",
|
||||
"Select the letterbox mode for the Prome VN UI.": "Seleccione el modo de franja negra para la interfaz de usuario VN de Prome.",
|
||||
"Horizontal Letterbox": "Franja negra horizontal",
|
||||
"Vertical Letterbox": "Franja negra vertical",
|
||||
"Letterbox Color": "Color de la franja negra",
|
||||
"Select the color of the letterbox.": "Seleccione el color de la franja negra.",
|
||||
"Letterbox Size": "Tamaño de la franja negra",
|
||||
"Set the size of the letterbox.": "Establezca el tamaño de la franja negra.",
|
||||
"Sprite Configuration": "Configuración de sprites",
|
||||
"Emulate Character Card as Sprite": "[BETA] Emular tarjeta de personaje como sprite",
|
||||
"Emulates the character card of a character to be a sprite. (Requires Prome to be enabled).": "Emula la tarjeta de personaje de un personaje para que sea un sprite. (Requiere que Prome esté iniciado).",
|
||||
"Enable Sprite Shake": "[BETA] Sprite Shake",
|
||||
"Shakes the character sprite when the character is speaking (Only works if Streaming is enabled in Preset Settings).": "Agita el sprite del personaje cuando el personaje está hablando (solo funciona si la transmisión está habilitada en la configuración preestablecida).",
|
||||
"Enable Focus Mode": "Modo de enfoque",
|
||||
"Focuses the current speaking character in chat. (Requires Prome to be enabled).": "Enfoca al personaje que está hablando en el chat. (Requiere que Prome esté iniciado).",
|
||||
"Darken Unfocused Character Sprites": "Oscurecer sprites de personajes",
|
||||
"Darkens non-speaking (unfocused) characters. (Requires Prome to be enabled).": "Oscurece a los personajes que no hablan (no enfocados). (Requiere que Prome esté iniciado).",
|
||||
"Auto-Hide Sprites": "Ocultar sprites automáticamente",
|
||||
"Auto-hides characters from the screen that haven't been in the conversation for a while up to X characters. (Requires Prome to be enabled).": "Oculta automáticamente a los personajes de la pantalla que no han estado en la conversación durante un tiempo hasta X personajes. (Requiere que Prome esté iniciado).",
|
||||
"Max Visible Sprites": "Máximo de personajes visibles",
|
||||
"Set the maximum number of visible sprites that appears in the VN screen.": "Establezca el número máximo de sprites visibles que aparecen en la pantalla VN.",
|
||||
"Sprite Shadow Configuration": "Configuración de sombra de sprites",
|
||||
"Enable Sprite Shadow": "Sombra de sprite",
|
||||
"Adds a shadow to the character sprite.": "Agrega una sombra al sprite del personaje.",
|
||||
"Shadow X Offset": "Desplazamiento X de la sombra",
|
||||
"Set the X offset of the character shadow.": "Establezca el desplazamiento X de la sombra del personaje.",
|
||||
"Shadow Y Offset": "Desplazamiento Y de la sombra",
|
||||
"Set the Y offset of the character shadow.": "Establezca el desplazamiento Y de la sombra del personaje.",
|
||||
"Shadow Blur": "Desenfoque de sombra",
|
||||
"Set the blur of the character shadow.": "Establezca el desenfoque de la sombra del personaje.",
|
||||
"Focus Mode Settings": "Configuración del modo de enfoque",
|
||||
"Focus Mode Animation": "Animación de modo de enfoque",
|
||||
"Select the animation for focus mode.": "Seleccione la animación para el modo de enfoque.",
|
||||
"Focus Mode Animation Speed": "Velocidad de animación del modo de enfoque",
|
||||
"Set the speed of the focus animation.": "Establezca la velocidad de la animación de enfoque.",
|
||||
"User Sprite Configuration": "[BETA] Configuración de sprites de usuario",
|
||||
"Enable User Sprite": "Sprites de usuario",
|
||||
"Enables the ability to use a user sprite for your persona.": "Habilita la capacidad de usar un sprite de usuario para tu persona.",
|
||||
"Sprite set": "Conjunto de sprites",
|
||||
"Type the name of the sprite set to use for your persona. (Place your sprites in the 'characters' folder in SillyTavern).": "Escriba el nombre del conjunto de sprites que desea utilizar para su persona. (Coloque sus sprites en la carpeta 'characters' en SillyTavern).",
|
||||
"Note: Create a sprite folder in the ": "Nota: Cree una carpeta de sprites en el ",
|
||||
" folder of your user directory (typically 'data/default-user'). Place your expressions there.": " carpeta de su directorio de usuario (normalmente 'data/default-user'). Coloque sus expresiones allí.",
|
||||
"Tint Configuration": "Configuración de tono",
|
||||
"Enable Chat Tint": "Tinte de chat",
|
||||
"Tints the chat background and/or character sprites.": "Tinta el fondo del chat y/o los sprites de personajes.",
|
||||
"Share World Tint With Characters": "Compartir tinte mundial con personajes*",
|
||||
"Applies the world tint to character sprites (Requires Prome to be enabled. This will override your character tint settings).": "Aplica el tinte mundial a los sprites de personajes (Requiere que Prome esté iniciado. Esto anulará la configuración de tinte de su personaje).",
|
||||
"Tint Presets": "Preajustes de tinte",
|
||||
"Select the tint preset to use for the Prome VN UI.": "Seleccione el preajuste de tinte que desea utilizar para la interfaz de usuario VN de Prome.",
|
||||
"World Tint Settings": "Configuración de tinte mundial",
|
||||
"Tints the world background.": "Tinta el fondo mundial.",
|
||||
"Enable World Tint": "Tinte mundial",
|
||||
"Set the strength of the world blur.": "Establezca la fuerza del desenfoque mundial.",
|
||||
"Brightness": "Brillo",
|
||||
"Set the brightness of the world.": "Establezca el brillo del mundo.",
|
||||
"Contrast": "Contraste",
|
||||
"Set the contrast of the world.": "Establezca el contraste del mundial.",
|
||||
"Grayscale": "Escala de grises",
|
||||
"Makes the world black and white.": "Hace que el mundo sea en blanco y negro.",
|
||||
"Hue": "Matiz",
|
||||
"Set the hue of the world tint.": "Establezca el matiz del tinte mundial.",
|
||||
"Invert": "Invertir",
|
||||
"Inverts the world colors.": "Invierte los colores del mundo.",
|
||||
"Saturate": "Saturar",
|
||||
"Saturates the world colors.": "Satura los colores del mundo.",
|
||||
"Makes the world warmer in color.": "Hace que el mundo sea más cálido en color.",
|
||||
"Character Tint Settings": "Configuración de tinte de sprites*",
|
||||
"Enable Character Tint (Requires Prome to be enabled)": "Tinte de sprites (Requiere que Prome esté iniciado)",
|
||||
"Set the strength of the character blur.": "Establezca la fuerza del desenfoque de personajes.",
|
||||
"Set the brightness of the character.": "Establezca el brillo de personaje.",
|
||||
"Set the contrast of the character.": "Establezca el contraste de personajes.",
|
||||
"Makes the character black and white.": "Hace que el personaje sea en blanco y negro.",
|
||||
"Set the hue of the character.": "Establezca el matiz del tinte de personajes.",
|
||||
"Inverts the character colors.": "Invierte los colores del personaje.",
|
||||
"Saturates the character colors.": "Satura los colores del personaje.",
|
||||
"Makes the character warmer in color.": "Hace que el personaje sea más cálido en color.",
|
||||
"Keybinds": "Atajos de teclado",
|
||||
"Commands": "Comandos",
|
||||
"Prome Keybinds": "Combinaciones de teclas de Prome",
|
||||
"Hide/Show SillyTavern's Sheld (Message Box)": "Ocultar/Mostrar el estante de SillyTavern (cuadro de mensaje)",
|
||||
"Prome Commands": "Comandos de Prome",
|
||||
"Show/Hide the letterbox (black bars) in the VN UI": "Mostrar/Ocultar la franja negra (barras negras) en la interfaz VN",
|
||||
"Toggles focus mode on character sprites": "Alterna el modo de enfoque en los sprites de personajes",
|
||||
"Sets the focus mode animation": "Establece la animación del modo de enfoque",
|
||||
"Toggles the defocus tint on non-speaking character sprites": "Alterna el tinte de desenfoque en los sprites de personajes que no hablan",
|
||||
"Toggles the shake animation when a character speaks on character sprites": "Alterna la animación de sacudida cuando un personaje habla en los sprites de personajes",
|
||||
"Toggles sprite shadows on character sprites": "Alterna las sombras de los sprites de personajes",
|
||||
"Toggles world/character tint on the VN UI": "Alterna el tinte mundial/de personajes en la interfaz VN",
|
||||
"Toggles world tint on the VN UI": "Alterna el tinte mundial en la interfaz VN",
|
||||
"Toggles character tint on the VN UI": "Alterna el tinte de personajes en la interfaz VN",
|
||||
"Toggles sharing world tint with character sprites (This will override Character Tint)": "Alterna el tinte mundial compartido con los sprites de personajes (esto anulará el tinte de personajes)",
|
||||
"Sets the expression of the user sprite": "Establece la expresión del sprite de usuario",
|
||||
"Sets the user sprite set to use for the user sprite": "Establece el conjunto de sprites de usuario para usar en el sprite de usuario",
|
||||
"Toggles the user sprite on the VN UI": "Alterna el sprite de usuario en la interfaz VN"
|
||||
}
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "Textaútfylling",
|
||||
"Chat Completion": "Spjalllokun",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "KoboldAI Hópur",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Forðastu að senda viðkvæm gögn til Hórdans.",
|
||||
"Review the Privacy statement": "Farið yfir Persónuverndarskýrsluna",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "aðskilið með kommum án bila milli",
|
||||
"Custom Stopping Strings": "Eigin stopp-strengir",
|
||||
"JSON serialized array of strings": "JSON raðað fylki af strengjum",
|
||||
"Replace Macro in Custom Stopping Strings": "Skiptu út í macro í sérsniðnum stoppa strengjum",
|
||||
"Replace Macro in Stop Strings": "Skiptu út í macro í sérsniðnum stoppa strengjum",
|
||||
"Auto-Continue": "Sjálfvirk Forná",
|
||||
"Allow for Chat Completion APIs": "Leyfa fyrir spjall Loka APIs",
|
||||
"Target length (tokens)": "Markaðarlengd (texti)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "Eyða þema",
|
||||
"Update a theme file": "Uppfæra þemu skrá",
|
||||
"Save as a new theme": "Vista sem nýja þemu",
|
||||
"Avatar Style": "Avatar Stíll",
|
||||
"Avatar Style:": "Avatar Stíll",
|
||||
"Circle": "Hring",
|
||||
"Square": "Reitur",
|
||||
"Rectangle": "Ferhyrningur",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "Kosstu kvenkortu fyrirspurn",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Ef merkt er og kortið inniheldur fangabrotsskil, notaðu það í staðinn",
|
||||
"Prefer Character Card Jailbreak": "Kosstu kvenkortu fangabrot",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Forðastu að klippa og breyta stærð innfluttra stafamynda. Þegar slökkt er á því skaltu skera/breyta stærð í 512x768.",
|
||||
"never_resize_avatars_tooltip": "Forðastu að klippa og breyta stærð innfluttra stafamynda. Þegar slökkt er á því skaltu skera/breyta stærð í 512x768.",
|
||||
"Never resize avatars": "Aldrei breyta stærðinni á merkjum",
|
||||
"Show actual file names on the disk, in the characters list display only": "Sýna raunveruleg nöfn skráa á diskinum, í lista yfir persónur sýna aðeins",
|
||||
"Show avatar filenames": "Sýna nöfn merkja",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "Sjálfvirkur sveip",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Virkjaðu sjálfvirka sveiflugerð. Stillingar í þessum hluta hafa aðeins áhrif þegar sjálfvirkur sveiflugerð er virk",
|
||||
"Minimum generated message length": "Lágmarks lengd á mynduðum skilaboðum",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Ef mynduðu skilaboðin eru styttri en þessi, kallaðu fram sjálfvirkar sveiflugerðar",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Ef mynduðu skilaboðin eru styttri en þessi, kallaðu fram sjálfvirkar sveiflugerðar",
|
||||
"Blacklisted words": "Svört orð",
|
||||
"words you dont want generated separated by comma ','": "orð sem þú vilt ekki að framleiða aðskilin með kommu ','",
|
||||
"Blacklisted word count to swipe": "Fjöldi svörtra orða til að sveipa",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "Nei",
|
||||
"popup-button-cancel": "Hætta við",
|
||||
"popup-button-import": "Flytja inn",
|
||||
"Advanced Defininitions": "Ítarleg skilgreiningar",
|
||||
"Advanced Definitions": "Ítarleg skilgreiningar",
|
||||
"Prompt Overrides": "Hnekkja hvetjandi",
|
||||
"(For Chat Completion and Instruct Mode)": "(Til að ljúka spjalli og leiðbeiningarham)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Settu inn {{original}} í hvora kassa til að innifela viðkomandi sjálfgefna framkallan frá kerfisstillingum.",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "keyrðu DrawThings app með HTTP API rofi virkt í notendaviðmótinu! Miðlarinn verður að vera aðgengilegur frá SillyTavern hýsingarvélinni.",
|
||||
"sd_vlad_url": "Dæmi: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "Miðlarinn verður að vera aðgengilegur frá SillyTavern hýsingarvélinni.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Ábending: Vistaðu API lykil í Horde KoboldAI API stillingum til að nota hann hér.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Ábending: Vistaðu API lykil í AI Horde API stillingum til að nota hann hér.",
|
||||
"Allow NSFW images from Horde": "Leyfa NSFW myndir frá Horde",
|
||||
"Sanitize prompts (recommended)": "Hreinsunarleiðbeiningar (ráðlagt)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Stilltu kynslóðarbreytur sjálfkrafa til að tryggja ókeypis myndmyndun.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Chub Lorebook (beinn hlekkur eða auðkenni)",
|
||||
"char_import_3": "JanitorAI karakter (beinn hlekkur eða UUID)",
|
||||
"char_import_4": "Pygmalion.chat karakter (beinn hlekkur eða UUID)",
|
||||
"char_import_5": "AICharacterCard.com Karakter (beinn hlekkur eða auðkenni)",
|
||||
"char_import_5": "AICharacterCards.com Karakter (beinn hlekkur eða auðkenni)",
|
||||
"char_import_6": "Beinn PNG hlekkur (sjá",
|
||||
"char_import_7": "fyrir leyfilega gestgjafa)",
|
||||
"char_import_8": "RisuRealm karakter (beinn hlekkur)",
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "Completamento del testo",
|
||||
"Chat Completion": "Completamento della chat",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "Orda di KoboldAI",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Evita di inviare informazioni sensibili all'Orda.",
|
||||
"Review the Privacy statement": "Revisione della dichiarazione sulla privacy",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "separati con virgole senza spazio tra loro",
|
||||
"Custom Stopping Strings": "Stringhe di Stop Personalizzate",
|
||||
"JSON serialized array of strings": "Matrice serializzata JSON di stringhe",
|
||||
"Replace Macro in Custom Stopping Strings": "Sostituisci Macro in Stringhe di Arresto Personalizzate",
|
||||
"Replace Macro in Stop Strings": "Sostituisci Macro in Stringhe di Arresto Personalizzate",
|
||||
"Auto-Continue": "Auto-continua",
|
||||
"Allow for Chat Completion APIs": "Consenti per API di completamento chat",
|
||||
"Target length (tokens)": "Lunghezza obiettivo (token)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "Elimina un tema",
|
||||
"Update a theme file": "Aggiorna un file di tema",
|
||||
"Save as a new theme": "Salva come nuovo tema",
|
||||
"Avatar Style": "Stile avatar",
|
||||
"Avatar Style:": "Stile avatar",
|
||||
"Circle": "Cerchio",
|
||||
"Square": "Quadrato",
|
||||
"Rectangle": "Rettangolo",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "Preferisci Prompt della Scheda Personaggio",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Se selezionato e la scheda del personaggio contiene una sovrascrittura jailbreak (Istruzione Storico Post), usalo invece",
|
||||
"Prefer Character Card Jailbreak": "Preferisci Jailbreak della Scheda Personaggio",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Evita di ritagliare e ridimensionare le immagini dei personaggi importati. Quando è disattivato, ritaglia/ridimensiona a 512x768.",
|
||||
"never_resize_avatars_tooltip": "Evita di ritagliare e ridimensionare le immagini dei personaggi importati. Quando è disattivato, ritaglia/ridimensiona a 512x768.",
|
||||
"Never resize avatars": "Non ridimensionare mai gli avatar",
|
||||
"Show actual file names on the disk, in the characters list display only": "Mostra i nomi file effettivi sul disco, solo nella visualizzazione dell'elenco dei personaggi",
|
||||
"Show avatar filenames": "Mostra nomi file avatar",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "Auto-swipe",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Abilita la funzione di auto-swipe. Le impostazioni in questa sezione hanno effetto solo quando l'auto-swipe è abilitato",
|
||||
"Minimum generated message length": "Lunghezza minima del messaggio generato",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Se il messaggio generato è più breve di questo, attiva un'automatica rimozione",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Se il messaggio generato è più breve di questo, attiva un'automatica rimozione",
|
||||
"Blacklisted words": "Parole in blacklist",
|
||||
"words you dont want generated separated by comma ','": "parole che non vuoi generate separate da virgola ','",
|
||||
"Blacklisted word count to swipe": "Numero di parole in blacklist per attivare un'automatica rimozione",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "NO",
|
||||
"popup-button-cancel": "Annulla",
|
||||
"popup-button-import": "Importare",
|
||||
"Advanced Defininitions": "Definizioni avanzate",
|
||||
"Advanced Definitions": "Definizioni avanzate",
|
||||
"Prompt Overrides": "Sostituzioni richieste",
|
||||
"(For Chat Completion and Instruct Mode)": "(Per il completamento della chat e la modalità istruzione)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Inserisci {{originale}} in uno dei due riquadri per includere il prompt predefinito corrispondente dalle impostazioni di sistema.",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "esegui l'app DrawThings con lo switch API HTTP abilitato nell'interfaccia utente! Il server deve essere accessibile dalla macchina host SillyTavern.",
|
||||
"sd_vlad_url": "Esempio: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "Il server deve essere accessibile dalla macchina host SillyTavern.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Suggerimento: salva una chiave API nelle impostazioni API Horde KoboldAI per usarla qui.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Suggerimento: salva una chiave API nelle impostazioni API AI Horde per usarla qui.",
|
||||
"Allow NSFW images from Horde": "Consenti immagini NSFW da Horde",
|
||||
"Sanitize prompts (recommended)": "Messaggi di disinfezione (consigliato)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Regola automaticamente i parametri di generazione per garantire generazioni di immagini gratuite.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Lorebook di Chub (collegamento diretto o ID)",
|
||||
"char_import_3": "Carattere JanitorAI (collegamento diretto o UUID)",
|
||||
"char_import_4": "Carattere Pygmalion.chat (collegamento diretto o UUID)",
|
||||
"char_import_5": "Carattere AICharacterCard.com (Link diretto o ID)",
|
||||
"char_import_5": "Carattere AICharacterCards.com (Link diretto o ID)",
|
||||
"char_import_6": "Collegamento PNG diretto (fare riferimento a",
|
||||
"char_import_7": "per gli host consentiti)",
|
||||
"char_import_8": "Personaggio RisuRealm (collegamento diretto)",
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "テキスト補完",
|
||||
"Chat Completion": "チャット完了",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "KoboldAI Horde",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Hordeに機密情報を送信しないでください。",
|
||||
"Review the Privacy statement": "プライバシー声明を確認する",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "間にスペースのないカンマで区切ります",
|
||||
"Custom Stopping Strings": "カスタム停止文字列",
|
||||
"JSON serialized array of strings": "文字列のJSONシリアル化配列",
|
||||
"Replace Macro in Custom Stopping Strings": "カスタム停止文字列内のマクロを置換する",
|
||||
"Replace Macro in Stop Strings": "カスタム停止文字列内のマクロを置換する",
|
||||
"Auto-Continue": "自動継続",
|
||||
"Allow for Chat Completion APIs": "チャット補完APIを許可",
|
||||
"Target length (tokens)": "ターゲット長さ(トークン)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "テーマを削除する",
|
||||
"Update a theme file": "テーマファイルを更新",
|
||||
"Save as a new theme": "新しいテーマとして保存",
|
||||
"Avatar Style": "アバタースタイル",
|
||||
"Avatar Style:": "アバタースタイル",
|
||||
"Circle": "円",
|
||||
"Square": "正方形",
|
||||
"Rectangle": "長方形",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "キャラクターカードのプロンプトを優先",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "チェックされていてキャラクターカードにジェイルブレイクオーバーライド(投稿履歴指示)が含まれている場合、それを代わりに使用します",
|
||||
"Prefer Character Card Jailbreak": "キャラクターカードのJailbreakを優先",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "インポートした文字画像の切り取りやサイズ変更を避けます。オフにすると、512x768 に切り取り/サイズ変更されます。",
|
||||
"never_resize_avatars_tooltip": "インポートした文字画像の切り取りやサイズ変更を避けます。オフにすると、512x768 に切り取り/サイズ変更されます。",
|
||||
"Never resize avatars": "アバターを常にリサイズしない",
|
||||
"Show actual file names on the disk, in the characters list display only": "ディスク上の実際のファイル名を表示します。キャラクターリストの表示にのみ",
|
||||
"Show avatar filenames": "アバターのファイル名を表示",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "オートスワイプ",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "自動スワイプ機能を有効にします。このセクションの設定は、自動スワイプが有効になっている場合にのみ効果があります",
|
||||
"Minimum generated message length": "生成されたメッセージの最小長",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "生成されたメッセージがこれよりも短い場合、自動スワイプをトリガーします",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "生成されたメッセージがこれよりも短い場合、自動スワイプをトリガーします",
|
||||
"Blacklisted words": "ブラックリストされた単語",
|
||||
"words you dont want generated separated by comma ','": "コンマ ',' で区切られた生成したくない単語",
|
||||
"Blacklisted word count to swipe": "スワイプするブラックリストされた単語の数",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "いいえ",
|
||||
"popup-button-cancel": "キャンセル",
|
||||
"popup-button-import": "インポート",
|
||||
"Advanced Defininitions": "高度な定義",
|
||||
"Advanced Definitions": "高度な定義",
|
||||
"Prompt Overrides": "プロンプトのオーバーライド",
|
||||
"(For Chat Completion and Instruct Mode)": "(チャット補完と指示モード用)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "システム設定からの対応するデフォルトのプロンプトを含めるには、どちらかのボックスに{{original}}を挿入します。",
|
||||
@@ -1274,6 +1274,8 @@
|
||||
"sd_Raw_Last_Message": "生の最後のメッセージ",
|
||||
"sd_Background": "背景",
|
||||
"Image Generation": "画像生成",
|
||||
"Stop Image Generation": "画像生成を停止",
|
||||
"Generate Caption": "画像説明を生成",
|
||||
"sd_refine_mode": "プロンプトを生成 API に送信する前に手動で編集できるようにする",
|
||||
"sd_refine_mode_txt": "生成前にプロンプトを編集する",
|
||||
"sd_interactive_mode": "「猫の写真を送ってください」のようなメッセージを送信するときに、画像を自動的に生成します。",
|
||||
@@ -1295,7 +1297,7 @@
|
||||
"sd_drawthings_auth_txt": "UI で HTTP API スイッチを有効にして DrawThings アプリを実行します。サーバーは SillyTavern ホスト マシンからアクセスできる必要があります。",
|
||||
"sd_vlad_url": "例: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "サーバーは SillyTavern ホスト マシンからアクセスできる必要があります。",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "ヒント: ここで使用するには、Horde KoboldAI API 設定に API キーを保存してください。",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "ヒント: ここで使用するには、AI Horde API 設定に API キーを保存してください。",
|
||||
"Allow NSFW images from Horde": "HordeからのNSFW画像を許可する",
|
||||
"Sanitize prompts (recommended)": "サニタイズプロンプト(推奨)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "生成パラメータを自動的に調整して、自由な画像生成を保証します。",
|
||||
@@ -1376,7 +1378,7 @@
|
||||
"char_import_2": "Chub ロアブック (直接リンクまたは ID)",
|
||||
"char_import_3": "JanitorAI キャラクター (直接リンクまたは UUID)",
|
||||
"char_import_4": "Pygmalion.chat キャラクター (直接リンクまたは UUID)",
|
||||
"char_import_5": "AICharacterCard.com キャラクター (直接リンクまたは ID)",
|
||||
"char_import_5": "AICharacterCards.com キャラクター (直接リンクまたは ID)",
|
||||
"char_import_6": "直接PNGリンク(参照",
|
||||
"char_import_7": "許可されたホストの場合)",
|
||||
"char_import_8": "RisuRealm キャラクター (直接リンク)",
|
||||
@@ -1439,5 +1441,8 @@
|
||||
"Still have questions?": "まだ質問がありますか?",
|
||||
"Join the SillyTavern Discord": "SillyTavernのDiscordに参加",
|
||||
"Post a GitHub issue": "GitHubの問題を投稿",
|
||||
"Contact the developers": "開発者に連絡"
|
||||
"Contact the developers": "開発者に連絡",
|
||||
"Stop Inspecting": "検査を停止",
|
||||
"Inspect Prompts": "プロンプトを検査",
|
||||
"Toggle prompt inspection": "プロンプト検査の切り替え"
|
||||
}
|
||||
|
@@ -211,7 +211,7 @@
|
||||
"Sampler Priority": "샘플러 우선 순위",
|
||||
"Ooba only. Determines the order of samplers.": "Ooba 전용. 샘플러의 순서를 결정합니다.",
|
||||
"Character Names Behavior": "캐릭터 이름 동작",
|
||||
"[title]character_names_none": "캐릭터 이름 접두사를 추가하지 않습니다. 그룹 채팅에서는 좋지 않을 수 있으므로, 이 설정을 선택할 때는 주의해야 합니다.",
|
||||
"character_names_none": "캐릭터 이름 접두사를 추가하지 않습니다. 그룹 채팅에서는 좋지 않을 수 있으므로, 이 설정을 선택할 때는 주의해야 합니다.",
|
||||
"Helps the model to associate messages with characters.": "모델이 메시지를 캐릭터와 연관시키는 데 도움이 됩니다.",
|
||||
"None": "없음",
|
||||
"None (not injected)": "없음 (삽입되지 않음)",
|
||||
@@ -269,7 +269,7 @@
|
||||
"Text Completion": "Text Completion",
|
||||
"Chat Completion": "Chat Completion",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "KoboldAI Horde",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "민감한 정보를 Horde에 보내지 않도록 합니다.",
|
||||
"Review the Privacy statement": "개인 정보 보호 정책 검토",
|
||||
@@ -404,7 +404,7 @@
|
||||
"Custom API Key": "커스텀 API 키",
|
||||
"Available Models": "사용 가능한 모델",
|
||||
"Prompt Post-Processing": "신속한 후처리",
|
||||
"[title]API Connections;[no_connection_text]api_no_connection": "연결이 되지 않았습니다...",
|
||||
"api_no_connection": "연결이 되지 않았습니다...",
|
||||
"Applies additional processing to the prompt before sending it to the API.": "API로 보내기 전에 프롬프트에 추가 처리를 적용합니다.",
|
||||
"Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "짧은 테스트 메시지를 보내어 API 연결을 확인합니다. 이에 대해 유료 크레딧이 지불될 수 있음을 인식하세요!",
|
||||
"Test Message": "테스트 메시지",
|
||||
@@ -492,7 +492,7 @@
|
||||
"separate with commas w/o space between": "쉼표로 구분 (공백 없이)",
|
||||
"Custom Stopping Strings": "사용자 정의 중지 문자열",
|
||||
"JSON serialized array of strings": "문자열의 JSON 직렬화된 배열",
|
||||
"Replace Macro in Custom Stopping Strings": "사용자 정의 중단 문자열에서 매크로 교체",
|
||||
"Replace Macro in Stop Strings": "사용자 정의 중단 문자열에서 매크로 교체",
|
||||
"Auto-Continue": "자동 계속하기",
|
||||
"Allow for Chat Completion APIs": "채팅 완성 API 허용",
|
||||
"Target length (tokens)": "대상 길이 (토큰)",
|
||||
@@ -568,7 +568,7 @@
|
||||
"Delete a theme": "테마 삭제",
|
||||
"Update a theme file": "테마 파일 업데이트",
|
||||
"Save as a new theme": "새 테마로 저장",
|
||||
"Avatar Style": "캐릭터 프로필 스타일",
|
||||
"Avatar Style:": "캐릭터 프로필 스타일",
|
||||
"Circle": "원",
|
||||
"Square": "정사각형",
|
||||
"Rectangle": "사각형",
|
||||
@@ -625,7 +625,7 @@
|
||||
"Single-row message input area. Mobile only, no effect on PC": "한 줄짜리 메시지 입력 영역. 모바일 전용, PC에는 영향 없음",
|
||||
"Compact Input Area (Mobile)": "조그마한 입력 영역 (모바일)",
|
||||
"Swipe # for All Messages": "모든 스와이프 메시지에 대해 번호 매기기",
|
||||
"[title]Display swipe numbers for all messages, not just the last.": "마지막 메시지만이 아니라 모든 메시지에 대한 스와이프 번호를 표시합니다.",
|
||||
"Display swipe numbers for all messages, not just the last.": "마지막 메시지만이 아니라 모든 메시지에 대한 스와이프 번호를 표시합니다.",
|
||||
"In the Character Management panel, show quick selection buttons for favorited characters": "캐릭터 관리 패널에서 즐겨찾는 캐릭터에 대한 빠른 선택 버튼을 표시합니다",
|
||||
"Characters Hotswap": "캐릭터 핫스왑",
|
||||
"Enable magnification for zoomed avatar display.": "마우스 포인터를 아바타 위에 올려두면 아바타가 확대 됩니다.",
|
||||
@@ -646,7 +646,7 @@
|
||||
"Prefer Character Card Prompt": "캐릭터 카드 프롬프트 선호",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "선택되어 있고 캐릭터 카드에 (Post-History 지시)탈옥 재정의가 포함 된 경우, 그것을 대신 사용합니다.",
|
||||
"Prefer Character Card Jailbreak": "캐릭터 카드 탈옥 선호",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "가져온 캐릭터 이미지를 자르거나 크기를 조정하지 마세요. 꺼져 있으면 512x768로 자르거나 크기를 조정합니다.",
|
||||
"never_resize_avatars_tooltip": "가져온 캐릭터 이미지를 자르거나 크기를 조정하지 마세요. 꺼져 있으면 512x768로 자르거나 크기를 조정합니다.",
|
||||
"Never resize avatars": "아바타 크기 변경하지 않음",
|
||||
"Show actual file names on the disk, in the characters list display only": "실제 파일 이름을 디스크에 표시하며 캐릭터 목록 디스플레이에만",
|
||||
"Show avatar filenames": "아바타 파일 이름 표시",
|
||||
@@ -724,7 +724,7 @@
|
||||
"Auto-swipe": "자동 스와이프",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "자동 스와이프 기능을 활성화합니다. 이 섹션의 설정은 자동 스와이프가 활성화되었을 때만 영향을 미칩니다",
|
||||
"Minimum generated message length": "생성된 메시지 최소 길이",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "생성된 메시지가이보다 짧으면 자동 스와이프를 트리거합니다",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "생성된 메시지가이보다 짧으면 자동 스와이프를 트리거합니다",
|
||||
"Blacklisted words": "금지어",
|
||||
"words you dont want generated separated by comma ','": "쉼표로 구분된 생성하지 않으려는 단어",
|
||||
"Blacklisted word count to swipe": "스와이프할 금지어 개수",
|
||||
@@ -895,7 +895,7 @@
|
||||
"popup-button-no": "아니요",
|
||||
"popup-button-cancel": "취소",
|
||||
"popup-button-import": "불러오기",
|
||||
"Advanced Defininitions": "고급 정의",
|
||||
"Advanced Definitions": "고급 정의",
|
||||
"Prompt Overrides": "프롬프트 무시",
|
||||
"(For Chat Completion and Instruct Mode)": "(채팅 완료 및 지시 모드의 경우)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "{{original}}를 해당 상자에 넣어 시스템 설정의 기본 프롬프트를 포함합니다.",
|
||||
@@ -1312,7 +1312,7 @@
|
||||
"sd_drawthings_auth_txt": "UI에서 HTTP API 스위치가 활성화된 상태에서 DrawThings 앱을 실행하세요! SillyTavern 호스트 시스템에서 서버에 액세스할 수 있어야 합니다.",
|
||||
"sd_vlad_url": "예: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "SillyTavern 호스트 시스템에서 서버에 액세스할 수 있어야 합니다.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "힌트: 여기에서 사용하려면 Horde KoboldAI API 설정에 API 키를 저장하세요.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "힌트: 여기에서 사용하려면 AI Horde API 설정에 API 키를 저장하세요.",
|
||||
"Allow NSFW images from Horde": "Horde의 NSFW 이미지 허용",
|
||||
"Sanitize prompts (recommended)": "프롬프트 삭제(권장)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "무료 이미지 생성을 보장하기 위해 생성 매개변수를 자동으로 조정합니다.",
|
||||
@@ -1395,7 +1395,7 @@
|
||||
"char_import_2": "Chub Lorebook(직접 링크 또는 ID)",
|
||||
"char_import_3": "JanitorAI 캐릭터(직접 링크 또는 UUID)",
|
||||
"char_import_4": "Pygmalion.chat 문자(직접 링크 또는 UUID)",
|
||||
"char_import_5": "AICharacterCard.com 캐릭터(직접 링크 또는 ID)",
|
||||
"char_import_5": "AICharacterCards.com 캐릭터(직접 링크 또는 ID)",
|
||||
"char_import_6": "직접 PNG 링크(참조",
|
||||
"char_import_7": "허용된 호스트의 경우)",
|
||||
"char_import_8": "RisuRealm 캐릭터 (직접링크)",
|
||||
@@ -1467,7 +1467,6 @@
|
||||
"menu within": "내의 메뉴",
|
||||
"Translate text to English before classification": "분류 전에 텍스트를 영어로 번역합니다.",
|
||||
"Show default images (emojis) if sprite missing": "해당하는 스프라이트가 없으면 기본 이미지 (이모지들)을 표시합니다.",
|
||||
"Image Type - talkinghead (extras)": "이미지 유형 - 토킹 헤드 (부가 사항)",
|
||||
"Classifier API": "분류를 위한 API",
|
||||
"Select the API for classifying expressions.": "감정 이미지들을 분류할 API를 선택하세요.",
|
||||
"Local": "로컬",
|
||||
@@ -1538,7 +1537,7 @@
|
||||
"Only apply color as accent": "색상은 오직 강조로써만 적용됩니다",
|
||||
"qr--colorClear": "색상 지우기",
|
||||
"Color": "색상",
|
||||
"[title]world_button_title": "캐릭터 로어. 클릭하여 로드하세요. Shift를 클릭하면 '월드 인포 링크' 팝업이 열립니다.",
|
||||
"world_button_title": "캐릭터 로어. 클릭하여 로드하세요. Shift를 클릭하면 '월드 인포 링크' 팝업이 열립니다.",
|
||||
"Select TTS Provider": "TTS 공급자 선택",
|
||||
"tts_enabled": "활성화",
|
||||
"Narrate user messages": "사용자 메시지 나레이션",
|
||||
@@ -1583,15 +1582,15 @@
|
||||
"Prompt Content": "프롬프트 내용",
|
||||
"Instruct Sequences": "지시 시퀀스",
|
||||
"Prefer Character Card Instructions": "캐릭터 카드의 지시사항을 선호",
|
||||
"[title]If checked and the character card contains a Post-History Instructions override, use that instead": "활성화 된 경우, 캐릭터 카드에 Post-History 지시 무시 항목이 포함되어 있으면, 카드 지시사항의 내용으로 대신 사용합니다.",
|
||||
"If checked and the character card contains a Post-History Instructions override, use that instead": "활성화 된 경우, 캐릭터 카드에 Post-History 지시 무시 항목이 포함되어 있으면, 카드 지시사항의 내용으로 대신 사용합니다.",
|
||||
"Auto-select Input Text": "입력 텍스트 자동 선택",
|
||||
"[title]Enable auto-select of input text in some text fields when clicking/selecting them. Applies to popup input textboxes, and possible other custom input fields.": "일부 텍스트 필드를 클릭하거나 선택할 때 자동으로 입력된 텍스트가 선택되도록 설정합니다. 팝업 입력창과 기타 커스텀 입력 필드에 적용됩니다.",
|
||||
"Enable auto-select of input text in some text fields when clicking/selecting them. Applies to popup input textboxes, and possible other custom input fields.": "일부 텍스트 필드를 클릭하거나 선택할 때 자동으로 입력된 텍스트가 선택되도록 설정합니다. 팝업 입력창과 기타 커스텀 입력 필드에 적용됩니다.",
|
||||
"Markdown Hotkeys": "마크다운 입력 단축키",
|
||||
"[title]markdown_hotkeys_desc": "특정 텍스트 입력창에서 마크다운 형식 문자를 입력하기 위한 단축키를 활성화합니다. '/help hotkeys'를 참고하세요.",
|
||||
"markdown_hotkeys_desc": "특정 텍스트 입력창에서 마크다운 형식 문자를 입력하기 위한 단축키를 활성화합니다. '/help hotkeys'를 참고하세요.",
|
||||
"Show group chat queue": "그룹 채팅 대기열 표시",
|
||||
"[title]In group chat, highlight the character(s) that are currently queued to generate responses and the order in which they will respond.": "그룹 채팅에서 응답을 생성하기 위해 현재 대기 중인 캐릭터와 응답할 순서를 강조 표시합니다.",
|
||||
"In group chat, highlight the character(s) that are currently queued to generate responses and the order in which they will respond.": "그룹 채팅에서 응답을 생성하기 위해 현재 대기 중인 캐릭터와 응답할 순서를 강조 표시합니다.",
|
||||
"Quick 'Impersonate' button": "빠른 '사칭' 버튼",
|
||||
"[title]Show a button in the input area to ask the AI to impersonate your character for a single message": "입력 영역에 AI에게 한 메시지 동안 당신의 캐릭터 연기를 사칭하도록 요청하는 버튼을 표시합니다.",
|
||||
"Show a button in the input area to ask the AI to impersonate your character for a single message": "입력 영역에 AI에게 한 메시지 동안 당신의 캐릭터 연기를 사칭하도록 요청하는 버튼을 표시합니다.",
|
||||
"Injection Template": "삽입 템플릿",
|
||||
"Query messages": "쿼리 메시지 수",
|
||||
"Score threshold": "점수 임계값",
|
||||
@@ -1614,7 +1613,7 @@
|
||||
"Ask": "묻기",
|
||||
"tag_import_none": "불러오지 않음",
|
||||
"tag_import_all": "전부",
|
||||
"Existing": "기존 태그 참조",
|
||||
"tag_import_existing": "기존 태그 참조",
|
||||
"You can add more": "원한다면",
|
||||
"or_welcome": "또는",
|
||||
"from other websites": "를 통해 다른 웹사이트들로부터 불러올 수 있습니다.",
|
||||
@@ -1623,4 +1622,4 @@
|
||||
"Master Import": "마스터 불러오기",
|
||||
"Master Export": "마스터 내보내기",
|
||||
"Chat Quick Reply Sets": "채팅 빠른 답장 세트들"
|
||||
}
|
||||
}
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "Tekstvoltooiing",
|
||||
"Chat Completion": "Chat-voltooiing",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "KoboldAI Horde",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Vermijd het verzenden van gevoelige informatie naar de Horde.",
|
||||
"Review the Privacy statement": "Bekijk de privacyverklaring",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "gescheiden met komma's zonder spatie ertussen",
|
||||
"Custom Stopping Strings": "Aangepaste Stopreeksen",
|
||||
"JSON serialized array of strings": "JSON geserialiseerde reeks van strings",
|
||||
"Replace Macro in Custom Stopping Strings": "Macro vervangen in aangepaste stopreeksen",
|
||||
"Replace Macro in Stop Strings": "Macro vervangen in aangepaste stopreeksen",
|
||||
"Auto-Continue": "Automatisch doorgaan",
|
||||
"Allow for Chat Completion APIs": "Chatvervolledigings-API's toestaan",
|
||||
"Target length (tokens)": "Doellengte (tokens)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "Verwijder een thema",
|
||||
"Update a theme file": "Werk een themabestand bij",
|
||||
"Save as a new theme": "Opslaan als nieuw thema",
|
||||
"Avatar Style": "Avatarstijl",
|
||||
"Avatar Style:": "Avatarstijl",
|
||||
"Circle": "Cirkel",
|
||||
"Square": "Vierkant",
|
||||
"Rectangle": "Rechthoek",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "Voorkeur karakterkaart prompt",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Als aangevinkt en de karakterkaart bevat een jailbreak-override (Post History Instruction), gebruik die in plaats daarvan",
|
||||
"Prefer Character Card Jailbreak": "Voorkeur karakterkaart jailbreak",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Vermijd het bijsnijden en vergroten/verkleinen van geïmporteerde karakterafbeeldingen. Indien uitgeschakeld, bijsnijden/formaat wijzigen naar 512 x 768.",
|
||||
"never_resize_avatars_tooltip": "Vermijd het bijsnijden en vergroten/verkleinen van geïmporteerde karakterafbeeldingen. Indien uitgeschakeld, bijsnijden/formaat wijzigen naar 512 x 768.",
|
||||
"Never resize avatars": "Avatars nooit verkleinen",
|
||||
"Show actual file names on the disk, in the characters list display only": "Toon de werkelijke bestandsnamen op de schijf, alleen in de weergave van de lijst met personages",
|
||||
"Show avatar filenames": "Toon avatar bestandsnamen",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "Automatisch vegen",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Schakel de automatische-vegen functie in. Instellingen in dit gedeelte hebben alleen effect wanneer automatisch vegen is ingeschakeld",
|
||||
"Minimum generated message length": "Minimale gegenereerde berichtlengte",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Als het gegenereerde bericht korter is dan dit, activeer dan een automatische veeg",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Als het gegenereerde bericht korter is dan dit, activeer dan een automatische veeg",
|
||||
"Blacklisted words": "Verboden woorden",
|
||||
"words you dont want generated separated by comma ','": "woorden die je niet gegenereerd wilt hebben gescheiden door komma ','",
|
||||
"Blacklisted word count to swipe": "Aantal verboden woorden om te vegen",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "Nee",
|
||||
"popup-button-cancel": "Annuleren",
|
||||
"popup-button-import": "Importeren",
|
||||
"Advanced Defininitions": "Geavanceerde definities",
|
||||
"Advanced Definitions": "Geavanceerde definities",
|
||||
"Prompt Overrides": "Prompt-overschrijvingen",
|
||||
"(For Chat Completion and Instruct Mode)": "(Voor voltooiing van chat en instructiemodus)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Voeg {{original}} in in elk vak in om de respectievelijke standaardprompt vanuit systeeminstellingen op te nemen.",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "voer de DrawThings-app uit met HTTP API-switch ingeschakeld in de gebruikersinterface! De server moet toegankelijk zijn vanaf de SillyTavern-hostmachine.",
|
||||
"sd_vlad_url": "Voorbeeld: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "De server moet toegankelijk zijn vanaf de SillyTavern-hostmachine.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Tip: sla een API-sleutel op in de Horde KoboldAI API-instellingen om deze hier te gebruiken.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Tip: sla een API-sleutel op in de AI Horde API-instellingen om deze hier te gebruiken.",
|
||||
"Allow NSFW images from Horde": "Sta NSFW-afbeeldingen van Horde toe",
|
||||
"Sanitize prompts (recommended)": "Ontsmettingsmeldingen (aanbevolen)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Pas de generatieparameters automatisch aan om vrije beeldgeneraties te garanderen.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Chub Lorebook (directe link of ID)",
|
||||
"char_import_3": "JanitorAI-personage (directe link of UUID)",
|
||||
"char_import_4": "Pygmalion.chat-teken (directe link of UUID)",
|
||||
"char_import_5": "AICharacterCard.com-teken (directe link of ID)",
|
||||
"char_import_5": "AICharacterCards.com-teken (directe link of ID)",
|
||||
"char_import_6": "Directe PNG-link (zie",
|
||||
"char_import_7": "voor toegestane hosts)",
|
||||
"char_import_8": "RisuRealm-personage (directe link)",
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "Conclusão de texto",
|
||||
"Chat Completion": "Conclusão do bate-papo",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "Horda KoboldAI",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Evite enviar informações sensíveis para a Horda.",
|
||||
"Review the Privacy statement": "Reveja a declaração de privacidade",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "separe com vírgulas sem espaço entre",
|
||||
"Custom Stopping Strings": "Cadeias de parada personalizadas",
|
||||
"JSON serialized array of strings": "Matriz de strings serializada em JSON",
|
||||
"Replace Macro in Custom Stopping Strings": "Substituir Macro em Strings de Parada Personalizadas",
|
||||
"Replace Macro in Stop Strings": "Substituir Macro em Strings de Parada Personalizadas",
|
||||
"Auto-Continue": "Auto-Continuar",
|
||||
"Allow for Chat Completion APIs": "Permitir APIs de Completar Chat",
|
||||
"Target length (tokens)": "Comprimento alvo (tokens)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "Excluir um tema",
|
||||
"Update a theme file": "Atualizar um arquivo de tema",
|
||||
"Save as a new theme": "Salvar como um novo tema",
|
||||
"Avatar Style": "Estilo de Avatar",
|
||||
"Avatar Style:": "Estilo de Avatar",
|
||||
"Circle": "Círculo",
|
||||
"Square": "Quadrado",
|
||||
"Rectangle": "Retângulo",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "Preferir Prompt do Cartão de Personagem",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Se marcado e o cartão de personagem contiver uma substituição de jailbreak (Instrução de Histórico de Postagens), use isso em vez disso",
|
||||
"Prefer Character Card Jailbreak": "Preferir Jailbreak do Cartão de Personagem",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Evite cortar e redimensionar imagens de personagens importados. Quando desativado, corte/redimensione para 512x768.",
|
||||
"never_resize_avatars_tooltip": "Evite cortar e redimensionar imagens de personagens importados. Quando desativado, corte/redimensione para 512x768.",
|
||||
"Never resize avatars": "Nunca redimensionar avatares",
|
||||
"Show actual file names on the disk, in the characters list display only": "Mostrar nomes de arquivo reais no disco, apenas na exibição da lista de personagens",
|
||||
"Show avatar filenames": "Mostrar nomes de arquivo de avatar",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "Auto-swipe",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Ativar a função de auto-swipe. As configurações nesta seção só têm efeito quando o auto-swipe está ativado",
|
||||
"Minimum generated message length": "Comprimento mínimo da mensagem gerada",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Se a mensagem gerada for mais curta que isso, acione um auto-swipe",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Se a mensagem gerada for mais curta que isso, acione um auto-swipe",
|
||||
"Blacklisted words": "Palavras proibidas",
|
||||
"words you dont want generated separated by comma ','": "palavras que você não quer geradas separadas por vírgula ','",
|
||||
"Blacklisted word count to swipe": "Contagem de palavras proibidas para swipe",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "Não",
|
||||
"popup-button-cancel": "Cancelar",
|
||||
"popup-button-import": "Importar",
|
||||
"Advanced Defininitions": "Definições Avançadas",
|
||||
"Advanced Definitions": "Definições Avançadas",
|
||||
"Prompt Overrides": "Substituições de prompt",
|
||||
"(For Chat Completion and Instruct Mode)": "(Para conclusão de bate-papo e modo de instrução)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Insira {{original}} em qualquer caixa para incluir o prompt padrão respectivo das configurações do sistema.",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "execute o aplicativo DrawThings com a opção HTTP API habilitada na IU! O servidor deve estar acessível a partir da máquina host SillyTavern.",
|
||||
"sd_vlad_url": "Exemplo: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "O servidor deve estar acessível a partir da máquina host SillyTavern.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Dica: salve uma chave de API nas configurações da API Horde KoboldAI para usá-la aqui.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Dica: salve uma chave de API nas configurações da API AI Horde para usá-la aqui.",
|
||||
"Allow NSFW images from Horde": "Permitir imagens NSFW da Horda",
|
||||
"Sanitize prompts (recommended)": "Solicitações de higienização (recomendado)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Ajuste automaticamente os parâmetros de geração para garantir gerações de imagens livres.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Chub Lorebook (link direto ou ID)",
|
||||
"char_import_3": "Personagem JanitorAI (Link Direto ou UUID)",
|
||||
"char_import_4": "Caractere Pygmalion.chat (Link Direto ou UUID)",
|
||||
"char_import_5": "Personagem AICharacterCard.com (link direto ou ID)",
|
||||
"char_import_5": "Personagem AICharacterCards.com (link direto ou ID)",
|
||||
"char_import_6": "Link PNG direto (consulte",
|
||||
"char_import_7": "para hosts permitidos)",
|
||||
"char_import_8": "Personagem RisuRealm (link direto)",
|
||||
|
@@ -161,7 +161,7 @@
|
||||
"View hidden API keys": "Посмотреть скрытые API-ключи",
|
||||
"Advanced Formatting": "Расширенное форматирование",
|
||||
"Context Template": "Шаблон контекста",
|
||||
"Replace Macro in Custom Stopping Strings": "Заменять макросы в пользовательских стоп-строках",
|
||||
"Replace Macro in Stop Strings": "Заменять макросы в пользовательских стоп-строках",
|
||||
"Story String": "Строка истории",
|
||||
"Example Separator": "Разделитель примеров сообщений",
|
||||
"Chat Start": "Начало чата",
|
||||
@@ -195,12 +195,12 @@
|
||||
"Yes": "Да",
|
||||
"No": "Нет",
|
||||
"Context %": "Процент контекста",
|
||||
"Budget Cap": "Бюджетный лимит",
|
||||
"Budget Cap": "Лимит бюджета",
|
||||
"(0 = disabled)": "(0 = отключено)",
|
||||
"None": "Отсутствует",
|
||||
"User Settings": "Настройки пользователя",
|
||||
"UI Language": "Язык интерфейса",
|
||||
"Avatar Style": "Аватарки",
|
||||
"Avatar Style:": "Аватарки",
|
||||
"Circle": "Круглые",
|
||||
"Rectangle": "Прямоугольные",
|
||||
"Square": "Квадратные",
|
||||
@@ -265,7 +265,7 @@
|
||||
"Current Members": "Текущие участники",
|
||||
"Delete": "Удалить",
|
||||
"Cancel": "Отменить",
|
||||
"Advanced Defininitions": "Расширенное описание",
|
||||
"Advanced Definitions": "Расширенное описание",
|
||||
"Personality summary": "Резюме по личности",
|
||||
"Scenario": "Сценарий",
|
||||
"Talkativeness": "Разговорчивость",
|
||||
@@ -294,12 +294,12 @@
|
||||
"Avoid sending sensitive information to the Horde.": "Избегайте отправки личной информации Horde",
|
||||
"Review the Privacy statement": "Ознакомиться с заявлением о конфиденциальности",
|
||||
"Trusted workers only": "Только доверенные рабочие машины",
|
||||
"For privacy reasons, your API key will be hidden after you reload the page.": "По причинам безопасности ваш API-ключ будет скрыт после перезагрузки страницы.",
|
||||
"For privacy reasons, your API key will be hidden after you reload the page.": "Из соображений безопасности ваш API-ключ будет скрыт после перезагрузки страницы.",
|
||||
"-- Horde models not loaded --": "--Модель Horde не загружена--",
|
||||
"Example: http://127.0.0.1:5000/api ": "Пример: http://127.0.0.1:5000/api",
|
||||
"No connection...": "Нет соединения...",
|
||||
"Get your NovelAI API Key": "Получите свой API-ключ для NovelAI",
|
||||
"KoboldAI Horde": "KoboldAI Horde",
|
||||
"AI Horde": "AI Horde",
|
||||
"NovelAI": "NovelAI",
|
||||
"OpenAI API key": "Ключ для API OpenAI",
|
||||
"Trim spaces": "Обрезать пробелы",
|
||||
@@ -331,7 +331,6 @@
|
||||
"UID ↘": "UID ↘",
|
||||
"Trigger% ↗": "Триггер% ↗",
|
||||
"Trigger% ↘": "Триггер% ↘",
|
||||
"Order:": "Порядок:",
|
||||
"Depth:": "Глубина:",
|
||||
"Character Lore First": "Сначала лор персонажа",
|
||||
"Global Lore First": "Сначала глобальный лор",
|
||||
@@ -347,7 +346,7 @@
|
||||
"After Char Defs": "↓Перс.",
|
||||
"Before AN": "↑АЗ",
|
||||
"After AN": "↓АЗ",
|
||||
"Order": "Порядок:",
|
||||
"Order": "Очерёдность:",
|
||||
"Update a theme file": "Обновить файл темы",
|
||||
"Save as a new theme": "Сохранить как новую тему",
|
||||
"Minimum number of blacklisted words detected to trigger an auto-swipe": "Минимальное количество обнаруженных запрещённых слов, при котором срабатывает авто-свайп.",
|
||||
@@ -427,7 +426,7 @@
|
||||
"Requests logprobs from the API for the Token Probabilities feature": "Запросить логпробы из API для функции Token Probabilities.",
|
||||
"Automatically reject and re-generate AI message based on configurable criteria": "Автоматическое отклонение и повторная генерация сообщений AI на основе настраиваемых критериев.",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Включить авто-свайп. Настройки в этом разделе действуют только при включенном авто-свайпе.",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Если сгенерированное сообщение короче этого значения, срабатывает авто-свайп.",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Если сгенерированное сообщение короче этого значения, срабатывает авто-свайп.",
|
||||
"Reload and redraw the currently open chat": "Перезагрузить и перерисовать открытый в данный момент чат.",
|
||||
"Auto-Expand Message Actions": "Развернуть действия",
|
||||
"Persona Management": "Управление персоной",
|
||||
@@ -497,7 +496,7 @@
|
||||
"What this keyword should mean to the AI, sent verbatim": "Что это ключевое слово должно означать для ИИ, отправляется дословно",
|
||||
"Filter to Character(s)": "Фильтр по персонажу(ам)",
|
||||
"Character Exclusion": "Исключить персонажей",
|
||||
"Inclusion Group": "Включить персонажей",
|
||||
"Inclusion Group": "Группа записей",
|
||||
"Only one entry with the same label will be activated": "Будет активна только одна запись с одинаковой меткой",
|
||||
"-- Characters not found --": "-- Персонажей не найдено --",
|
||||
"(This will be the first message from the character that starts every chat)": "(Это будет первое сообщение от персонажа, когда вы начинаете новый чат)",
|
||||
@@ -541,7 +540,7 @@
|
||||
"NOT ANY": "НЕ ЛЮБОЙ",
|
||||
"Optional Filter": "Дополнительный фильтр",
|
||||
"New Entry": "Новая запись",
|
||||
"Fill empty Memo/Titles with Keywords": "Заполните пустые Заметки/Названия ключевыми словами",
|
||||
"Fill empty Memo/Titles with Keywords": "Заполнить пустые названия ключевыми словами",
|
||||
"AI Response Formatting": "Формат ответа ИИ",
|
||||
"Change Background Image": "Изменить фон",
|
||||
"Extensions": "Расширения",
|
||||
@@ -576,10 +575,10 @@
|
||||
"Characters sorting order": "Порядок сортировки персонажей",
|
||||
"Remove": "Убрать",
|
||||
"Select a World Info file for": "Выбрать файл с миром для",
|
||||
"Primary Lorebook": "Основного лорбука",
|
||||
"A selected World Info will be bound to this character as its own Lorebook.": "Информация о мире будет привязана к персонажу как его собственный лорбук",
|
||||
"When generating an AI reply, it will be combined with the entries from a global World Info selector.": "Когда ИИ генерирует ответ, он будет совмещён с записями из глобально выбранного мира",
|
||||
"Exporting a character would also export the selected Lorebook file embedded in the JSON data.": "При экспорте персонажа вместе с ним также выгрузится выбранный лорбук в виде JSON",
|
||||
"Primary Lorebook": "Основной лорбук",
|
||||
"A selected World Info will be bound to this character as its own Lorebook.": "Информация о мире будет привязана к персонажу как его собственный лорбук.",
|
||||
"When generating an AI reply, it will be combined with the entries from a global World Info selector.": "Когда ИИ генерирует ответ, он будет совмещён с записями из глобально выбранного мира.",
|
||||
"Exporting a character would also export the selected Lorebook file embedded in the JSON data.": "При экспорте персонажа вместе с ним также выгрузится выбранный лорбук в виде JSON.",
|
||||
"Additional Lorebooks": "Вспомогательные лорбуки",
|
||||
"Associate one or more auxillary Lorebooks with this character.": "Привязать к этому персонажу один или больше вспомогательных лорбуков",
|
||||
"NOTE: These choices are optional and won't be preserved on character export!": "ВНИМАНИЕ: эти выборы необязательные и не будут сохранены при экспорте персонажа!",
|
||||
@@ -594,7 +593,7 @@
|
||||
"Prompt": "Промпт",
|
||||
"Copy": "Скопировать",
|
||||
"Confirm": "Подтвердить",
|
||||
"Copy this message": "Скопировать сообщение",
|
||||
"Copy this message": "Продублировать сообщение",
|
||||
"Delete this message": "Удалить сообщение",
|
||||
"Move message up": "Переместить сообщение вверх",
|
||||
"Move message down": "Переместить сообщение вниз",
|
||||
@@ -613,7 +612,7 @@
|
||||
"Ask AI to write your message for you": "Попросить ИИ написать сообщение за вас",
|
||||
"Continue the last message": "Продолжить текущее сообщение",
|
||||
"Bind user name to that avatar": "Закрепить имя за этим аватаром",
|
||||
"Select this as default persona for the new chats.": "Выберать эту Персону в качестве персоны по умолчанию для новых чатов.",
|
||||
"Select this as default persona for the new chats.": "Выбирать эту персону по умолчанию для всех новых чатов.",
|
||||
"Change persona image": "Сменить аватар персоны",
|
||||
"Delete persona": "Удалить персону",
|
||||
"Reduced Motion": "Сокращение анимаций",
|
||||
@@ -628,7 +627,7 @@
|
||||
"UI Theme": "Тема UI",
|
||||
"This message is invisible for the AI": "Это сообщение невидимо для ИИ",
|
||||
"Sampler Priority": "Приоритет сэмплеров",
|
||||
"Ooba only. Determines the order of samplers.": "Только Ooba. Определяет порядок сэмплеров.",
|
||||
"Ooba only. Determines the order of samplers.": "Только oobabooga. Определяет порядок сэмплеров.",
|
||||
"Load default order": "Загрузить стандартный порядок",
|
||||
"Max Tokens Second": "Макс. кол-во токенов в секунду",
|
||||
"CFG": "CFG",
|
||||
@@ -641,7 +640,7 @@
|
||||
"Token Probabilities": "Вероятности токенов",
|
||||
"Close chat": "Закрыть чат",
|
||||
"Manage chat files": "Все чаты",
|
||||
"Import Extension From Git Repo": "Импортировать расширение из Git Repository",
|
||||
"Import Extension From Git Repo": "Импортировать расширение из Git-репозитория.",
|
||||
"Install extension": "Установить расширение",
|
||||
"Manage extensions": "Управление расширениями",
|
||||
"Tokens persona description": "Токенов",
|
||||
@@ -967,7 +966,7 @@
|
||||
"char_import_2": "Лорбук с Chub (прямая ссылка или ID)",
|
||||
"char_import_3": "Персонаж с JanitorAI (прямая ссылка или UUID)",
|
||||
"char_import_4": "Персонаж с Pygmalion.chat (прямая ссылка или UUID)",
|
||||
"char_import_5": "Персонаж с AICharacterCard.com (прямая ссылка или ID)",
|
||||
"char_import_5": "Персонаж с AICharacterCards.com (прямая ссылка или ID)",
|
||||
"char_import_6": "Прямая ссылка на PNG-файл (чтобы узнать список разрешённых хостов, загляните в",
|
||||
"char_import_7": ")",
|
||||
"Grammar String": "Грамматика",
|
||||
@@ -996,7 +995,7 @@
|
||||
"Set your custom avatar.": "Установить аватарку",
|
||||
"Remove your custom avatar.": "Сбросить аватарку",
|
||||
"Make a Snapshot": "Сделать снимок",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Не менять размер картинок у импортируемых персонажей. При отключении все картинки будут приводиться к размеру 512х768",
|
||||
"never_resize_avatars_tooltip": "Не менять размер картинок у импортируемых персонажей. При отключении все картинки будут приводиться к размеру 512х768",
|
||||
"Char List Subheader": "Доп. заголовок в списке персонажей",
|
||||
"# Messages to Load": "Сколько сообщений загружать",
|
||||
"(0 = All)": "(0 = все)",
|
||||
@@ -1123,16 +1122,15 @@
|
||||
"help_hotkeys_0": "Горячие клавиши",
|
||||
"You can browse a list of bundled characters in the": "Комплектных персонажей можно найти в меню",
|
||||
"Download Extensions & Assets": "Загрузить расширения и ресурсы",
|
||||
"menu within": "внутри этих кубиков",
|
||||
"menu within": "в меню",
|
||||
"Assets URL": "URL с описанием ресурсов",
|
||||
"Custom (OpenAI-compatible)": "Кастомный (совместимый с OpenAI)",
|
||||
"Custom Endpoint (Base URL)": "Кастомный эндпоинт (базовый URL)",
|
||||
"Example: http://localhost:1234/v1": "Пример: http://localhost:1234/v1",
|
||||
"at the end of the URL!": "!",
|
||||
"Custom API Key": "Ключ от кастомного API",
|
||||
"(Optional)": "(необязательно)",
|
||||
"Enter a Model ID": "Введите идентификатор модели",
|
||||
"Example: gpt-3.5-turbo": "Пример: gpt-3.5-turbo",
|
||||
"Example: gpt-4o": "Пример: gpt-4o",
|
||||
"Available Models": "Доступные модели",
|
||||
"Prompt Post-Processing": "Постобработка промпта",
|
||||
"Applies additional processing to the prompt before sending it to the API.": "Позволяет обработать промпт перед отправкой в API.",
|
||||
@@ -1342,7 +1340,7 @@
|
||||
"Chat Lorebook": "Chat Lorebook for",
|
||||
"chat_world_template_txt": "A selected World Info will be bound to this chat. When generating an AI reply,\n it will be combined with the entries from global and character lorebooks.",
|
||||
"Use tag as folder": "Tag as folder",
|
||||
"WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Статус записи:\n 🔵 Постоянная\n 🟢 Обычная\n 🔗 Векторизованная\n ❌ Отключена",
|
||||
"WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized": "Статус записи:\n 🔵 Постоянная\n 🟢 Обычная\n 🔗 Векторизованная",
|
||||
"WI_Entry_Status_Constant": "Постоянная",
|
||||
"WI_Entry_Status_Normal": "Обычная",
|
||||
"WI_Entry_Status_Vectorized": "Векторизованная",
|
||||
@@ -1366,13 +1364,7 @@
|
||||
"Can be used to automatically activate Quick Replies": "Can be used to automatically activate Quick Replies",
|
||||
"Automation ID": "Automation ID",
|
||||
"( None )": "( None )",
|
||||
"Delay until recursion (this entry can only be activated on recursive checking)": "Delay until recursion (this entry can only be activated on recursive checking)",
|
||||
"Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group": "Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.\rSupports multiple comma-separated groups.\r\rDocumentation: World Info - Inclusion Group",
|
||||
"Prioritize this entry: When checked, this entry is prioritized out of all selections.If multiple are prioritized, the one with the highest 'Order' is chosen.": "Prioritize this entry: When checked, this entry is prioritized out of all selections.\rIf multiple are prioritized, the one with the highest 'Order' is chosen.\r",
|
||||
"A relative likelihood of entry activation within the group": "A relative likelihood of entry activation within the group",
|
||||
"Group Weight": "Group Weight",
|
||||
"Add Memo": "Add Memo",
|
||||
"close": "close",
|
||||
"reset": "reset",
|
||||
"save": "save",
|
||||
"Open checkpoint chat": "Открыть чат из чекпоинта",
|
||||
@@ -1461,7 +1453,7 @@
|
||||
"sd_drawthings_auth_txt": "run DrawThings app with HTTP API switch enabled in the UI! The server must be accessible from the SillyTavern host machine.",
|
||||
"sd_vlad_url": "Example: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "The server must be accessible from the SillyTavern host machine.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Hint: Save an API key in Horde KoboldAI API settings to use it here.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Hint: Save an API key in AI Horde API settings to use it here.",
|
||||
"Allow NSFW images from Horde": "Разрешить NSFW-картинки в Horde",
|
||||
"Sanitize prompts (recommended)": "Sanitize prompts (recommended)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Automatically adjust generation parameters to ensure free image generations.",
|
||||
@@ -1629,7 +1621,7 @@
|
||||
"Defines on importing cards which action should be chosen for importing its listed tags. 'Ask' will always display the dialog.": "Выберите, какие действия следует предпринять по отношению к тегам импортируемой карточки. При выборе опции \"Спрашивать\" вы будете решать это индивидуально для каждой карточки.",
|
||||
"Ask": "Спрашивать",
|
||||
"tag_import_all": "Все",
|
||||
"Existing": "Только существующие",
|
||||
"tag_import_existing": "Только существующие",
|
||||
"tag_import_none": "Не импортировать",
|
||||
"Using a proxy that you're not running yourself is a risk to your data privacy.": "Помните, что используя чужую прокси, вы подвергаете риску конфиденциальность своих данных.",
|
||||
"ANY support requests will be REFUSED if you are using a proxy.": "НЕ РАССЧИТЫВАЙТЕ на нашу поддержку, если используете прокси.",
|
||||
@@ -1950,7 +1942,7 @@
|
||||
"and connect to an": "и подключитесь к",
|
||||
"You can add more": "Можете добавить больше",
|
||||
"from other websites": "с других сайтов.",
|
||||
"Go to the": "Загляните в",
|
||||
"Go to the": "Заходите в",
|
||||
"to install additional features.": ", чтобы установить разные дополнительные ресурсы.",
|
||||
"or_welcome": "; также доступен",
|
||||
"Claude API Key": "Ключ от API Claude",
|
||||
@@ -1965,7 +1957,7 @@
|
||||
"Save": "Сохранить",
|
||||
"Chat Lorebook": "Лорбук для чата",
|
||||
"chat_world_template_txt": "Выбранный мир будет привязан к этому чату. Будет добавляться в промпт наряду с глобальным лорбуком и лором персонажа.",
|
||||
"world_button_title": "Лор персонажа\n\nНажмите, чтобы загрузить\nShift + клик, чтобы открыть диалог привязки мира",
|
||||
"world_button_title": "Лор персонажа\n\nНажмите, чтобы загрузить\nShift + ЛКМ, чтобы открыть диалог привязки мира",
|
||||
"No auxillary Lorebooks set. Click here to select.": "Вспомогательный лорбук не выбран. Нажмите, чтобы выбрать.",
|
||||
"ext_regex_user_input_desc": "Отправленные вами сообщения.",
|
||||
"ext_regex_ai_input_desc": "Полученные от API ответы.",
|
||||
@@ -2035,5 +2027,181 @@
|
||||
"tags_sorting_desc": "Автоматически сортировать теги по алфавиту после создания или переименования одного из них.\nПри выключении новые теги будут просто добавляться в конец.\n\nЕсли вручную перетащить один из тегов на другое место, автосортировка отключится.",
|
||||
"Imported tags:": "Импортируемые теги:",
|
||||
"Importing Tags": "Импорт тегов",
|
||||
"Couldn't import tags:": "Не удалось импортировать теги:"
|
||||
"Couldn't import tags:": "Не удалось импортировать теги:",
|
||||
"Allow fallback models": "Разрешить fallback-модели",
|
||||
"Allow fallback providers": "Разрешить fallback-провайдеров",
|
||||
"To use instruct formatting, switch to OpenRouter under Text Completion API.": "Переключитесь на OpenRouter в Text Completion API, чтобы использовать форматирование Instruct-режима.",
|
||||
"Select providers. No selection = all providers.": "Выберите провайдера. Нет выбранного = выбраны все.",
|
||||
"Model Providers": "Провайдеры моделей",
|
||||
"Select a model": "Выберите модель",
|
||||
"Search models...": "Искать по моделям...",
|
||||
"[Currently loaded]": "[Загруженная сейчас]",
|
||||
"Search providers...": "Искать по провайдерам...",
|
||||
"Automatically chooses an alternative provider if chosen providers can't serve your request.": "Автоматически переключаться на другого провайдера, если текущий не может обслужить запрос.",
|
||||
"Example: 127.0.0.1:8000": "Пример: 127.0.0.1:8000",
|
||||
"Edit a connection profile": "Редактировать профиль соединения",
|
||||
"System Prompt Name": "Название системного промпта",
|
||||
"Use System Prompt": "Использовать системный промпт",
|
||||
"Hint:": "Подсказка:",
|
||||
"Click on the setting name to omit it from the profile.": "Нажмите на название настройки, чтобы исключить её из профиля",
|
||||
"Included settings:": "Сохранённые параметры:",
|
||||
"Server URL": "Адрес сервера",
|
||||
"NanoGPT API Key": "Ключ от API NanoGPT",
|
||||
"NanoGPT Model": "Модель NanoGPT",
|
||||
"Use extension settings": "Использовать настройки из расширения",
|
||||
"DeepSeek API Key": "Ключ от API DeepSeek",
|
||||
"DeepSeek Model": "Модель DeepSeek",
|
||||
"prompt_post_processing_merge": "Объединять идущие подряд сообщения с одной ролью",
|
||||
"prompt_post_processing_semi": "Semi-strict (чередовать роли)",
|
||||
"prompt_post_processing_strict": "Strict (чередовать роли, сначала пользователь)",
|
||||
"Select Horde models": "Выбрать модель из Horde",
|
||||
"Model ID (optional)": "Идентификатор модели (необязательно)",
|
||||
"Derive context size from backend": "Использовать бэкенд для определения размера контекста",
|
||||
"Rename current preset": "Переименовать пресет",
|
||||
"No Worlds active. Click here to select.": "Нет активных миров. Нажмите, чтобы выбрать.",
|
||||
"Title/Memo": "Название",
|
||||
"Strategy": "Статус",
|
||||
"Position": "Позиция",
|
||||
"Trigger %": "% срабатывания",
|
||||
"Use global": "Глоб. настройка",
|
||||
"Whole Words": "Целые слова",
|
||||
"Non-recursable (will not be activated by another)": "Не рекурсивная (не активируется другими)",
|
||||
"Delay until recursion (can only be activated on recursive checking)": "Рекурсивная (активируется только рекурсией)",
|
||||
"Toggle entry's active state.": "Вкл/выкл запись.",
|
||||
"Prioritize": "Важная",
|
||||
"Prioritize this entry: When checked, this entry is prioritized out of all selections.If multiple are prioritized, the one with the highest 'Order' is chosen.": "Важная запись получает приоритет среди всех выбранных. Если важных записей несколько, выбирается та, у которой выше \"Очерёдность\".",
|
||||
"Group Weight": "Вес в группе",
|
||||
"A relative likelihood of entry activation within the group": "Относительная вероятность активации записи в рамках группы",
|
||||
"Sticky": "Липучка",
|
||||
"Sticky entries will stay active for N messages after being triggered.": "Запись-\"липучка\" останется активной в течение N сообщений после срабатывания.",
|
||||
"Cooldown": "Кулдаун",
|
||||
"Entries with a cooldown can't be activated N messages after being triggered.": "Запись с заданным кулдауном не активируется следующие N сообщений после срабатывания.",
|
||||
"Delay": "Задержка",
|
||||
"Entries with a delay can't be activated until there are N messages present in the chat.": "Запись с заданной задержкой может активироваться только после того, как в чате наберётся N сообщений.",
|
||||
"Non-sticky": "Нет",
|
||||
"No cooldown": "Нет",
|
||||
"No delay": "Нет",
|
||||
"Filter to Characters or Tags": "Фильтровать по персонажам или тегам",
|
||||
"Switch to plaintext mode": "Вкл/выкл режим чистого текста",
|
||||
"Exclude": "Режим исключения",
|
||||
"Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry": "Инвертировать логику: для выбранных в фильтре персонажей/тегов данная запись активна НЕ БУДЕТ",
|
||||
"Apply current sorting as Order": "Настроить Очерёдность в соответствии с текущей сортировкой",
|
||||
"Create a new World Info": "Создать новый мир",
|
||||
"Enter a name for the new file:": "Название нового файла:",
|
||||
"Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group": "Если сразу несколько записей из одной группы окажутся активированными, по факту сработает только одна. Одна запись может входить в несколько групп, отделяются запятыми. Раздел в документации: World Info - Inclusion Group",
|
||||
"Valid World Info file name is required": "Требуется корректное имя для файла мира",
|
||||
"World Info file has an invalid format": "Файл мира имеет неизвестный формат",
|
||||
"World Info file has no entries": "В файле нет ни одной записи",
|
||||
"Character not found.": "Персонаж не найден",
|
||||
"Open a chat to get a name of the chat-bound lorebook": "Чтобы получить название привязанного к чату лорбука, требуется открыть чат.",
|
||||
"File is not valid: ${0}": "Файл повреждён или имеет неизвестный формат: ${0}",
|
||||
"The world with ${0} is invalid or corrupted.": "Мир ${0} повреждён или имеет неизвестный формат.",
|
||||
"Deactivated all worlds": "Все миры отключены",
|
||||
"No world found named: ${0}": "Не найдено мира с название ${0}",
|
||||
"Activated world: ${0}": "Мир ${0} включён",
|
||||
"Deactivated world: ${0}": "Мир ${0} отключён",
|
||||
"World was not active: ${0}": "Мир ${0} не включён",
|
||||
"The world '${0}' has been imported and linked to the character successfully.": "Мир ${0} успешно импортирован и привязан к персонажу.",
|
||||
"World/Lorebook imported": "Мир/лорбук импортирован",
|
||||
"Are you sure you want to import '${0}'?": "Вы точно хотите импортировать '${0}'?",
|
||||
"It will overwrite the World/Lorebook with the same name.": "Существующий мир с таким же названием будет перезаписан.",
|
||||
"Automatically 'continue' a response if the model stopped before reaching a certain amount of tokens.": "Автоматически \"продолжать\" ответ, если он оказался короче, чем целевая длина (в токенах).",
|
||||
"None (not injected)": "Никуда",
|
||||
"ext_sum_injection_position_none": "Пересказ не будет вставляться в промпт. Однако его по-прежнему можно будет вставить с помощью макроса {{summary}}",
|
||||
"ext_sum_include_wi_scan": "Учитывать при сканировании лорбуком",
|
||||
"ext_sum_include_wi_scan_desc": "Учитывать актуальный пересказ при сканировании промпта лорбуком.",
|
||||
"ext_sum_force_tip": "Отправить запрос на создание пересказа прямо сейчас.",
|
||||
"ext_sum_restore_tip": "Откатиться к предыдущему пересказу; используйте несколько раз, чтобы очистить историю пересказов для чата",
|
||||
"Built-in Extensions:": "Комплектные расширения:",
|
||||
"Installed Extensions:": "Установленные расширения:",
|
||||
"Loading third-party extensions... Please wait...": "Загрузка сторонних расширений... Пожалуйста, подождите...",
|
||||
"The page will be reloaded shortly...": "Страница будет перезагружена...",
|
||||
"Extensions state changed": "Изменено состояние расширения",
|
||||
"Error loading extensions. See browser console for details.": "Не удалось загрузить расширения. Подробности см. в консоли браузера.",
|
||||
"You don't have permission to update global extensions.": "Отсутствуют права на обновление глобальных расширений.",
|
||||
"Extension update failed": "Не удалось обновить расширение",
|
||||
"Extension ${0} updated to ${1}": "Расширение ${0} обновлено до ${1}",
|
||||
"Reload the page to apply updates": "Чтобы изменения вступили в силу, обновите страницу",
|
||||
"You don't have permission to delete global extensions.": "Отсутствуют права на удаление глобальных расширений.",
|
||||
"Are you sure you want to delete ${0}?": "Вы точно хотите удалить ${0}?",
|
||||
"You don't have permission to move extensions.": "Отсутствуют права на перемещение расширений.",
|
||||
"Are you sure you want to move ${0} to your local extensions? This will make it available only for you.": "Вы точно хотите сделать ${0} локальным расширением? После этого оно будет доступно только вам.",
|
||||
"Are you sure you want to move ${0} to the global extensions? This will make it available for all users.": "Вы точно хотите сделать ${0} глобальным расширением? После этого оно будет доступно всем пользователям.",
|
||||
"Extension ${0} moved.": "Расширение ${0} перемещено.",
|
||||
"Extension ${0} deleted": "Расширение ${0} удалено.",
|
||||
"Please wait...": "Пожалуйста, подождите...",
|
||||
"Installing extension": "Идёт установка расширения",
|
||||
"Extension installation failed": "Не удалось установить расширение",
|
||||
"Extension '${0}' by ${1} (version ${2}) has been installed successfully!": "Расширение ${0} от автора ${1} (версия ${2}) успешно установлено!",
|
||||
"Extension installation successful": "Расширение установлено",
|
||||
"Extension updates available": "Доступных обновлений расширений",
|
||||
"Auto-updating extensions. This may take several minutes.": "Запущено автоматическое обновление расширений. Это может занять несколько минут.",
|
||||
"Install just for me": "Установить только мне",
|
||||
"Install": "Установить",
|
||||
"Install for all users": "Установить для всех пользователей",
|
||||
"Modules provided by your Extras API:": "Модули из Extras API:",
|
||||
"Not connected to the API!": "Нет соединения с API!",
|
||||
"ext_type_system": "Это комплектное расширение. Его нельзя удалить, а обновляется оно вместе со всей системой.",
|
||||
"Update all": "Обновить все",
|
||||
"Close": "Закрыть",
|
||||
"Optional modules:": "Необязательные модули:",
|
||||
"Sort: Display Name": "Сортировать: по названию",
|
||||
"Sort: Loading Order": "Сортировать: в порядке загрузки",
|
||||
"Click to toggle": "Нажмите, чтобы включить или выключить",
|
||||
"Loading Asset List": "Загрузить список ресурсов",
|
||||
"Don't ask again for this URL": "Запомнить выбор для этого адреса",
|
||||
"Are you sure you want to connect to the following url?": "Вы точно хотите подключиться к этому адресу?",
|
||||
"All": "Всё",
|
||||
"Characters": "Персонажи",
|
||||
"Ambient sounds": "Звуковой эмбиент",
|
||||
"Blip sounds": "Звуки уведомлений",
|
||||
"Background music": "Фоновая музыка",
|
||||
"Search": "Поиск",
|
||||
"extension_install_1": "Чтобы загружать расширения из этого списка, у вас должен быть установлен ",
|
||||
"extension_install_2": ".",
|
||||
"extension_install_3": "Нажмите на иконку ",
|
||||
"extension_install_4": ", чтобы перейти в репозиторий расширения и получить более подробную информацию о нём.",
|
||||
"Extension repo/guide:": "Репозиторий расширения:",
|
||||
"Preview in browser": "Предпросмотр",
|
||||
"Adds a function tool": "Частично или полностью работает через вызов функций",
|
||||
"Tool": "Функции",
|
||||
"Move extension": "Переместить расширение",
|
||||
"ext_type_local": "Это локальное расширение, доступно только вам",
|
||||
"ext_type_global": "Это глобальное расширение, доступно всем пользователям",
|
||||
"Move": "Переместить",
|
||||
"Enter the Git URL of the extension to install": "Введите Git-адрес расширения",
|
||||
"Please be aware that using external extensions can have unintended side effects and may pose security risks. Always make sure you trust the source before importing an extension. We are not responsible for any damage caused by third-party extensions.": "помните, что используя расширения от сторонних авторов, вы можете подвергать систему опасности. Устанавливайте расширения только от проверенных разработчиков. Мы не несём ответственности за любой ущерб, причинённый сторонними расширениями.",
|
||||
"Disclaimer:": "Внимание:",
|
||||
"Example:": "Пример:",
|
||||
"context_derived": "Считывать из метаданных модели (по возможности)",
|
||||
"instruct_derived": "Считывать из метаданных модели (по возможности)",
|
||||
"Confirm token parsing with": "Чтобы убедиться в правильности выделения токенов, используйте",
|
||||
"Reasoning Effort": "Рассуждения",
|
||||
"Constrains effort on reasoning for reasoning models.": "Регулирует объём внутренних рассуждений модели (reasoning), для моделей которые поддерживают эту возможность.\nНа данный момент поддерживаются три значения: Подробные, Обычные, Поверхностные.\nПри менее подробном рассуждении ответ получается быстрее, а также экономятся токены, уходящие на рассуждения.",
|
||||
"openai_reasoning_effort_low": "Поверхностные",
|
||||
"openai_reasoning_effort_medium": "Обычные",
|
||||
"openai_reasoning_effort_high": "Подробные",
|
||||
"Persona Lore Alt+Click to open the lorebook": "Лорбук данной персоны\nAlt + ЛКМ чтобы открыть лорбук",
|
||||
"Persona Lorebook for": "Лорбук для персоны",
|
||||
"persona_world_template_txt": "Выбранная Информация о мире будет привязана к этой персоне. Информация будет добавляться в каждом промпте вместе с глобальным лорбуком и лорбуками персонажа и чата.",
|
||||
"Global list": "Глобальный список",
|
||||
"Preset-specific list": "Список для данного пресета",
|
||||
"Banned tokens/strings are being sent in the request.": "Запрещённые токены и строки отсылаются в запросе.",
|
||||
"Banned tokens/strings are NOT being sent in the request.": "Запрещённые токены и строки НЕ отсылаются в запросе.",
|
||||
"Add a reasoning block": "Добавить блок рассуждений",
|
||||
"Create a copy of this message?": "Продублировать это сообщение?",
|
||||
"Max Recursion Steps": "Макс. глубина рекурсии",
|
||||
"0 = unlimited, 1 = scans once and doesn't recurse, 2 = scans once and recurses once, etc": "0 = неограничено, 1 = сканировать единожды, 2 = сканировать единожды и сделать один повторный проход, и т.д.\n(неактивно при указанном мин. числе активаций)",
|
||||
"(disabled when max recursion steps are used)": "(неактивно при указанной макс. глубине рекурсии)",
|
||||
"Enter a valid API URL": "Введите корректный адрес API",
|
||||
"No Ollama model selected.": "Не выбрана модель Ollama",
|
||||
"Background Fitting": "Способ подгонки фона под разрешение",
|
||||
"Chat Lore Alt+Click to open the lorebook": "Лорбук данного чата\nAlt + ЛКМ чтобы открыть лорбук",
|
||||
"Token Counter": "Подсчитать токены",
|
||||
"Type / paste in the box below to see the number of tokens in the text.": "Введите или вставьте текст в окошко ниже, чтобы подсчитать количество токенов в нём.",
|
||||
"Selected tokenizer:": "Выбранный токенайзер:",
|
||||
"Input:": "Входные данные:",
|
||||
"Tokenized text:": "Токенизированный текст:",
|
||||
"Token IDs:": "Идентификаторы токенов:",
|
||||
"Tokens:": "Токенов:"
|
||||
}
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "Завершення тексту",
|
||||
"Chat Completion": "Завершення чату",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "KoboldAI Horde",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Уникайте надсилання чутливої інформації в Horde.",
|
||||
"Review the Privacy statement": "Перегляньте заяву про конфіденційність",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "розділяйте комами без пропусків між ними",
|
||||
"Custom Stopping Strings": "Власні рядки зупинки",
|
||||
"JSON serialized array of strings": "JSON-серіалізований масив рядків",
|
||||
"Replace Macro in Custom Stopping Strings": "Замінювати макроси у власних рядках зупинки",
|
||||
"Replace Macro in Stop Strings": "Замінювати макроси у власних рядках зупинки",
|
||||
"Auto-Continue": "Автоматичне продовження",
|
||||
"Allow for Chat Completion APIs": "Дозволити для Chat Completion API",
|
||||
"Target length (tokens)": "Цільова довжина (токени)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "Видалити тему",
|
||||
"Update a theme file": "Оновити файл теми",
|
||||
"Save as a new theme": "Зберегти як нову тему",
|
||||
"Avatar Style": "Стиль аватара",
|
||||
"Avatar Style:": "Стиль аватара",
|
||||
"Circle": "Коло",
|
||||
"Square": "Квадрат",
|
||||
"Rectangle": "Прямокутник",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "Перевага запиту персонажа",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Якщо відмічено і картка персонажа містить заміну джейлбрейку (Інструкцію), використовуйте її замість цього",
|
||||
"Prefer Character Card Jailbreak": "Перевага джейлбрейку персонажа",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Уникайте обрізання та зміни розміру імпортованих зображень символів. Коли вимкнено, обрізати/змінити розмір до 512x768.",
|
||||
"never_resize_avatars_tooltip": "Уникайте обрізання та зміни розміру імпортованих зображень символів. Коли вимкнено, обрізати/змінити розмір до 512x768.",
|
||||
"Never resize avatars": "Ніколи не змінювати розмір аватарів",
|
||||
"Show actual file names on the disk, in the characters list display only": "Показувати фактичні назви файлів на диску, тільки у відображенні списку персонажів",
|
||||
"Show avatar filenames": "Показувати імена файлів аватарів",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "Автоматичний змах",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Вмикає функцію автоматичного змаху. Налаштування в цьому розділі діють лише тоді, коли увімкнено автоматичний змах",
|
||||
"Minimum generated message length": "Мінімальна довжина згенерованого повідомлення",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Якщо згенероване повідомлення коротше за це, викликайте автоматичний змаху",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Якщо згенероване повідомлення коротше за це, викликайте автоматичний змаху",
|
||||
"Blacklisted words": "Список заборонених слів",
|
||||
"words you dont want generated separated by comma ','": "слова, які ви не хочете генерувати, розділені комою ','",
|
||||
"Blacklisted word count to swipe": "Кількість заборонених слів для змаху",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "Немає",
|
||||
"popup-button-cancel": "Скасувати",
|
||||
"popup-button-import": "Імпорт",
|
||||
"Advanced Defininitions": "Розширені визначення",
|
||||
"Advanced Definitions": "Розширені визначення",
|
||||
"Prompt Overrides": "Перевизначення підказок",
|
||||
"(For Chat Completion and Instruct Mode)": "(Для завершення чату та режиму інструктажу)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Вставте {{original}} в будь-яке поле, щоб включити відповідний запит з налаштувань системи.",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "запустіть програму DrawThings із увімкненим перемикачем HTTP API в інтерфейсі користувача! Сервер має бути доступним із хост-машини SillyTavern.",
|
||||
"sd_vlad_url": "Приклад: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "Сервер має бути доступним із хост-машини SillyTavern.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Підказка: збережіть ключ API в налаштуваннях Horde KoboldAI API, щоб використовувати його тут.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Підказка: збережіть ключ API в налаштуваннях AI Horde API, щоб використовувати його тут.",
|
||||
"Allow NSFW images from Horde": "Дозволити зображення NSFW від Horde",
|
||||
"Sanitize prompts (recommended)": "Очистити підказки (рекомендовано)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Автоматично налаштовуйте параметри генерації, щоб забезпечити вільне створення зображень.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Chub Lorebook (пряме посилання або ID)",
|
||||
"char_import_3": "Символ JanitorAI (пряме посилання або UUID)",
|
||||
"char_import_4": "Символ Pygmalion.chat (пряме посилання або UUID)",
|
||||
"char_import_5": "Символ AICharacterCard.com (пряме посилання або ідентифікатор)",
|
||||
"char_import_5": "Символ AICharacterCards.com (пряме посилання або ідентифікатор)",
|
||||
"char_import_6": "Пряме посилання на PNG (див",
|
||||
"char_import_7": "для дозволених хостів)",
|
||||
"char_import_8": "Персонаж RisuRealm (пряме посилання)",
|
||||
|
@@ -267,7 +267,7 @@
|
||||
"Text Completion": "Text Completion",
|
||||
"Chat Completion": "Chat Completion",
|
||||
"NovelAI": "NovelAI",
|
||||
"KoboldAI Horde": "KoboldAI Horde",
|
||||
"AI Horde": "AI Horde",
|
||||
"KoboldAI": "KoboldAI",
|
||||
"Avoid sending sensitive information to the Horde.": "Tránh gửi thông tin nhạy cảm cho Horde.",
|
||||
"Review the Privacy statement": "Xem lại Chính sách bảo mật",
|
||||
@@ -482,7 +482,7 @@
|
||||
"separate with commas w/o space between": "phân tách bằng dấu phẩy không có khoảng trắng giữa",
|
||||
"Custom Stopping Strings": "Chuỗi dừng tùy chỉnh",
|
||||
"JSON serialized array of strings": "Mảng chuỗi được tuần tự hóa JSON",
|
||||
"Replace Macro in Custom Stopping Strings": "Thay thế Macro trong Chuỗi Dừng Tùy chỉnh",
|
||||
"Replace Macro in Stop Strings": "Thay thế Macro trong Chuỗi Dừng Tùy chỉnh",
|
||||
"Auto-Continue": "Tự động Tiếp tục",
|
||||
"Allow for Chat Completion APIs": "Cho phép các API hoàn thành Trò chuyện",
|
||||
"Target length (tokens)": "Độ dài mục tiêu (token)",
|
||||
@@ -558,7 +558,7 @@
|
||||
"Delete a theme": "Xóa một chủ đề",
|
||||
"Update a theme file": "Cập nhật một tập tin chủ đề",
|
||||
"Save as a new theme": "Lưu dưới dạng chủ đề mới",
|
||||
"Avatar Style": "Kiểu hình đại diện",
|
||||
"Avatar Style:": "Kiểu hình đại diện",
|
||||
"Circle": "Hình tròn",
|
||||
"Square": "Hình vuông",
|
||||
"Rectangle": "Hình chữ nhật",
|
||||
@@ -633,7 +633,7 @@
|
||||
"Prefer Character Card Prompt": "Ưu tiên Gợi ý từ Card",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Nếu được kiểm tra và thẻ nhân vật chứa một lệnh phá vỡ giam giữ (Hướng dẫn Lịch sử Bài viết), hãy sử dụng thay vào đó",
|
||||
"Prefer Character Card Jailbreak": "Ưu tiên Jailbreak từ Card",
|
||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Tránh cắt xén và thay đổi kích thước hình ảnh ký tự đã nhập. Khi tắt, hãy cắt/thay đổi kích thước thành 512x768.",
|
||||
"never_resize_avatars_tooltip": "Tránh cắt xén và thay đổi kích thước hình ảnh ký tự đã nhập. Khi tắt, hãy cắt/thay đổi kích thước thành 512x768.",
|
||||
"Never resize avatars": "Không bao giờ thay đổi kích thước hình đại diện",
|
||||
"Show actual file names on the disk, in the characters list display only": "Hiển thị tên tệp thực tế trên đĩa, chỉ trong danh sách nhân vật",
|
||||
"Show avatar filenames": "Hiển thị tên tệp hình đại diện",
|
||||
@@ -709,7 +709,7 @@
|
||||
"Auto-swipe": "Tự động vuốt",
|
||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Bật chức năng tự động vuốt. Các cài đặt trong phần này chỉ có tác dụng khi tự động vuốt được bật",
|
||||
"Minimum generated message length": "Độ dài tối thiểu của tin nhắn được tạo",
|
||||
"If the generated message is shorter than this, trigger an auto-swipe": "Nếu tin nhắn được tạo ra ngắn hơn điều này, kích hoạt tự động vuốt",
|
||||
"If the generated message is shorter than these many characters, trigger an auto-swipe": "Nếu tin nhắn được tạo ra ngắn hơn điều này, kích hoạt tự động vuốt",
|
||||
"Blacklisted words": "Từ trong danh sách đen",
|
||||
"words you dont want generated separated by comma ','": "các từ bạn không muốn được tạo ra được phân tách bằng dấu phẩy ','",
|
||||
"Blacklisted word count to swipe": "Số từ trong danh sách đen để vuốt",
|
||||
@@ -879,7 +879,7 @@
|
||||
"popup-button-no": "KHÔNG",
|
||||
"popup-button-cancel": "Hủy",
|
||||
"popup-button-import": "Nhập",
|
||||
"Advanced Defininitions": "Các Định nghĩa Nâng cao",
|
||||
"Advanced Definitions": "Các Định nghĩa Nâng cao",
|
||||
"Prompt Overrides": "Ghi đè Prompt",
|
||||
"(For Chat Completion and Instruct Mode)": "(Đối với chế độ hoàn thành trò chuyện và hướng dẫn)",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Chèn {{original}} vào bất kỳ hộp nào để bao gồm Prompt mặc định tương ứng từ cài đặt hệ thống.",
|
||||
@@ -1295,7 +1295,7 @@
|
||||
"sd_drawthings_auth_txt": "chạy ứng dụng DrawThings với tính năng chuyển đổi API HTTP được bật trong giao diện người dùng! Máy chủ phải có thể truy cập được từ máy chủ SillyTavern.",
|
||||
"sd_vlad_url": "Ví dụ: {{vlad_url}}",
|
||||
"The server must be accessible from the SillyTavern host machine.": "Máy chủ phải có thể truy cập được từ máy chủ SillyTavern.",
|
||||
"Hint: Save an API key in Horde KoboldAI API settings to use it here.": "Gợi ý: Lưu khóa API trong cài đặt API Horde KoboldAI để sử dụng tại đây.",
|
||||
"Hint: Save an API key in AI Horde API settings to use it here.": "Gợi ý: Lưu khóa API trong cài đặt API AI Horde để sử dụng tại đây.",
|
||||
"Allow NSFW images from Horde": "Cho phép hình ảnh NSFW từ Horde",
|
||||
"Sanitize prompts (recommended)": "Nhắc nhở vệ sinh (khuyến nghị)",
|
||||
"Automatically adjust generation parameters to ensure free image generations.": "Tự động điều chỉnh các thông số tạo để đảm bảo tạo ra hình ảnh miễn phí.",
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"char_import_2": "Chub (Nhập URL trực tiếp hoặc ID)",
|
||||
"char_import_3": "JanitorAI (Nhập URL trực tiếp hoặc UUID)",
|
||||
"char_import_4": "Pygmalion.chat (Nhập URL trực tiếp hoặc UUID)",
|
||||
"char_import_5": "AICharacterCard.com (Nhập URL trực tiếp hoặc ID)",
|
||||
"char_import_5": "AICharacterCards.com (Nhập URL trực tiếp hoặc ID)",
|
||||
"char_import_6": "Nhập PNG trực tiếp (tham khảo",
|
||||
"char_import_7": "đối với các máy chủ được phép)",
|
||||
"char_import_8": "RisuRealm (URL trực tiếp)",
|
||||
|
2130
public/script.js
@@ -395,7 +395,7 @@ class BulkEditOverlay {
|
||||
|
||||
/**
|
||||
* @typedef {object} LastSelected - An object noting the last selected character and its state.
|
||||
* @property {string} [characterId] - The character id of the last selected character.
|
||||
* @property {number} [characterId] - The character id of the last selected character.
|
||||
* @property {boolean} [select] - The selected state of the last selected character. <c>true</c> if it was selected, <c>false</c> if it was deselected.
|
||||
*/
|
||||
|
||||
@@ -672,10 +672,10 @@ class BulkEditOverlay {
|
||||
* @param {HTMLElement} currentCharacter - The html element of the currently toggled character
|
||||
*/
|
||||
handleShiftClick = (currentCharacter) => {
|
||||
const characterId = currentCharacter.getAttribute('chid');
|
||||
const characterId = Number(currentCharacter.getAttribute('data-chid'));
|
||||
const select = !this.selectedCharacters.includes(characterId);
|
||||
|
||||
if (this.lastSelected.characterId && this.lastSelected.select !== undefined) {
|
||||
if (this.lastSelected.characterId >= 0 && this.lastSelected.select !== undefined) {
|
||||
// Only if select state and the last select state match we execute the range select
|
||||
if (select === this.lastSelected.select) {
|
||||
this.toggleCharactersInRange(currentCharacter, select);
|
||||
@@ -691,7 +691,7 @@ class BulkEditOverlay {
|
||||
* @param {boolean} [param1.markState] - Whether the toggle of this character should be remembered as the last done toggle
|
||||
*/
|
||||
toggleSingleCharacter = (character, { markState = true } = {}) => {
|
||||
const characterId = character.getAttribute('chid');
|
||||
const characterId = Number(character.getAttribute('data-chid'));
|
||||
|
||||
const select = !this.selectedCharacters.includes(characterId);
|
||||
const legacyBulkEditCheckbox = character.querySelector('.' + BulkEditOverlay.legacySelectedClass);
|
||||
@@ -699,11 +699,11 @@ class BulkEditOverlay {
|
||||
if (select) {
|
||||
character.classList.add(BulkEditOverlay.selectedClass);
|
||||
if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = true;
|
||||
this.#selectedCharacters.push(String(characterId));
|
||||
this.#selectedCharacters.push(characterId);
|
||||
} else {
|
||||
character.classList.remove(BulkEditOverlay.selectedClass);
|
||||
if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = false;
|
||||
this.#selectedCharacters = this.#selectedCharacters.filter(item => String(characterId) !== item);
|
||||
this.#selectedCharacters = this.#selectedCharacters.filter(item => characterId !== item);
|
||||
}
|
||||
|
||||
this.updateSelectedCount();
|
||||
@@ -732,15 +732,15 @@ class BulkEditOverlay {
|
||||
* @param {boolean} select - <c>true</c> if the characters in the range are to be selected, <c>false</c> if deselected
|
||||
*/
|
||||
toggleCharactersInRange = (currentCharacter, select) => {
|
||||
const currentCharacterId = currentCharacter.getAttribute('chid');
|
||||
const currentCharacterId = Number(currentCharacter.getAttribute('data-chid'));
|
||||
const characters = Array.from(document.querySelectorAll('#' + BulkEditOverlay.containerId + ' .' + BulkEditOverlay.characterClass));
|
||||
|
||||
const startIndex = characters.findIndex(c => c.getAttribute('chid') === this.lastSelected.characterId);
|
||||
const endIndex = characters.findIndex(c => c.getAttribute('chid') === currentCharacterId);
|
||||
const startIndex = characters.findIndex(c => Number(c.getAttribute('data-chid')) === Number(this.lastSelected.characterId));
|
||||
const endIndex = characters.findIndex(c => Number(c.getAttribute('data-chid')) === currentCharacterId);
|
||||
|
||||
for (let i = Math.min(startIndex, endIndex); i <= Math.max(startIndex, endIndex); i++) {
|
||||
const character = characters[i];
|
||||
const characterId = character.getAttribute('chid');
|
||||
const characterId = Number(character.getAttribute('data-chid'));
|
||||
const isCharacterSelected = this.selectedCharacters.includes(characterId);
|
||||
|
||||
// Only toggle the character if it wasn't on the state we have are toggling towards.
|
||||
|
@@ -11,6 +11,7 @@ import { debounce_timeout } from './constants.js';
|
||||
import { renderTemplateAsync } from './templates.js';
|
||||
import { Popup } from './popup.js';
|
||||
import { t } from './i18n.js';
|
||||
import { isMobile } from './RossAscends-mods.js';
|
||||
|
||||
function debouncePromise(func, delay) {
|
||||
let timeoutId;
|
||||
@@ -1208,7 +1209,7 @@ class PromptManager {
|
||||
const forbidOverridesBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block');
|
||||
|
||||
nameField.value = prompt.name ?? '';
|
||||
roleField.value = prompt.role ?? 'system';
|
||||
roleField.value = prompt.role || 'system';
|
||||
promptField.value = prompt.content ?? '';
|
||||
promptField.disabled = prompt.marker ?? false;
|
||||
injectionPositionField.value = prompt.injection_position ?? INJECTION_POSITION.RELATIVE;
|
||||
@@ -1518,7 +1519,7 @@ class PromptManager {
|
||||
let detachSpanHtml = '';
|
||||
if (this.isPromptDeletionAllowed(prompt)) {
|
||||
detachSpanHtml = `
|
||||
<span title="Remove" class="prompt-manager-detach-action caution fa-solid fa-chain-broken"></span>
|
||||
<span title="Remove" class="prompt-manager-detach-action caution fa-solid fa-chain-broken fa-xs"></span>
|
||||
`;
|
||||
} else {
|
||||
detachSpanHtml = '<span class="fa-solid"></span>';
|
||||
@@ -1527,7 +1528,7 @@ class PromptManager {
|
||||
let editSpanHtml = '';
|
||||
if (this.isPromptEditAllowed(prompt)) {
|
||||
editSpanHtml = `
|
||||
<span title="edit" class="prompt-manager-edit-action fa-solid fa-pencil"></span>
|
||||
<span title="edit" class="prompt-manager-edit-action fa-solid fa-pencil fa-xs"></span>
|
||||
`;
|
||||
} else {
|
||||
editSpanHtml = '<span class="fa-solid"></span>';
|
||||
@@ -1550,16 +1551,28 @@ class PromptManager {
|
||||
const isInjectionPrompt = prompt.injection_position === INJECTION_POSITION.ABSOLUTE;
|
||||
const isOverriddenPrompt = Array.isArray(this.overriddenPrompts) && this.overriddenPrompts.includes(prompt.identifier);
|
||||
const importantClass = isImportantPrompt ? `${prefix}prompt_manager_important` : '';
|
||||
const iconLookup = prompt.role === 'system' && (prompt.marker || prompt.system_prompt) ? '' : prompt.role;
|
||||
|
||||
//add role icons to the right of prompt name
|
||||
const promptRoles = {
|
||||
assistant: { roleIcon: 'fa-robot', roleTitle: 'Prompt will be sent as Assistant' },
|
||||
user: { roleIcon: 'fa-user', roleTitle: 'Prompt will be sent as User' },
|
||||
};
|
||||
const roleIcon = promptRoles[iconLookup]?.roleIcon || '';
|
||||
const roleTitle = promptRoles[iconLookup]?.roleTitle || '';
|
||||
|
||||
listItemHtml += `
|
||||
<li class="${prefix}prompt_manager_prompt ${draggableClass} ${enabledClass} ${markerClass} ${importantClass}" data-pm-identifier="${prompt.identifier}">
|
||||
<li class="${prefix}prompt_manager_prompt ${draggableClass} ${enabledClass} ${markerClass} ${importantClass}" data-pm-identifier="${escapeHtml(prompt.identifier)}">
|
||||
<span class="drag-handle">☰</span>
|
||||
<span class="${prefix}prompt_manager_prompt_name" data-pm-name="${encodedName}">
|
||||
${isMarkerPrompt ? '<span class="fa-fw fa-solid fa-thumb-tack" title="Marker"></span>' : ''}
|
||||
${isSystemPrompt ? '<span class="fa-fw fa-solid fa-square-poll-horizontal" title="Global Prompt"></span>' : ''}
|
||||
${isImportantPrompt ? '<span class="fa-fw fa-solid fa-star" title="Important Prompt"></span>' : ''}
|
||||
${isUserPrompt ? '<span class="fa-fw fa-solid fa-user" title="User Prompt"></span>' : ''}
|
||||
${isUserPrompt ? '<span class="fa-fw fa-solid fa-asterisk" title="Preset Prompt"></span>' : ''}
|
||||
${isInjectionPrompt ? '<span class="fa-fw fa-solid fa-syringe" title="In-Chat Injection"></span>' : ''}
|
||||
${this.isPromptInspectionAllowed(prompt) ? `<a title="${encodedName}" class="prompt-manager-inspect-action">${encodedName}</a>` : `<span title="${encodedName}">${encodedName}</span>`}
|
||||
${isInjectionPrompt ? `<small class="prompt-manager-injection-depth">@ ${prompt.injection_depth}</small>` : ''}
|
||||
${roleIcon ? `<span data-role="${escapeHtml(prompt.role)}" class="fa-xs fa-solid ${roleIcon}" title="${roleTitle}"></span>` : ''}
|
||||
${isInjectionPrompt ? `<small class="prompt-manager-injection-depth">@ ${escapeHtml(prompt.injection_depth)}</small>` : ''}
|
||||
${isOverriddenPrompt ? '<small class="fa-solid fa-address-card prompt-manager-overridden" title="Pulled from a character card"></small>' : ''}
|
||||
</span>
|
||||
<span>
|
||||
@@ -1730,6 +1743,7 @@ class PromptManager {
|
||||
makeDraggable() {
|
||||
$(`#${this.configuration.prefix}prompt_manager_list`).sortable({
|
||||
delay: this.configuration.sortableDelay,
|
||||
handle: isMobile() ? '.drag-handle' : null,
|
||||
items: `.${this.configuration.prefix}prompt_manager_prompt_draggable`,
|
||||
update: (event, ui) => {
|
||||
const promptOrder = this.getPromptOrderForCharacter(this.activeCharacter);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DOMPurify, Bowser } from '../lib.js';
|
||||
import { DOMPurify, Bowser, slideToggle } from '../lib.js';
|
||||
|
||||
import {
|
||||
characters,
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
menu_type,
|
||||
substituteParams,
|
||||
sendTextareaMessage,
|
||||
getSlideToggleOptions,
|
||||
} from '../script.js';
|
||||
|
||||
import {
|
||||
@@ -26,7 +27,6 @@ import {
|
||||
send_on_enter_options,
|
||||
} from './power-user.js';
|
||||
|
||||
import { LoadLocal, SaveLocal, LoadLocalBool } from './f-localStorage.js';
|
||||
import { selected_group, is_group_generating, openGroupById } from './group-chats.js';
|
||||
import { getTagKeyForEntity, applyTagsOnCharacterSelect } from './tags.js';
|
||||
import {
|
||||
@@ -40,6 +40,8 @@ import { textgen_types, textgenerationwebui_settings as textgen_settings, getTex
|
||||
import { debounce_timeout } from './constants.js';
|
||||
|
||||
import { Popup } from './popup.js';
|
||||
import { accountStorage } from './util/AccountStorage.js';
|
||||
import { getCurrentUserHandle } from './user.js';
|
||||
|
||||
var RPanelPin = document.getElementById('rm_button_panel_pin');
|
||||
var LPanelPin = document.getElementById('lm_button_panel_pin');
|
||||
@@ -278,17 +280,32 @@ async function RA_autoloadchat() {
|
||||
// active character is the name, we should look it up in the character list and get the id
|
||||
if (active_character !== null && active_character !== undefined) {
|
||||
const active_character_id = characters.findIndex(x => getTagKeyForEntity(x) === active_character);
|
||||
if (active_character_id !== null) {
|
||||
await selectCharacterById(String(active_character_id));
|
||||
if (active_character_id !== -1) {
|
||||
await selectCharacterById(active_character_id);
|
||||
|
||||
// Do a little tomfoolery to spoof the tag selector
|
||||
const selectedCharElement = $(`#rm_print_characters_block .character_select[chid="${active_character_id}"]`);
|
||||
applyTagsOnCharacterSelect.call(selectedCharElement);
|
||||
} else {
|
||||
setActiveCharacter(null);
|
||||
saveSettingsDebounced();
|
||||
console.warn(`Currently active character with ID ${active_character} not found. Resetting to no active character.`);
|
||||
}
|
||||
}
|
||||
|
||||
if (active_group !== null && active_group !== undefined) {
|
||||
await openGroupById(String(active_group));
|
||||
if (active_character) {
|
||||
console.warn('Active character and active group are both set. Only active character will be loaded. Resetting active group.');
|
||||
setActiveGroup(null);
|
||||
saveSettingsDebounced();
|
||||
} else {
|
||||
const result = await openGroupById(String(active_group));
|
||||
if (!result) {
|
||||
setActiveGroup(null);
|
||||
saveSettingsDebounced();
|
||||
console.warn(`Currently active group with ID ${active_group} not found. Resetting to no active group.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the character list hadn't been loaded yet, try again.
|
||||
@@ -299,7 +316,10 @@ export async function favsToHotswap() {
|
||||
const entities = getEntitiesList({ doFilter: false });
|
||||
const container = $('#right-nav-panel .hotswap');
|
||||
|
||||
const favs = entities.filter(x => x.item.fav || x.item.fav == 'true');
|
||||
// Hard limit is required because even if all hotswaps don't fit the screen, their images would still be loaded
|
||||
// 25 is roughly calculated as the maximum number of favs that can fit an ultrawide monitor with the default theme
|
||||
const FAVS_LIMIT = 25;
|
||||
const favs = entities.filter(x => x.item.fav || x.item.fav == 'true').slice(0, FAVS_LIMIT);
|
||||
|
||||
//helpful instruction message if no characters are favorited
|
||||
if (favs.length == 0) {
|
||||
@@ -315,7 +335,7 @@ function RA_checkOnlineStatus() {
|
||||
if (online_status == 'no_connection') {
|
||||
const send_textarea = $('#send_textarea');
|
||||
send_textarea.attr('placeholder', send_textarea.attr('no_connection_text')); //Input bar placeholder tells users they are not connected
|
||||
//$('#send_form').addClass('no-connection'); //entire input form area is red when not connected
|
||||
$('#send_form').addClass('no-connection');
|
||||
$('#send_but').addClass('displayNone'); //send button is hidden when not connected;
|
||||
$('#mes_continue').addClass('displayNone'); //continue button is hidden when not connected;
|
||||
$('#mes_impersonate').addClass('displayNone'); //continue button is hidden when not connected;
|
||||
@@ -326,7 +346,7 @@ function RA_checkOnlineStatus() {
|
||||
if (online_status !== undefined && online_status !== 'no_connection') {
|
||||
const send_textarea = $('#send_textarea');
|
||||
send_textarea.attr('placeholder', send_textarea.attr('connected_text')); //on connect, placeholder tells user to type message
|
||||
//$('#send_form').removeClass('no-connection');
|
||||
$('#send_form').removeClass('no-connection');
|
||||
$('#API-status-top').removeClass('fa-plug-circle-exclamation redOverlayGlow');
|
||||
$('#API-status-top').addClass('fa-plug');
|
||||
connection_made = true;
|
||||
@@ -389,6 +409,7 @@ function RA_autoconnect(PrevApi) {
|
||||
|| (secret_state[SECRET_KEYS.ZEROONEAI] && oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI)
|
||||
|| (secret_state[SECRET_KEYS.BLOCKENTROPY] && oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY)
|
||||
|| (secret_state[SECRET_KEYS.NANOGPT] && oai_settings.chat_completion_source == chat_completion_sources.NANOGPT)
|
||||
|| (secret_state[SECRET_KEYS.DEEPSEEK] && oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK)
|
||||
|| (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM)
|
||||
) {
|
||||
$('#api_button_openai').trigger('click');
|
||||
@@ -407,32 +428,34 @@ function RA_autoconnect(PrevApi) {
|
||||
function OpenNavPanels() {
|
||||
if (!isMobile()) {
|
||||
//auto-open R nav if locked and previously open
|
||||
if (LoadLocalBool('NavLockOn') == true && LoadLocalBool('NavOpened') == true) {
|
||||
if (accountStorage.getItem('NavLockOn') == 'true' && accountStorage.getItem('NavOpened') == 'true') {
|
||||
//console.log("RA -- clicking right nav to open");
|
||||
$('#rightNavDrawerIcon').click();
|
||||
}
|
||||
|
||||
//auto-open L nav if locked and previously open
|
||||
if (LoadLocalBool('LNavLockOn') == true && LoadLocalBool('LNavOpened') == true) {
|
||||
if (accountStorage.getItem('LNavLockOn') == 'true' && accountStorage.getItem('LNavOpened') == 'true') {
|
||||
console.debug('RA -- clicking left nav to open');
|
||||
$('#leftNavDrawerIcon').click();
|
||||
}
|
||||
|
||||
//auto-open WI if locked and previously open
|
||||
if (LoadLocalBool('WINavLockOn') == true && LoadLocalBool('WINavOpened') == true) {
|
||||
if (accountStorage.getItem('WINavLockOn') == 'true' && accountStorage.getItem('WINavOpened') == 'true') {
|
||||
console.debug('RA -- clicking WI to open');
|
||||
$('#WIDrawerIcon').click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getUserInputKey = () => getCurrentUserHandle() + '_userInput';
|
||||
|
||||
function restoreUserInput() {
|
||||
if (!power_user.restore_user_input) {
|
||||
console.debug('restoreUserInput disabled');
|
||||
return;
|
||||
}
|
||||
|
||||
const userInput = LoadLocal('userInput');
|
||||
const userInput = localStorage.getItem(getUserInputKey());
|
||||
if (userInput) {
|
||||
$('#send_textarea').val(userInput)[0].dispatchEvent(new Event('input', { bubbles: true }));
|
||||
}
|
||||
@@ -440,7 +463,8 @@ function restoreUserInput() {
|
||||
|
||||
function saveUserInput() {
|
||||
const userInput = String($('#send_textarea').val());
|
||||
SaveLocal('userInput', userInput);
|
||||
localStorage.setItem(getUserInputKey(), userInput);
|
||||
console.debug('User Input -- ', userInput);
|
||||
}
|
||||
const saveUserInputDebounced = debounce(saveUserInput);
|
||||
|
||||
@@ -737,7 +761,7 @@ export function initRossMods() {
|
||||
|
||||
//toggle pin class when lock toggle clicked
|
||||
$(RPanelPin).on('click', function () {
|
||||
SaveLocal('NavLockOn', $(RPanelPin).prop('checked'));
|
||||
accountStorage.setItem('NavLockOn', $(RPanelPin).prop('checked'));
|
||||
if ($(RPanelPin).prop('checked') == true) {
|
||||
//console.log('adding pin class to right nav');
|
||||
$(RightNavPanel).addClass('pinnedOpen');
|
||||
@@ -748,14 +772,14 @@ export function initRossMods() {
|
||||
$(RightNavDrawerIcon).removeClass('drawerPinnedOpen');
|
||||
|
||||
if ($(RightNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {
|
||||
$(RightNavPanel).slideToggle(200, 'swing');
|
||||
$(RightNavDrawerIcon).toggleClass('openIcon closedIcon');
|
||||
slideToggle(RightNavPanel, getSlideToggleOptions());
|
||||
$(RightNavDrawerIcon).toggleClass('closedIcon openIcon');
|
||||
$(RightNavPanel).toggleClass('openDrawer closedDrawer');
|
||||
}
|
||||
}
|
||||
});
|
||||
$(LPanelPin).on('click', function () {
|
||||
SaveLocal('LNavLockOn', $(LPanelPin).prop('checked'));
|
||||
accountStorage.setItem('LNavLockOn', $(LPanelPin).prop('checked'));
|
||||
if ($(LPanelPin).prop('checked') == true) {
|
||||
//console.log('adding pin class to Left nav');
|
||||
$(LeftNavPanel).addClass('pinnedOpen');
|
||||
@@ -766,15 +790,15 @@ export function initRossMods() {
|
||||
$(LeftNavDrawerIcon).removeClass('drawerPinnedOpen');
|
||||
|
||||
if ($(LeftNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {
|
||||
$(LeftNavPanel).slideToggle(200, 'swing');
|
||||
$(LeftNavDrawerIcon).toggleClass('openIcon closedIcon');
|
||||
slideToggle(LeftNavPanel, getSlideToggleOptions());
|
||||
$(LeftNavDrawerIcon).toggleClass('closedIcon openIcon');
|
||||
$(LeftNavPanel).toggleClass('openDrawer closedDrawer');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(WIPanelPin).on('click', function () {
|
||||
SaveLocal('WINavLockOn', $(WIPanelPin).prop('checked'));
|
||||
accountStorage.setItem('WINavLockOn', $(WIPanelPin).prop('checked'));
|
||||
if ($(WIPanelPin).prop('checked') == true) {
|
||||
console.debug('adding pin class to WI');
|
||||
$(WorldInfo).addClass('pinnedOpen');
|
||||
@@ -786,16 +810,16 @@ export function initRossMods() {
|
||||
|
||||
if ($(WorldInfo).hasClass('openDrawer') && $('.openDrawer').length > 1) {
|
||||
console.debug('closing WI after lock removal');
|
||||
$(WorldInfo).slideToggle(200, 'swing');
|
||||
$(WIDrawerIcon).toggleClass('openIcon closedIcon');
|
||||
slideToggle(WorldInfo, getSlideToggleOptions());
|
||||
$(WIDrawerIcon).toggleClass('closedIcon openIcon');
|
||||
$(WorldInfo).toggleClass('openDrawer closedDrawer');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// read the state of right Nav Lock and apply to rightnav classlist
|
||||
$(RPanelPin).prop('checked', LoadLocalBool('NavLockOn'));
|
||||
if (LoadLocalBool('NavLockOn') == true) {
|
||||
$(RPanelPin).prop('checked', accountStorage.getItem('NavLockOn') == 'true');
|
||||
if (accountStorage.getItem('NavLockOn') == 'true') {
|
||||
//console.log('setting pin class via local var');
|
||||
$(RightNavPanel).addClass('pinnedOpen');
|
||||
$(RightNavDrawerIcon).addClass('drawerPinnedOpen');
|
||||
@@ -806,8 +830,8 @@ export function initRossMods() {
|
||||
$(RightNavDrawerIcon).addClass('drawerPinnedOpen');
|
||||
}
|
||||
// read the state of left Nav Lock and apply to leftnav classlist
|
||||
$(LPanelPin).prop('checked', LoadLocalBool('LNavLockOn'));
|
||||
if (LoadLocalBool('LNavLockOn') == true) {
|
||||
$(LPanelPin).prop('checked', accountStorage.getItem('LNavLockOn') === 'true');
|
||||
if (accountStorage.getItem('LNavLockOn') == 'true') {
|
||||
//console.log('setting pin class via local var');
|
||||
$(LeftNavPanel).addClass('pinnedOpen');
|
||||
$(LeftNavDrawerIcon).addClass('drawerPinnedOpen');
|
||||
@@ -819,8 +843,8 @@ export function initRossMods() {
|
||||
}
|
||||
|
||||
// read the state of left Nav Lock and apply to leftnav classlist
|
||||
$(WIPanelPin).prop('checked', LoadLocalBool('WINavLockOn'));
|
||||
if (LoadLocalBool('WINavLockOn') == true) {
|
||||
$(WIPanelPin).prop('checked', accountStorage.getItem('WINavLockOn') === 'true');
|
||||
if (accountStorage.getItem('WINavLockOn') == 'true') {
|
||||
//console.log('setting pin class via local var');
|
||||
$(WorldInfo).addClass('pinnedOpen');
|
||||
$(WIDrawerIcon).addClass('drawerPinnedOpen');
|
||||
@@ -835,22 +859,22 @@ export function initRossMods() {
|
||||
//save state of Right nav being open or closed
|
||||
$('#rightNavDrawerIcon').on('click', function () {
|
||||
if (!$('#rightNavDrawerIcon').hasClass('openIcon')) {
|
||||
SaveLocal('NavOpened', 'true');
|
||||
} else { SaveLocal('NavOpened', 'false'); }
|
||||
accountStorage.setItem('NavOpened', 'true');
|
||||
} else { accountStorage.setItem('NavOpened', 'false'); }
|
||||
});
|
||||
|
||||
//save state of Left nav being open or closed
|
||||
$('#leftNavDrawerIcon').on('click', function () {
|
||||
if (!$('#leftNavDrawerIcon').hasClass('openIcon')) {
|
||||
SaveLocal('LNavOpened', 'true');
|
||||
} else { SaveLocal('LNavOpened', 'false'); }
|
||||
accountStorage.setItem('LNavOpened', 'true');
|
||||
} else { accountStorage.setItem('LNavOpened', 'false'); }
|
||||
});
|
||||
|
||||
//save state of Left nav being open or closed
|
||||
$('#WorldInfo').on('click', function () {
|
||||
if (!$('#WorldInfo').hasClass('openIcon')) {
|
||||
SaveLocal('WINavOpened', 'true');
|
||||
} else { SaveLocal('WINavOpened', 'false'); }
|
||||
accountStorage.setItem('WINavOpened', 'true');
|
||||
} else { accountStorage.setItem('WINavOpened', 'false'); }
|
||||
});
|
||||
|
||||
var chatbarInFocus = false;
|
||||
@@ -866,27 +890,60 @@ export function initRossMods() {
|
||||
OpenNavPanels();
|
||||
}, 300);
|
||||
|
||||
$(SelectedCharacterTab).click(function () { SaveLocal('SelectedNavTab', 'rm_button_selected_ch'); });
|
||||
$('#rm_button_characters').click(function () { SaveLocal('SelectedNavTab', 'rm_button_characters'); });
|
||||
$(SelectedCharacterTab).click(function () { accountStorage.setItem('SelectedNavTab', 'rm_button_selected_ch'); });
|
||||
$('#rm_button_characters').click(function () { accountStorage.setItem('SelectedNavTab', 'rm_button_characters'); });
|
||||
|
||||
// when a char is selected from the list, save them as the auto-load character for next page load
|
||||
|
||||
// when a char is selected from the list, save their name as the auto-load character for next page load
|
||||
$(document).on('click', '.character_select', function () {
|
||||
const characterId = $(this).attr('chid') || $(this).data('id');
|
||||
const characterId = $(this).attr('data-chid');
|
||||
setActiveCharacter(characterId);
|
||||
setActiveGroup(null);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$(document).on('click', '.group_select', function () {
|
||||
const groupId = $(this).attr('chid') || $(this).attr('grid') || $(this).data('id');
|
||||
const groupId = $(this).attr('data-chid') || $(this).attr('data-grid');
|
||||
setActiveCharacter(null);
|
||||
setActiveGroup(groupId);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
const cssAutofit = CSS.supports('field-sizing', 'content');
|
||||
|
||||
if (cssAutofit) {
|
||||
let lastHeight = chatBlock.offsetHeight;
|
||||
const chatBlockResizeObserver = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.target !== chatBlock) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const threshold = 1;
|
||||
const newHeight = chatBlock.offsetHeight;
|
||||
const deltaHeight = newHeight - lastHeight;
|
||||
const isScrollAtBottom = Math.abs(chatBlock.scrollHeight - chatBlock.scrollTop - newHeight) <= threshold;
|
||||
|
||||
if (!isScrollAtBottom && Math.abs(deltaHeight) > threshold) {
|
||||
chatBlock.scrollTop -= deltaHeight;
|
||||
}
|
||||
lastHeight = newHeight;
|
||||
}
|
||||
});
|
||||
|
||||
chatBlockResizeObserver.observe(chatBlock);
|
||||
}
|
||||
|
||||
sendTextArea.addEventListener('input', () => {
|
||||
saveUserInputDebounced();
|
||||
|
||||
if (cssAutofit) {
|
||||
// Unset modifications made with a manual resize
|
||||
sendTextArea.style.height = 'auto';
|
||||
return;
|
||||
}
|
||||
|
||||
const hasContent = sendTextArea.value !== '';
|
||||
const fitsCurrentSize = sendTextArea.scrollHeight <= sendTextArea.offsetHeight;
|
||||
const isScrollbarShown = sendTextArea.clientWidth < sendTextArea.offsetWidth;
|
||||
@@ -894,7 +951,6 @@ export function initRossMods() {
|
||||
const needsDebounce = hasContent && (fitsCurrentSize || (isScrollbarShown && isHalfScreenHeight));
|
||||
if (needsDebounce) autoFitSendTextAreaDebounced();
|
||||
else autoFitSendTextArea();
|
||||
saveUserInputDebounced();
|
||||
});
|
||||
|
||||
restoreUserInput();
|
||||
@@ -962,6 +1018,14 @@ export function initRossMods() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isModifiedKeyboardEvent(event) {
|
||||
return (event instanceof KeyboardEvent &&
|
||||
event.shiftKey ||
|
||||
event.ctrlKey ||
|
||||
event.altKey ||
|
||||
event.metaKey);
|
||||
}
|
||||
|
||||
$(document).on('keydown', async function (event) {
|
||||
await processHotkeys(event.originalEvent);
|
||||
});
|
||||
@@ -1029,14 +1093,21 @@ export function initRossMods() {
|
||||
// Ctrl+Enter for Regeneration Last Response. If editing, accept the edits instead
|
||||
if (event.ctrlKey && event.key == 'Enter') {
|
||||
const editMesDone = $('.mes_edit_done:visible');
|
||||
const reasoningMesDone = $('.mes_reasoning_edit_done:visible');
|
||||
if (editMesDone.length > 0) {
|
||||
console.debug('Accepting edits with Ctrl+Enter');
|
||||
$('#send_textarea').focus();
|
||||
$('#send_textarea').trigger('focus');
|
||||
editMesDone.trigger('click');
|
||||
return;
|
||||
} else if (is_send_press == false) {
|
||||
} else if (reasoningMesDone.length > 0) {
|
||||
console.debug('Accepting edits with Ctrl+Enter');
|
||||
$('#send_textarea').trigger('focus');
|
||||
reasoningMesDone.trigger('click');
|
||||
return;
|
||||
}
|
||||
else if (is_send_press == false) {
|
||||
const skipConfirmKey = 'RegenerateWithCtrlEnter';
|
||||
const skipConfirm = LoadLocalBool(skipConfirmKey);
|
||||
const skipConfirm = accountStorage.getItem(skipConfirmKey) === 'true';
|
||||
function doRegenerate() {
|
||||
console.debug('Regenerating with Ctrl+Enter');
|
||||
$('#option_regenerate').trigger('click');
|
||||
@@ -1048,13 +1119,15 @@ export function initRossMods() {
|
||||
let regenerateWithCtrlEnter = false;
|
||||
const result = await Popup.show.confirm('Regenerate Message', 'Are you sure you want to regenerate the latest message?', {
|
||||
customInputs: [{ id: 'regenerateWithCtrlEnter', label: 'Don\'t ask again' }],
|
||||
onClose: (popup) => regenerateWithCtrlEnter = popup.inputResults.get('regenerateWithCtrlEnter') ?? false,
|
||||
onClose: (popup) => {
|
||||
regenerateWithCtrlEnter = popup.inputResults.get('regenerateWithCtrlEnter') ?? false;
|
||||
},
|
||||
});
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
SaveLocal(skipConfirmKey, regenerateWithCtrlEnter);
|
||||
accountStorage.setItem(skipConfirmKey, String(regenerateWithCtrlEnter));
|
||||
doRegenerate();
|
||||
}
|
||||
return;
|
||||
@@ -1076,9 +1149,10 @@ export function initRossMods() {
|
||||
$('#send_textarea').val() === '' &&
|
||||
$('#character_popup').css('display') === 'none' &&
|
||||
$('#shadow_select_chat_popup').css('display') === 'none' &&
|
||||
!isInputElementInFocus()
|
||||
!isInputElementInFocus() &&
|
||||
!isModifiedKeyboardEvent(event)
|
||||
) {
|
||||
$('.swipe_left:last').click();
|
||||
$('.swipe_left:last').trigger('click', { source: 'keyboard', repeated: event.repeat });
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1089,9 +1163,10 @@ export function initRossMods() {
|
||||
$('#send_textarea').val() === '' &&
|
||||
$('#character_popup').css('display') === 'none' &&
|
||||
$('#shadow_select_chat_popup').css('display') === 'none' &&
|
||||
!isInputElementInFocus()
|
||||
!isInputElementInFocus() &&
|
||||
!isModifiedKeyboardEvent(event)
|
||||
) {
|
||||
$('.swipe_right:last').click();
|
||||
$('.swipe_right:last').trigger('click', { source: 'keyboard', repeated: event.repeat });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -299,7 +299,7 @@ function loadSettings() {
|
||||
$('#extension_floating_role').val(chat_metadata[metadata_keys.role]);
|
||||
$(`input[name="extension_floating_position"][value="${chat_metadata[metadata_keys.position]}"]`).prop('checked', true);
|
||||
|
||||
if (extension_settings.note.chara && getContext().characterId) {
|
||||
if (extension_settings.note.chara && getContext().characterId !== undefined) {
|
||||
const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());
|
||||
|
||||
$('#extension_floating_chara').val(charaNote ? charaNote.prompt : '');
|
||||
@@ -389,49 +389,49 @@ export function setFloatingPrompt() {
|
||||
}
|
||||
|
||||
function onANMenuItemClick() {
|
||||
if (selected_group || this_chid) {
|
||||
//show AN if it's hidden
|
||||
if ($('#floatingPrompt').css('display') !== 'flex') {
|
||||
$('#floatingPrompt').addClass('resizing');
|
||||
$('#floatingPrompt').css('display', 'flex');
|
||||
$('#floatingPrompt').css('opacity', 0.0);
|
||||
$('#floatingPrompt').transition({
|
||||
opacity: 1.0,
|
||||
duration: animation_duration,
|
||||
}, async function () {
|
||||
await delay(50);
|
||||
$('#floatingPrompt').removeClass('resizing');
|
||||
});
|
||||
|
||||
//auto-open the main AN inline drawer
|
||||
if ($('#ANBlockToggle')
|
||||
.siblings('.inline-drawer-content')
|
||||
.css('display') !== 'block') {
|
||||
$('#floatingPrompt').addClass('resizing');
|
||||
$('#ANBlockToggle').click();
|
||||
}
|
||||
} else {
|
||||
//hide AN if it's already displayed
|
||||
$('#floatingPrompt').addClass('resizing');
|
||||
$('#floatingPrompt').transition({
|
||||
opacity: 0.0,
|
||||
duration: animation_duration,
|
||||
},
|
||||
async function () {
|
||||
await delay(50);
|
||||
$('#floatingPrompt').removeClass('resizing');
|
||||
});
|
||||
setTimeout(function () {
|
||||
$('#floatingPrompt').hide();
|
||||
}, animation_duration);
|
||||
|
||||
}
|
||||
//duplicate options menu close handler from script.js
|
||||
//because this listener takes priority
|
||||
$('#options').stop().fadeOut(animation_duration);
|
||||
} else {
|
||||
if (!selected_group && this_chid === undefined) {
|
||||
toastr.warning(t`Select a character before trying to use Author's Note`, '', { timeOut: 2000 });
|
||||
return;
|
||||
}
|
||||
|
||||
//show AN if it's hidden
|
||||
if ($('#floatingPrompt').css('display') !== 'flex') {
|
||||
$('#floatingPrompt').addClass('resizing');
|
||||
$('#floatingPrompt').css('display', 'flex');
|
||||
$('#floatingPrompt').css('opacity', 0.0);
|
||||
$('#floatingPrompt').transition({
|
||||
opacity: 1.0,
|
||||
duration: animation_duration,
|
||||
}, async function () {
|
||||
await delay(50);
|
||||
$('#floatingPrompt').removeClass('resizing');
|
||||
});
|
||||
|
||||
//auto-open the main AN inline drawer
|
||||
if ($('#ANBlockToggle')
|
||||
.siblings('.inline-drawer-content')
|
||||
.css('display') !== 'block') {
|
||||
$('#floatingPrompt').addClass('resizing');
|
||||
$('#ANBlockToggle').click();
|
||||
}
|
||||
} else {
|
||||
//hide AN if it's already displayed
|
||||
$('#floatingPrompt').addClass('resizing');
|
||||
$('#floatingPrompt').transition({
|
||||
opacity: 0.0,
|
||||
duration: animation_duration,
|
||||
}, async function () {
|
||||
await delay(50);
|
||||
$('#floatingPrompt').removeClass('resizing');
|
||||
});
|
||||
setTimeout(function () {
|
||||
$('#floatingPrompt').hide();
|
||||
}, animation_duration);
|
||||
}
|
||||
|
||||
//duplicate options menu close handler from script.js
|
||||
//because this listener takes priority
|
||||
$('#options').stop().fadeOut(animation_duration);
|
||||
}
|
||||
|
||||
async function onChatChanged() {
|
||||
@@ -440,13 +440,13 @@ async function onChatChanged() {
|
||||
const context = getContext();
|
||||
|
||||
// Disable the chara note if in a group
|
||||
$('#extension_floating_chara').prop('disabled', context.groupId ? true : false);
|
||||
$('#extension_floating_chara').prop('disabled', !!context.groupId);
|
||||
|
||||
const tokenCounter1 = chat_metadata[metadata_keys.prompt] ? await getTokenCountAsync(chat_metadata[metadata_keys.prompt]) : 0;
|
||||
$('#extension_floating_prompt_token_counter').text(tokenCounter1);
|
||||
|
||||
let tokenCounter2;
|
||||
if (extension_settings.note.chara && context.characterId) {
|
||||
if (extension_settings.note.chara && context.characterId !== undefined) {
|
||||
const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());
|
||||
|
||||
if (charaNote) {
|
||||
@@ -566,7 +566,7 @@ export function initAuthorsNote() {
|
||||
namedArgumentList: [],
|
||||
unnamedArgumentList: [
|
||||
new SlashCommandArgument(
|
||||
'position', [ARGUMENT_TYPE.STRING], false, false, null, ['system', 'user', 'assistant'],
|
||||
'role', [ARGUMENT_TYPE.STRING], false, false, null, ['system', 'user', 'assistant'],
|
||||
),
|
||||
],
|
||||
helpString: `
|
||||
|
@@ -12,6 +12,7 @@ const LIST_METADATA_KEY = 'chat_backgrounds';
|
||||
export let background_settings = {
|
||||
name: '__transparent.png',
|
||||
url: generateUrlParameter('__transparent.png', false),
|
||||
fitting: 'classic',
|
||||
};
|
||||
|
||||
export function loadBackgroundSettings(settings) {
|
||||
@@ -19,7 +20,12 @@ export function loadBackgroundSettings(settings) {
|
||||
if (!backgroundSettings || !backgroundSettings.name || !backgroundSettings.url) {
|
||||
backgroundSettings = background_settings;
|
||||
}
|
||||
if (!backgroundSettings.fitting) {
|
||||
backgroundSettings.fitting = 'classic';
|
||||
}
|
||||
setBackground(backgroundSettings.name, backgroundSettings.url);
|
||||
setFittingClass(backgroundSettings.fitting);
|
||||
$('#background_fitting').val(backgroundSettings.fitting);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,8 +96,13 @@ function highlightLockedBackground() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the background for the current chat
|
||||
* @param {Event} e Click event
|
||||
* @returns {string} Empty string
|
||||
*/
|
||||
function onLockBackgroundClick(e) {
|
||||
e.stopPropagation();
|
||||
e?.stopPropagation();
|
||||
|
||||
const chatName = getCurrentChatId();
|
||||
|
||||
@@ -100,7 +111,7 @@ function onLockBackgroundClick(e) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const relativeBgImage = getUrlParameter(this);
|
||||
const relativeBgImage = getUrlParameter(this) ?? background_settings.url;
|
||||
|
||||
saveBackgroundMetadata(relativeBgImage);
|
||||
setCustomBackground();
|
||||
@@ -108,8 +119,13 @@ function onLockBackgroundClick(e) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the background for the current chat
|
||||
* @param {Event} e Click event
|
||||
* @returns {string} Empty string
|
||||
*/
|
||||
function onUnlockBackgroundClick(e) {
|
||||
e.stopPropagation();
|
||||
e?.stopPropagation();
|
||||
removeBackgroundMetadata();
|
||||
unsetCustomBackground();
|
||||
highlightLockedBackground();
|
||||
@@ -333,6 +349,14 @@ async function autoBackgroundCommand() {
|
||||
const bestMatch = fuse.search(reply, { limit: 1 });
|
||||
|
||||
if (bestMatch.length == 0) {
|
||||
for (const option of options) {
|
||||
if (String(reply).toLowerCase().includes(option.text.toLowerCase())) {
|
||||
console.debug('Fallback choosing background:', option);
|
||||
option.element.click();
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
toastr.warning('No match found. Please try again.');
|
||||
return '';
|
||||
}
|
||||
@@ -462,6 +486,18 @@ function highlightNewBackground(bg) {
|
||||
flashHighlight(newBg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fitting class for the background element
|
||||
* @param {string} fitting Fitting type
|
||||
*/
|
||||
function setFittingClass(fitting) {
|
||||
const backgrounds = $('#bg1, #bg_custom');
|
||||
for (const option of ['cover', 'contain', 'stretch', 'center']) {
|
||||
backgrounds.toggleClass(option, option === fitting);
|
||||
}
|
||||
background_settings.fitting = fitting;
|
||||
}
|
||||
|
||||
function onBackgroundFilterInput() {
|
||||
const filterValue = String($(this).val()).toLowerCase();
|
||||
$('#bg_menu_content > div').each(function () {
|
||||
@@ -487,12 +523,12 @@ export function initBackgrounds() {
|
||||
$('#add_bg_button').on('change', onBackgroundUploadSelected);
|
||||
$('#bg-filter').on('input', onBackgroundFilterInput);
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'lockbg',
|
||||
callback: onLockBackgroundClick,
|
||||
callback: () => onLockBackgroundClick(new CustomEvent('click')),
|
||||
aliases: ['bglock'],
|
||||
helpString: 'Locks a background for the currently selected chat',
|
||||
}));
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'unlockbg',
|
||||
callback: onUnlockBackgroundClick,
|
||||
callback: () => onUnlockBackgroundClick(new CustomEvent('click')),
|
||||
aliases: ['bgunlock'],
|
||||
helpString: 'Unlocks a background for the currently selected chat',
|
||||
}));
|
||||
@@ -502,4 +538,9 @@ export function initBackgrounds() {
|
||||
helpString: 'Automatically changes the background based on the chat context using the AI request prompt',
|
||||
}));
|
||||
|
||||
$('#background_fitting').on('input', function () {
|
||||
background_settings.fitting = String($(this).val());
|
||||
setFittingClass(background_settings.fitting);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
}
|
||||
|