mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-01-20 05:18:17 -05:00
Compare commits
776 Commits
v6.2.0a1
...
controlnet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21a05f4287 | ||
|
|
efcb1bea7f | ||
|
|
e0d7a401f3 | ||
|
|
aac979e9a4 | ||
|
|
3b0d7f076d | ||
|
|
e1acbcdbd5 | ||
|
|
7d9b81550b | ||
|
|
6a447dd1fe | ||
|
|
c2dc63ddbc | ||
|
|
1bc689d531 | ||
|
|
4829975827 | ||
|
|
49da4e00c3 | ||
|
|
89dfe5e729 | ||
|
|
6816d366df | ||
|
|
9d3d2a36c9 | ||
|
|
ed231044c8 | ||
|
|
b51a232794 | ||
|
|
4412143a6e | ||
|
|
de11cafdb3 | ||
|
|
4d9114aa7d | ||
|
|
67e2da1ebf | ||
|
|
33ecc591c3 | ||
|
|
b57459a226 | ||
|
|
01282b1c90 | ||
|
|
3f302906dc | ||
|
|
81d56596fb | ||
|
|
b536b0df0c | ||
|
|
692af1d93d | ||
|
|
bb7ef77b50 | ||
|
|
1862548573 | ||
|
|
242c1b6350 | ||
|
|
fc6e4bb04e | ||
|
|
20841abca6 | ||
|
|
e8b69d99a4 | ||
|
|
d6eaff8237 | ||
|
|
068b095956 | ||
|
|
f795a47340 | ||
|
|
df47345eb0 | ||
|
|
def04095a4 | ||
|
|
28be8f0911 | ||
|
|
b50c44bac0 | ||
|
|
b4ce0e02fc | ||
|
|
d6442d9a34 | ||
|
|
4528bcafaf | ||
|
|
8b82b81ee2 | ||
|
|
757acdd49e | ||
|
|
94b7cc583a | ||
|
|
b663a6bac4 | ||
|
|
65d40153fb | ||
|
|
c8b741a514 | ||
|
|
6d3aeffed9 | ||
|
|
203be96910 | ||
|
|
b0aa48ddb8 | ||
|
|
867dbe51e5 | ||
|
|
ff8948b6f1 | ||
|
|
fa3a6425a6 | ||
|
|
c5992ece89 | ||
|
|
12a6239929 | ||
|
|
e9238c59f4 | ||
|
|
c1cbbe51d6 | ||
|
|
4219b4a288 | ||
|
|
48c8a9c09d | ||
|
|
a67efdf4ad | ||
|
|
d6ff9c2e49 | ||
|
|
e768a3bc7b | ||
|
|
7273700f61 | ||
|
|
f909e81d91 | ||
|
|
8c85f168f6 | ||
|
|
263d86d46f | ||
|
|
0921805160 | ||
|
|
517f4811e7 | ||
|
|
0dc73c8803 | ||
|
|
26702b54c0 | ||
|
|
2d65e4543f | ||
|
|
309113956b | ||
|
|
0ac4099bc6 | ||
|
|
899dc739fa | ||
|
|
4e2439fc8e | ||
|
|
00864c24e0 | ||
|
|
b73aaa7d6f | ||
|
|
85057ae704 | ||
|
|
c3fb3a43a2 | ||
|
|
51d0a15a1b | ||
|
|
5991067fd9 | ||
|
|
32c2d3f740 | ||
|
|
c661f86b34 | ||
|
|
cc72d8eab4 | ||
|
|
e8550f9355 | ||
|
|
a1d0386ca4 | ||
|
|
495d089f85 | ||
|
|
913b91e9dd | ||
|
|
3e907f4e14 | ||
|
|
756df6ebe4 | ||
|
|
2a6be99152 | ||
|
|
3099e2bf9d | ||
|
|
6921f0412a | ||
|
|
022d5a8863 | ||
|
|
af99beedc5 | ||
|
|
f3d83dc6b7 | ||
|
|
ebc3f18a1a | ||
|
|
aeb512f8d9 | ||
|
|
a1810acb93 | ||
|
|
aa35a5083b | ||
|
|
4f17de0b32 | ||
|
|
370c3cd59b | ||
|
|
67214e16c0 | ||
|
|
4880a1d946 | ||
|
|
0f0988610f | ||
|
|
6805d28b7a | ||
|
|
9b45a24136 | ||
|
|
4e9d66a64b | ||
|
|
8fec530b0f | ||
|
|
50c66f8671 | ||
|
|
f0aa39ea81 | ||
|
|
faac814a3d | ||
|
|
fb9545bb90 | ||
|
|
8ad2ee83b6 | ||
|
|
f8ad62b5eb | ||
|
|
03ae78bc7c | ||
|
|
ec1a058dbe | ||
|
|
9e4d441e2e | ||
|
|
3770fd22f8 | ||
|
|
a0232b0e63 | ||
|
|
e1e964bf0e | ||
|
|
1b1759cffc | ||
|
|
d828502bc8 | ||
|
|
7a073b6de7 | ||
|
|
338ff8d588 | ||
|
|
a3625efd3a | ||
|
|
5efb37fe63 | ||
|
|
aef0b81d5b | ||
|
|
544edff507 | ||
|
|
42b1adab22 | ||
|
|
a2b9d12e88 | ||
|
|
7a94fb6c04 | ||
|
|
efcd159704 | ||
|
|
997e619a9d | ||
|
|
4bc184ff16 | ||
|
|
0b605a745b | ||
|
|
22b038ce3b | ||
|
|
0bb5d647b5 | ||
|
|
4a3599929b | ||
|
|
f959ce8323 | ||
|
|
74e1047870 | ||
|
|
732881c51b | ||
|
|
107be8e166 | ||
|
|
3c2f654da8 | ||
|
|
474fd44e50 | ||
|
|
0dc5f8fd65 | ||
|
|
d4215fb460 | ||
|
|
0cd05ee9fd | ||
|
|
9fcb3af1d8 | ||
|
|
c9da7e2172 | ||
|
|
9788735d6b | ||
|
|
d6139748e2 | ||
|
|
602dfb1e5d | ||
|
|
5bb3a78f56 | ||
|
|
d58df1e17b | ||
|
|
5d0e37eb2f | ||
|
|
486b333cef | ||
|
|
6fa437af03 | ||
|
|
787ef6fa27 | ||
|
|
7f0571c229 | ||
|
|
f5a58c0ceb | ||
|
|
d16eef4e66 | ||
|
|
681ff2b2b3 | ||
|
|
0d81b4ce98 | ||
|
|
99f1667ced | ||
|
|
aa5597ab4d | ||
|
|
9bbb8e8a5e | ||
|
|
f284d282c1 | ||
|
|
4231488da6 | ||
|
|
a014867e68 | ||
|
|
22654fbc9c | ||
|
|
daa4fd751c | ||
|
|
3fd265c333 | ||
|
|
26a3a9130c | ||
|
|
3dfeaab4b2 | ||
|
|
a33707cc76 | ||
|
|
21e13daf6e | ||
|
|
fa2614ee02 | ||
|
|
4be6ddb23d | ||
|
|
bba0e01926 | ||
|
|
20d57d5ccf | ||
|
|
d9121271a2 | ||
|
|
30b487c71c | ||
|
|
8a81c05caf | ||
|
|
a0dceecab9 | ||
|
|
98945a4560 | ||
|
|
9610f34dd4 | ||
|
|
8a00d855b4 | ||
|
|
25430f04c5 | ||
|
|
b2b53c4481 | ||
|
|
c6696d7913 | ||
|
|
8bcb6648f1 | ||
|
|
0ee360ba6c | ||
|
|
09bbe3eef9 | ||
|
|
d14b7a48f5 | ||
|
|
1db55b0ffa | ||
|
|
3104a1baa6 | ||
|
|
0e523ca2c1 | ||
|
|
75daef2aba | ||
|
|
b036b18986 | ||
|
|
93535fa3c2 | ||
|
|
dcafb44f8a | ||
|
|
44b1d8d1fc | ||
|
|
6f70a6bd10 | ||
|
|
0546aeed1d | ||
|
|
8933f3f5dd | ||
|
|
29cdefe873 | ||
|
|
df299bb37f | ||
|
|
481fb42371 | ||
|
|
631a04b48c | ||
|
|
547e1941f4 | ||
|
|
031d25ed63 | ||
|
|
27f4af0eb4 | ||
|
|
e0a0617093 | ||
|
|
e6a763b887 | ||
|
|
3c9c49f7d9 | ||
|
|
26690d47b7 | ||
|
|
fcaff6ce09 | ||
|
|
afd7296cb2 | ||
|
|
d6f42c76d5 | ||
|
|
68f39fe907 | ||
|
|
23a528545f | ||
|
|
c69d04a7f0 | ||
|
|
60f1e2d7ad | ||
|
|
cb386bec28 | ||
|
|
f29ceb3f12 | ||
|
|
4f51bc9421 | ||
|
|
0c41abab79 | ||
|
|
cb457c3402 | ||
|
|
606ad73814 | ||
|
|
fe70bd538a | ||
|
|
b5c7316c0a | ||
|
|
460aec03ea | ||
|
|
6730d86a13 | ||
|
|
c4bc03cb1f | ||
|
|
136ee28199 | ||
|
|
2c6d266c0a | ||
|
|
f779920eaa | ||
|
|
01bef5d165 | ||
|
|
72851d3e84 | ||
|
|
4ba85c62ca | ||
|
|
313aedb00a | ||
|
|
85bd324d74 | ||
|
|
4a04411e74 | ||
|
|
299a4db3bb | ||
|
|
390faa592c | ||
|
|
2463aeb84a | ||
|
|
ec8df163d1 | ||
|
|
a198b7da78 | ||
|
|
fb11770852 | ||
|
|
6b6f3d56f7 | ||
|
|
29d00eef9a | ||
|
|
6972cd708d | ||
|
|
82893804ff | ||
|
|
47ffe365bc | ||
|
|
f7b03b1e63 | ||
|
|
356e38e82a | ||
|
|
5ea077bb8c | ||
|
|
3c4b303555 | ||
|
|
b8651cb1a2 | ||
|
|
a6527c0ba1 | ||
|
|
6e40eca754 | ||
|
|
53fab17c33 | ||
|
|
3876d88b3c | ||
|
|
82b4526691 | ||
|
|
f56ba11394 | ||
|
|
32eb5190f2 | ||
|
|
72e378789d | ||
|
|
f10ddb0cab | ||
|
|
286127077d | ||
|
|
36278bc044 | ||
|
|
7a1c7ca43a | ||
|
|
8303d567d5 | ||
|
|
1fe19c1242 | ||
|
|
127a43865c | ||
|
|
24a48884cb | ||
|
|
47cee816fd | ||
|
|
90bacaddda | ||
|
|
c0cc9f421e | ||
|
|
dbb9032648 | ||
|
|
b9e32e59a2 | ||
|
|
545a1d8737 | ||
|
|
c4718403a2 | ||
|
|
eb308b1ff7 | ||
|
|
a277bea804 | ||
|
|
30619c0420 | ||
|
|
504d8e32be | ||
|
|
f21229cd14 | ||
|
|
640ec676c3 | ||
|
|
6370412e9c | ||
|
|
edec2c2775 | ||
|
|
bd38be31d8 | ||
|
|
b938ae0a7e | ||
|
|
6e5b1ed55f | ||
|
|
5970bd38c2 | ||
|
|
e046417cf5 | ||
|
|
27a2cd19bd | ||
|
|
0df631b802 | ||
|
|
5bb7cd168d | ||
|
|
b4ba84ad35 | ||
|
|
d1628f51c9 | ||
|
|
17c1304ce2 | ||
|
|
cc9a85f7d0 | ||
|
|
7e2999649a | ||
|
|
1473142f73 | ||
|
|
49343546e7 | ||
|
|
39d5879405 | ||
|
|
4b4ec29a09 | ||
|
|
dc6811076f | ||
|
|
0568784ee9 | ||
|
|
895eac6bcd | ||
|
|
fe0efa9bdf | ||
|
|
acabc8bd54 | ||
|
|
89f999af08 | ||
|
|
9ae76bef51 | ||
|
|
0999b43616 | ||
|
|
e6e4f58163 | ||
|
|
b371930e02 | ||
|
|
9b50e2303b | ||
|
|
49d1810991 | ||
|
|
b1b009f7b8 | ||
|
|
3431e6385c | ||
|
|
5db1027d32 | ||
|
|
579f182fe9 | ||
|
|
55bf41f63f | ||
|
|
fc32fd2d2e | ||
|
|
a2b6536078 | ||
|
|
144c54a6c8 | ||
|
|
ca40daeb97 | ||
|
|
e600cdc826 | ||
|
|
b7c52f33dc | ||
|
|
e78157fcf0 | ||
|
|
7d7b98249f | ||
|
|
f5bf84f304 | ||
|
|
c30d5bece2 | ||
|
|
27845b2f1b | ||
|
|
bad6eea077 | ||
|
|
9c26ac5ce3 | ||
|
|
b7306bb5c9 | ||
|
|
0c115177b2 | ||
|
|
5aae41b5bb | ||
|
|
7ad09a2f79 | ||
|
|
5a6d3639b7 | ||
|
|
84617d3df2 | ||
|
|
e05f30749e | ||
|
|
88a2e27338 | ||
|
|
15a6fd76c8 | ||
|
|
6adb46a86c | ||
|
|
e8a74eb79d | ||
|
|
dcd716c384 | ||
|
|
56697635dd | ||
|
|
5b5657e292 | ||
|
|
ad3dfbe1ed | ||
|
|
59ddc4f7b0 | ||
|
|
4653b79f12 | ||
|
|
778d6f167f | ||
|
|
05c71f50f1 | ||
|
|
406e0be39c | ||
|
|
0d71234a12 | ||
|
|
e38019bb70 | ||
|
|
a879880b42 | ||
|
|
71c8accbfe | ||
|
|
154fb99daf | ||
|
|
0df476ce13 | ||
|
|
e7ad830fa9 | ||
|
|
e81e0a8286 | ||
|
|
d0f7e72cbb | ||
|
|
fdead4fb8c | ||
|
|
31c9945b32 | ||
|
|
22de8a4b12 | ||
|
|
89cb3c3230 | ||
|
|
7bb99ece4e | ||
|
|
28f040123f | ||
|
|
1be3a4db64 | ||
|
|
cb44c995d2 | ||
|
|
9b9b35c315 | ||
|
|
f6edab6032 | ||
|
|
f79665b023 | ||
|
|
6b1bc7a87d | ||
|
|
c6f2994c84 | ||
|
|
0cff67ff23 | ||
|
|
e957c11c9a | ||
|
|
4baa685c7a | ||
|
|
1bd5907a12 | ||
|
|
2fd56e6029 | ||
|
|
b0548edc8c | ||
|
|
41d781176f | ||
|
|
8709de0b33 | ||
|
|
af43fe2fd4 | ||
|
|
ebbb11c3b1 | ||
|
|
0fc8c08da3 | ||
|
|
bfadcffe3c | ||
|
|
49c2332c13 | ||
|
|
dacef158c4 | ||
|
|
0c34d8201e | ||
|
|
77132075ff | ||
|
|
f008d3b0b2 | ||
|
|
4e66ccefe8 | ||
|
|
5d0ed45326 | ||
|
|
379d633ac6 | ||
|
|
93bba1b692 | ||
|
|
667e175ab7 | ||
|
|
de146aa4aa | ||
|
|
ed9c2c8208 | ||
|
|
9d984878f3 | ||
|
|
585eb8c69d | ||
|
|
c105bae127 | ||
|
|
c39f26266f | ||
|
|
47dffd123a | ||
|
|
b946ec3172 | ||
|
|
024c02329d | ||
|
|
4b43b59472 | ||
|
|
d11f115e1a | ||
|
|
92253ce854 | ||
|
|
0ebbfa90c9 | ||
|
|
fdfee11e37 | ||
|
|
6091bf4f60 | ||
|
|
07271ca468 | ||
|
|
3971382a6d | ||
|
|
0d827d8306 | ||
|
|
ec793cb636 | ||
|
|
e4f24c4dc4 | ||
|
|
a6b0581939 | ||
|
|
2a6cfde488 | ||
|
|
8c2e6a3988 | ||
|
|
0b05b24e9a | ||
|
|
842d729ec8 | ||
|
|
8642e8881d | ||
|
|
239fb86a46 | ||
|
|
269d4fe670 | ||
|
|
20813b5615 | ||
|
|
36c16d2781 | ||
|
|
3ae99df091 | ||
|
|
431fd83a43 | ||
|
|
ab41f71a36 | ||
|
|
1f526a1c27 | ||
|
|
8a60def51f | ||
|
|
4845d31857 | ||
|
|
0de5097207 | ||
|
|
505c75a5ab | ||
|
|
4c32b2a123 | ||
|
|
b2ed3c99d4 | ||
|
|
8eb3f40e1b | ||
|
|
9fcba3b876 | ||
|
|
5cabc37a87 | ||
|
|
c5a76806c1 | ||
|
|
bc6dd12083 | ||
|
|
41e1697e79 | ||
|
|
378f33bc92 | ||
|
|
1bf25fadb3 | ||
|
|
6a20271dba | ||
|
|
e36490c2ec | ||
|
|
d4378d9f2a | ||
|
|
1cc6893d0d | ||
|
|
b16d1a943d | ||
|
|
6c375b228e | ||
|
|
23cde86bc4 | ||
|
|
c6f2d127ef | ||
|
|
fb0a924918 | ||
|
|
2d9c82da85 | ||
|
|
7e031e9c01 | ||
|
|
26fe937d97 | ||
|
|
55139bb169 | ||
|
|
6a7fe6668b | ||
|
|
f5fdba795a | ||
|
|
84dc4e4ea9 | ||
|
|
24f22d539f | ||
|
|
89efe9c2b1 | ||
|
|
fbf8aa17c8 | ||
|
|
e55d39a20b | ||
|
|
3a1cedbced | ||
|
|
3d9889e272 | ||
|
|
b2026d9c00 | ||
|
|
f631b5178f | ||
|
|
8df3067599 | ||
|
|
b377b80446 | ||
|
|
7828102b67 | ||
|
|
1b0d599dc2 | ||
|
|
aa4e3adadb | ||
|
|
637d19c22b | ||
|
|
45b4432833 | ||
|
|
b71829a827 | ||
|
|
d95a698ebd | ||
|
|
49d569ec59 | ||
|
|
6ef1c2a5e1 | ||
|
|
0ec6d33086 | ||
|
|
64dfa125d2 | ||
|
|
67042e6dec | ||
|
|
a918198d4f | ||
|
|
288ac0a293 | ||
|
|
963c2ec60c | ||
|
|
79e8482b27 | ||
|
|
f98bbc32dd | ||
|
|
9380d8901c | ||
|
|
67de3f2d9b | ||
|
|
530d20c1be | ||
|
|
4d8bcad15b | ||
|
|
5c93e53195 | ||
|
|
e9c4e12454 | ||
|
|
295b5a20a8 | ||
|
|
eff9c7b92f | ||
|
|
07565d4015 | ||
|
|
94ba840948 | ||
|
|
bd251f8cce | ||
|
|
97719b0aab | ||
|
|
e89266bfe3 | ||
|
|
453ef1a220 | ||
|
|
faf8f0f291 | ||
|
|
5d36499982 | ||
|
|
151d67a0cc | ||
|
|
72431ff197 | ||
|
|
0de1feed76 | ||
|
|
7ffb626dbe | ||
|
|
79753289b1 | ||
|
|
bac4c05fd9 | ||
|
|
8a3b5d2c6f | ||
|
|
309578c19a | ||
|
|
fd58e1d0f2 | ||
|
|
04ffb979ce | ||
|
|
35c00d5a83 | ||
|
|
c2b49d58f5 | ||
|
|
6ff6b40a35 | ||
|
|
1f1beda567 | ||
|
|
91d62eb242 | ||
|
|
013e02d08b | ||
|
|
115053972c | ||
|
|
bcab754ac2 | ||
|
|
f1a542aca2 | ||
|
|
0701cc63a1 | ||
|
|
9337710b45 | ||
|
|
592ef5a9ee | ||
|
|
5fe39a3ae9 | ||
|
|
1888c586ca | ||
|
|
88922a467e | ||
|
|
84115e598c | ||
|
|
370fc67777 | ||
|
|
fa810e1d02 | ||
|
|
ec5043aa83 | ||
|
|
9a2a0cef74 | ||
|
|
c205c1d19e | ||
|
|
ae1a815453 | ||
|
|
687bc281e5 | ||
|
|
567316d753 | ||
|
|
53ac7c9d2c | ||
|
|
90be2a0cdf | ||
|
|
c7fb8f69ae | ||
|
|
7fecb8e88b | ||
|
|
ee6a2a6603 | ||
|
|
2496ac19c4 | ||
|
|
e34ed199c9 | ||
|
|
569533ef80 | ||
|
|
dfac73f9f0 | ||
|
|
f4219d5db3 | ||
|
|
04d1958e93 | ||
|
|
47d7d93e78 | ||
|
|
0e17950949 | ||
|
|
b0cfdc94b5 | ||
|
|
bb153b55d3 | ||
|
|
93ef637d59 | ||
|
|
c5689ca1a7 | ||
|
|
008e421ad4 | ||
|
|
28a77ab06c | ||
|
|
be48d3c12d | ||
|
|
518b21a49a | ||
|
|
68825ca9eb | ||
|
|
73c5f0b479 | ||
|
|
7b4e04cd7c | ||
|
|
ae4368fabe | ||
|
|
df8e39a9e1 | ||
|
|
45b43de571 | ||
|
|
6d18a72a05 | ||
|
|
af58a75e97 | ||
|
|
fd4c3bd27a | ||
|
|
1f8a60ded2 | ||
|
|
b1b677997d | ||
|
|
f17b43d736 | ||
|
|
c009a50489 | ||
|
|
97a16c455c | ||
|
|
a8a07598c8 | ||
|
|
23206e22e8 | ||
|
|
f4aba52b90 | ||
|
|
d17c273939 | ||
|
|
aeb5e7d50a | ||
|
|
580ad30832 | ||
|
|
6390f7d734 | ||
|
|
5ddbfefb6a | ||
|
|
bbf5ed7956 | ||
|
|
19cd6eed08 | ||
|
|
9c1eb263a8 | ||
|
|
75755189a7 | ||
|
|
a9ab72d27d | ||
|
|
678eb34995 | ||
|
|
ef7050f560 | ||
|
|
9787d9de74 | ||
|
|
bb4a50bab2 | ||
|
|
f3554b4e1b | ||
|
|
9dcb025241 | ||
|
|
ecf646066a | ||
|
|
3fd10b68cd | ||
|
|
6e32c7993c | ||
|
|
8329533848 | ||
|
|
fc7157b029 | ||
|
|
a1897f7490 | ||
|
|
a89b3efd14 | ||
|
|
5259693ed1 | ||
|
|
d77c24206d | ||
|
|
c5069557f3 | ||
|
|
9b220f61bd | ||
|
|
7fc3af12cc | ||
|
|
e2721b46b6 | ||
|
|
17118a04bd | ||
|
|
24788e3c83 | ||
|
|
056387c981 | ||
|
|
8a43d90273 | ||
|
|
4f9b9760db | ||
|
|
fdaddafa56 | ||
|
|
23d59abbd7 | ||
|
|
cf7fa5bce8 | ||
|
|
39e41998bb | ||
|
|
c6eff71b74 | ||
|
|
6ea4c47757 | ||
|
|
91f91aa835 | ||
|
|
ea7868d076 | ||
|
|
7d86f00d82 | ||
|
|
7785061e7d | ||
|
|
3370052e54 | ||
|
|
325dacd29c | ||
|
|
f4981a6ba9 | ||
|
|
8c159942eb | ||
|
|
deb4dc64af | ||
|
|
1a11437b6f | ||
|
|
04572c94ad | ||
|
|
1e9e78089e | ||
|
|
e65f93663d | ||
|
|
2a796fe25e | ||
|
|
61ff9ee3a7 | ||
|
|
111408c046 | ||
|
|
d7619d465e | ||
|
|
8ad4f6e56d | ||
|
|
bf4899526f | ||
|
|
6435d265c6 | ||
|
|
3163ef454d | ||
|
|
7ea636df70 | ||
|
|
1869824803 | ||
|
|
66fc8af8a6 | ||
|
|
48cb6b12f0 | ||
|
|
68e30a9864 | ||
|
|
f65dc2c081 | ||
|
|
0cd77443a7 | ||
|
|
185ed86424 | ||
|
|
fed817ab83 | ||
|
|
e0b45db69a | ||
|
|
2beac1fb04 | ||
|
|
e522de33f8 | ||
|
|
d591b50c25 | ||
|
|
b365aad6d8 | ||
|
|
65ad392361 | ||
|
|
56d75e1c77 | ||
|
|
df77a12efe | ||
|
|
faf662d12e | ||
|
|
44a7dfd486 | ||
|
|
bb15e5cf06 | ||
|
|
1a1c846be3 | ||
|
|
93c896a370 | ||
|
|
053d7c8c8e | ||
|
|
5296263954 | ||
|
|
a36b70c01c | ||
|
|
854a2a5a7a | ||
|
|
f9c64b0609 | ||
|
|
5889fa536a | ||
|
|
0e71ba892f | ||
|
|
d766a21223 | ||
|
|
5c8c54eab8 | ||
|
|
f296f4525c | ||
|
|
7c9ba4cb52 | ||
|
|
6784fd5b43 | ||
|
|
11d68cc646 | ||
|
|
ea8c877025 | ||
|
|
7a3c2332dd | ||
|
|
3835fd2f72 | ||
|
|
6f8746040c | ||
|
|
35e3940a09 | ||
|
|
415616d83f | ||
|
|
afb67efef9 | ||
|
|
1ed1fefa60 | ||
|
|
fa94a05c77 | ||
|
|
7a23d8266f | ||
|
|
a44de079dd | ||
|
|
c3c1a3edd8 | ||
|
|
ea26b5b147 | ||
|
|
4226b741b1 | ||
|
|
1424b7c254 | ||
|
|
933fb2294c | ||
|
|
5a181ee0fd | ||
|
|
3b0d59e459 | ||
|
|
fec296e41d | ||
|
|
ae4e38c6d0 | ||
|
|
a9f3f1a4b2 | ||
|
|
8a73df4fe1 | ||
|
|
ea2e1ea8f0 | ||
|
|
e8aa91931d | ||
|
|
8d22a314a6 | ||
|
|
57ce2b8aa7 | ||
|
|
6b810cb3fb | ||
|
|
4f3a5dcc43 | ||
|
|
c3ae14cf73 | ||
|
|
b9c44b92d5 | ||
|
|
5a68b4ddbc | ||
|
|
18a722839b | ||
|
|
7370cb9be6 | ||
|
|
cc4df52f82 | ||
|
|
1cb4ef05a4 | ||
|
|
7da141101c | ||
|
|
2571e199c5 | ||
|
|
79e93f905e | ||
|
|
f562e4f835 | ||
|
|
47e220aaf3 | ||
|
|
9365154bfe | ||
|
|
afc6911c96 | ||
|
|
afa1ee7ffd | ||
|
|
5a102f6b53 | ||
|
|
af345a33f3 | ||
|
|
038b110a82 | ||
|
|
f3cd49d46e | ||
|
|
ca7d7c9d93 | ||
|
|
1addeb4b59 | ||
|
|
6ea4884b0c | ||
|
|
aed9b1013e | ||
|
|
6962536b4a | ||
|
|
7e59d040aa | ||
|
|
e7c67da2c2 | ||
|
|
c44571bc36 | ||
|
|
ca257650d4 | ||
|
|
6a9962d2bb | ||
|
|
9492569a2c | ||
|
|
61e711620d | ||
|
|
3cf82505bb | ||
|
|
53bcbc58f5 | ||
|
|
42f3990f7a | ||
|
|
456205da17 | ||
|
|
ca0684700e | ||
|
|
6a702821ef | ||
|
|
682d271f6f | ||
|
|
e872c253b1 | ||
|
|
28633c9983 | ||
|
|
70ac58e64a | ||
|
|
e653837236 | ||
|
|
2bbfcc2f13 | ||
|
|
d6e0e439c5 | ||
|
|
26aab60f81 | ||
|
|
1cdd4b5980 | ||
|
|
89ceecc870 | ||
|
|
687cccdb99 | ||
|
|
c84f8465b8 | ||
|
|
4b5c481b7a | ||
|
|
2caa1b166d | ||
|
|
1b6ebede7b | ||
|
|
017d38eee2 | ||
|
|
78eb6b0338 | ||
|
|
3e8e0f6ddf | ||
|
|
8213f62d3b | ||
|
|
233740a40e | ||
|
|
8c5fcfd0fd | ||
|
|
6d7b231196 | ||
|
|
31ca314b02 | ||
|
|
0db304f1ee | ||
|
|
a3cb3e03f4 | ||
|
|
641a6cfdb7 | ||
|
|
f27471cea7 | ||
|
|
47508b8d6c | ||
|
|
28e0242907 | ||
|
|
96523ca01f | ||
|
|
c10a6fdab1 |
1
.github/pull_request_template.md
vendored
1
.github/pull_request_template.md
vendored
@@ -18,5 +18,6 @@
|
|||||||
|
|
||||||
- [ ] _The PR has a short but descriptive title, suitable for a changelog_
|
- [ ] _The PR has a short but descriptive title, suitable for a changelog_
|
||||||
- [ ] _Tests added / updated (if applicable)_
|
- [ ] _Tests added / updated (if applicable)_
|
||||||
|
- [ ] _❗Changes to a redux slice have a corresponding migration_
|
||||||
- [ ] _Documentation added / updated (if applicable)_
|
- [ ] _Documentation added / updated (if applicable)_
|
||||||
- [ ] _Updated `What's New` copy (if doing a release after this PR)_
|
- [ ] _Updated `What's New` copy (if doing a release after this PR)_
|
||||||
|
|||||||
8
.github/workflows/build-container.yml
vendored
8
.github/workflows/build-container.yml
vendored
@@ -45,6 +45,9 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Free up more disk space on the runner
|
- name: Free up more disk space on the runner
|
||||||
# https://github.com/actions/runner-images/issues/2840#issuecomment-1284059930
|
# https://github.com/actions/runner-images/issues/2840#issuecomment-1284059930
|
||||||
|
# the /mnt dir has 70GBs of free space
|
||||||
|
# /dev/sda1 74G 28K 70G 1% /mnt
|
||||||
|
# According to some online posts the /mnt is not always there, so checking before setting docker to use it
|
||||||
run: |
|
run: |
|
||||||
echo "----- Free space before cleanup"
|
echo "----- Free space before cleanup"
|
||||||
df -h
|
df -h
|
||||||
@@ -52,6 +55,11 @@ jobs:
|
|||||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
sudo swapoff /mnt/swapfile
|
sudo swapoff /mnt/swapfile
|
||||||
sudo rm -rf /mnt/swapfile
|
sudo rm -rf /mnt/swapfile
|
||||||
|
if [ -d /mnt ]; then
|
||||||
|
sudo chmod -R 777 /mnt
|
||||||
|
echo '{"data-root": "/mnt/docker-root"}' | sudo tee /etc/docker/daemon.json
|
||||||
|
sudo systemctl restart docker
|
||||||
|
fi
|
||||||
echo "----- Free space after cleanup"
|
echo "----- Free space after cleanup"
|
||||||
df -h
|
df -h
|
||||||
|
|
||||||
|
|||||||
30
.github/workflows/lfs-checks.yml
vendored
Normal file
30
.github/workflows/lfs-checks.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Checks that large files and LFS-tracked files are properly checked in with pointer format.
|
||||||
|
# Uses https://github.com/ppremk/lfs-warning to detect LFS issues.
|
||||||
|
|
||||||
|
name: 'lfs checks'
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- 'ready_for_review'
|
||||||
|
- 'opened'
|
||||||
|
- 'synchronize'
|
||||||
|
merge_group:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lfs-check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
permissions:
|
||||||
|
# Required to label and comment on the PRs
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: check lfs files
|
||||||
|
uses: ppremk/lfs-warning@v3.3
|
||||||
12
.github/workflows/typegen-checks.yml
vendored
12
.github/workflows/typegen-checks.yml
vendored
@@ -39,6 +39,18 @@ jobs:
|
|||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Free up more disk space on the runner
|
||||||
|
# https://github.com/actions/runner-images/issues/2840#issuecomment-1284059930
|
||||||
|
run: |
|
||||||
|
echo "----- Free space before cleanup"
|
||||||
|
df -h
|
||||||
|
sudo rm -rf /usr/share/dotnet
|
||||||
|
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
|
sudo swapoff /mnt/swapfile
|
||||||
|
sudo rm -rf /mnt/swapfile
|
||||||
|
echo "----- Free space after cleanup"
|
||||||
|
df -h
|
||||||
|
|
||||||
- name: check for changed files
|
- name: check for changed files
|
||||||
if: ${{ inputs.always_run != true }}
|
if: ${{ inputs.always_run != true }}
|
||||||
id: changed-files
|
id: changed-files
|
||||||
|
|||||||
@@ -22,6 +22,10 @@
|
|||||||
## GPU_DRIVER can be set to either `cuda` or `rocm` to enable GPU support in the container accordingly.
|
## GPU_DRIVER can be set to either `cuda` or `rocm` to enable GPU support in the container accordingly.
|
||||||
# GPU_DRIVER=cuda #| rocm
|
# GPU_DRIVER=cuda #| rocm
|
||||||
|
|
||||||
|
## If you are using ROCM, you will need to ensure that the render group within the container and the host system use the same group ID.
|
||||||
|
## To obtain the group ID of the render group on the host system, run `getent group render` and grab the number.
|
||||||
|
# RENDER_GROUP_ID=
|
||||||
|
|
||||||
## CONTAINER_UID can be set to the UID of the user on the host system that should own the files in the container.
|
## CONTAINER_UID can be set to the UID of the user on the host system that should own the files in the container.
|
||||||
## It is usually not necessary to change this. Use `id -u` on the host system to find the UID.
|
## It is usually not necessary to change this. Use `id -u` on the host system to find the UID.
|
||||||
# CONTAINER_UID=1000
|
# CONTAINER_UID=1000
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ ENV \
|
|||||||
UV_MANAGED_PYTHON=1 \
|
UV_MANAGED_PYTHON=1 \
|
||||||
UV_LINK_MODE=copy \
|
UV_LINK_MODE=copy \
|
||||||
UV_PROJECT_ENVIRONMENT=/opt/venv \
|
UV_PROJECT_ENVIRONMENT=/opt/venv \
|
||||||
UV_INDEX="https://download.pytorch.org/whl/cu124" \
|
|
||||||
INVOKEAI_ROOT=/invokeai \
|
INVOKEAI_ROOT=/invokeai \
|
||||||
INVOKEAI_HOST=0.0.0.0 \
|
INVOKEAI_HOST=0.0.0.0 \
|
||||||
INVOKEAI_PORT=9090 \
|
INVOKEAI_PORT=9090 \
|
||||||
@@ -74,19 +73,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \
|
|||||||
--mount=type=bind,source=uv.lock,target=uv.lock \
|
--mount=type=bind,source=uv.lock,target=uv.lock \
|
||||||
# this is just to get the package manager to recognize that the project exists, without making changes to the docker layer
|
# this is just to get the package manager to recognize that the project exists, without making changes to the docker layer
|
||||||
--mount=type=bind,source=invokeai/version,target=invokeai/version \
|
--mount=type=bind,source=invokeai/version,target=invokeai/version \
|
||||||
if [ "$TARGETPLATFORM" = "linux/arm64" ] || [ "$GPU_DRIVER" = "cpu" ]; then UV_INDEX="https://download.pytorch.org/whl/cpu"; \
|
ulimit -n 30000 && \
|
||||||
elif [ "$GPU_DRIVER" = "rocm" ]; then UV_INDEX="https://download.pytorch.org/whl/rocm6.2"; \
|
uv sync --extra $GPU_DRIVER --frozen
|
||||||
fi && \
|
|
||||||
uv sync --frozen
|
|
||||||
|
|
||||||
# build patchmatch
|
|
||||||
RUN cd /usr/lib/$(uname -p)-linux-gnu/pkgconfig/ && ln -sf opencv4.pc opencv.pc
|
|
||||||
RUN python -c "from patchmatch import patch_match"
|
|
||||||
|
|
||||||
# Link amdgpu.ids for ROCm builds
|
# Link amdgpu.ids for ROCm builds
|
||||||
# contributed by https://github.com/Rubonnek
|
# contributed by https://github.com/Rubonnek
|
||||||
RUN mkdir -p "/opt/amdgpu/share/libdrm" &&\
|
RUN mkdir -p "/opt/amdgpu/share/libdrm" &&\
|
||||||
ln -s "/usr/share/libdrm/amdgpu.ids" "/opt/amdgpu/share/libdrm/amdgpu.ids"
|
ln -s "/usr/share/libdrm/amdgpu.ids" "/opt/amdgpu/share/libdrm/amdgpu.ids" && groupadd render
|
||||||
|
|
||||||
|
# build patchmatch
|
||||||
|
RUN cd /usr/lib/$(uname -p)-linux-gnu/pkgconfig/ && ln -sf opencv4.pc opencv.pc
|
||||||
|
RUN python -c "from patchmatch import patch_match"
|
||||||
|
|
||||||
RUN mkdir -p ${INVOKEAI_ROOT} && chown -R ${CONTAINER_UID}:${CONTAINER_GID} ${INVOKEAI_ROOT}
|
RUN mkdir -p ${INVOKEAI_ROOT} && chown -R ${CONTAINER_UID}:${CONTAINER_GID} ${INVOKEAI_ROOT}
|
||||||
|
|
||||||
@@ -105,8 +102,6 @@ COPY invokeai ${INVOKEAI_SRC}/invokeai
|
|||||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
|
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
|
||||||
--mount=type=bind,source=uv.lock,target=uv.lock \
|
--mount=type=bind,source=uv.lock,target=uv.lock \
|
||||||
if [ "$TARGETPLATFORM" = "linux/arm64" ] || [ "$GPU_DRIVER" = "cpu" ]; then UV_INDEX="https://download.pytorch.org/whl/cpu"; \
|
ulimit -n 30000 && \
|
||||||
elif [ "$GPU_DRIVER" = "rocm" ]; then UV_INDEX="https://download.pytorch.org/whl/rocm6.2"; \
|
uv pip install -e .[$GPU_DRIVER]
|
||||||
fi && \
|
|
||||||
uv pip install -e .
|
|
||||||
|
|
||||||
|
|||||||
136
docker/Dockerfile-rocm-full
Normal file
136
docker/Dockerfile-rocm-full
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# syntax=docker/dockerfile:1.4
|
||||||
|
|
||||||
|
#### Web UI ------------------------------------
|
||||||
|
|
||||||
|
FROM docker.io/node:22-slim AS web-builder
|
||||||
|
ENV PNPM_HOME="/pnpm"
|
||||||
|
ENV PATH="$PNPM_HOME:$PATH"
|
||||||
|
RUN corepack use pnpm@8.x
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
COPY invokeai/frontend/web/ ./
|
||||||
|
RUN --mount=type=cache,target=/pnpm/store \
|
||||||
|
pnpm install --frozen-lockfile
|
||||||
|
RUN npx vite build
|
||||||
|
|
||||||
|
## Backend ---------------------------------------
|
||||||
|
|
||||||
|
FROM library/ubuntu:24.04
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
|
||||||
|
RUN --mount=type=cache,target=/var/cache/apt \
|
||||||
|
--mount=type=cache,target=/var/lib/apt \
|
||||||
|
apt update && apt install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
git \
|
||||||
|
gosu \
|
||||||
|
libglib2.0-0 \
|
||||||
|
libgl1 \
|
||||||
|
libglx-mesa0 \
|
||||||
|
build-essential \
|
||||||
|
libopencv-dev \
|
||||||
|
libstdc++-10-dev \
|
||||||
|
wget
|
||||||
|
|
||||||
|
ENV \
|
||||||
|
PYTHONUNBUFFERED=1 \
|
||||||
|
PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
VIRTUAL_ENV=/opt/venv \
|
||||||
|
INVOKEAI_SRC=/opt/invokeai \
|
||||||
|
PYTHON_VERSION=3.12 \
|
||||||
|
UV_PYTHON=3.12 \
|
||||||
|
UV_COMPILE_BYTECODE=1 \
|
||||||
|
UV_MANAGED_PYTHON=1 \
|
||||||
|
UV_LINK_MODE=copy \
|
||||||
|
UV_PROJECT_ENVIRONMENT=/opt/venv \
|
||||||
|
INVOKEAI_ROOT=/invokeai \
|
||||||
|
INVOKEAI_HOST=0.0.0.0 \
|
||||||
|
INVOKEAI_PORT=9090 \
|
||||||
|
PATH="/opt/venv/bin:$PATH" \
|
||||||
|
CONTAINER_UID=${CONTAINER_UID:-1000} \
|
||||||
|
CONTAINER_GID=${CONTAINER_GID:-1000}
|
||||||
|
|
||||||
|
ARG GPU_DRIVER=cuda
|
||||||
|
|
||||||
|
# Install `uv` for package management
|
||||||
|
COPY --from=ghcr.io/astral-sh/uv:0.6.9 /uv /uvx /bin/
|
||||||
|
|
||||||
|
# Install python & allow non-root user to use it by traversing the /root dir without read permissions
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
|
uv python install ${PYTHON_VERSION} && \
|
||||||
|
# chmod --recursive a+rX /root/.local/share/uv/python
|
||||||
|
chmod 711 /root
|
||||||
|
|
||||||
|
WORKDIR ${INVOKEAI_SRC}
|
||||||
|
|
||||||
|
# Install project's dependencies as a separate layer so they aren't rebuilt every commit.
|
||||||
|
# bind-mount instead of copy to defer adding sources to the image until next layer.
|
||||||
|
#
|
||||||
|
# NOTE: there are no pytorch builds for arm64 + cuda, only cpu
|
||||||
|
# x86_64/CUDA is the default
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
|
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
|
||||||
|
--mount=type=bind,source=uv.lock,target=uv.lock \
|
||||||
|
# this is just to get the package manager to recognize that the project exists, without making changes to the docker layer
|
||||||
|
--mount=type=bind,source=invokeai/version,target=invokeai/version \
|
||||||
|
ulimit -n 30000 && \
|
||||||
|
uv sync --extra $GPU_DRIVER --frozen
|
||||||
|
|
||||||
|
RUN --mount=type=cache,target=/var/cache/apt \
|
||||||
|
--mount=type=cache,target=/var/lib/apt \
|
||||||
|
if [ "$GPU_DRIVER" = "rocm" ]; then \
|
||||||
|
wget -O /tmp/amdgpu-install.deb \
|
||||||
|
https://repo.radeon.com/amdgpu-install/6.3.4/ubuntu/noble/amdgpu-install_6.3.60304-1_all.deb && \
|
||||||
|
apt install -y /tmp/amdgpu-install.deb && \
|
||||||
|
apt update && \
|
||||||
|
amdgpu-install --usecase=rocm -y && \
|
||||||
|
apt-get autoclean && \
|
||||||
|
apt clean && \
|
||||||
|
rm -rf /tmp/* /var/tmp/* && \
|
||||||
|
usermod -a -G render ubuntu && \
|
||||||
|
usermod -a -G video ubuntu && \
|
||||||
|
echo "\\n/opt/rocm/lib\\n/opt/rocm/lib64" >> /etc/ld.so.conf.d/rocm.conf && \
|
||||||
|
ldconfig && \
|
||||||
|
update-alternatives --auto rocm; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Heathen711: Leaving this for review input, will remove before merge
|
||||||
|
# RUN --mount=type=cache,target=/var/cache/apt \
|
||||||
|
# --mount=type=cache,target=/var/lib/apt \
|
||||||
|
# if [ "$GPU_DRIVER" = "rocm" ]; then \
|
||||||
|
# groupadd render && \
|
||||||
|
# usermod -a -G render ubuntu && \
|
||||||
|
# usermod -a -G video ubuntu; \
|
||||||
|
# fi
|
||||||
|
|
||||||
|
## Link amdgpu.ids for ROCm builds
|
||||||
|
## contributed by https://github.com/Rubonnek
|
||||||
|
# RUN mkdir -p "/opt/amdgpu/share/libdrm" &&\
|
||||||
|
# ln -s "/usr/share/libdrm/amdgpu.ids" "/opt/amdgpu/share/libdrm/amdgpu.ids"
|
||||||
|
|
||||||
|
# build patchmatch
|
||||||
|
RUN cd /usr/lib/$(uname -p)-linux-gnu/pkgconfig/ && ln -sf opencv4.pc opencv.pc
|
||||||
|
RUN python -c "from patchmatch import patch_match"
|
||||||
|
|
||||||
|
RUN mkdir -p ${INVOKEAI_ROOT} && chown -R ${CONTAINER_UID}:${CONTAINER_GID} ${INVOKEAI_ROOT}
|
||||||
|
|
||||||
|
COPY docker/docker-entrypoint.sh ./
|
||||||
|
ENTRYPOINT ["/opt/invokeai/docker-entrypoint.sh"]
|
||||||
|
CMD ["invokeai-web"]
|
||||||
|
|
||||||
|
# --link requires buldkit w/ dockerfile syntax 1.4, does not work with podman
|
||||||
|
COPY --link --from=web-builder /build/dist ${INVOKEAI_SRC}/invokeai/frontend/web/dist
|
||||||
|
|
||||||
|
# add sources last to minimize image changes on code changes
|
||||||
|
COPY invokeai ${INVOKEAI_SRC}/invokeai
|
||||||
|
|
||||||
|
# this should not increase image size because we've already installed dependencies
|
||||||
|
# in a previous layer
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
|
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
|
||||||
|
--mount=type=bind,source=uv.lock,target=uv.lock \
|
||||||
|
ulimit -n 30000 && \
|
||||||
|
uv pip install -e .[$GPU_DRIVER]
|
||||||
|
|
||||||
@@ -47,8 +47,9 @@ services:
|
|||||||
|
|
||||||
invokeai-rocm:
|
invokeai-rocm:
|
||||||
<<: *invokeai
|
<<: *invokeai
|
||||||
devices:
|
environment:
|
||||||
- /dev/kfd:/dev/kfd
|
- AMD_VISIBLE_DEVICES=all
|
||||||
- /dev/dri:/dev/dri
|
- RENDER_GROUP_ID=${RENDER_GROUP_ID}
|
||||||
|
runtime: amd
|
||||||
profiles:
|
profiles:
|
||||||
- rocm
|
- rocm
|
||||||
|
|||||||
@@ -21,6 +21,17 @@ _=$(id ${USER} 2>&1) || useradd -u ${USER_ID} ${USER}
|
|||||||
# ensure the UID is correct
|
# ensure the UID is correct
|
||||||
usermod -u ${USER_ID} ${USER} 1>/dev/null
|
usermod -u ${USER_ID} ${USER} 1>/dev/null
|
||||||
|
|
||||||
|
## ROCM specific configuration
|
||||||
|
# render group within the container must match the host render group
|
||||||
|
# otherwise the container will not be able to access the host GPU.
|
||||||
|
if [[ -v "RENDER_GROUP_ID" ]] && [[ ! -z "${RENDER_GROUP_ID}" ]]; then
|
||||||
|
# ensure the render group exists
|
||||||
|
groupmod -g ${RENDER_GROUP_ID} render
|
||||||
|
usermod -a -G render ${USER}
|
||||||
|
usermod -a -G video ${USER}
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
### Set the $PUBLIC_KEY env var to enable SSH access.
|
### Set the $PUBLIC_KEY env var to enable SSH access.
|
||||||
# We do not install openssh-server in the image by default to avoid bloat.
|
# We do not install openssh-server in the image by default to avoid bloat.
|
||||||
# but it is useful to have the full SSH server e.g. on Runpod.
|
# but it is useful to have the full SSH server e.g. on Runpod.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ run() {
|
|||||||
|
|
||||||
# parse .env file for build args
|
# parse .env file for build args
|
||||||
build_args=$(awk '$1 ~ /=[^$]/ && $0 !~ /^#/ {print "--build-arg " $0 " "}' .env) &&
|
build_args=$(awk '$1 ~ /=[^$]/ && $0 !~ /^#/ {print "--build-arg " $0 " "}' .env) &&
|
||||||
profile="$(awk -F '=' '/GPU_DRIVER/ {print $2}' .env)"
|
profile="$(awk -F '=' '/GPU_DRIVER=/ {print $2}' .env)"
|
||||||
|
|
||||||
# default to 'cuda' profile
|
# default to 'cuda' profile
|
||||||
[[ -z "$profile" ]] && profile="cuda"
|
[[ -z "$profile" ]] && profile="cuda"
|
||||||
@@ -30,7 +30,7 @@ run() {
|
|||||||
|
|
||||||
printf "%s\n" "starting service $service_name"
|
printf "%s\n" "starting service $service_name"
|
||||||
docker compose --profile "$profile" up -d "$service_name"
|
docker compose --profile "$profile" up -d "$service_name"
|
||||||
docker compose logs -f
|
docker compose --profile "$profile" logs -f
|
||||||
}
|
}
|
||||||
|
|
||||||
run
|
run
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ If the key is unrecognized, this call raises an
|
|||||||
|
|
||||||
#### exists(key) -> AnyModelConfig
|
#### exists(key) -> AnyModelConfig
|
||||||
|
|
||||||
Returns True if a model with the given key exists in the databsae.
|
Returns True if a model with the given key exists in the database.
|
||||||
|
|
||||||
#### search_by_path(path) -> AnyModelConfig
|
#### search_by_path(path) -> AnyModelConfig
|
||||||
|
|
||||||
@@ -718,7 +718,7 @@ When downloading remote models is implemented, additional
|
|||||||
configuration information, such as list of trigger terms, will be
|
configuration information, such as list of trigger terms, will be
|
||||||
retrieved from the HuggingFace and Civitai model repositories.
|
retrieved from the HuggingFace and Civitai model repositories.
|
||||||
|
|
||||||
The probed values can be overriden by providing a dictionary in the
|
The probed values can be overridden by providing a dictionary in the
|
||||||
optional `config` argument passed to `import_model()`. You may provide
|
optional `config` argument passed to `import_model()`. You may provide
|
||||||
overriding values for any of the model's configuration
|
overriding values for any of the model's configuration
|
||||||
attributes. Here is an example of setting the
|
attributes. Here is an example of setting the
|
||||||
@@ -841,7 +841,7 @@ variable.
|
|||||||
|
|
||||||
#### installer.start(invoker)
|
#### installer.start(invoker)
|
||||||
|
|
||||||
The `start` method is called by the API intialization routines when
|
The `start` method is called by the API initialization routines when
|
||||||
the API starts up. Its effect is to call `sync_to_config()` to
|
the API starts up. Its effect is to call `sync_to_config()` to
|
||||||
synchronize the model record store database with what's currently on
|
synchronize the model record store database with what's currently on
|
||||||
disk.
|
disk.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ We thank [all contributors](https://github.com/invoke-ai/InvokeAI/graphs/contrib
|
|||||||
- @psychedelicious (Spencer Mabrito) - Web Team Leader
|
- @psychedelicious (Spencer Mabrito) - Web Team Leader
|
||||||
- @joshistoast (Josh Corbett) - Web Development
|
- @joshistoast (Josh Corbett) - Web Development
|
||||||
- @cheerio (Mary Rogers) - Lead Engineer & Web App Development
|
- @cheerio (Mary Rogers) - Lead Engineer & Web App Development
|
||||||
- @ebr (Eugene Brodsky) - Cloud/DevOps/Sofware engineer; your friendly neighbourhood cluster-autoscaler
|
- @ebr (Eugene Brodsky) - Cloud/DevOps/Software engineer; your friendly neighbourhood cluster-autoscaler
|
||||||
- @sunija - Standalone version
|
- @sunija - Standalone version
|
||||||
- @brandon (Brandon Rising) - Platform, Infrastructure, Backend Systems
|
- @brandon (Brandon Rising) - Platform, Infrastructure, Backend Systems
|
||||||
- @ryanjdick (Ryan Dick) - Machine Learning & Training
|
- @ryanjdick (Ryan Dick) - Machine Learning & Training
|
||||||
|
|||||||
@@ -69,34 +69,34 @@ The following commands vary depending on the version of Invoke being installed a
|
|||||||
- If you have an Nvidia 20xx series GPU or older, use `invokeai[xformers]`.
|
- If you have an Nvidia 20xx series GPU or older, use `invokeai[xformers]`.
|
||||||
- If you have an Nvidia 30xx series GPU or newer, or do not have an Nvidia GPU, use `invokeai`.
|
- If you have an Nvidia 30xx series GPU or newer, or do not have an Nvidia GPU, use `invokeai`.
|
||||||
|
|
||||||
7. Determine the `PyPI` index URL to use for installation, if any. This is necessary to get the right version of torch installed.
|
7. Determine the torch backend to use for installation, if any. This is necessary to get the right version of torch installed. This is acheived by using [UV's built in torch support.](https://docs.astral.sh/uv/guides/integration/pytorch/#automatic-backend-selection)
|
||||||
|
|
||||||
=== "Invoke v5.12 and later"
|
=== "Invoke v5.12 and later"
|
||||||
|
|
||||||
- If you are on Windows or Linux with an Nvidia GPU, use `https://download.pytorch.org/whl/cu128`.
|
- If you are on Windows or Linux with an Nvidia GPU, use `--torch-backend=cu128`.
|
||||||
- If you are on Linux with no GPU, use `https://download.pytorch.org/whl/cpu`.
|
- If you are on Linux with no GPU, use `--torch-backend=cpu`.
|
||||||
- If you are on Linux with an AMD GPU, use `https://download.pytorch.org/whl/rocm6.2.4`.
|
- If you are on Linux with an AMD GPU, use `--torch-backend=rocm6.3`.
|
||||||
- **In all other cases, do not use an index.**
|
- **In all other cases, do not use a torch backend.**
|
||||||
|
|
||||||
=== "Invoke v5.10.0 to v5.11.0"
|
=== "Invoke v5.10.0 to v5.11.0"
|
||||||
|
|
||||||
- If you are on Windows or Linux with an Nvidia GPU, use `https://download.pytorch.org/whl/cu126`.
|
- If you are on Windows or Linux with an Nvidia GPU, use `--torch-backend=cu126`.
|
||||||
- If you are on Linux with no GPU, use `https://download.pytorch.org/whl/cpu`.
|
- If you are on Linux with no GPU, use `--torch-backend=cpu`.
|
||||||
- If you are on Linux with an AMD GPU, use `https://download.pytorch.org/whl/rocm6.2.4`.
|
- If you are on Linux with an AMD GPU, use `--torch-backend=rocm6.2.4`.
|
||||||
- **In all other cases, do not use an index.**
|
- **In all other cases, do not use an index.**
|
||||||
|
|
||||||
=== "Invoke v5.0.0 to v5.9.1"
|
=== "Invoke v5.0.0 to v5.9.1"
|
||||||
|
|
||||||
- If you are on Windows with an Nvidia GPU, use `https://download.pytorch.org/whl/cu124`.
|
- If you are on Windows with an Nvidia GPU, use `--torch-backend=cu124`.
|
||||||
- If you are on Linux with no GPU, use `https://download.pytorch.org/whl/cpu`.
|
- If you are on Linux with no GPU, use `--torch-backend=cpu`.
|
||||||
- If you are on Linux with an AMD GPU, use `https://download.pytorch.org/whl/rocm6.1`.
|
- If you are on Linux with an AMD GPU, use `--torch-backend=rocm6.1`.
|
||||||
- **In all other cases, do not use an index.**
|
- **In all other cases, do not use an index.**
|
||||||
|
|
||||||
=== "Invoke v4"
|
=== "Invoke v4"
|
||||||
|
|
||||||
- If you are on Windows with an Nvidia GPU, use `https://download.pytorch.org/whl/cu124`.
|
- If you are on Windows with an Nvidia GPU, use `--torch-backend=cu124`.
|
||||||
- If you are on Linux with no GPU, use `https://download.pytorch.org/whl/cpu`.
|
- If you are on Linux with no GPU, use `--torch-backend=cpu`.
|
||||||
- If you are on Linux with an AMD GPU, use `https://download.pytorch.org/whl/rocm5.2`.
|
- If you are on Linux with an AMD GPU, use `--torch-backend=rocm5.2`.
|
||||||
- **In all other cases, do not use an index.**
|
- **In all other cases, do not use an index.**
|
||||||
|
|
||||||
8. Install the `invokeai` package. Substitute the package specifier and version.
|
8. Install the `invokeai` package. Substitute the package specifier and version.
|
||||||
@@ -105,10 +105,10 @@ The following commands vary depending on the version of Invoke being installed a
|
|||||||
uv pip install <PACKAGE_SPECIFIER>==<VERSION> --python 3.12 --python-preference only-managed --force-reinstall
|
uv pip install <PACKAGE_SPECIFIER>==<VERSION> --python 3.12 --python-preference only-managed --force-reinstall
|
||||||
```
|
```
|
||||||
|
|
||||||
If you determined you needed to use a `PyPI` index URL in the previous step, you'll need to add `--index=<INDEX_URL>` like this:
|
If you determined you needed to use a torch backend in the previous step, you'll need to set the backend like this:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
uv pip install <PACKAGE_SPECIFIER>==<VERSION> --python 3.12 --python-preference only-managed --index=<INDEX_URL> --force-reinstall
|
uv pip install <PACKAGE_SPECIFIER>==<VERSION> --python 3.12 --python-preference only-managed --torch-backend=<VERSION> --force-reinstall
|
||||||
```
|
```
|
||||||
|
|
||||||
9. Deactivate and reactivate your venv so that the invokeai-specific commands become available in the environment:
|
9. Deactivate and reactivate your venv so that the invokeai-specific commands become available in the environment:
|
||||||
|
|||||||
@@ -33,30 +33,45 @@ Hardware requirements vary significantly depending on model and image output siz
|
|||||||
|
|
||||||
More detail on system requirements can be found [here](./requirements.md).
|
More detail on system requirements can be found [here](./requirements.md).
|
||||||
|
|
||||||
## Step 2: Download
|
## Step 2: Download and Set Up the Launcher
|
||||||
|
|
||||||
Download the most recent launcher for your operating system:
|
The Launcher manages your Invoke install. Follow these instructions to download and set up the Launcher.
|
||||||
|
|
||||||
- [Download for Windows](https://download.invoke.ai/Invoke%20Community%20Edition.exe)
|
!!! info "Instructions for each OS"
|
||||||
- [Download for macOS](https://download.invoke.ai/Invoke%20Community%20Edition.dmg)
|
|
||||||
- [Download for Linux](https://download.invoke.ai/Invoke%20Community%20Edition.AppImage)
|
|
||||||
|
|
||||||
## Step 3: Install or Update
|
=== "Windows"
|
||||||
|
|
||||||
Run the launcher you just downloaded, click **Install** and follow the instructions to get set up.
|
- [Download for Windows](https://github.com/invoke-ai/launcher/releases/latest/download/Invoke.Community.Edition.Setup.latest.exe)
|
||||||
|
- Run the `EXE` to install the Launcher and start it.
|
||||||
|
- A desktop shortcut will be created; use this to run the Launcher in the future.
|
||||||
|
- You can delete the `EXE` file you downloaded.
|
||||||
|
|
||||||
|
=== "macOS"
|
||||||
|
|
||||||
|
- [Download for macOS](https://github.com/invoke-ai/launcher/releases/latest/download/Invoke.Community.Edition-latest-arm64.dmg)
|
||||||
|
- Open the `DMG` and drag the app into `Applications`.
|
||||||
|
- Run the Launcher using its entry in `Applications`.
|
||||||
|
- You can delete the `DMG` file you downloaded.
|
||||||
|
|
||||||
|
=== "Linux"
|
||||||
|
|
||||||
|
- [Download for Linux](https://github.com/invoke-ai/launcher/releases/latest/download/Invoke.Community.Edition-latest.AppImage)
|
||||||
|
- You may need to edit the `AppImage` file properties and make it executable.
|
||||||
|
- Optionally move the file to a location that does not require admin privileges and add a desktop shortcut for it.
|
||||||
|
- Run the Launcher by double-clicking the `AppImage` or the shortcut you made.
|
||||||
|
|
||||||
|
## Step 3: Install Invoke
|
||||||
|
|
||||||
|
Run the Launcher you just set up if you haven't already. Click **Install** and follow the instructions to install (or update) Invoke.
|
||||||
|
|
||||||
If you have an existing Invoke installation, you can select it and let the launcher manage the install. You'll be able to update or launch the installation.
|
If you have an existing Invoke installation, you can select it and let the launcher manage the install. You'll be able to update or launch the installation.
|
||||||
|
|
||||||
!!! warning "Problem running the launcher on macOS"
|
!!! tip "Updating"
|
||||||
|
|
||||||
macOS may not allow you to run the launcher. We are working to resolve this by signing the launcher executable. Until that is done, you can manually flag the launcher as safe:
|
The Launcher will check for updates for itself _and_ Invoke.
|
||||||
|
|
||||||
- Open the **Invoke Community Edition.dmg** file.
|
- When the Launcher detects an update is available for itself, you'll get a small popup window. Click through this and the Launcher will update itself.
|
||||||
- Drag the launcher to **Applications**.
|
- When the Launcher detects an update for Invoke, you'll see a small green alert in the Launcher. Click that and follow the instructions to update Invoke.
|
||||||
- Open a terminal.
|
|
||||||
- Run `xattr -d 'com.apple.quarantine' /Applications/Invoke\ Community\ Edition.app`.
|
|
||||||
|
|
||||||
You should now be able to run the launcher.
|
|
||||||
|
|
||||||
## Step 4: Launch
|
## Step 4: Launch
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ Nodes have a "Use Cache" option in their footer. This allows for performance imp
|
|||||||
|
|
||||||
There are several node grouping concepts that can be examined with a narrow focus. These (and other) groupings can be pieced together to make up functional graph setups, and are important to understanding how groups of nodes work together as part of a whole. Note that the screenshots below aren't examples of complete functioning node graphs (see Examples).
|
There are several node grouping concepts that can be examined with a narrow focus. These (and other) groupings can be pieced together to make up functional graph setups, and are important to understanding how groups of nodes work together as part of a whole. Note that the screenshots below aren't examples of complete functioning node graphs (see Examples).
|
||||||
|
|
||||||
### Noise
|
### Create Latent Noise
|
||||||
|
|
||||||
An initial noise tensor is necessary for the latent diffusion process. As a result, the Denoising node requires a noise node input.
|
An initial noise tensor is necessary for the latent diffusion process. As a result, the Denoising node requires a noise node input.
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from invokeai.app.services.board_images.board_images_default import BoardImagesS
|
|||||||
from invokeai.app.services.board_records.board_records_sqlite import SqliteBoardRecordStorage
|
from invokeai.app.services.board_records.board_records_sqlite import SqliteBoardRecordStorage
|
||||||
from invokeai.app.services.boards.boards_default import BoardService
|
from invokeai.app.services.boards.boards_default import BoardService
|
||||||
from invokeai.app.services.bulk_download.bulk_download_default import BulkDownloadService
|
from invokeai.app.services.bulk_download.bulk_download_default import BulkDownloadService
|
||||||
|
from invokeai.app.services.client_state_persistence.client_state_persistence_sqlite import ClientStatePersistenceSqlite
|
||||||
from invokeai.app.services.config.config_default import InvokeAIAppConfig
|
from invokeai.app.services.config.config_default import InvokeAIAppConfig
|
||||||
from invokeai.app.services.download.download_default import DownloadQueueService
|
from invokeai.app.services.download.download_default import DownloadQueueService
|
||||||
from invokeai.app.services.events.events_fastapievents import FastAPIEventService
|
from invokeai.app.services.events.events_fastapievents import FastAPIEventService
|
||||||
@@ -151,6 +152,7 @@ class ApiDependencies:
|
|||||||
style_preset_records = SqliteStylePresetRecordsStorage(db=db)
|
style_preset_records = SqliteStylePresetRecordsStorage(db=db)
|
||||||
style_preset_image_files = StylePresetImageFileStorageDisk(style_presets_folder / "images")
|
style_preset_image_files = StylePresetImageFileStorageDisk(style_presets_folder / "images")
|
||||||
workflow_thumbnails = WorkflowThumbnailFileStorageDisk(workflow_thumbnails_folder)
|
workflow_thumbnails = WorkflowThumbnailFileStorageDisk(workflow_thumbnails_folder)
|
||||||
|
client_state_persistence = ClientStatePersistenceSqlite(db=db)
|
||||||
|
|
||||||
services = InvocationServices(
|
services = InvocationServices(
|
||||||
board_image_records=board_image_records,
|
board_image_records=board_image_records,
|
||||||
@@ -181,6 +183,7 @@ class ApiDependencies:
|
|||||||
style_preset_records=style_preset_records,
|
style_preset_records=style_preset_records,
|
||||||
style_preset_image_files=style_preset_image_files,
|
style_preset_image_files=style_preset_image_files,
|
||||||
workflow_thumbnails=workflow_thumbnails,
|
workflow_thumbnails=workflow_thumbnails,
|
||||||
|
client_state_persistence=client_state_persistence,
|
||||||
)
|
)
|
||||||
|
|
||||||
ApiDependencies.invoker = Invoker(services)
|
ApiDependencies.invoker = Invoker(services)
|
||||||
|
|||||||
39
invokeai/app/api/routers/board_videos.py
Normal file
39
invokeai/app/api/routers/board_videos.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
from fastapi import Body, HTTPException
|
||||||
|
from fastapi.routing import APIRouter
|
||||||
|
|
||||||
|
from invokeai.app.services.videos_common import AddVideosToBoardResult, RemoveVideosFromBoardResult
|
||||||
|
|
||||||
|
board_videos_router = APIRouter(prefix="/v1/board_videos", tags=["boards"])
|
||||||
|
|
||||||
|
|
||||||
|
@board_videos_router.post(
|
||||||
|
"/batch",
|
||||||
|
operation_id="add_videos_to_board",
|
||||||
|
responses={
|
||||||
|
201: {"description": "Videos were added to board successfully"},
|
||||||
|
},
|
||||||
|
status_code=201,
|
||||||
|
response_model=AddVideosToBoardResult,
|
||||||
|
)
|
||||||
|
async def add_videos_to_board(
|
||||||
|
board_id: str = Body(description="The id of the board to add to"),
|
||||||
|
video_ids: list[str] = Body(description="The ids of the videos to add", embed=True),
|
||||||
|
) -> AddVideosToBoardResult:
|
||||||
|
"""Adds a list of videos to a board"""
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@board_videos_router.post(
|
||||||
|
"/batch/delete",
|
||||||
|
operation_id="remove_videos_from_board",
|
||||||
|
responses={
|
||||||
|
201: {"description": "Videos were removed from board successfully"},
|
||||||
|
},
|
||||||
|
status_code=201,
|
||||||
|
response_model=RemoveVideosFromBoardResult,
|
||||||
|
)
|
||||||
|
async def remove_videos_from_board(
|
||||||
|
video_ids: list[str] = Body(description="The ids of the videos to remove", embed=True),
|
||||||
|
) -> RemoveVideosFromBoardResult:
|
||||||
|
"""Removes a list of videos from their board, if they had one"""
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
58
invokeai/app/api/routers/client_state.py
Normal file
58
invokeai/app/api/routers/client_state.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
from fastapi import Body, HTTPException, Path, Query
|
||||||
|
from fastapi.routing import APIRouter
|
||||||
|
|
||||||
|
from invokeai.app.api.dependencies import ApiDependencies
|
||||||
|
from invokeai.backend.util.logging import logging
|
||||||
|
|
||||||
|
client_state_router = APIRouter(prefix="/v1/client_state", tags=["client_state"])
|
||||||
|
|
||||||
|
|
||||||
|
@client_state_router.get(
|
||||||
|
"/{queue_id}/get_by_key",
|
||||||
|
operation_id="get_client_state_by_key",
|
||||||
|
response_model=str | None,
|
||||||
|
)
|
||||||
|
async def get_client_state_by_key(
|
||||||
|
queue_id: str = Path(description="The queue id to perform this operation on"),
|
||||||
|
key: str = Query(..., description="Key to get"),
|
||||||
|
) -> str | None:
|
||||||
|
"""Gets the client state"""
|
||||||
|
try:
|
||||||
|
return ApiDependencies.invoker.services.client_state_persistence.get_by_key(queue_id, key)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error getting client state: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail="Error setting client state")
|
||||||
|
|
||||||
|
|
||||||
|
@client_state_router.post(
|
||||||
|
"/{queue_id}/set_by_key",
|
||||||
|
operation_id="set_client_state",
|
||||||
|
response_model=str,
|
||||||
|
)
|
||||||
|
async def set_client_state(
|
||||||
|
queue_id: str = Path(description="The queue id to perform this operation on"),
|
||||||
|
key: str = Query(..., description="Key to set"),
|
||||||
|
value: str = Body(..., description="Stringified value to set"),
|
||||||
|
) -> str:
|
||||||
|
"""Sets the client state"""
|
||||||
|
try:
|
||||||
|
return ApiDependencies.invoker.services.client_state_persistence.set_by_key(queue_id, key, value)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error setting client state: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail="Error setting client state")
|
||||||
|
|
||||||
|
|
||||||
|
@client_state_router.post(
|
||||||
|
"/{queue_id}/delete",
|
||||||
|
operation_id="delete_client_state",
|
||||||
|
responses={204: {"description": "Client state deleted"}},
|
||||||
|
)
|
||||||
|
async def delete_client_state(
|
||||||
|
queue_id: str = Path(description="The queue id to perform this operation on"),
|
||||||
|
) -> None:
|
||||||
|
"""Deletes the client state"""
|
||||||
|
try:
|
||||||
|
ApiDependencies.invoker.services.client_state_persistence.delete(queue_id)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error deleting client state: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail="Error deleting client state")
|
||||||
@@ -7,7 +7,6 @@ from pydantic import BaseModel, Field
|
|||||||
from invokeai.app.api.dependencies import ApiDependencies
|
from invokeai.app.api.dependencies import ApiDependencies
|
||||||
from invokeai.app.services.session_processor.session_processor_common import SessionProcessorStatus
|
from invokeai.app.services.session_processor.session_processor_common import SessionProcessorStatus
|
||||||
from invokeai.app.services.session_queue.session_queue_common import (
|
from invokeai.app.services.session_queue.session_queue_common import (
|
||||||
QUEUE_ITEM_STATUS,
|
|
||||||
Batch,
|
Batch,
|
||||||
BatchStatus,
|
BatchStatus,
|
||||||
CancelAllExceptCurrentResult,
|
CancelAllExceptCurrentResult,
|
||||||
@@ -18,6 +17,7 @@ from invokeai.app.services.session_queue.session_queue_common import (
|
|||||||
DeleteByDestinationResult,
|
DeleteByDestinationResult,
|
||||||
EnqueueBatchResult,
|
EnqueueBatchResult,
|
||||||
FieldIdentifier,
|
FieldIdentifier,
|
||||||
|
ItemIdsResult,
|
||||||
PruneResult,
|
PruneResult,
|
||||||
RetryItemsResult,
|
RetryItemsResult,
|
||||||
SessionQueueCountsByDestination,
|
SessionQueueCountsByDestination,
|
||||||
@@ -25,7 +25,7 @@ from invokeai.app.services.session_queue.session_queue_common import (
|
|||||||
SessionQueueItemNotFoundError,
|
SessionQueueItemNotFoundError,
|
||||||
SessionQueueStatus,
|
SessionQueueStatus,
|
||||||
)
|
)
|
||||||
from invokeai.app.services.shared.pagination import CursorPaginatedResults
|
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
|
||||||
|
|
||||||
session_queue_router = APIRouter(prefix="/v1/queue", tags=["queue"])
|
session_queue_router = APIRouter(prefix="/v1/queue", tags=["queue"])
|
||||||
|
|
||||||
@@ -68,36 +68,6 @@ async def enqueue_batch(
|
|||||||
raise HTTPException(status_code=500, detail=f"Unexpected error while enqueuing batch: {e}")
|
raise HTTPException(status_code=500, detail=f"Unexpected error while enqueuing batch: {e}")
|
||||||
|
|
||||||
|
|
||||||
@session_queue_router.get(
|
|
||||||
"/{queue_id}/list",
|
|
||||||
operation_id="list_queue_items",
|
|
||||||
responses={
|
|
||||||
200: {"model": CursorPaginatedResults[SessionQueueItem]},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
async def list_queue_items(
|
|
||||||
queue_id: str = Path(description="The queue id to perform this operation on"),
|
|
||||||
limit: int = Query(default=50, description="The number of items to fetch"),
|
|
||||||
status: Optional[QUEUE_ITEM_STATUS] = Query(default=None, description="The status of items to fetch"),
|
|
||||||
cursor: Optional[int] = Query(default=None, description="The pagination cursor"),
|
|
||||||
priority: int = Query(default=0, description="The pagination cursor priority"),
|
|
||||||
destination: Optional[str] = Query(default=None, description="The destination of queue items to fetch"),
|
|
||||||
) -> CursorPaginatedResults[SessionQueueItem]:
|
|
||||||
"""Gets cursor-paginated queue items"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
return ApiDependencies.invoker.services.session_queue.list_queue_items(
|
|
||||||
queue_id=queue_id,
|
|
||||||
limit=limit,
|
|
||||||
status=status,
|
|
||||||
cursor=cursor,
|
|
||||||
priority=priority,
|
|
||||||
destination=destination,
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
raise HTTPException(status_code=500, detail=f"Unexpected error while listing all items: {e}")
|
|
||||||
|
|
||||||
|
|
||||||
@session_queue_router.get(
|
@session_queue_router.get(
|
||||||
"/{queue_id}/list_all",
|
"/{queue_id}/list_all",
|
||||||
operation_id="list_all_queue_items",
|
operation_id="list_all_queue_items",
|
||||||
@@ -119,6 +89,56 @@ async def list_all_queue_items(
|
|||||||
raise HTTPException(status_code=500, detail=f"Unexpected error while listing all queue items: {e}")
|
raise HTTPException(status_code=500, detail=f"Unexpected error while listing all queue items: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
@session_queue_router.get(
|
||||||
|
"/{queue_id}/item_ids",
|
||||||
|
operation_id="get_queue_item_ids",
|
||||||
|
responses={
|
||||||
|
200: {"model": ItemIdsResult},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
async def get_queue_item_ids(
|
||||||
|
queue_id: str = Path(description="The queue id to perform this operation on"),
|
||||||
|
order_dir: SQLiteDirection = Query(default=SQLiteDirection.Descending, description="The order of sort"),
|
||||||
|
) -> ItemIdsResult:
|
||||||
|
"""Gets all queue item ids that match the given parameters"""
|
||||||
|
try:
|
||||||
|
return ApiDependencies.invoker.services.session_queue.get_queue_item_ids(queue_id=queue_id, order_dir=order_dir)
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=f"Unexpected error while listing all queue item ids: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
@session_queue_router.post(
|
||||||
|
"/{queue_id}/items_by_ids",
|
||||||
|
operation_id="get_queue_items_by_item_ids",
|
||||||
|
responses={200: {"model": list[SessionQueueItem]}},
|
||||||
|
)
|
||||||
|
async def get_queue_items_by_item_ids(
|
||||||
|
queue_id: str = Path(description="The queue id to perform this operation on"),
|
||||||
|
item_ids: list[int] = Body(
|
||||||
|
embed=True, description="Object containing list of queue item ids to fetch queue items for"
|
||||||
|
),
|
||||||
|
) -> list[SessionQueueItem]:
|
||||||
|
"""Gets queue items for the specified queue item ids. Maintains order of item ids."""
|
||||||
|
try:
|
||||||
|
session_queue_service = ApiDependencies.invoker.services.session_queue
|
||||||
|
|
||||||
|
# Fetch queue items preserving the order of requested item ids
|
||||||
|
queue_items: list[SessionQueueItem] = []
|
||||||
|
for item_id in item_ids:
|
||||||
|
try:
|
||||||
|
queue_item = session_queue_service.get_queue_item(item_id=item_id)
|
||||||
|
if queue_item.queue_id != queue_id: # Auth protection for items from other queues
|
||||||
|
continue
|
||||||
|
queue_items.append(queue_item)
|
||||||
|
except Exception:
|
||||||
|
# Skip missing queue items - they may have been deleted between item id fetch and queue item fetch
|
||||||
|
continue
|
||||||
|
|
||||||
|
return queue_items
|
||||||
|
except Exception:
|
||||||
|
raise HTTPException(status_code=500, detail="Failed to get queue items")
|
||||||
|
|
||||||
|
|
||||||
@session_queue_router.put(
|
@session_queue_router.put(
|
||||||
"/{queue_id}/processor/resume",
|
"/{queue_id}/processor/resume",
|
||||||
operation_id="resume",
|
operation_id="resume",
|
||||||
@@ -354,7 +374,10 @@ async def get_queue_item(
|
|||||||
) -> SessionQueueItem:
|
) -> SessionQueueItem:
|
||||||
"""Gets a queue item"""
|
"""Gets a queue item"""
|
||||||
try:
|
try:
|
||||||
return ApiDependencies.invoker.services.session_queue.get_queue_item(item_id)
|
queue_item = ApiDependencies.invoker.services.session_queue.get_queue_item(item_id=item_id)
|
||||||
|
if queue_item.queue_id != queue_id:
|
||||||
|
raise HTTPException(status_code=404, detail=f"Queue item with id {item_id} not found in queue {queue_id}")
|
||||||
|
return queue_item
|
||||||
except SessionQueueItemNotFoundError:
|
except SessionQueueItemNotFoundError:
|
||||||
raise HTTPException(status_code=404, detail=f"Queue item with id {item_id} not found in queue {queue_id}")
|
raise HTTPException(status_code=404, detail=f"Queue item with id {item_id} not found in queue {queue_id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
119
invokeai/app/api/routers/videos.py
Normal file
119
invokeai/app/api/routers/videos.py
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from fastapi import Body, HTTPException, Path, Query
|
||||||
|
from fastapi.routing import APIRouter
|
||||||
|
|
||||||
|
from invokeai.app.services.shared.pagination import OffsetPaginatedResults
|
||||||
|
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
|
||||||
|
from invokeai.app.services.videos_common import (
|
||||||
|
DeleteVideosResult,
|
||||||
|
StarredVideosResult,
|
||||||
|
UnstarredVideosResult,
|
||||||
|
VideoDTO,
|
||||||
|
VideoIdsResult,
|
||||||
|
VideoRecordChanges,
|
||||||
|
)
|
||||||
|
|
||||||
|
videos_router = APIRouter(prefix="/v1/videos", tags=["videos"])
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.patch(
|
||||||
|
"/i/{video_id}",
|
||||||
|
operation_id="update_video",
|
||||||
|
response_model=VideoDTO,
|
||||||
|
)
|
||||||
|
async def update_video(
|
||||||
|
video_id: str = Path(description="The id of the video to update"),
|
||||||
|
video_changes: VideoRecordChanges = Body(description="The changes to apply to the video"),
|
||||||
|
) -> VideoDTO:
|
||||||
|
"""Updates a video"""
|
||||||
|
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.get(
|
||||||
|
"/i/{video_id}",
|
||||||
|
operation_id="get_video_dto",
|
||||||
|
response_model=VideoDTO,
|
||||||
|
)
|
||||||
|
async def get_video_dto(
|
||||||
|
video_id: str = Path(description="The id of the video to get"),
|
||||||
|
) -> VideoDTO:
|
||||||
|
"""Gets a video's DTO"""
|
||||||
|
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.post("/delete", operation_id="delete_videos_from_list", response_model=DeleteVideosResult)
|
||||||
|
async def delete_videos_from_list(
|
||||||
|
video_ids: list[str] = Body(description="The list of ids of videos to delete", embed=True),
|
||||||
|
) -> DeleteVideosResult:
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.post("/star", operation_id="star_videos_in_list", response_model=StarredVideosResult)
|
||||||
|
async def star_videos_in_list(
|
||||||
|
video_ids: list[str] = Body(description="The list of ids of videos to star", embed=True),
|
||||||
|
) -> StarredVideosResult:
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.post("/unstar", operation_id="unstar_videos_in_list", response_model=UnstarredVideosResult)
|
||||||
|
async def unstar_videos_in_list(
|
||||||
|
video_ids: list[str] = Body(description="The list of ids of videos to unstar", embed=True),
|
||||||
|
) -> UnstarredVideosResult:
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.delete("/uncategorized", operation_id="delete_uncategorized_videos", response_model=DeleteVideosResult)
|
||||||
|
async def delete_uncategorized_videos() -> DeleteVideosResult:
|
||||||
|
"""Deletes all videos that are uncategorized"""
|
||||||
|
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.get("/", operation_id="list_video_dtos", response_model=OffsetPaginatedResults[VideoDTO])
|
||||||
|
async def list_video_dtos(
|
||||||
|
is_intermediate: Optional[bool] = Query(default=None, description="Whether to list intermediate videos."),
|
||||||
|
board_id: Optional[str] = Query(
|
||||||
|
default=None,
|
||||||
|
description="The board id to filter by. Use 'none' to find videos without a board.",
|
||||||
|
),
|
||||||
|
offset: int = Query(default=0, description="The page offset"),
|
||||||
|
limit: int = Query(default=10, description="The number of videos per page"),
|
||||||
|
order_dir: SQLiteDirection = Query(default=SQLiteDirection.Descending, description="The order of sort"),
|
||||||
|
starred_first: bool = Query(default=True, description="Whether to sort by starred videos first"),
|
||||||
|
search_term: Optional[str] = Query(default=None, description="The term to search for"),
|
||||||
|
) -> OffsetPaginatedResults[VideoDTO]:
|
||||||
|
"""Lists video DTOs"""
|
||||||
|
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.get("/ids", operation_id="get_video_ids")
|
||||||
|
async def get_video_ids(
|
||||||
|
is_intermediate: Optional[bool] = Query(default=None, description="Whether to list intermediate videos."),
|
||||||
|
board_id: Optional[str] = Query(
|
||||||
|
default=None,
|
||||||
|
description="The board id to filter by. Use 'none' to find videos without a board.",
|
||||||
|
),
|
||||||
|
order_dir: SQLiteDirection = Query(default=SQLiteDirection.Descending, description="The order of sort"),
|
||||||
|
starred_first: bool = Query(default=True, description="Whether to sort by starred videos first"),
|
||||||
|
search_term: Optional[str] = Query(default=None, description="The term to search for"),
|
||||||
|
) -> VideoIdsResult:
|
||||||
|
"""Gets ordered list of video ids with metadata for optimistic updates"""
|
||||||
|
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@videos_router.post(
|
||||||
|
"/videos_by_ids",
|
||||||
|
operation_id="get_videos_by_ids",
|
||||||
|
responses={200: {"model": list[VideoDTO]}},
|
||||||
|
)
|
||||||
|
async def get_videos_by_ids(
|
||||||
|
video_ids: list[str] = Body(embed=True, description="Object containing list of video ids to fetch DTOs for"),
|
||||||
|
) -> list[VideoDTO]:
|
||||||
|
"""Gets video DTOs for the specified video ids. Maintains order of input ids."""
|
||||||
|
|
||||||
|
raise HTTPException(status_code=501, detail="Not implemented")
|
||||||
@@ -18,7 +18,9 @@ from invokeai.app.api.no_cache_staticfiles import NoCacheStaticFiles
|
|||||||
from invokeai.app.api.routers import (
|
from invokeai.app.api.routers import (
|
||||||
app_info,
|
app_info,
|
||||||
board_images,
|
board_images,
|
||||||
|
board_videos,
|
||||||
boards,
|
boards,
|
||||||
|
client_state,
|
||||||
download_queue,
|
download_queue,
|
||||||
images,
|
images,
|
||||||
model_manager,
|
model_manager,
|
||||||
@@ -26,6 +28,7 @@ from invokeai.app.api.routers import (
|
|||||||
session_queue,
|
session_queue,
|
||||||
style_presets,
|
style_presets,
|
||||||
utilities,
|
utilities,
|
||||||
|
videos,
|
||||||
workflows,
|
workflows,
|
||||||
)
|
)
|
||||||
from invokeai.app.api.sockets import SocketIO
|
from invokeai.app.api.sockets import SocketIO
|
||||||
@@ -124,13 +127,16 @@ app.include_router(utilities.utilities_router, prefix="/api")
|
|||||||
app.include_router(model_manager.model_manager_router, prefix="/api")
|
app.include_router(model_manager.model_manager_router, prefix="/api")
|
||||||
app.include_router(download_queue.download_queue_router, prefix="/api")
|
app.include_router(download_queue.download_queue_router, prefix="/api")
|
||||||
app.include_router(images.images_router, prefix="/api")
|
app.include_router(images.images_router, prefix="/api")
|
||||||
|
app.include_router(videos.videos_router, prefix="/api")
|
||||||
app.include_router(boards.boards_router, prefix="/api")
|
app.include_router(boards.boards_router, prefix="/api")
|
||||||
app.include_router(board_images.board_images_router, prefix="/api")
|
app.include_router(board_images.board_images_router, prefix="/api")
|
||||||
|
app.include_router(board_videos.board_videos_router, prefix="/api")
|
||||||
app.include_router(model_relationships.model_relationships_router, prefix="/api")
|
app.include_router(model_relationships.model_relationships_router, prefix="/api")
|
||||||
app.include_router(app_info.app_router, prefix="/api")
|
app.include_router(app_info.app_router, prefix="/api")
|
||||||
app.include_router(session_queue.session_queue_router, prefix="/api")
|
app.include_router(session_queue.session_queue_router, prefix="/api")
|
||||||
app.include_router(workflows.workflows_router, prefix="/api")
|
app.include_router(workflows.workflows_router, prefix="/api")
|
||||||
app.include_router(style_presets.style_presets_router, prefix="/api")
|
app.include_router(style_presets.style_presets_router, prefix="/api")
|
||||||
|
app.include_router(client_state.client_state_router, prefix="/api")
|
||||||
|
|
||||||
app.openapi = get_openapi_func(app)
|
app.openapi = get_openapi_func(app)
|
||||||
|
|
||||||
@@ -155,6 +161,12 @@ def overridden_redoc() -> HTMLResponse:
|
|||||||
|
|
||||||
web_root_path = Path(list(web_dir.__path__)[0])
|
web_root_path = Path(list(web_dir.__path__)[0])
|
||||||
|
|
||||||
|
if app_config.unsafe_disable_picklescan:
|
||||||
|
logger.warning(
|
||||||
|
"The unsafe_disable_picklescan option is enabled. This disables malware scanning while installing and"
|
||||||
|
"loading models, which may allow malicious code to be executed. Use at your own risk."
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
app.mount("/", NoCacheStaticFiles(directory=Path(web_root_path, "dist"), html=True), name="ui")
|
app.mount("/", NoCacheStaticFiles(directory=Path(web_root_path, "dist"), html=True), name="ui")
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from invokeai.app.services.shared.invocation_context import InvocationContext
|
|||||||
from invokeai.backend.model_manager.load.load_base import LoadedModel
|
from invokeai.backend.model_manager.load.load_base import LoadedModel
|
||||||
from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
|
from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
|
||||||
from invokeai.backend.util.devices import TorchDevice
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_cogview4
|
||||||
|
|
||||||
# TODO(ryand): This is effectively a copy of SD3ImageToLatentsInvocation and a subset of ImageToLatentsInvocation. We
|
# TODO(ryand): This is effectively a copy of SD3ImageToLatentsInvocation and a subset of ImageToLatentsInvocation. We
|
||||||
# should refactor to avoid this duplication.
|
# should refactor to avoid this duplication.
|
||||||
@@ -38,7 +39,11 @@ class CogView4ImageToLatentsInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def vae_encode(vae_info: LoadedModel, image_tensor: torch.Tensor) -> torch.Tensor:
|
def vae_encode(vae_info: LoadedModel, image_tensor: torch.Tensor) -> torch.Tensor:
|
||||||
with vae_info as vae:
|
assert isinstance(vae_info.model, AutoencoderKL)
|
||||||
|
estimated_working_memory = estimate_vae_working_memory_cogview4(
|
||||||
|
operation="encode", image_tensor=image_tensor, vae=vae_info.model
|
||||||
|
)
|
||||||
|
with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):
|
||||||
assert isinstance(vae, AutoencoderKL)
|
assert isinstance(vae, AutoencoderKL)
|
||||||
|
|
||||||
vae.disable_tiling()
|
vae.disable_tiling()
|
||||||
@@ -62,6 +67,8 @@ class CogView4ImageToLatentsInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
image_tensor = einops.rearrange(image_tensor, "c h w -> 1 c h w")
|
image_tensor = einops.rearrange(image_tensor, "c h w -> 1 c h w")
|
||||||
|
|
||||||
vae_info = context.models.load(self.vae.vae)
|
vae_info = context.models.load(self.vae.vae)
|
||||||
|
assert isinstance(vae_info.model, AutoencoderKL)
|
||||||
|
|
||||||
latents = self.vae_encode(vae_info=vae_info, image_tensor=image_tensor)
|
latents = self.vae_encode(vae_info=vae_info, image_tensor=image_tensor)
|
||||||
|
|
||||||
latents = latents.to("cpu")
|
latents = latents.to("cpu")
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from einops import rearrange
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from invokeai.app.invocations.baseinvocation import BaseInvocation, Classification, invocation
|
from invokeai.app.invocations.baseinvocation import BaseInvocation, Classification, invocation
|
||||||
from invokeai.app.invocations.constants import LATENT_SCALE_FACTOR
|
|
||||||
from invokeai.app.invocations.fields import (
|
from invokeai.app.invocations.fields import (
|
||||||
FieldDescriptions,
|
FieldDescriptions,
|
||||||
Input,
|
Input,
|
||||||
@@ -20,6 +19,7 @@ from invokeai.app.invocations.primitives import ImageOutput
|
|||||||
from invokeai.app.services.shared.invocation_context import InvocationContext
|
from invokeai.app.services.shared.invocation_context import InvocationContext
|
||||||
from invokeai.backend.stable_diffusion.extensions.seamless import SeamlessExt
|
from invokeai.backend.stable_diffusion.extensions.seamless import SeamlessExt
|
||||||
from invokeai.backend.util.devices import TorchDevice
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_cogview4
|
||||||
|
|
||||||
# TODO(ryand): This is effectively a copy of SD3LatentsToImageInvocation and a subset of LatentsToImageInvocation. We
|
# TODO(ryand): This is effectively a copy of SD3LatentsToImageInvocation and a subset of LatentsToImageInvocation. We
|
||||||
# should refactor to avoid this duplication.
|
# should refactor to avoid this duplication.
|
||||||
@@ -39,22 +39,15 @@ class CogView4LatentsToImageInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
latents: LatentsField = InputField(description=FieldDescriptions.latents, input=Input.Connection)
|
latents: LatentsField = InputField(description=FieldDescriptions.latents, input=Input.Connection)
|
||||||
vae: VAEField = InputField(description=FieldDescriptions.vae, input=Input.Connection)
|
vae: VAEField = InputField(description=FieldDescriptions.vae, input=Input.Connection)
|
||||||
|
|
||||||
def _estimate_working_memory(self, latents: torch.Tensor, vae: AutoencoderKL) -> int:
|
|
||||||
"""Estimate the working memory required by the invocation in bytes."""
|
|
||||||
out_h = LATENT_SCALE_FACTOR * latents.shape[-2]
|
|
||||||
out_w = LATENT_SCALE_FACTOR * latents.shape[-1]
|
|
||||||
element_size = next(vae.parameters()).element_size()
|
|
||||||
scaling_constant = 2200 # Determined experimentally.
|
|
||||||
working_memory = out_h * out_w * element_size * scaling_constant
|
|
||||||
return int(working_memory)
|
|
||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
def invoke(self, context: InvocationContext) -> ImageOutput:
|
def invoke(self, context: InvocationContext) -> ImageOutput:
|
||||||
latents = context.tensors.load(self.latents.latents_name)
|
latents = context.tensors.load(self.latents.latents_name)
|
||||||
|
|
||||||
vae_info = context.models.load(self.vae.vae)
|
vae_info = context.models.load(self.vae.vae)
|
||||||
assert isinstance(vae_info.model, (AutoencoderKL))
|
assert isinstance(vae_info.model, (AutoencoderKL))
|
||||||
estimated_working_memory = self._estimate_working_memory(latents, vae_info.model)
|
estimated_working_memory = estimate_vae_working_memory_cogview4(
|
||||||
|
operation="decode", image_tensor=latents, vae=vae_info.model
|
||||||
|
)
|
||||||
with (
|
with (
|
||||||
SeamlessExt.static_patch_model(vae_info.model, self.vae.seamless_axes),
|
SeamlessExt.static_patch_model(vae_info.model, self.vae.seamless_axes),
|
||||||
vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae),
|
vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae),
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, Callable, Optional, Tuple
|
from typing import Any, Callable, Optional, Tuple
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict, Field, RootModel, TypeAdapter, model_validator
|
from pydantic import BaseModel, ConfigDict, Field, RootModel, TypeAdapter
|
||||||
from pydantic.fields import _Unset
|
from pydantic.fields import _Unset
|
||||||
from pydantic_core import PydanticUndefined
|
from pydantic_core import PydanticUndefined
|
||||||
|
|
||||||
from invokeai.app.util.metaenum import MetaEnum
|
from invokeai.app.util.metaenum import MetaEnum
|
||||||
|
from invokeai.backend.image_util.segment_anything.shared import BoundingBox
|
||||||
from invokeai.backend.util.logging import InvokeAILogger
|
from invokeai.backend.util.logging import InvokeAILogger
|
||||||
|
|
||||||
logger = InvokeAILogger.get_logger()
|
logger = InvokeAILogger.get_logger()
|
||||||
@@ -64,12 +65,16 @@ class UIType(str, Enum, metaclass=MetaEnum):
|
|||||||
Imagen3Model = "Imagen3ModelField"
|
Imagen3Model = "Imagen3ModelField"
|
||||||
Imagen4Model = "Imagen4ModelField"
|
Imagen4Model = "Imagen4ModelField"
|
||||||
ChatGPT4oModel = "ChatGPT4oModelField"
|
ChatGPT4oModel = "ChatGPT4oModelField"
|
||||||
|
Gemini2_5Model = "Gemini2_5ModelField"
|
||||||
FluxKontextModel = "FluxKontextModelField"
|
FluxKontextModel = "FluxKontextModelField"
|
||||||
|
Veo3Model = "Veo3ModelField"
|
||||||
|
RunwayModel = "RunwayModelField"
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Misc Field Types
|
# region Misc Field Types
|
||||||
Scheduler = "SchedulerField"
|
Scheduler = "SchedulerField"
|
||||||
Any = "AnyField"
|
Any = "AnyField"
|
||||||
|
Video = "VideoField"
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Internal Field Types
|
# region Internal Field Types
|
||||||
@@ -224,6 +229,12 @@ class ImageField(BaseModel):
|
|||||||
image_name: str = Field(description="The name of the image")
|
image_name: str = Field(description="The name of the image")
|
||||||
|
|
||||||
|
|
||||||
|
class VideoField(BaseModel):
|
||||||
|
"""A video primitive field"""
|
||||||
|
|
||||||
|
video_id: str = Field(description="The id of the video")
|
||||||
|
|
||||||
|
|
||||||
class BoardField(BaseModel):
|
class BoardField(BaseModel):
|
||||||
"""A board primitive field"""
|
"""A board primitive field"""
|
||||||
|
|
||||||
@@ -321,14 +332,9 @@ class ConditioningField(BaseModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class BoundingBoxField(BaseModel):
|
class BoundingBoxField(BoundingBox):
|
||||||
"""A bounding box primitive value."""
|
"""A bounding box primitive value."""
|
||||||
|
|
||||||
x_min: int = Field(ge=0, description="The minimum x-coordinate of the bounding box (inclusive).")
|
|
||||||
x_max: int = Field(ge=0, description="The maximum x-coordinate of the bounding box (exclusive).")
|
|
||||||
y_min: int = Field(ge=0, description="The minimum y-coordinate of the bounding box (inclusive).")
|
|
||||||
y_max: int = Field(ge=0, description="The maximum y-coordinate of the bounding box (exclusive).")
|
|
||||||
|
|
||||||
score: Optional[float] = Field(
|
score: Optional[float] = Field(
|
||||||
default=None,
|
default=None,
|
||||||
ge=0.0,
|
ge=0.0,
|
||||||
@@ -337,21 +343,6 @@ class BoundingBoxField(BaseModel):
|
|||||||
"when the bounding box was produced by a detector and has an associated confidence score.",
|
"when the bounding box was produced by a detector and has an associated confidence score.",
|
||||||
)
|
)
|
||||||
|
|
||||||
@model_validator(mode="after")
|
|
||||||
def check_coords(self):
|
|
||||||
if self.x_min > self.x_max:
|
|
||||||
raise ValueError(f"x_min ({self.x_min}) is greater than x_max ({self.x_max}).")
|
|
||||||
if self.y_min > self.y_max:
|
|
||||||
raise ValueError(f"y_min ({self.y_min}) is greater than y_max ({self.y_max}).")
|
|
||||||
return self
|
|
||||||
|
|
||||||
def tuple(self) -> Tuple[int, int, int, int]:
|
|
||||||
"""
|
|
||||||
Returns the bounding box as a tuple suitable for use with PIL's `Image.crop()` method.
|
|
||||||
This method returns a tuple of the form (left, upper, right, lower) == (x_min, y_min, x_max, y_max).
|
|
||||||
"""
|
|
||||||
return (self.x_min, self.y_min, self.x_max, self.y_max)
|
|
||||||
|
|
||||||
|
|
||||||
class MetadataField(RootModel[dict[str, Any]]):
|
class MetadataField(RootModel[dict[str, Any]]):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ from invokeai.backend.util.devices import TorchDevice
|
|||||||
title="FLUX Denoise",
|
title="FLUX Denoise",
|
||||||
tags=["image", "flux"],
|
tags=["image", "flux"],
|
||||||
category="image",
|
category="image",
|
||||||
version="4.0.0",
|
version="4.1.0",
|
||||||
)
|
)
|
||||||
class FluxDenoiseInvocation(BaseInvocation):
|
class FluxDenoiseInvocation(BaseInvocation):
|
||||||
"""Run denoising process with a FLUX transformer model."""
|
"""Run denoising process with a FLUX transformer model."""
|
||||||
@@ -153,7 +153,7 @@ class FluxDenoiseInvocation(BaseInvocation):
|
|||||||
description=FieldDescriptions.ip_adapter, title="IP-Adapter", default=None, input=Input.Connection
|
description=FieldDescriptions.ip_adapter, title="IP-Adapter", default=None, input=Input.Connection
|
||||||
)
|
)
|
||||||
|
|
||||||
kontext_conditioning: Optional[FluxKontextConditioningField] = InputField(
|
kontext_conditioning: FluxKontextConditioningField | list[FluxKontextConditioningField] | None = InputField(
|
||||||
default=None,
|
default=None,
|
||||||
description="FLUX Kontext conditioning (reference image).",
|
description="FLUX Kontext conditioning (reference image).",
|
||||||
input=Input.Connection,
|
input=Input.Connection,
|
||||||
@@ -328,6 +328,21 @@ class FluxDenoiseInvocation(BaseInvocation):
|
|||||||
cfg_scale_end_step=self.cfg_scale_end_step,
|
cfg_scale_end_step=self.cfg_scale_end_step,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
kontext_extension = None
|
||||||
|
if self.kontext_conditioning:
|
||||||
|
if not self.controlnet_vae:
|
||||||
|
raise ValueError("A VAE (e.g., controlnet_vae) must be provided to use Kontext conditioning.")
|
||||||
|
|
||||||
|
kontext_extension = KontextExtension(
|
||||||
|
context=context,
|
||||||
|
kontext_conditioning=self.kontext_conditioning
|
||||||
|
if isinstance(self.kontext_conditioning, list)
|
||||||
|
else [self.kontext_conditioning],
|
||||||
|
vae_field=self.controlnet_vae,
|
||||||
|
device=TorchDevice.choose_torch_device(),
|
||||||
|
dtype=inference_dtype,
|
||||||
|
)
|
||||||
|
|
||||||
with ExitStack() as exit_stack:
|
with ExitStack() as exit_stack:
|
||||||
# Prepare ControlNet extensions.
|
# Prepare ControlNet extensions.
|
||||||
# Note: We do this before loading the transformer model to minimize peak memory (see implementation).
|
# Note: We do this before loading the transformer model to minimize peak memory (see implementation).
|
||||||
@@ -385,19 +400,6 @@ class FluxDenoiseInvocation(BaseInvocation):
|
|||||||
dtype=inference_dtype,
|
dtype=inference_dtype,
|
||||||
)
|
)
|
||||||
|
|
||||||
kontext_extension = None
|
|
||||||
if self.kontext_conditioning is not None:
|
|
||||||
if not self.controlnet_vae:
|
|
||||||
raise ValueError("A VAE (e.g., controlnet_vae) must be provided to use Kontext conditioning.")
|
|
||||||
|
|
||||||
kontext_extension = KontextExtension(
|
|
||||||
context=context,
|
|
||||||
kontext_conditioning=self.kontext_conditioning,
|
|
||||||
vae_field=self.controlnet_vae,
|
|
||||||
device=TorchDevice.choose_torch_device(),
|
|
||||||
dtype=inference_dtype,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Prepare Kontext conditioning if provided
|
# Prepare Kontext conditioning if provided
|
||||||
img_cond_seq = None
|
img_cond_seq = None
|
||||||
img_cond_seq_ids = None
|
img_cond_seq_ids = None
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from einops import rearrange
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from invokeai.app.invocations.baseinvocation import BaseInvocation, invocation
|
from invokeai.app.invocations.baseinvocation import BaseInvocation, invocation
|
||||||
from invokeai.app.invocations.constants import LATENT_SCALE_FACTOR
|
|
||||||
from invokeai.app.invocations.fields import (
|
from invokeai.app.invocations.fields import (
|
||||||
FieldDescriptions,
|
FieldDescriptions,
|
||||||
Input,
|
Input,
|
||||||
@@ -18,6 +17,7 @@ from invokeai.app.services.shared.invocation_context import InvocationContext
|
|||||||
from invokeai.backend.flux.modules.autoencoder import AutoEncoder
|
from invokeai.backend.flux.modules.autoencoder import AutoEncoder
|
||||||
from invokeai.backend.model_manager.load.load_base import LoadedModel
|
from invokeai.backend.model_manager.load.load_base import LoadedModel
|
||||||
from invokeai.backend.util.devices import TorchDevice
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_flux
|
||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
@@ -39,17 +39,11 @@ class FluxVaeDecodeInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
input=Input.Connection,
|
input=Input.Connection,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _estimate_working_memory(self, latents: torch.Tensor, vae: AutoEncoder) -> int:
|
|
||||||
"""Estimate the working memory required by the invocation in bytes."""
|
|
||||||
out_h = LATENT_SCALE_FACTOR * latents.shape[-2]
|
|
||||||
out_w = LATENT_SCALE_FACTOR * latents.shape[-1]
|
|
||||||
element_size = next(vae.parameters()).element_size()
|
|
||||||
scaling_constant = 2200 # Determined experimentally.
|
|
||||||
working_memory = out_h * out_w * element_size * scaling_constant
|
|
||||||
return int(working_memory)
|
|
||||||
|
|
||||||
def _vae_decode(self, vae_info: LoadedModel, latents: torch.Tensor) -> Image.Image:
|
def _vae_decode(self, vae_info: LoadedModel, latents: torch.Tensor) -> Image.Image:
|
||||||
estimated_working_memory = self._estimate_working_memory(latents, vae_info.model)
|
assert isinstance(vae_info.model, AutoEncoder)
|
||||||
|
estimated_working_memory = estimate_vae_working_memory_flux(
|
||||||
|
operation="decode", image_tensor=latents, vae=vae_info.model
|
||||||
|
)
|
||||||
with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):
|
with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):
|
||||||
assert isinstance(vae, AutoEncoder)
|
assert isinstance(vae, AutoEncoder)
|
||||||
vae_dtype = next(iter(vae.parameters())).dtype
|
vae_dtype = next(iter(vae.parameters())).dtype
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from invokeai.backend.flux.modules.autoencoder import AutoEncoder
|
|||||||
from invokeai.backend.model_manager import LoadedModel
|
from invokeai.backend.model_manager import LoadedModel
|
||||||
from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
|
from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
|
||||||
from invokeai.backend.util.devices import TorchDevice
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_flux
|
||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
@@ -41,8 +42,12 @@ class FluxVaeEncodeInvocation(BaseInvocation):
|
|||||||
# TODO(ryand): Write a util function for generating random tensors that is consistent across devices / dtypes.
|
# TODO(ryand): Write a util function for generating random tensors that is consistent across devices / dtypes.
|
||||||
# There's a starting point in get_noise(...), but it needs to be extracted and generalized. This function
|
# There's a starting point in get_noise(...), but it needs to be extracted and generalized. This function
|
||||||
# should be used for VAE encode sampling.
|
# should be used for VAE encode sampling.
|
||||||
|
assert isinstance(vae_info.model, AutoEncoder)
|
||||||
|
estimated_working_memory = estimate_vae_working_memory_flux(
|
||||||
|
operation="encode", image_tensor=image_tensor, vae=vae_info.model
|
||||||
|
)
|
||||||
generator = torch.Generator(device=TorchDevice.choose_torch_device()).manual_seed(0)
|
generator = torch.Generator(device=TorchDevice.choose_torch_device()).manual_seed(0)
|
||||||
with vae_info as vae:
|
with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):
|
||||||
assert isinstance(vae, AutoEncoder)
|
assert isinstance(vae, AutoEncoder)
|
||||||
vae_dtype = next(iter(vae.parameters())).dtype
|
vae_dtype = next(iter(vae.parameters())).dtype
|
||||||
image_tensor = image_tensor.to(device=TorchDevice.choose_torch_device(), dtype=vae_dtype)
|
image_tensor = image_tensor.to(device=TorchDevice.choose_torch_device(), dtype=vae_dtype)
|
||||||
|
|||||||
@@ -1347,3 +1347,96 @@ class PasteImageIntoBoundingBoxInvocation(BaseInvocation, WithMetadata, WithBoar
|
|||||||
|
|
||||||
image_dto = context.images.save(image=target_image)
|
image_dto = context.images.save(image=target_image)
|
||||||
return ImageOutput.build(image_dto)
|
return ImageOutput.build(image_dto)
|
||||||
|
|
||||||
|
|
||||||
|
@invocation(
|
||||||
|
"flux_kontext_image_prep",
|
||||||
|
title="FLUX Kontext Image Prep",
|
||||||
|
tags=["image", "concatenate", "flux", "kontext"],
|
||||||
|
category="image",
|
||||||
|
version="1.0.0",
|
||||||
|
)
|
||||||
|
class FluxKontextConcatenateImagesInvocation(BaseInvocation, WithMetadata, WithBoard):
|
||||||
|
"""Prepares an image or images for use with FLUX Kontext. The first/single image is resized to the nearest
|
||||||
|
preferred Kontext resolution. All other images are concatenated horizontally, maintaining their aspect ratio."""
|
||||||
|
|
||||||
|
images: list[ImageField] = InputField(
|
||||||
|
description="The images to concatenate",
|
||||||
|
min_length=1,
|
||||||
|
max_length=10,
|
||||||
|
)
|
||||||
|
|
||||||
|
use_preferred_resolution: bool = InputField(
|
||||||
|
default=True, description="Use FLUX preferred resolutions for the first image"
|
||||||
|
)
|
||||||
|
|
||||||
|
def invoke(self, context: InvocationContext) -> ImageOutput:
|
||||||
|
from invokeai.backend.flux.util import PREFERED_KONTEXT_RESOLUTIONS
|
||||||
|
|
||||||
|
# Step 1: Load all images
|
||||||
|
pil_images = []
|
||||||
|
for image_field in self.images:
|
||||||
|
image = context.images.get_pil(image_field.image_name, mode="RGBA")
|
||||||
|
pil_images.append(image)
|
||||||
|
|
||||||
|
# Step 2: Determine target resolution for the first image
|
||||||
|
first_image = pil_images[0]
|
||||||
|
width, height = first_image.size
|
||||||
|
|
||||||
|
if self.use_preferred_resolution:
|
||||||
|
aspect_ratio = width / height
|
||||||
|
|
||||||
|
# Find the closest preferred resolution for the first image
|
||||||
|
_, target_width, target_height = min(
|
||||||
|
((abs(aspect_ratio - w / h), w, h) for w, h in PREFERED_KONTEXT_RESOLUTIONS), key=lambda x: x[0]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Apply BFL's scaling formula
|
||||||
|
scaled_height = 2 * int(target_height / 16)
|
||||||
|
final_height = 8 * scaled_height # This will be consistent for all images
|
||||||
|
scaled_width = 2 * int(target_width / 16)
|
||||||
|
first_width = 8 * scaled_width
|
||||||
|
else:
|
||||||
|
# Use original dimensions of first image, ensuring divisibility by 16
|
||||||
|
final_height = 16 * (height // 16)
|
||||||
|
first_width = 16 * (width // 16)
|
||||||
|
# Ensure minimum dimensions
|
||||||
|
if final_height < 16:
|
||||||
|
final_height = 16
|
||||||
|
if first_width < 16:
|
||||||
|
first_width = 16
|
||||||
|
|
||||||
|
# Step 3: Process and resize all images with consistent height
|
||||||
|
processed_images = []
|
||||||
|
total_width = 0
|
||||||
|
|
||||||
|
for i, image in enumerate(pil_images):
|
||||||
|
if i == 0:
|
||||||
|
# First image uses the calculated dimensions
|
||||||
|
final_width = first_width
|
||||||
|
else:
|
||||||
|
# Subsequent images maintain aspect ratio with the same height
|
||||||
|
img_aspect_ratio = image.width / image.height
|
||||||
|
# Calculate width that maintains aspect ratio at the target height
|
||||||
|
calculated_width = int(final_height * img_aspect_ratio)
|
||||||
|
# Ensure width is divisible by 16 for proper VAE encoding
|
||||||
|
final_width = 16 * (calculated_width // 16)
|
||||||
|
# Ensure minimum width
|
||||||
|
if final_width < 16:
|
||||||
|
final_width = 16
|
||||||
|
|
||||||
|
# Resize image to calculated dimensions
|
||||||
|
resized_image = image.resize((final_width, final_height), Image.Resampling.LANCZOS)
|
||||||
|
processed_images.append(resized_image)
|
||||||
|
total_width += final_width
|
||||||
|
|
||||||
|
# Step 4: Concatenate images horizontally
|
||||||
|
concatenated_image = Image.new("RGB", (total_width, final_height))
|
||||||
|
x_offset = 0
|
||||||
|
for img in processed_images:
|
||||||
|
concatenated_image.paste(img, (x_offset, 0))
|
||||||
|
x_offset += img.width
|
||||||
|
|
||||||
|
# Save the concatenated image
|
||||||
|
image_dto = context.images.save(image=concatenated_image)
|
||||||
|
return ImageOutput.build(image_dto)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from invokeai.backend.model_manager import LoadedModel
|
|||||||
from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
|
from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
|
||||||
from invokeai.backend.stable_diffusion.vae_tiling import patch_vae_tiling_params
|
from invokeai.backend.stable_diffusion.vae_tiling import patch_vae_tiling_params
|
||||||
from invokeai.backend.util.devices import TorchDevice
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_sd15_sdxl
|
||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
@@ -52,11 +53,24 @@ class ImageToLatentsInvocation(BaseInvocation):
|
|||||||
tile_size: int = InputField(default=0, multiple_of=8, description=FieldDescriptions.vae_tile_size)
|
tile_size: int = InputField(default=0, multiple_of=8, description=FieldDescriptions.vae_tile_size)
|
||||||
fp32: bool = InputField(default=False, description=FieldDescriptions.fp32)
|
fp32: bool = InputField(default=False, description=FieldDescriptions.fp32)
|
||||||
|
|
||||||
@staticmethod
|
@classmethod
|
||||||
def vae_encode(
|
def vae_encode(
|
||||||
vae_info: LoadedModel, upcast: bool, tiled: bool, image_tensor: torch.Tensor, tile_size: int = 0
|
cls,
|
||||||
|
vae_info: LoadedModel,
|
||||||
|
upcast: bool,
|
||||||
|
tiled: bool,
|
||||||
|
image_tensor: torch.Tensor,
|
||||||
|
tile_size: int = 0,
|
||||||
) -> torch.Tensor:
|
) -> torch.Tensor:
|
||||||
with vae_info as vae:
|
assert isinstance(vae_info.model, (AutoencoderKL, AutoencoderTiny))
|
||||||
|
estimated_working_memory = estimate_vae_working_memory_sd15_sdxl(
|
||||||
|
operation="encode",
|
||||||
|
image_tensor=image_tensor,
|
||||||
|
vae=vae_info.model,
|
||||||
|
tile_size=tile_size if tiled else None,
|
||||||
|
fp32=upcast,
|
||||||
|
)
|
||||||
|
with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):
|
||||||
assert isinstance(vae, (AutoencoderKL, AutoencoderTiny))
|
assert isinstance(vae, (AutoencoderKL, AutoencoderTiny))
|
||||||
orig_dtype = vae.dtype
|
orig_dtype = vae.dtype
|
||||||
if upcast:
|
if upcast:
|
||||||
@@ -113,6 +127,7 @@ class ImageToLatentsInvocation(BaseInvocation):
|
|||||||
image = context.images.get_pil(self.image.image_name)
|
image = context.images.get_pil(self.image.image_name)
|
||||||
|
|
||||||
vae_info = context.models.load(self.vae.vae)
|
vae_info = context.models.load(self.vae.vae)
|
||||||
|
assert isinstance(vae_info.model, (AutoencoderKL, AutoencoderTiny))
|
||||||
|
|
||||||
image_tensor = image_resized_to_grid_as_tensor(image.convert("RGB"))
|
image_tensor = image_resized_to_grid_as_tensor(image.convert("RGB"))
|
||||||
if image_tensor.dim() == 3:
|
if image_tensor.dim() == 3:
|
||||||
@@ -120,7 +135,11 @@ class ImageToLatentsInvocation(BaseInvocation):
|
|||||||
|
|
||||||
context.util.signal_progress("Running VAE encoder")
|
context.util.signal_progress("Running VAE encoder")
|
||||||
latents = self.vae_encode(
|
latents = self.vae_encode(
|
||||||
vae_info=vae_info, upcast=self.fp32, tiled=self.tiled, image_tensor=image_tensor, tile_size=self.tile_size
|
vae_info=vae_info,
|
||||||
|
upcast=self.fp32,
|
||||||
|
tiled=self.tiled or context.config.get().force_tiled_decode,
|
||||||
|
image_tensor=image_tensor,
|
||||||
|
tile_size=self.tile_size,
|
||||||
)
|
)
|
||||||
|
|
||||||
latents = latents.to("cpu")
|
latents = latents.to("cpu")
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from invokeai.app.services.shared.invocation_context import InvocationContext
|
|||||||
from invokeai.backend.stable_diffusion.extensions.seamless import SeamlessExt
|
from invokeai.backend.stable_diffusion.extensions.seamless import SeamlessExt
|
||||||
from invokeai.backend.stable_diffusion.vae_tiling import patch_vae_tiling_params
|
from invokeai.backend.stable_diffusion.vae_tiling import patch_vae_tiling_params
|
||||||
from invokeai.backend.util.devices import TorchDevice
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_sd15_sdxl
|
||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
@@ -53,39 +54,6 @@ class LatentsToImageInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
tile_size: int = InputField(default=0, multiple_of=8, description=FieldDescriptions.vae_tile_size)
|
tile_size: int = InputField(default=0, multiple_of=8, description=FieldDescriptions.vae_tile_size)
|
||||||
fp32: bool = InputField(default=False, description=FieldDescriptions.fp32)
|
fp32: bool = InputField(default=False, description=FieldDescriptions.fp32)
|
||||||
|
|
||||||
def _estimate_working_memory(
|
|
||||||
self, latents: torch.Tensor, use_tiling: bool, vae: AutoencoderKL | AutoencoderTiny
|
|
||||||
) -> int:
|
|
||||||
"""Estimate the working memory required by the invocation in bytes."""
|
|
||||||
# It was found experimentally that the peak working memory scales linearly with the number of pixels and the
|
|
||||||
# element size (precision). This estimate is accurate for both SD1 and SDXL.
|
|
||||||
element_size = 4 if self.fp32 else 2
|
|
||||||
scaling_constant = 2200 # Determined experimentally.
|
|
||||||
|
|
||||||
if use_tiling:
|
|
||||||
tile_size = self.tile_size
|
|
||||||
if tile_size == 0:
|
|
||||||
tile_size = vae.tile_sample_min_size
|
|
||||||
assert isinstance(tile_size, int)
|
|
||||||
out_h = tile_size
|
|
||||||
out_w = tile_size
|
|
||||||
working_memory = out_h * out_w * element_size * scaling_constant
|
|
||||||
|
|
||||||
# We add 25% to the working memory estimate when tiling is enabled to account for factors like tile overlap
|
|
||||||
# and number of tiles. We could make this more precise in the future, but this should be good enough for
|
|
||||||
# most use cases.
|
|
||||||
working_memory = working_memory * 1.25
|
|
||||||
else:
|
|
||||||
out_h = LATENT_SCALE_FACTOR * latents.shape[-2]
|
|
||||||
out_w = LATENT_SCALE_FACTOR * latents.shape[-1]
|
|
||||||
working_memory = out_h * out_w * element_size * scaling_constant
|
|
||||||
|
|
||||||
if self.fp32:
|
|
||||||
# If we are running in FP32, then we should account for the likely increase in model size (~250MB).
|
|
||||||
working_memory += 250 * 2**20
|
|
||||||
|
|
||||||
return int(working_memory)
|
|
||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
def invoke(self, context: InvocationContext) -> ImageOutput:
|
def invoke(self, context: InvocationContext) -> ImageOutput:
|
||||||
latents = context.tensors.load(self.latents.latents_name)
|
latents = context.tensors.load(self.latents.latents_name)
|
||||||
@@ -94,8 +62,13 @@ class LatentsToImageInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
|
|
||||||
vae_info = context.models.load(self.vae.vae)
|
vae_info = context.models.load(self.vae.vae)
|
||||||
assert isinstance(vae_info.model, (AutoencoderKL, AutoencoderTiny))
|
assert isinstance(vae_info.model, (AutoencoderKL, AutoencoderTiny))
|
||||||
|
estimated_working_memory = estimate_vae_working_memory_sd15_sdxl(
|
||||||
estimated_working_memory = self._estimate_working_memory(latents, use_tiling, vae_info.model)
|
operation="decode",
|
||||||
|
image_tensor=latents,
|
||||||
|
vae=vae_info.model,
|
||||||
|
tile_size=self.tile_size if use_tiling else None,
|
||||||
|
fp32=self.fp32,
|
||||||
|
)
|
||||||
with (
|
with (
|
||||||
SeamlessExt.static_patch_model(vae_info.model, self.vae.seamless_axes),
|
SeamlessExt.static_patch_model(vae_info.model, self.vae.seamless_axes),
|
||||||
vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae),
|
vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae),
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from invokeai.app.invocations.fields import (
|
|||||||
SD3ConditioningField,
|
SD3ConditioningField,
|
||||||
TensorField,
|
TensorField,
|
||||||
UIComponent,
|
UIComponent,
|
||||||
|
VideoField,
|
||||||
)
|
)
|
||||||
from invokeai.app.services.images.images_common import ImageDTO
|
from invokeai.app.services.images.images_common import ImageDTO
|
||||||
from invokeai.app.services.shared.invocation_context import InvocationContext
|
from invokeai.app.services.shared.invocation_context import InvocationContext
|
||||||
@@ -287,6 +288,30 @@ class ImageCollectionInvocation(BaseInvocation):
|
|||||||
return ImageCollectionOutput(collection=self.collection)
|
return ImageCollectionOutput(collection=self.collection)
|
||||||
|
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region Video
|
||||||
|
|
||||||
|
|
||||||
|
@invocation_output("video_output")
|
||||||
|
class VideoOutput(BaseInvocationOutput):
|
||||||
|
"""Base class for nodes that output a video"""
|
||||||
|
|
||||||
|
video: VideoField = OutputField(description="The output video")
|
||||||
|
width: int = OutputField(description="The width of the video in pixels")
|
||||||
|
height: int = OutputField(description="The height of the video in pixels")
|
||||||
|
duration_seconds: float = OutputField(description="The duration of the video in seconds")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def build(cls, video_id: str, width: int, height: int, duration_seconds: float) -> "VideoOutput":
|
||||||
|
return cls(
|
||||||
|
video=VideoField(video_id=video_id),
|
||||||
|
width=width,
|
||||||
|
height=height,
|
||||||
|
duration_seconds=duration_seconds,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region DenoiseMask
|
# region DenoiseMask
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from invokeai.app.services.shared.invocation_context import InvocationContext
|
|||||||
from invokeai.backend.model_manager.load.load_base import LoadedModel
|
from invokeai.backend.model_manager.load.load_base import LoadedModel
|
||||||
from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
|
from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor
|
||||||
from invokeai.backend.util.devices import TorchDevice
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_sd3
|
||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
@@ -34,7 +35,11 @@ class SD3ImageToLatentsInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def vae_encode(vae_info: LoadedModel, image_tensor: torch.Tensor) -> torch.Tensor:
|
def vae_encode(vae_info: LoadedModel, image_tensor: torch.Tensor) -> torch.Tensor:
|
||||||
with vae_info as vae:
|
assert isinstance(vae_info.model, AutoencoderKL)
|
||||||
|
estimated_working_memory = estimate_vae_working_memory_sd3(
|
||||||
|
operation="encode", image_tensor=image_tensor, vae=vae_info.model
|
||||||
|
)
|
||||||
|
with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):
|
||||||
assert isinstance(vae, AutoencoderKL)
|
assert isinstance(vae, AutoencoderKL)
|
||||||
|
|
||||||
vae.disable_tiling()
|
vae.disable_tiling()
|
||||||
@@ -58,6 +63,8 @@ class SD3ImageToLatentsInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
image_tensor = einops.rearrange(image_tensor, "c h w -> 1 c h w")
|
image_tensor = einops.rearrange(image_tensor, "c h w -> 1 c h w")
|
||||||
|
|
||||||
vae_info = context.models.load(self.vae.vae)
|
vae_info = context.models.load(self.vae.vae)
|
||||||
|
assert isinstance(vae_info.model, AutoencoderKL)
|
||||||
|
|
||||||
latents = self.vae_encode(vae_info=vae_info, image_tensor=image_tensor)
|
latents = self.vae_encode(vae_info=vae_info, image_tensor=image_tensor)
|
||||||
|
|
||||||
latents = latents.to("cpu")
|
latents = latents.to("cpu")
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from einops import rearrange
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from invokeai.app.invocations.baseinvocation import BaseInvocation, invocation
|
from invokeai.app.invocations.baseinvocation import BaseInvocation, invocation
|
||||||
from invokeai.app.invocations.constants import LATENT_SCALE_FACTOR
|
|
||||||
from invokeai.app.invocations.fields import (
|
from invokeai.app.invocations.fields import (
|
||||||
FieldDescriptions,
|
FieldDescriptions,
|
||||||
Input,
|
Input,
|
||||||
@@ -20,6 +19,7 @@ from invokeai.app.invocations.primitives import ImageOutput
|
|||||||
from invokeai.app.services.shared.invocation_context import InvocationContext
|
from invokeai.app.services.shared.invocation_context import InvocationContext
|
||||||
from invokeai.backend.stable_diffusion.extensions.seamless import SeamlessExt
|
from invokeai.backend.stable_diffusion.extensions.seamless import SeamlessExt
|
||||||
from invokeai.backend.util.devices import TorchDevice
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_sd3
|
||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
@@ -41,22 +41,15 @@ class SD3LatentsToImageInvocation(BaseInvocation, WithMetadata, WithBoard):
|
|||||||
input=Input.Connection,
|
input=Input.Connection,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _estimate_working_memory(self, latents: torch.Tensor, vae: AutoencoderKL) -> int:
|
|
||||||
"""Estimate the working memory required by the invocation in bytes."""
|
|
||||||
out_h = LATENT_SCALE_FACTOR * latents.shape[-2]
|
|
||||||
out_w = LATENT_SCALE_FACTOR * latents.shape[-1]
|
|
||||||
element_size = next(vae.parameters()).element_size()
|
|
||||||
scaling_constant = 2200 # Determined experimentally.
|
|
||||||
working_memory = out_h * out_w * element_size * scaling_constant
|
|
||||||
return int(working_memory)
|
|
||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
def invoke(self, context: InvocationContext) -> ImageOutput:
|
def invoke(self, context: InvocationContext) -> ImageOutput:
|
||||||
latents = context.tensors.load(self.latents.latents_name)
|
latents = context.tensors.load(self.latents.latents_name)
|
||||||
|
|
||||||
vae_info = context.models.load(self.vae.vae)
|
vae_info = context.models.load(self.vae.vae)
|
||||||
assert isinstance(vae_info.model, (AutoencoderKL))
|
assert isinstance(vae_info.model, (AutoencoderKL))
|
||||||
estimated_working_memory = self._estimate_working_memory(latents, vae_info.model)
|
estimated_working_memory = estimate_vae_working_memory_sd3(
|
||||||
|
operation="decode", image_tensor=latents, vae=vae_info.model
|
||||||
|
)
|
||||||
with (
|
with (
|
||||||
SeamlessExt.static_patch_model(vae_info.model, self.vae.seamless_axes),
|
SeamlessExt.static_patch_model(vae_info.model, self.vae.seamless_axes),
|
||||||
vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae),
|
vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae),
|
||||||
|
|||||||
@@ -1,72 +1,75 @@
|
|||||||
from enum import Enum
|
from itertools import zip_longest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import torch
|
import torch
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field, model_validator
|
||||||
from transformers import AutoProcessor
|
|
||||||
from transformers.models.sam import SamModel
|
from transformers.models.sam import SamModel
|
||||||
from transformers.models.sam.processing_sam import SamProcessor
|
from transformers.models.sam.processing_sam import SamProcessor
|
||||||
|
from transformers.models.sam2 import Sam2Model
|
||||||
|
from transformers.models.sam2.processing_sam2 import Sam2Processor
|
||||||
|
|
||||||
from invokeai.app.invocations.baseinvocation import BaseInvocation, invocation
|
from invokeai.app.invocations.baseinvocation import BaseInvocation, invocation
|
||||||
from invokeai.app.invocations.fields import BoundingBoxField, ImageField, InputField, TensorField
|
from invokeai.app.invocations.fields import BoundingBoxField, ImageField, InputField, TensorField
|
||||||
from invokeai.app.invocations.primitives import MaskOutput
|
from invokeai.app.invocations.primitives import MaskOutput
|
||||||
from invokeai.app.services.shared.invocation_context import InvocationContext
|
from invokeai.app.services.shared.invocation_context import InvocationContext
|
||||||
from invokeai.backend.image_util.segment_anything.mask_refinement import mask_to_polygon, polygon_to_mask
|
from invokeai.backend.image_util.segment_anything.mask_refinement import mask_to_polygon, polygon_to_mask
|
||||||
|
from invokeai.backend.image_util.segment_anything.segment_anything_2_pipeline import SegmentAnything2Pipeline
|
||||||
from invokeai.backend.image_util.segment_anything.segment_anything_pipeline import SegmentAnythingPipeline
|
from invokeai.backend.image_util.segment_anything.segment_anything_pipeline import SegmentAnythingPipeline
|
||||||
|
from invokeai.backend.image_util.segment_anything.shared import SAMInput, SAMPoint
|
||||||
|
|
||||||
SegmentAnythingModelKey = Literal["segment-anything-base", "segment-anything-large", "segment-anything-huge"]
|
SegmentAnythingModelKey = Literal[
|
||||||
|
"segment-anything-base",
|
||||||
|
"segment-anything-large",
|
||||||
|
"segment-anything-huge",
|
||||||
|
"segment-anything-2-tiny",
|
||||||
|
"segment-anything-2-small",
|
||||||
|
"segment-anything-2-base",
|
||||||
|
"segment-anything-2-large",
|
||||||
|
]
|
||||||
SEGMENT_ANYTHING_MODEL_IDS: dict[SegmentAnythingModelKey, str] = {
|
SEGMENT_ANYTHING_MODEL_IDS: dict[SegmentAnythingModelKey, str] = {
|
||||||
"segment-anything-base": "facebook/sam-vit-base",
|
"segment-anything-base": "facebook/sam-vit-base",
|
||||||
"segment-anything-large": "facebook/sam-vit-large",
|
"segment-anything-large": "facebook/sam-vit-large",
|
||||||
"segment-anything-huge": "facebook/sam-vit-huge",
|
"segment-anything-huge": "facebook/sam-vit-huge",
|
||||||
|
"segment-anything-2-tiny": "facebook/sam2.1-hiera-tiny",
|
||||||
|
"segment-anything-2-small": "facebook/sam2.1-hiera-small",
|
||||||
|
"segment-anything-2-base": "facebook/sam2.1-hiera-base-plus",
|
||||||
|
"segment-anything-2-large": "facebook/sam2.1-hiera-large",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SAMPointLabel(Enum):
|
|
||||||
negative = -1
|
|
||||||
neutral = 0
|
|
||||||
positive = 1
|
|
||||||
|
|
||||||
|
|
||||||
class SAMPoint(BaseModel):
|
|
||||||
x: int = Field(..., description="The x-coordinate of the point")
|
|
||||||
y: int = Field(..., description="The y-coordinate of the point")
|
|
||||||
label: SAMPointLabel = Field(..., description="The label of the point")
|
|
||||||
|
|
||||||
|
|
||||||
class SAMPointsField(BaseModel):
|
class SAMPointsField(BaseModel):
|
||||||
points: list[SAMPoint] = Field(..., description="The points of the object")
|
points: list[SAMPoint] = Field(..., description="The points of the object", min_length=1)
|
||||||
|
|
||||||
def to_list(self) -> list[list[int]]:
|
def to_list(self) -> list[list[float]]:
|
||||||
return [[point.x, point.y, point.label.value] for point in self.points]
|
return [[point.x, point.y, point.label.value] for point in self.points]
|
||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
"segment_anything",
|
"segment_anything",
|
||||||
title="Segment Anything",
|
title="Segment Anything",
|
||||||
tags=["prompt", "segmentation"],
|
tags=["prompt", "segmentation", "sam", "sam2"],
|
||||||
category="segmentation",
|
category="segmentation",
|
||||||
version="1.2.0",
|
version="1.3.0",
|
||||||
)
|
)
|
||||||
class SegmentAnythingInvocation(BaseInvocation):
|
class SegmentAnythingInvocation(BaseInvocation):
|
||||||
"""Runs a Segment Anything Model."""
|
"""Runs a Segment Anything Model (SAM or SAM2)."""
|
||||||
|
|
||||||
# Reference:
|
# Reference:
|
||||||
# - https://arxiv.org/pdf/2304.02643
|
# - https://arxiv.org/pdf/2304.02643
|
||||||
# - https://huggingface.co/docs/transformers/v4.43.3/en/model_doc/grounding-dino#grounded-sam
|
# - https://huggingface.co/docs/transformers/v4.43.3/en/model_doc/grounding-dino#grounded-sam
|
||||||
# - https://github.com/NielsRogge/Transformers-Tutorials/blob/a39f33ac1557b02ebfb191ea7753e332b5ca933f/Grounding%20DINO/GroundingDINO_with_Segment_Anything.ipynb
|
# - https://github.com/NielsRogge/Transformers-Tutorials/blob/a39f33ac1557b02ebfb191ea7753e332b5ca933f/Grounding%20DINO/GroundingDINO_with_Segment_Anything.ipynb
|
||||||
|
|
||||||
model: SegmentAnythingModelKey = InputField(description="The Segment Anything model to use.")
|
model: SegmentAnythingModelKey = InputField(description="The Segment Anything model to use (SAM or SAM2).")
|
||||||
image: ImageField = InputField(description="The image to segment.")
|
image: ImageField = InputField(description="The image to segment.")
|
||||||
bounding_boxes: list[BoundingBoxField] | None = InputField(
|
bounding_boxes: list[BoundingBoxField] | None = InputField(
|
||||||
default=None, description="The bounding boxes to prompt the SAM model with."
|
default=None, description="The bounding boxes to prompt the model with."
|
||||||
)
|
)
|
||||||
point_lists: list[SAMPointsField] | None = InputField(
|
point_lists: list[SAMPointsField] | None = InputField(
|
||||||
default=None,
|
default=None,
|
||||||
description="The list of point lists to prompt the SAM model with. Each list of points represents a single object.",
|
description="The list of point lists to prompt the model with. Each list of points represents a single object.",
|
||||||
)
|
)
|
||||||
apply_polygon_refinement: bool = InputField(
|
apply_polygon_refinement: bool = InputField(
|
||||||
description="Whether to apply polygon refinement to the masks. This will smooth the edges of the masks slightly and ensure that each mask consists of a single closed polygon (before merging).",
|
description="Whether to apply polygon refinement to the masks. This will smooth the edges of the masks slightly and ensure that each mask consists of a single closed polygon (before merging).",
|
||||||
@@ -77,14 +80,18 @@ class SegmentAnythingInvocation(BaseInvocation):
|
|||||||
default="all",
|
default="all",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def validate_points_and_boxes_len(self):
|
||||||
|
if self.point_lists is not None and self.bounding_boxes is not None:
|
||||||
|
if len(self.point_lists) != len(self.bounding_boxes):
|
||||||
|
raise ValueError("If both point_lists and bounding_boxes are provided, they must have the same length.")
|
||||||
|
return self
|
||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
def invoke(self, context: InvocationContext) -> MaskOutput:
|
def invoke(self, context: InvocationContext) -> MaskOutput:
|
||||||
# The models expect a 3-channel RGB image.
|
# The models expect a 3-channel RGB image.
|
||||||
image_pil = context.images.get_pil(self.image.image_name, mode="RGB")
|
image_pil = context.images.get_pil(self.image.image_name, mode="RGB")
|
||||||
|
|
||||||
if self.point_lists is not None and self.bounding_boxes is not None:
|
|
||||||
raise ValueError("Only one of point_lists or bounding_box can be provided.")
|
|
||||||
|
|
||||||
if (not self.bounding_boxes or len(self.bounding_boxes) == 0) and (
|
if (not self.bounding_boxes or len(self.bounding_boxes) == 0) and (
|
||||||
not self.point_lists or len(self.point_lists) == 0
|
not self.point_lists or len(self.point_lists) == 0
|
||||||
):
|
):
|
||||||
@@ -111,26 +118,38 @@ class SegmentAnythingInvocation(BaseInvocation):
|
|||||||
# model, and figure out how to make it work in the pipeline.
|
# model, and figure out how to make it work in the pipeline.
|
||||||
# torch_dtype=TorchDevice.choose_torch_dtype(),
|
# torch_dtype=TorchDevice.choose_torch_dtype(),
|
||||||
)
|
)
|
||||||
|
sam_processor = SamProcessor.from_pretrained(model_path, local_files_only=True)
|
||||||
sam_processor = AutoProcessor.from_pretrained(model_path, local_files_only=True)
|
|
||||||
assert isinstance(sam_processor, SamProcessor)
|
|
||||||
return SegmentAnythingPipeline(sam_model=sam_model, sam_processor=sam_processor)
|
return SegmentAnythingPipeline(sam_model=sam_model, sam_processor=sam_processor)
|
||||||
|
|
||||||
def _segment(self, context: InvocationContext, image: Image.Image) -> list[torch.Tensor]:
|
@staticmethod
|
||||||
"""Use Segment Anything (SAM) to generate masks given an image + a set of bounding boxes."""
|
def _load_sam_2_model(model_path: Path):
|
||||||
# Convert the bounding boxes to the SAM input format.
|
sam2_model = Sam2Model.from_pretrained(model_path, local_files_only=True)
|
||||||
sam_bounding_boxes = (
|
sam2_processor = Sam2Processor.from_pretrained(model_path, local_files_only=True)
|
||||||
[[bb.x_min, bb.y_min, bb.x_max, bb.y_max] for bb in self.bounding_boxes] if self.bounding_boxes else None
|
return SegmentAnything2Pipeline(sam2_model=sam2_model, sam2_processor=sam2_processor)
|
||||||
)
|
|
||||||
sam_points = [p.to_list() for p in self.point_lists] if self.point_lists else None
|
|
||||||
|
|
||||||
with (
|
def _segment(self, context: InvocationContext, image: Image.Image) -> list[torch.Tensor]:
|
||||||
context.models.load_remote_model(
|
"""Use Segment Anything (SAM or SAM2) to generate masks given an image + a set of bounding boxes."""
|
||||||
source=SEGMENT_ANYTHING_MODEL_IDS[self.model], loader=SegmentAnythingInvocation._load_sam_model
|
|
||||||
) as sam_pipeline,
|
source = SEGMENT_ANYTHING_MODEL_IDS[self.model]
|
||||||
):
|
inputs: list[SAMInput] = []
|
||||||
assert isinstance(sam_pipeline, SegmentAnythingPipeline)
|
for bbox_field, point_field in zip_longest(self.bounding_boxes or [], self.point_lists or [], fillvalue=None):
|
||||||
masks = sam_pipeline.segment(image=image, bounding_boxes=sam_bounding_boxes, point_lists=sam_points)
|
inputs.append(
|
||||||
|
SAMInput(
|
||||||
|
bounding_box=bbox_field,
|
||||||
|
points=point_field.points if point_field else None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if "sam2" in source:
|
||||||
|
loader = SegmentAnythingInvocation._load_sam_2_model
|
||||||
|
with context.models.load_remote_model(source=source, loader=loader) as pipeline:
|
||||||
|
assert isinstance(pipeline, SegmentAnything2Pipeline)
|
||||||
|
masks = pipeline.segment(image=image, inputs=inputs)
|
||||||
|
else:
|
||||||
|
loader = SegmentAnythingInvocation._load_sam_model
|
||||||
|
with context.models.load_remote_model(source=source, loader=loader) as pipeline:
|
||||||
|
assert isinstance(pipeline, SegmentAnythingPipeline)
|
||||||
|
masks = pipeline.segment(image=image, inputs=inputs)
|
||||||
|
|
||||||
masks = self._process_masks(masks)
|
masks = self._process_masks(masks)
|
||||||
if self.apply_polygon_refinement:
|
if self.apply_polygon_refinement:
|
||||||
|
|||||||
@@ -49,3 +49,11 @@ class BoardImageRecordStorageBase(ABC):
|
|||||||
) -> int:
|
) -> int:
|
||||||
"""Gets the number of images for a board."""
|
"""Gets the number of images for a board."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_asset_count_for_board(
|
||||||
|
self,
|
||||||
|
board_id: str,
|
||||||
|
) -> int:
|
||||||
|
"""Gets the number of assets for a board."""
|
||||||
|
pass
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ from typing import Optional, cast
|
|||||||
|
|
||||||
from invokeai.app.services.board_image_records.board_image_records_base import BoardImageRecordStorageBase
|
from invokeai.app.services.board_image_records.board_image_records_base import BoardImageRecordStorageBase
|
||||||
from invokeai.app.services.image_records.image_records_common import (
|
from invokeai.app.services.image_records.image_records_common import (
|
||||||
|
ASSETS_CATEGORIES,
|
||||||
|
IMAGE_CATEGORIES,
|
||||||
ImageCategory,
|
ImageCategory,
|
||||||
ImageRecord,
|
ImageRecord,
|
||||||
deserialize_image_record,
|
deserialize_image_record,
|
||||||
@@ -151,15 +153,38 @@ class SqliteBoardImageRecordStorage(BoardImageRecordStorageBase):
|
|||||||
|
|
||||||
def get_image_count_for_board(self, board_id: str) -> int:
|
def get_image_count_for_board(self, board_id: str) -> int:
|
||||||
with self._db.transaction() as cursor:
|
with self._db.transaction() as cursor:
|
||||||
|
# Convert the enum values to unique list of strings
|
||||||
|
category_strings = [c.value for c in set(IMAGE_CATEGORIES)]
|
||||||
|
# Create the correct length of placeholders
|
||||||
|
placeholders = ",".join("?" * len(category_strings))
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"""--sql
|
f"""--sql
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM board_images
|
FROM board_images
|
||||||
INNER JOIN images ON board_images.image_name = images.image_name
|
INNER JOIN images ON board_images.image_name = images.image_name
|
||||||
WHERE images.is_intermediate = FALSE
|
WHERE images.is_intermediate = FALSE AND images.image_category IN ( {placeholders} )
|
||||||
AND board_images.board_id = ?;
|
AND board_images.board_id = ?;
|
||||||
""",
|
""",
|
||||||
(board_id,),
|
(*category_strings, board_id),
|
||||||
|
)
|
||||||
|
count = cast(int, cursor.fetchone()[0])
|
||||||
|
return count
|
||||||
|
|
||||||
|
def get_asset_count_for_board(self, board_id: str) -> int:
|
||||||
|
with self._db.transaction() as cursor:
|
||||||
|
# Convert the enum values to unique list of strings
|
||||||
|
category_strings = [c.value for c in set(ASSETS_CATEGORIES)]
|
||||||
|
# Create the correct length of placeholders
|
||||||
|
placeholders = ",".join("?" * len(category_strings))
|
||||||
|
cursor.execute(
|
||||||
|
f"""--sql
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM board_images
|
||||||
|
INNER JOIN images ON board_images.image_name = images.image_name
|
||||||
|
WHERE images.is_intermediate = FALSE AND images.image_category IN ( {placeholders} )
|
||||||
|
AND board_images.board_id = ?;
|
||||||
|
""",
|
||||||
|
(*category_strings, board_id),
|
||||||
)
|
)
|
||||||
count = cast(int, cursor.fetchone()[0])
|
count = cast(int, cursor.fetchone()[0])
|
||||||
return count
|
return count
|
||||||
|
|||||||
@@ -12,12 +12,20 @@ class BoardDTO(BoardRecord):
|
|||||||
"""The URL of the thumbnail of the most recent image in the board."""
|
"""The URL of the thumbnail of the most recent image in the board."""
|
||||||
image_count: int = Field(description="The number of images in the board.")
|
image_count: int = Field(description="The number of images in the board.")
|
||||||
"""The number of images in the board."""
|
"""The number of images in the board."""
|
||||||
|
asset_count: int = Field(description="The number of assets in the board.")
|
||||||
|
"""The number of assets in the board."""
|
||||||
|
video_count: int = Field(description="The number of videos in the board.")
|
||||||
|
"""The number of videos in the board."""
|
||||||
|
|
||||||
|
|
||||||
def board_record_to_dto(board_record: BoardRecord, cover_image_name: Optional[str], image_count: int) -> BoardDTO:
|
def board_record_to_dto(
|
||||||
|
board_record: BoardRecord, cover_image_name: Optional[str], image_count: int, asset_count: int, video_count: int
|
||||||
|
) -> BoardDTO:
|
||||||
"""Converts a board record to a board DTO."""
|
"""Converts a board record to a board DTO."""
|
||||||
return BoardDTO(
|
return BoardDTO(
|
||||||
**board_record.model_dump(exclude={"cover_image_name"}),
|
**board_record.model_dump(exclude={"cover_image_name"}),
|
||||||
cover_image_name=cover_image_name,
|
cover_image_name=cover_image_name,
|
||||||
image_count=image_count,
|
image_count=image_count,
|
||||||
|
asset_count=asset_count,
|
||||||
|
video_count=video_count,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class BoardService(BoardServiceABC):
|
|||||||
board_name: str,
|
board_name: str,
|
||||||
) -> BoardDTO:
|
) -> BoardDTO:
|
||||||
board_record = self.__invoker.services.board_records.save(board_name)
|
board_record = self.__invoker.services.board_records.save(board_name)
|
||||||
return board_record_to_dto(board_record, None, 0)
|
return board_record_to_dto(board_record, None, 0, 0, 0)
|
||||||
|
|
||||||
def get_dto(self, board_id: str) -> BoardDTO:
|
def get_dto(self, board_id: str) -> BoardDTO:
|
||||||
board_record = self.__invoker.services.board_records.get(board_id)
|
board_record = self.__invoker.services.board_records.get(board_id)
|
||||||
@@ -27,7 +27,9 @@ class BoardService(BoardServiceABC):
|
|||||||
else:
|
else:
|
||||||
cover_image_name = None
|
cover_image_name = None
|
||||||
image_count = self.__invoker.services.board_image_records.get_image_count_for_board(board_id)
|
image_count = self.__invoker.services.board_image_records.get_image_count_for_board(board_id)
|
||||||
return board_record_to_dto(board_record, cover_image_name, image_count)
|
asset_count = self.__invoker.services.board_image_records.get_asset_count_for_board(board_id)
|
||||||
|
video_count = 0 # noop for OSS
|
||||||
|
return board_record_to_dto(board_record, cover_image_name, image_count, asset_count, video_count)
|
||||||
|
|
||||||
def update(
|
def update(
|
||||||
self,
|
self,
|
||||||
@@ -42,7 +44,9 @@ class BoardService(BoardServiceABC):
|
|||||||
cover_image_name = None
|
cover_image_name = None
|
||||||
|
|
||||||
image_count = self.__invoker.services.board_image_records.get_image_count_for_board(board_id)
|
image_count = self.__invoker.services.board_image_records.get_image_count_for_board(board_id)
|
||||||
return board_record_to_dto(board_record, cover_image_name, image_count)
|
asset_count = self.__invoker.services.board_image_records.get_asset_count_for_board(board_id)
|
||||||
|
video_count = 0 # noop for OSS
|
||||||
|
return board_record_to_dto(board_record, cover_image_name, image_count, asset_count, video_count)
|
||||||
|
|
||||||
def delete(self, board_id: str) -> None:
|
def delete(self, board_id: str) -> None:
|
||||||
self.__invoker.services.board_records.delete(board_id)
|
self.__invoker.services.board_records.delete(board_id)
|
||||||
@@ -67,7 +71,9 @@ class BoardService(BoardServiceABC):
|
|||||||
cover_image_name = None
|
cover_image_name = None
|
||||||
|
|
||||||
image_count = self.__invoker.services.board_image_records.get_image_count_for_board(r.board_id)
|
image_count = self.__invoker.services.board_image_records.get_image_count_for_board(r.board_id)
|
||||||
board_dtos.append(board_record_to_dto(r, cover_image_name, image_count))
|
asset_count = self.__invoker.services.board_image_records.get_asset_count_for_board(r.board_id)
|
||||||
|
video_count = 0 # noop for OSS
|
||||||
|
board_dtos.append(board_record_to_dto(r, cover_image_name, image_count, asset_count, video_count))
|
||||||
|
|
||||||
return OffsetPaginatedResults[BoardDTO](items=board_dtos, offset=offset, limit=limit, total=len(board_dtos))
|
return OffsetPaginatedResults[BoardDTO](items=board_dtos, offset=offset, limit=limit, total=len(board_dtos))
|
||||||
|
|
||||||
@@ -84,6 +90,8 @@ class BoardService(BoardServiceABC):
|
|||||||
cover_image_name = None
|
cover_image_name = None
|
||||||
|
|
||||||
image_count = self.__invoker.services.board_image_records.get_image_count_for_board(r.board_id)
|
image_count = self.__invoker.services.board_image_records.get_image_count_for_board(r.board_id)
|
||||||
board_dtos.append(board_record_to_dto(r, cover_image_name, image_count))
|
asset_count = self.__invoker.services.board_image_records.get_asset_count_for_board(r.board_id)
|
||||||
|
video_count = 0 # noop for OSS
|
||||||
|
board_dtos.append(board_record_to_dto(r, cover_image_name, image_count, asset_count, video_count))
|
||||||
|
|
||||||
return board_dtos
|
return board_dtos
|
||||||
|
|||||||
@@ -150,4 +150,15 @@ class BulkDownloadService(BulkDownloadBase):
|
|||||||
def _is_valid_path(self, path: Union[str, Path]) -> bool:
|
def _is_valid_path(self, path: Union[str, Path]) -> bool:
|
||||||
"""Validates the path given for a bulk download."""
|
"""Validates the path given for a bulk download."""
|
||||||
path = path if isinstance(path, Path) else Path(path)
|
path = path if isinstance(path, Path) else Path(path)
|
||||||
return path.exists()
|
|
||||||
|
# Resolve the path to handle any path traversal attempts (e.g., ../)
|
||||||
|
resolved_path = path.resolve()
|
||||||
|
|
||||||
|
# The path may not traverse out of the bulk downloads folder or its subfolders
|
||||||
|
does_not_traverse = resolved_path.parent == self._bulk_downloads_folder.resolve()
|
||||||
|
|
||||||
|
# The path must exist and be a .zip file
|
||||||
|
does_exist = resolved_path.exists()
|
||||||
|
is_zip_file = resolved_path.suffix == ".zip"
|
||||||
|
|
||||||
|
return does_exist and is_zip_file and does_not_traverse
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
class ClientStatePersistenceABC(ABC):
|
||||||
|
"""
|
||||||
|
Base class for client persistence implementations.
|
||||||
|
This class defines the interface for persisting client data.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def set_by_key(self, queue_id: str, key: str, value: str) -> str:
|
||||||
|
"""
|
||||||
|
Set a key-value pair for the client.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The key to set.
|
||||||
|
value (str): The value to set for the key.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The value that was set.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_by_key(self, queue_id: str, key: str) -> str | None:
|
||||||
|
"""
|
||||||
|
Get the value for a specific key of the client.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The key to retrieve the value for.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str | None: The value associated with the key, or None if the key does not exist.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def delete(self, queue_id: str) -> None:
|
||||||
|
"""
|
||||||
|
Delete all client state.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from invokeai.app.services.client_state_persistence.client_state_persistence_base import ClientStatePersistenceABC
|
||||||
|
from invokeai.app.services.invoker import Invoker
|
||||||
|
from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase
|
||||||
|
|
||||||
|
|
||||||
|
class ClientStatePersistenceSqlite(ClientStatePersistenceABC):
|
||||||
|
"""
|
||||||
|
Base class for client persistence implementations.
|
||||||
|
This class defines the interface for persisting client data.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, db: SqliteDatabase) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self._db = db
|
||||||
|
self._default_row_id = 1
|
||||||
|
|
||||||
|
def start(self, invoker: Invoker) -> None:
|
||||||
|
self._invoker = invoker
|
||||||
|
|
||||||
|
def _get(self) -> dict[str, str] | None:
|
||||||
|
with self._db.transaction() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
f"""
|
||||||
|
SELECT data FROM client_state
|
||||||
|
WHERE id = {self._default_row_id}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if row is None:
|
||||||
|
return None
|
||||||
|
return json.loads(row[0])
|
||||||
|
|
||||||
|
def set_by_key(self, queue_id: str, key: str, value: str) -> str:
|
||||||
|
state = self._get() or {}
|
||||||
|
state.update({key: value})
|
||||||
|
|
||||||
|
with self._db.transaction() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
f"""
|
||||||
|
INSERT INTO client_state (id, data)
|
||||||
|
VALUES ({self._default_row_id}, ?)
|
||||||
|
ON CONFLICT(id) DO UPDATE
|
||||||
|
SET data = excluded.data;
|
||||||
|
""",
|
||||||
|
(json.dumps(state),),
|
||||||
|
)
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_by_key(self, queue_id: str, key: str) -> str | None:
|
||||||
|
state = self._get()
|
||||||
|
if state is None:
|
||||||
|
return None
|
||||||
|
return state.get(key, None)
|
||||||
|
|
||||||
|
def delete(self, queue_id: str) -> None:
|
||||||
|
with self._db.transaction() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
f"""
|
||||||
|
DELETE FROM client_state
|
||||||
|
WHERE id = {self._default_row_id}
|
||||||
|
"""
|
||||||
|
)
|
||||||
@@ -107,6 +107,7 @@ class InvokeAIAppConfig(BaseSettings):
|
|||||||
hashing_algorithm: Model hashing algorthim for model installs. 'blake3_multi' is best for SSDs. 'blake3_single' is best for spinning disk HDDs. 'random' disables hashing, instead assigning a UUID to models. Useful when using a memory db to reduce model installation time, or if you don't care about storing stable hashes for models. Alternatively, any other hashlib algorithm is accepted, though these are not nearly as performant as blake3.<br>Valid values: `blake3_multi`, `blake3_single`, `random`, `md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha512`, `blake2b`, `blake2s`, `sha3_224`, `sha3_256`, `sha3_384`, `sha3_512`, `shake_128`, `shake_256`
|
hashing_algorithm: Model hashing algorthim for model installs. 'blake3_multi' is best for SSDs. 'blake3_single' is best for spinning disk HDDs. 'random' disables hashing, instead assigning a UUID to models. Useful when using a memory db to reduce model installation time, or if you don't care about storing stable hashes for models. Alternatively, any other hashlib algorithm is accepted, though these are not nearly as performant as blake3.<br>Valid values: `blake3_multi`, `blake3_single`, `random`, `md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha512`, `blake2b`, `blake2s`, `sha3_224`, `sha3_256`, `sha3_384`, `sha3_512`, `shake_128`, `shake_256`
|
||||||
remote_api_tokens: List of regular expression and token pairs used when downloading models from URLs. The download URL is tested against the regex, and if it matches, the token is provided in as a Bearer token.
|
remote_api_tokens: List of regular expression and token pairs used when downloading models from URLs. The download URL is tested against the regex, and if it matches, the token is provided in as a Bearer token.
|
||||||
scan_models_on_startup: Scan the models directory on startup, registering orphaned models. This is typically only used in conjunction with `use_memory_db` for testing purposes.
|
scan_models_on_startup: Scan the models directory on startup, registering orphaned models. This is typically only used in conjunction with `use_memory_db` for testing purposes.
|
||||||
|
unsafe_disable_picklescan: UNSAFE. Disable the picklescan security check during model installation. Recommended only for development and testing purposes. This will allow arbitrary code execution during model installation, so should never be used in production.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_root: Optional[Path] = PrivateAttr(default=None)
|
_root: Optional[Path] = PrivateAttr(default=None)
|
||||||
@@ -196,6 +197,7 @@ class InvokeAIAppConfig(BaseSettings):
|
|||||||
hashing_algorithm: HASHING_ALGORITHMS = Field(default="blake3_single", description="Model hashing algorthim for model installs. 'blake3_multi' is best for SSDs. 'blake3_single' is best for spinning disk HDDs. 'random' disables hashing, instead assigning a UUID to models. Useful when using a memory db to reduce model installation time, or if you don't care about storing stable hashes for models. Alternatively, any other hashlib algorithm is accepted, though these are not nearly as performant as blake3.")
|
hashing_algorithm: HASHING_ALGORITHMS = Field(default="blake3_single", description="Model hashing algorthim for model installs. 'blake3_multi' is best for SSDs. 'blake3_single' is best for spinning disk HDDs. 'random' disables hashing, instead assigning a UUID to models. Useful when using a memory db to reduce model installation time, or if you don't care about storing stable hashes for models. Alternatively, any other hashlib algorithm is accepted, though these are not nearly as performant as blake3.")
|
||||||
remote_api_tokens: Optional[list[URLRegexTokenPair]] = Field(default=None, description="List of regular expression and token pairs used when downloading models from URLs. The download URL is tested against the regex, and if it matches, the token is provided in as a Bearer token.")
|
remote_api_tokens: Optional[list[URLRegexTokenPair]] = Field(default=None, description="List of regular expression and token pairs used when downloading models from URLs. The download URL is tested against the regex, and if it matches, the token is provided in as a Bearer token.")
|
||||||
scan_models_on_startup: bool = Field(default=False, description="Scan the models directory on startup, registering orphaned models. This is typically only used in conjunction with `use_memory_db` for testing purposes.")
|
scan_models_on_startup: bool = Field(default=False, description="Scan the models directory on startup, registering orphaned models. This is typically only used in conjunction with `use_memory_db` for testing purposes.")
|
||||||
|
unsafe_disable_picklescan: bool = Field(default=False, description="UNSAFE. Disable the picklescan security check during model installation. Recommended only for development and testing purposes. This will allow arbitrary code execution during model installation, so should never be used in production.")
|
||||||
|
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
|
|||||||
@@ -234,8 +234,8 @@ class QueueItemStatusChangedEvent(QueueItemEventBase):
|
|||||||
error_type: Optional[str] = Field(default=None, description="The error type, if any")
|
error_type: Optional[str] = Field(default=None, description="The error type, if any")
|
||||||
error_message: Optional[str] = Field(default=None, description="The error message, if any")
|
error_message: Optional[str] = Field(default=None, description="The error message, if any")
|
||||||
error_traceback: Optional[str] = Field(default=None, description="The error traceback, if any")
|
error_traceback: Optional[str] = Field(default=None, description="The error traceback, if any")
|
||||||
created_at: Optional[str] = Field(default=None, description="The timestamp when the queue item was created")
|
created_at: str = Field(description="The timestamp when the queue item was created")
|
||||||
updated_at: Optional[str] = Field(default=None, description="The timestamp when the queue item was last updated")
|
updated_at: str = Field(description="The timestamp when the queue item was last updated")
|
||||||
started_at: Optional[str] = Field(default=None, description="The timestamp when the queue item was started")
|
started_at: Optional[str] = Field(default=None, description="The timestamp when the queue item was started")
|
||||||
completed_at: Optional[str] = Field(default=None, description="The timestamp when the queue item was completed")
|
completed_at: Optional[str] = Field(default=None, description="The timestamp when the queue item was completed")
|
||||||
batch_status: BatchStatus = Field(description="The status of the batch")
|
batch_status: BatchStatus = Field(description="The status of the batch")
|
||||||
@@ -258,8 +258,8 @@ class QueueItemStatusChangedEvent(QueueItemEventBase):
|
|||||||
error_type=queue_item.error_type,
|
error_type=queue_item.error_type,
|
||||||
error_message=queue_item.error_message,
|
error_message=queue_item.error_message,
|
||||||
error_traceback=queue_item.error_traceback,
|
error_traceback=queue_item.error_traceback,
|
||||||
created_at=str(queue_item.created_at) if queue_item.created_at else None,
|
created_at=str(queue_item.created_at),
|
||||||
updated_at=str(queue_item.updated_at) if queue_item.updated_at else None,
|
updated_at=str(queue_item.updated_at),
|
||||||
started_at=str(queue_item.started_at) if queue_item.started_at else None,
|
started_at=str(queue_item.started_at) if queue_item.started_at else None,
|
||||||
completed_at=str(queue_item.completed_at) if queue_item.completed_at else None,
|
completed_at=str(queue_item.completed_at) if queue_item.completed_at else None,
|
||||||
batch_status=batch_status,
|
batch_status=batch_status,
|
||||||
|
|||||||
@@ -58,6 +58,15 @@ class ImageCategory(str, Enum, metaclass=MetaEnum):
|
|||||||
"""OTHER: The image is some other type of image with a specialized purpose. To be used by external nodes."""
|
"""OTHER: The image is some other type of image with a specialized purpose. To be used by external nodes."""
|
||||||
|
|
||||||
|
|
||||||
|
IMAGE_CATEGORIES: list[ImageCategory] = [ImageCategory.GENERAL]
|
||||||
|
ASSETS_CATEGORIES: list[ImageCategory] = [
|
||||||
|
ImageCategory.CONTROL,
|
||||||
|
ImageCategory.MASK,
|
||||||
|
ImageCategory.USER,
|
||||||
|
ImageCategory.OTHER,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class InvalidImageCategoryException(ValueError):
|
class InvalidImageCategoryException(ValueError):
|
||||||
"""Raised when a provided value is not a valid ImageCategory.
|
"""Raised when a provided value is not a valid ImageCategory.
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ if TYPE_CHECKING:
|
|||||||
from invokeai.app.services.board_records.board_records_base import BoardRecordStorageBase
|
from invokeai.app.services.board_records.board_records_base import BoardRecordStorageBase
|
||||||
from invokeai.app.services.boards.boards_base import BoardServiceABC
|
from invokeai.app.services.boards.boards_base import BoardServiceABC
|
||||||
from invokeai.app.services.bulk_download.bulk_download_base import BulkDownloadBase
|
from invokeai.app.services.bulk_download.bulk_download_base import BulkDownloadBase
|
||||||
|
from invokeai.app.services.client_state_persistence.client_state_persistence_base import ClientStatePersistenceABC
|
||||||
from invokeai.app.services.config import InvokeAIAppConfig
|
from invokeai.app.services.config import InvokeAIAppConfig
|
||||||
from invokeai.app.services.download import DownloadQueueServiceBase
|
from invokeai.app.services.download import DownloadQueueServiceBase
|
||||||
from invokeai.app.services.events.events_base import EventServiceBase
|
from invokeai.app.services.events.events_base import EventServiceBase
|
||||||
@@ -73,6 +74,7 @@ class InvocationServices:
|
|||||||
style_preset_records: "StylePresetRecordsStorageBase",
|
style_preset_records: "StylePresetRecordsStorageBase",
|
||||||
style_preset_image_files: "StylePresetImageFileStorageBase",
|
style_preset_image_files: "StylePresetImageFileStorageBase",
|
||||||
workflow_thumbnails: "WorkflowThumbnailServiceBase",
|
workflow_thumbnails: "WorkflowThumbnailServiceBase",
|
||||||
|
client_state_persistence: "ClientStatePersistenceABC",
|
||||||
):
|
):
|
||||||
self.board_images = board_images
|
self.board_images = board_images
|
||||||
self.board_image_records = board_image_records
|
self.board_image_records = board_image_records
|
||||||
@@ -102,3 +104,4 @@ class InvocationServices:
|
|||||||
self.style_preset_records = style_preset_records
|
self.style_preset_records = style_preset_records
|
||||||
self.style_preset_image_files = style_preset_image_files
|
self.style_preset_image_files = style_preset_image_files
|
||||||
self.workflow_thumbnails = workflow_thumbnails
|
self.workflow_thumbnails = workflow_thumbnails
|
||||||
|
self.client_state_persistence = client_state_persistence
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import threading
|
|||||||
import time
|
import time
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from queue import Empty, Queue
|
from queue import Empty, Queue
|
||||||
from shutil import copyfile, copytree, move, rmtree
|
from shutil import move, rmtree
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union
|
||||||
|
|
||||||
@@ -186,13 +186,15 @@ class ModelInstallService(ModelInstallServiceBase):
|
|||||||
info: AnyModelConfig = self._probe(Path(model_path), config) # type: ignore
|
info: AnyModelConfig = self._probe(Path(model_path), config) # type: ignore
|
||||||
|
|
||||||
if preferred_name := config.name:
|
if preferred_name := config.name:
|
||||||
preferred_name = Path(preferred_name).with_suffix(model_path.suffix)
|
if Path(model_path).is_file():
|
||||||
|
# Careful! Don't use pathlib.Path(...).with_suffix - it can will strip everything after the first dot.
|
||||||
|
preferred_name = f"{preferred_name}{model_path.suffix}"
|
||||||
|
|
||||||
dest_path = (
|
dest_path = (
|
||||||
self.app_config.models_path / info.base.value / info.type.value / (preferred_name or model_path.name)
|
self.app_config.models_path / info.base.value / info.type.value / (preferred_name or model_path.name)
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
new_path = self._copy_model(model_path, dest_path)
|
new_path = self._move_model(model_path, dest_path)
|
||||||
except FileExistsError as excp:
|
except FileExistsError as excp:
|
||||||
raise DuplicateModelException(
|
raise DuplicateModelException(
|
||||||
f"A model named {model_path.name} is already installed at {dest_path.as_posix()}"
|
f"A model named {model_path.name} is already installed at {dest_path.as_posix()}"
|
||||||
@@ -617,30 +619,17 @@ class ModelInstallService(ModelInstallServiceBase):
|
|||||||
self.record_store.update_model(key, ModelRecordChanges(path=model.path))
|
self.record_store.update_model(key, ModelRecordChanges(path=model.path))
|
||||||
return model
|
return model
|
||||||
|
|
||||||
def _copy_model(self, old_path: Path, new_path: Path) -> Path:
|
|
||||||
if old_path == new_path:
|
|
||||||
return old_path
|
|
||||||
new_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
if old_path.is_dir():
|
|
||||||
copytree(old_path, new_path)
|
|
||||||
else:
|
|
||||||
copyfile(old_path, new_path)
|
|
||||||
return new_path
|
|
||||||
|
|
||||||
def _move_model(self, old_path: Path, new_path: Path) -> Path:
|
def _move_model(self, old_path: Path, new_path: Path) -> Path:
|
||||||
if old_path == new_path:
|
if old_path == new_path:
|
||||||
return old_path
|
return old_path
|
||||||
|
|
||||||
|
if new_path.exists():
|
||||||
|
raise FileExistsError(f"Cannot move {old_path} to {new_path}: destination already exists")
|
||||||
|
|
||||||
new_path.parent.mkdir(parents=True, exist_ok=True)
|
new_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
# if path already exists then we jigger the name to make it unique
|
|
||||||
counter: int = 1
|
|
||||||
while new_path.exists():
|
|
||||||
path = new_path.with_stem(new_path.stem + f"_{counter:02d}")
|
|
||||||
if not path.exists():
|
|
||||||
new_path = path
|
|
||||||
counter += 1
|
|
||||||
move(old_path, new_path)
|
move(old_path, new_path)
|
||||||
|
|
||||||
return new_path
|
return new_path
|
||||||
|
|
||||||
def _probe(self, model_path: Path, config: Optional[ModelRecordChanges] = None):
|
def _probe(self, model_path: Path, config: Optional[ModelRecordChanges] = None):
|
||||||
|
|||||||
@@ -87,9 +87,21 @@ class ModelLoadService(ModelLoadServiceBase):
|
|||||||
def torch_load_file(checkpoint: Path) -> AnyModel:
|
def torch_load_file(checkpoint: Path) -> AnyModel:
|
||||||
scan_result = scan_file_path(checkpoint)
|
scan_result = scan_file_path(checkpoint)
|
||||||
if scan_result.infected_files != 0:
|
if scan_result.infected_files != 0:
|
||||||
raise Exception(f"The model at {checkpoint} is potentially infected by malware. Aborting load.")
|
if self._app_config.unsafe_disable_picklescan:
|
||||||
|
self._logger.warning(
|
||||||
|
f"Model at {checkpoint} is potentially infected by malware, but picklescan is disabled. "
|
||||||
|
"Proceeding with caution."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise Exception(f"The model at {checkpoint} is potentially infected by malware. Aborting load.")
|
||||||
if scan_result.scan_err:
|
if scan_result.scan_err:
|
||||||
raise Exception(f"Error scanning model at {checkpoint} for malware. Aborting load.")
|
if self._app_config.unsafe_disable_picklescan:
|
||||||
|
self._logger.warning(
|
||||||
|
f"Error scanning model at {checkpoint} for malware, but picklescan is disabled. "
|
||||||
|
"Proceeding with caution."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise Exception(f"Error scanning model at {checkpoint} for malware. Aborting load.")
|
||||||
|
|
||||||
result = torch_load(checkpoint, map_location="cpu")
|
result = torch_load(checkpoint, map_location="cpu")
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from invokeai.app.util.model_exclude_null import BaseModelExcludeNull
|
|||||||
from invokeai.backend.model_manager.config import (
|
from invokeai.backend.model_manager.config import (
|
||||||
AnyModelConfig,
|
AnyModelConfig,
|
||||||
ControlAdapterDefaultSettings,
|
ControlAdapterDefaultSettings,
|
||||||
|
LoraModelDefaultSettings,
|
||||||
MainModelDefaultSettings,
|
MainModelDefaultSettings,
|
||||||
)
|
)
|
||||||
from invokeai.backend.model_manager.taxonomy import (
|
from invokeai.backend.model_manager.taxonomy import (
|
||||||
@@ -83,8 +84,8 @@ class ModelRecordChanges(BaseModelExcludeNull):
|
|||||||
file_size: Optional[int] = Field(description="Size of model file", default=None)
|
file_size: Optional[int] = Field(description="Size of model file", default=None)
|
||||||
format: Optional[str] = Field(description="format of model file", default=None)
|
format: Optional[str] = Field(description="format of model file", default=None)
|
||||||
trigger_phrases: Optional[set[str]] = Field(description="Set of trigger phrases for this model", default=None)
|
trigger_phrases: Optional[set[str]] = Field(description="Set of trigger phrases for this model", default=None)
|
||||||
default_settings: Optional[MainModelDefaultSettings | ControlAdapterDefaultSettings] = Field(
|
default_settings: Optional[MainModelDefaultSettings | LoraModelDefaultSettings | ControlAdapterDefaultSettings] = (
|
||||||
description="Default settings for this model", default=None
|
Field(description="Default settings for this model", default=None)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Checkpoint-specific changes
|
# Checkpoint-specific changes
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ from abc import ABC, abstractmethod
|
|||||||
from typing import Any, Coroutine, Optional
|
from typing import Any, Coroutine, Optional
|
||||||
|
|
||||||
from invokeai.app.services.session_queue.session_queue_common import (
|
from invokeai.app.services.session_queue.session_queue_common import (
|
||||||
QUEUE_ITEM_STATUS,
|
|
||||||
Batch,
|
Batch,
|
||||||
BatchStatus,
|
BatchStatus,
|
||||||
CancelAllExceptCurrentResult,
|
CancelAllExceptCurrentResult,
|
||||||
@@ -15,6 +14,7 @@ from invokeai.app.services.session_queue.session_queue_common import (
|
|||||||
EnqueueBatchResult,
|
EnqueueBatchResult,
|
||||||
IsEmptyResult,
|
IsEmptyResult,
|
||||||
IsFullResult,
|
IsFullResult,
|
||||||
|
ItemIdsResult,
|
||||||
PruneResult,
|
PruneResult,
|
||||||
RetryItemsResult,
|
RetryItemsResult,
|
||||||
SessionQueueCountsByDestination,
|
SessionQueueCountsByDestination,
|
||||||
@@ -22,7 +22,7 @@ from invokeai.app.services.session_queue.session_queue_common import (
|
|||||||
SessionQueueStatus,
|
SessionQueueStatus,
|
||||||
)
|
)
|
||||||
from invokeai.app.services.shared.graph import GraphExecutionState
|
from invokeai.app.services.shared.graph import GraphExecutionState
|
||||||
from invokeai.app.services.shared.pagination import CursorPaginatedResults
|
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
|
||||||
|
|
||||||
|
|
||||||
class SessionQueueBase(ABC):
|
class SessionQueueBase(ABC):
|
||||||
@@ -135,19 +135,6 @@ class SessionQueueBase(ABC):
|
|||||||
"""Deletes all queue items except in-progress items"""
|
"""Deletes all queue items except in-progress items"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def list_queue_items(
|
|
||||||
self,
|
|
||||||
queue_id: str,
|
|
||||||
limit: int,
|
|
||||||
priority: int,
|
|
||||||
cursor: Optional[int] = None,
|
|
||||||
status: Optional[QUEUE_ITEM_STATUS] = None,
|
|
||||||
destination: Optional[str] = None,
|
|
||||||
) -> CursorPaginatedResults[SessionQueueItem]:
|
|
||||||
"""Gets a page of session queue items"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def list_all_queue_items(
|
def list_all_queue_items(
|
||||||
self,
|
self,
|
||||||
@@ -157,9 +144,18 @@ class SessionQueueBase(ABC):
|
|||||||
"""Gets all queue items that match the given parameters"""
|
"""Gets all queue items that match the given parameters"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_queue_item_ids(
|
||||||
|
self,
|
||||||
|
queue_id: str,
|
||||||
|
order_dir: SQLiteDirection = SQLiteDirection.Descending,
|
||||||
|
) -> ItemIdsResult:
|
||||||
|
"""Gets all queue item ids that match the given parameters"""
|
||||||
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_queue_item(self, item_id: int) -> SessionQueueItem:
|
def get_queue_item(self, item_id: int) -> SessionQueueItem:
|
||||||
"""Gets a session queue item by ID"""
|
"""Gets a session queue item by ID for a given queue"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
|||||||
@@ -176,6 +176,14 @@ DEFAULT_QUEUE_ID = "default"
|
|||||||
|
|
||||||
QUEUE_ITEM_STATUS = Literal["pending", "in_progress", "completed", "failed", "canceled"]
|
QUEUE_ITEM_STATUS = Literal["pending", "in_progress", "completed", "failed", "canceled"]
|
||||||
|
|
||||||
|
|
||||||
|
class ItemIdsResult(BaseModel):
|
||||||
|
"""Response containing ordered item ids with metadata for optimistic updates."""
|
||||||
|
|
||||||
|
item_ids: list[int] = Field(description="Ordered list of item ids")
|
||||||
|
total_count: int = Field(description="Total number of queue items matching the query")
|
||||||
|
|
||||||
|
|
||||||
NodeFieldValueValidator = TypeAdapter(list[NodeFieldValue])
|
NodeFieldValueValidator = TypeAdapter(list[NodeFieldValue])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from invokeai.app.services.session_queue.session_queue_common import (
|
|||||||
EnqueueBatchResult,
|
EnqueueBatchResult,
|
||||||
IsEmptyResult,
|
IsEmptyResult,
|
||||||
IsFullResult,
|
IsFullResult,
|
||||||
|
ItemIdsResult,
|
||||||
PruneResult,
|
PruneResult,
|
||||||
RetryItemsResult,
|
RetryItemsResult,
|
||||||
SessionQueueCountsByDestination,
|
SessionQueueCountsByDestination,
|
||||||
@@ -33,7 +34,7 @@ from invokeai.app.services.session_queue.session_queue_common import (
|
|||||||
prepare_values_to_insert,
|
prepare_values_to_insert,
|
||||||
)
|
)
|
||||||
from invokeai.app.services.shared.graph import GraphExecutionState
|
from invokeai.app.services.shared.graph import GraphExecutionState
|
||||||
from invokeai.app.services.shared.pagination import CursorPaginatedResults
|
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
|
||||||
from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase
|
from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase
|
||||||
|
|
||||||
|
|
||||||
@@ -587,59 +588,6 @@ class SqliteSessionQueue(SessionQueueBase):
|
|||||||
)
|
)
|
||||||
return self.get_queue_item(item_id)
|
return self.get_queue_item(item_id)
|
||||||
|
|
||||||
def list_queue_items(
|
|
||||||
self,
|
|
||||||
queue_id: str,
|
|
||||||
limit: int,
|
|
||||||
priority: int,
|
|
||||||
cursor: Optional[int] = None,
|
|
||||||
status: Optional[QUEUE_ITEM_STATUS] = None,
|
|
||||||
destination: Optional[str] = None,
|
|
||||||
) -> CursorPaginatedResults[SessionQueueItem]:
|
|
||||||
with self._db.transaction() as cursor_:
|
|
||||||
item_id = cursor
|
|
||||||
query = """--sql
|
|
||||||
SELECT *
|
|
||||||
FROM session_queue
|
|
||||||
WHERE queue_id = ?
|
|
||||||
"""
|
|
||||||
params: list[Union[str, int]] = [queue_id]
|
|
||||||
|
|
||||||
if status is not None:
|
|
||||||
query += """--sql
|
|
||||||
AND status = ?
|
|
||||||
"""
|
|
||||||
params.append(status)
|
|
||||||
|
|
||||||
if destination is not None:
|
|
||||||
query += """---sql
|
|
||||||
AND destination = ?
|
|
||||||
"""
|
|
||||||
params.append(destination)
|
|
||||||
|
|
||||||
if item_id is not None:
|
|
||||||
query += """--sql
|
|
||||||
AND (priority < ?) OR (priority = ? AND item_id > ?)
|
|
||||||
"""
|
|
||||||
params.extend([priority, priority, item_id])
|
|
||||||
|
|
||||||
query += """--sql
|
|
||||||
ORDER BY
|
|
||||||
priority DESC,
|
|
||||||
item_id ASC
|
|
||||||
LIMIT ?
|
|
||||||
"""
|
|
||||||
params.append(limit + 1)
|
|
||||||
cursor_.execute(query, params)
|
|
||||||
results = cast(list[sqlite3.Row], cursor_.fetchall())
|
|
||||||
items = [SessionQueueItem.queue_item_from_dict(dict(result)) for result in results]
|
|
||||||
has_more = False
|
|
||||||
if len(items) > limit:
|
|
||||||
# remove the extra item
|
|
||||||
items.pop()
|
|
||||||
has_more = True
|
|
||||||
return CursorPaginatedResults(items=items, limit=limit, has_more=has_more)
|
|
||||||
|
|
||||||
def list_all_queue_items(
|
def list_all_queue_items(
|
||||||
self,
|
self,
|
||||||
queue_id: str,
|
queue_id: str,
|
||||||
@@ -671,6 +619,26 @@ class SqliteSessionQueue(SessionQueueBase):
|
|||||||
items = [SessionQueueItem.queue_item_from_dict(dict(result)) for result in results]
|
items = [SessionQueueItem.queue_item_from_dict(dict(result)) for result in results]
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
def get_queue_item_ids(
|
||||||
|
self,
|
||||||
|
queue_id: str,
|
||||||
|
order_dir: SQLiteDirection = SQLiteDirection.Descending,
|
||||||
|
) -> ItemIdsResult:
|
||||||
|
with self._db.transaction() as cursor_:
|
||||||
|
query = f"""--sql
|
||||||
|
SELECT item_id
|
||||||
|
FROM session_queue
|
||||||
|
WHERE queue_id = ?
|
||||||
|
ORDER BY created_at {order_dir.value}
|
||||||
|
"""
|
||||||
|
query_params = [queue_id]
|
||||||
|
|
||||||
|
cursor_.execute(query, query_params)
|
||||||
|
result = cast(list[sqlite3.Row], cursor_.fetchall())
|
||||||
|
item_ids = [row[0] for row in result]
|
||||||
|
|
||||||
|
return ItemIdsResult(item_ids=item_ids, total_count=len(item_ids))
|
||||||
|
|
||||||
def get_queue_status(self, queue_id: str) -> SessionQueueStatus:
|
def get_queue_status(self, queue_id: str) -> SessionQueueStatus:
|
||||||
with self._db.transaction() as cursor:
|
with self._db.transaction() as cursor:
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from invokeai.app.services.shared.sqlite_migrator.migrations.migration_17 import
|
|||||||
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_18 import build_migration_18
|
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_18 import build_migration_18
|
||||||
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_19 import build_migration_19
|
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_19 import build_migration_19
|
||||||
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_20 import build_migration_20
|
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_20 import build_migration_20
|
||||||
|
from invokeai.app.services.shared.sqlite_migrator.migrations.migration_21 import build_migration_21
|
||||||
from invokeai.app.services.shared.sqlite_migrator.sqlite_migrator_impl import SqliteMigrator
|
from invokeai.app.services.shared.sqlite_migrator.sqlite_migrator_impl import SqliteMigrator
|
||||||
|
|
||||||
|
|
||||||
@@ -63,6 +64,7 @@ def init_db(config: InvokeAIAppConfig, logger: Logger, image_files: ImageFileSto
|
|||||||
migrator.register_migration(build_migration_18())
|
migrator.register_migration(build_migration_18())
|
||||||
migrator.register_migration(build_migration_19(app_config=config))
|
migrator.register_migration(build_migration_19(app_config=config))
|
||||||
migrator.register_migration(build_migration_20())
|
migrator.register_migration(build_migration_20())
|
||||||
|
migrator.register_migration(build_migration_21())
|
||||||
migrator.run_migrations()
|
migrator.run_migrations()
|
||||||
|
|
||||||
return db
|
return db
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import sqlite3
|
||||||
|
|
||||||
|
from invokeai.app.services.shared.sqlite_migrator.sqlite_migrator_common import Migration
|
||||||
|
|
||||||
|
|
||||||
|
class Migration21Callback:
|
||||||
|
def __call__(self, cursor: sqlite3.Cursor) -> None:
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
CREATE TABLE client_state (
|
||||||
|
id INTEGER PRIMARY KEY CHECK(id = 1),
|
||||||
|
data TEXT NOT NULL, -- Frontend will handle the shape of this data
|
||||||
|
updated_at DATETIME NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
CREATE TRIGGER tg_client_state_updated_at
|
||||||
|
AFTER UPDATE ON client_state
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE client_state
|
||||||
|
SET updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = OLD.id;
|
||||||
|
END;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def build_migration_21() -> Migration:
|
||||||
|
"""Builds the migration object for migrating from version 20 to version 21. This includes:
|
||||||
|
- Creating the `client_state` table.
|
||||||
|
- Adding a trigger to update the `updated_at` field on updates.
|
||||||
|
"""
|
||||||
|
return Migration(
|
||||||
|
from_version=20,
|
||||||
|
to_version=21,
|
||||||
|
callback=Migration21Callback(),
|
||||||
|
)
|
||||||
179
invokeai/app/services/videos_common.py
Normal file
179
invokeai/app/services/videos_common.py
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
import datetime
|
||||||
|
from typing import Optional, Union
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field, StrictBool, StrictStr
|
||||||
|
|
||||||
|
from invokeai.app.util.misc import get_iso_timestamp
|
||||||
|
from invokeai.app.util.model_exclude_null import BaseModelExcludeNull
|
||||||
|
|
||||||
|
VIDEO_DTO_COLS = ", ".join(
|
||||||
|
[
|
||||||
|
"videos." + c
|
||||||
|
for c in [
|
||||||
|
"video_id",
|
||||||
|
"width",
|
||||||
|
"height",
|
||||||
|
"session_id",
|
||||||
|
"node_id",
|
||||||
|
"is_intermediate",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
"starred",
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VideoRecord(BaseModelExcludeNull):
|
||||||
|
"""Deserialized video record without metadata."""
|
||||||
|
|
||||||
|
video_id: str = Field(description="The unique id of the video.")
|
||||||
|
"""The unique id of the video."""
|
||||||
|
width: int = Field(description="The width of the video in px.")
|
||||||
|
"""The actual width of the video in px. This may be different from the width in metadata."""
|
||||||
|
height: int = Field(description="The height of the video in px.")
|
||||||
|
"""The actual height of the video in px. This may be different from the height in metadata."""
|
||||||
|
created_at: Union[datetime.datetime, str] = Field(description="The created timestamp of the video.")
|
||||||
|
"""The created timestamp of the video."""
|
||||||
|
updated_at: Union[datetime.datetime, str] = Field(description="The updated timestamp of the video.")
|
||||||
|
"""The updated timestamp of the video."""
|
||||||
|
deleted_at: Optional[Union[datetime.datetime, str]] = Field(
|
||||||
|
default=None, description="The deleted timestamp of the video."
|
||||||
|
)
|
||||||
|
"""The deleted timestamp of the video."""
|
||||||
|
is_intermediate: bool = Field(description="Whether this is an intermediate video.")
|
||||||
|
"""Whether this is an intermediate video."""
|
||||||
|
session_id: Optional[str] = Field(
|
||||||
|
default=None,
|
||||||
|
description="The session ID that generated this video, if it is a generated video.",
|
||||||
|
)
|
||||||
|
"""The session ID that generated this video, if it is a generated video."""
|
||||||
|
node_id: Optional[str] = Field(
|
||||||
|
default=None,
|
||||||
|
description="The node ID that generated this video, if it is a generated video.",
|
||||||
|
)
|
||||||
|
"""The node ID that generated this video, if it is a generated video."""
|
||||||
|
starred: bool = Field(description="Whether this video is starred.")
|
||||||
|
"""Whether this video is starred."""
|
||||||
|
|
||||||
|
|
||||||
|
class VideoRecordChanges(BaseModelExcludeNull):
|
||||||
|
"""A set of changes to apply to a video record.
|
||||||
|
|
||||||
|
Only limited changes are valid:
|
||||||
|
- `session_id`: change the session associated with a video
|
||||||
|
- `is_intermediate`: change the video's `is_intermediate` flag
|
||||||
|
- `starred`: change whether the video is starred
|
||||||
|
"""
|
||||||
|
|
||||||
|
session_id: Optional[StrictStr] = Field(
|
||||||
|
default=None,
|
||||||
|
description="The video's new session ID.",
|
||||||
|
)
|
||||||
|
"""The video's new session ID."""
|
||||||
|
is_intermediate: Optional[StrictBool] = Field(default=None, description="The video's new `is_intermediate` flag.")
|
||||||
|
"""The video's new `is_intermediate` flag."""
|
||||||
|
starred: Optional[StrictBool] = Field(default=None, description="The video's new `starred` state")
|
||||||
|
"""The video's new `starred` state."""
|
||||||
|
|
||||||
|
|
||||||
|
def deserialize_video_record(video_dict: dict) -> VideoRecord:
|
||||||
|
"""Deserializes a video record."""
|
||||||
|
|
||||||
|
# Retrieve all the values, setting "reasonable" defaults if they are not present.
|
||||||
|
video_id = video_dict.get("video_id", "unknown")
|
||||||
|
width = video_dict.get("width", 0)
|
||||||
|
height = video_dict.get("height", 0)
|
||||||
|
session_id = video_dict.get("session_id", None)
|
||||||
|
node_id = video_dict.get("node_id", None)
|
||||||
|
created_at = video_dict.get("created_at", get_iso_timestamp())
|
||||||
|
updated_at = video_dict.get("updated_at", get_iso_timestamp())
|
||||||
|
deleted_at = video_dict.get("deleted_at", get_iso_timestamp())
|
||||||
|
is_intermediate = video_dict.get("is_intermediate", False)
|
||||||
|
starred = video_dict.get("starred", False)
|
||||||
|
|
||||||
|
return VideoRecord(
|
||||||
|
video_id=video_id,
|
||||||
|
width=width,
|
||||||
|
height=height,
|
||||||
|
session_id=session_id,
|
||||||
|
node_id=node_id,
|
||||||
|
created_at=created_at,
|
||||||
|
updated_at=updated_at,
|
||||||
|
deleted_at=deleted_at,
|
||||||
|
is_intermediate=is_intermediate,
|
||||||
|
starred=starred,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VideoCollectionCounts(BaseModel):
|
||||||
|
starred_count: int = Field(description="The number of starred videos in the collection.")
|
||||||
|
unstarred_count: int = Field(description="The number of unstarred videos in the collection.")
|
||||||
|
|
||||||
|
|
||||||
|
class VideoIdsResult(BaseModel):
|
||||||
|
"""Response containing ordered video ids with metadata for optimistic updates."""
|
||||||
|
|
||||||
|
video_ids: list[str] = Field(description="Ordered list of video ids")
|
||||||
|
starred_count: int = Field(description="Number of starred videos (when starred_first=True)")
|
||||||
|
total_count: int = Field(description="Total number of videos matching the query")
|
||||||
|
|
||||||
|
|
||||||
|
class VideoUrlsDTO(BaseModelExcludeNull):
|
||||||
|
"""The URLs for an image and its thumbnail."""
|
||||||
|
|
||||||
|
video_id: str = Field(description="The unique id of the video.")
|
||||||
|
"""The unique id of the video."""
|
||||||
|
video_url: str = Field(description="The URL of the video.")
|
||||||
|
"""The URL of the video."""
|
||||||
|
thumbnail_url: str = Field(description="The URL of the video's thumbnail.")
|
||||||
|
"""The URL of the video's thumbnail."""
|
||||||
|
|
||||||
|
|
||||||
|
class VideoDTO(VideoRecord, VideoUrlsDTO):
|
||||||
|
"""Deserialized video record, enriched for the frontend."""
|
||||||
|
|
||||||
|
board_id: Optional[str] = Field(
|
||||||
|
default=None, description="The id of the board the image belongs to, if one exists."
|
||||||
|
)
|
||||||
|
"""The id of the board the image belongs to, if one exists."""
|
||||||
|
|
||||||
|
|
||||||
|
def video_record_to_dto(
|
||||||
|
video_record: VideoRecord,
|
||||||
|
video_url: str,
|
||||||
|
thumbnail_url: str,
|
||||||
|
board_id: Optional[str],
|
||||||
|
) -> VideoDTO:
|
||||||
|
"""Converts a video record to a video DTO."""
|
||||||
|
return VideoDTO(
|
||||||
|
**video_record.model_dump(),
|
||||||
|
video_url=video_url,
|
||||||
|
thumbnail_url=thumbnail_url,
|
||||||
|
board_id=board_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ResultWithAffectedBoards(BaseModel):
|
||||||
|
affected_boards: list[str] = Field(description="The ids of boards affected by the delete operation")
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteVideosResult(ResultWithAffectedBoards):
|
||||||
|
deleted_videos: list[str] = Field(description="The ids of the videos that were deleted")
|
||||||
|
|
||||||
|
|
||||||
|
class StarredVideosResult(ResultWithAffectedBoards):
|
||||||
|
starred_videos: list[str] = Field(description="The ids of the videos that were starred")
|
||||||
|
|
||||||
|
|
||||||
|
class UnstarredVideosResult(ResultWithAffectedBoards):
|
||||||
|
unstarred_videos: list[str] = Field(description="The ids of the videos that were unstarred")
|
||||||
|
|
||||||
|
|
||||||
|
class AddVideosToBoardResult(ResultWithAffectedBoards):
|
||||||
|
added_videos: list[str] = Field(description="The video ids that were added to the board")
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveVideosFromBoardResult(ResultWithAffectedBoards):
|
||||||
|
removed_videos: list[str] = Field(description="The video ids that were removed from their board")
|
||||||
@@ -112,7 +112,7 @@ def denoise(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Slice prediction to only include the main image tokens
|
# Slice prediction to only include the main image tokens
|
||||||
if img_input_ids is not None:
|
if img_cond_seq is not None:
|
||||||
pred = pred[:, :original_seq_len]
|
pred = pred[:, :original_seq_len]
|
||||||
|
|
||||||
step_cfg_scale = cfg_scale[step_index]
|
step_cfg_scale = cfg_scale[step_index]
|
||||||
@@ -125,9 +125,26 @@ def denoise(
|
|||||||
if neg_regional_prompting_extension is None:
|
if neg_regional_prompting_extension is None:
|
||||||
raise ValueError("Negative text conditioning is required when cfg_scale is not 1.0.")
|
raise ValueError("Negative text conditioning is required when cfg_scale is not 1.0.")
|
||||||
|
|
||||||
|
# For negative prediction with Kontext, we need to include the reference images
|
||||||
|
# to maintain consistency between positive and negative passes. Without this,
|
||||||
|
# CFG would create artifacts as the attention mechanism would see different
|
||||||
|
# spatial structures in each pass
|
||||||
|
neg_img_input = img
|
||||||
|
neg_img_input_ids = img_ids
|
||||||
|
|
||||||
|
# Add channel-wise conditioning for negative pass if present
|
||||||
|
if img_cond is not None:
|
||||||
|
neg_img_input = torch.cat((neg_img_input, img_cond), dim=-1)
|
||||||
|
|
||||||
|
# Add sequence-wise conditioning (Kontext) for negative pass
|
||||||
|
# This ensures reference images are processed consistently
|
||||||
|
if img_cond_seq is not None:
|
||||||
|
neg_img_input = torch.cat((neg_img_input, img_cond_seq), dim=1)
|
||||||
|
neg_img_input_ids = torch.cat((neg_img_input_ids, img_cond_seq_ids), dim=1)
|
||||||
|
|
||||||
neg_pred = model(
|
neg_pred = model(
|
||||||
img=img,
|
img=neg_img_input,
|
||||||
img_ids=img_ids,
|
img_ids=neg_img_input_ids,
|
||||||
txt=neg_regional_prompting_extension.regional_text_conditioning.t5_embeddings,
|
txt=neg_regional_prompting_extension.regional_text_conditioning.t5_embeddings,
|
||||||
txt_ids=neg_regional_prompting_extension.regional_text_conditioning.t5_txt_ids,
|
txt_ids=neg_regional_prompting_extension.regional_text_conditioning.t5_txt_ids,
|
||||||
y=neg_regional_prompting_extension.regional_text_conditioning.clip_embeddings,
|
y=neg_regional_prompting_extension.regional_text_conditioning.clip_embeddings,
|
||||||
@@ -140,6 +157,10 @@ def denoise(
|
|||||||
ip_adapter_extensions=neg_ip_adapter_extensions,
|
ip_adapter_extensions=neg_ip_adapter_extensions,
|
||||||
regional_prompting_extension=neg_regional_prompting_extension,
|
regional_prompting_extension=neg_regional_prompting_extension,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Slice negative prediction to match main image tokens
|
||||||
|
if img_cond_seq is not None:
|
||||||
|
neg_pred = neg_pred[:, :original_seq_len]
|
||||||
pred = neg_pred + step_cfg_scale * (pred - neg_pred)
|
pred = neg_pred + step_cfg_scale * (pred - neg_pred)
|
||||||
|
|
||||||
preview_img = img - t_curr * pred
|
preview_img = img - t_curr * pred
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import einops
|
|
||||||
import numpy as np
|
|
||||||
import torch
|
import torch
|
||||||
|
import torch.nn.functional as F
|
||||||
|
import torchvision.transforms as T
|
||||||
from einops import repeat
|
from einops import repeat
|
||||||
from PIL import Image
|
|
||||||
|
|
||||||
from invokeai.app.invocations.fields import FluxKontextConditioningField
|
from invokeai.app.invocations.fields import FluxKontextConditioningField
|
||||||
from invokeai.app.invocations.flux_vae_encode import FluxVaeEncodeInvocation
|
|
||||||
from invokeai.app.invocations.model import VAEField
|
from invokeai.app.invocations.model import VAEField
|
||||||
from invokeai.app.services.shared.invocation_context import InvocationContext
|
from invokeai.app.services.shared.invocation_context import InvocationContext
|
||||||
|
from invokeai.backend.flux.modules.autoencoder import AutoEncoder
|
||||||
from invokeai.backend.flux.sampling_utils import pack
|
from invokeai.backend.flux.sampling_utils import pack
|
||||||
from invokeai.backend.flux.util import PREFERED_KONTEXT_RESOLUTIONS
|
from invokeai.backend.util.devices import TorchDevice
|
||||||
|
|
||||||
|
|
||||||
def generate_img_ids_with_offset(
|
def generate_img_ids_with_offset(
|
||||||
@@ -19,8 +18,10 @@ def generate_img_ids_with_offset(
|
|||||||
device: torch.device,
|
device: torch.device,
|
||||||
dtype: torch.dtype,
|
dtype: torch.dtype,
|
||||||
idx_offset: int = 0,
|
idx_offset: int = 0,
|
||||||
|
h_offset: int = 0,
|
||||||
|
w_offset: int = 0,
|
||||||
) -> torch.Tensor:
|
) -> torch.Tensor:
|
||||||
"""Generate tensor of image position ids with an optional offset.
|
"""Generate tensor of image position ids with optional index and spatial offsets.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
latent_height (int): Height of image in latent space (after packing, this becomes h//2).
|
latent_height (int): Height of image in latent space (after packing, this becomes h//2).
|
||||||
@@ -28,7 +29,9 @@ def generate_img_ids_with_offset(
|
|||||||
batch_size (int): Number of images in the batch.
|
batch_size (int): Number of images in the batch.
|
||||||
device (torch.device): Device to create tensors on.
|
device (torch.device): Device to create tensors on.
|
||||||
dtype (torch.dtype): Data type for the tensors.
|
dtype (torch.dtype): Data type for the tensors.
|
||||||
idx_offset (int): Offset to add to the first dimension of the image ids.
|
idx_offset (int): Offset to add to the first dimension of the image ids (default: 0).
|
||||||
|
h_offset (int): Spatial offset for height/y-coordinates in latent space (default: 0).
|
||||||
|
w_offset (int): Spatial offset for width/x-coordinates in latent space (default: 0).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
torch.Tensor: Image position ids with shape [batch_size, (latent_height//2 * latent_width//2), 3].
|
torch.Tensor: Image position ids with shape [batch_size, (latent_height//2 * latent_width//2), 3].
|
||||||
@@ -42,6 +45,10 @@ def generate_img_ids_with_offset(
|
|||||||
packed_height = latent_height // 2
|
packed_height = latent_height // 2
|
||||||
packed_width = latent_width // 2
|
packed_width = latent_width // 2
|
||||||
|
|
||||||
|
# Convert spatial offsets from latent space to packed space
|
||||||
|
packed_h_offset = h_offset // 2
|
||||||
|
packed_w_offset = w_offset // 2
|
||||||
|
|
||||||
# Create base tensor for position IDs with shape [packed_height, packed_width, 3]
|
# Create base tensor for position IDs with shape [packed_height, packed_width, 3]
|
||||||
# The 3 channels represent: [batch_offset, y_position, x_position]
|
# The 3 channels represent: [batch_offset, y_position, x_position]
|
||||||
img_ids = torch.zeros(packed_height, packed_width, 3, device=device, dtype=dtype)
|
img_ids = torch.zeros(packed_height, packed_width, 3, device=device, dtype=dtype)
|
||||||
@@ -49,13 +56,13 @@ def generate_img_ids_with_offset(
|
|||||||
# Set the batch offset for all positions
|
# Set the batch offset for all positions
|
||||||
img_ids[..., 0] = idx_offset
|
img_ids[..., 0] = idx_offset
|
||||||
|
|
||||||
# Create y-coordinate indices (vertical positions)
|
# Create y-coordinate indices (vertical positions) with spatial offset
|
||||||
y_indices = torch.arange(packed_height, device=device, dtype=dtype)
|
y_indices = torch.arange(packed_height, device=device, dtype=dtype) + packed_h_offset
|
||||||
# Broadcast y_indices to match the spatial dimensions [packed_height, 1]
|
# Broadcast y_indices to match the spatial dimensions [packed_height, 1]
|
||||||
img_ids[..., 1] = y_indices[:, None]
|
img_ids[..., 1] = y_indices[:, None]
|
||||||
|
|
||||||
# Create x-coordinate indices (horizontal positions)
|
# Create x-coordinate indices (horizontal positions) with spatial offset
|
||||||
x_indices = torch.arange(packed_width, device=device, dtype=dtype)
|
x_indices = torch.arange(packed_width, device=device, dtype=dtype) + packed_w_offset
|
||||||
# Broadcast x_indices to match the spatial dimensions [1, packed_width]
|
# Broadcast x_indices to match the spatial dimensions [1, packed_width]
|
||||||
img_ids[..., 2] = x_indices[None, :]
|
img_ids[..., 2] = x_indices[None, :]
|
||||||
|
|
||||||
@@ -73,14 +80,14 @@ class KontextExtension:
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
kontext_conditioning: FluxKontextConditioningField,
|
kontext_conditioning: list[FluxKontextConditioningField],
|
||||||
context: InvocationContext,
|
context: InvocationContext,
|
||||||
vae_field: VAEField,
|
vae_field: VAEField,
|
||||||
device: torch.device,
|
device: torch.device,
|
||||||
dtype: torch.dtype,
|
dtype: torch.dtype,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Initializes the KontextExtension, pre-processing the reference image
|
Initializes the KontextExtension, pre-processing the reference images
|
||||||
into latents and positional IDs.
|
into latents and positional IDs.
|
||||||
"""
|
"""
|
||||||
self._context = context
|
self._context = context
|
||||||
@@ -93,54 +100,116 @@ class KontextExtension:
|
|||||||
self.kontext_latents, self.kontext_ids = self._prepare_kontext()
|
self.kontext_latents, self.kontext_ids = self._prepare_kontext()
|
||||||
|
|
||||||
def _prepare_kontext(self) -> tuple[torch.Tensor, torch.Tensor]:
|
def _prepare_kontext(self) -> tuple[torch.Tensor, torch.Tensor]:
|
||||||
"""Encodes the reference image and prepares its latents and IDs."""
|
"""Encodes the reference images and prepares their concatenated latents and IDs with spatial tiling."""
|
||||||
image = self._context.images.get_pil(self.kontext_conditioning.image.image_name)
|
all_latents = []
|
||||||
|
all_ids = []
|
||||||
|
|
||||||
# Calculate aspect ratio of input image
|
# Track cumulative dimensions for spatial tiling
|
||||||
width, height = image.size
|
# These track the running extent of the virtual canvas in latent space
|
||||||
aspect_ratio = width / height
|
canvas_h = 0 # Running canvas height
|
||||||
|
canvas_w = 0 # Running canvas width
|
||||||
|
|
||||||
# Find the closest preferred resolution by aspect ratio
|
|
||||||
_, target_width, target_height = min(
|
|
||||||
((abs(aspect_ratio - w / h), w, h) for w, h in PREFERED_KONTEXT_RESOLUTIONS), key=lambda x: x[0]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Apply BFL's scaling formula
|
|
||||||
# This ensures compatibility with the model's training
|
|
||||||
scaled_width = 2 * int(target_width / 16)
|
|
||||||
scaled_height = 2 * int(target_height / 16)
|
|
||||||
|
|
||||||
# Resize to the exact resolution used during training
|
|
||||||
image = image.convert("RGB")
|
|
||||||
final_width = 8 * scaled_width
|
|
||||||
final_height = 8 * scaled_height
|
|
||||||
image = image.resize((final_width, final_height), Image.Resampling.LANCZOS)
|
|
||||||
|
|
||||||
# Convert to tensor with same normalization as BFL
|
|
||||||
image_np = np.array(image)
|
|
||||||
image_tensor = torch.from_numpy(image_np).float() / 127.5 - 1.0
|
|
||||||
image_tensor = einops.rearrange(image_tensor, "h w c -> 1 c h w")
|
|
||||||
image_tensor = image_tensor.to(self._device)
|
|
||||||
|
|
||||||
# Continue with VAE encoding
|
|
||||||
vae_info = self._context.models.load(self._vae_field.vae)
|
vae_info = self._context.models.load(self._vae_field.vae)
|
||||||
kontext_latents_unpacked = FluxVaeEncodeInvocation.vae_encode(vae_info=vae_info, image_tensor=image_tensor)
|
|
||||||
|
|
||||||
# Extract tensor dimensions
|
for idx, kontext_field in enumerate(self.kontext_conditioning):
|
||||||
batch_size, _, latent_height, latent_width = kontext_latents_unpacked.shape
|
image = self._context.images.get_pil(kontext_field.image.image_name)
|
||||||
|
|
||||||
# Pack the latents and generate IDs
|
# Convert to RGB
|
||||||
kontext_latents_packed = pack(kontext_latents_unpacked).to(self._device, self._dtype)
|
image = image.convert("RGB")
|
||||||
kontext_ids = generate_img_ids_with_offset(
|
|
||||||
latent_height=latent_height,
|
|
||||||
latent_width=latent_width,
|
|
||||||
batch_size=batch_size,
|
|
||||||
device=self._device,
|
|
||||||
dtype=self._dtype,
|
|
||||||
idx_offset=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
return kontext_latents_packed, kontext_ids
|
# Convert to tensor using torchvision transforms for consistency
|
||||||
|
transformation = T.Compose(
|
||||||
|
[
|
||||||
|
T.ToTensor(), # Converts PIL image to tensor and scales to [0, 1]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
image_tensor = transformation(image)
|
||||||
|
# Convert from [0, 1] to [-1, 1] range expected by VAE
|
||||||
|
image_tensor = image_tensor * 2.0 - 1.0
|
||||||
|
image_tensor = image_tensor.unsqueeze(0) # Add batch dimension
|
||||||
|
image_tensor = image_tensor.to(self._device)
|
||||||
|
|
||||||
|
# Continue with VAE encoding
|
||||||
|
# Don't sample from the distribution for reference images - use the mean (matching ComfyUI)
|
||||||
|
# Estimate working memory for encode operation (50% of decode memory requirements)
|
||||||
|
img_h = image_tensor.shape[-2]
|
||||||
|
img_w = image_tensor.shape[-1]
|
||||||
|
element_size = next(vae_info.model.parameters()).element_size()
|
||||||
|
scaling_constant = 1100 # 50% of decode scaling constant (2200)
|
||||||
|
estimated_working_memory = int(img_h * img_w * element_size * scaling_constant)
|
||||||
|
|
||||||
|
with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):
|
||||||
|
assert isinstance(vae, AutoEncoder)
|
||||||
|
vae_dtype = next(iter(vae.parameters())).dtype
|
||||||
|
image_tensor = image_tensor.to(device=TorchDevice.choose_torch_device(), dtype=vae_dtype)
|
||||||
|
# Use sample=False to get the distribution mean without noise
|
||||||
|
kontext_latents_unpacked = vae.encode(image_tensor, sample=False)
|
||||||
|
TorchDevice.empty_cache()
|
||||||
|
|
||||||
|
# Extract tensor dimensions
|
||||||
|
batch_size, _, latent_height, latent_width = kontext_latents_unpacked.shape
|
||||||
|
|
||||||
|
# Pad latents to be compatible with patch_size=2
|
||||||
|
# This ensures dimensions are even for the pack() function
|
||||||
|
pad_h = (2 - latent_height % 2) % 2
|
||||||
|
pad_w = (2 - latent_width % 2) % 2
|
||||||
|
if pad_h > 0 or pad_w > 0:
|
||||||
|
kontext_latents_unpacked = F.pad(kontext_latents_unpacked, (0, pad_w, 0, pad_h), mode="circular")
|
||||||
|
# Update dimensions after padding
|
||||||
|
_, _, latent_height, latent_width = kontext_latents_unpacked.shape
|
||||||
|
|
||||||
|
# Pack the latents
|
||||||
|
kontext_latents_packed = pack(kontext_latents_unpacked).to(self._device, self._dtype)
|
||||||
|
|
||||||
|
# Determine spatial offsets for this reference image
|
||||||
|
h_offset = 0
|
||||||
|
w_offset = 0
|
||||||
|
|
||||||
|
if idx > 0: # First image starts at (0, 0)
|
||||||
|
# Calculate potential canvas dimensions for each tiling option
|
||||||
|
# Option 1: Tile vertically (below existing content)
|
||||||
|
potential_h_vertical = canvas_h + latent_height
|
||||||
|
|
||||||
|
# Option 2: Tile horizontally (to the right of existing content)
|
||||||
|
potential_w_horizontal = canvas_w + latent_width
|
||||||
|
|
||||||
|
# Choose arrangement that minimizes the maximum dimension
|
||||||
|
# This keeps the canvas closer to square, optimizing attention computation
|
||||||
|
if potential_h_vertical > potential_w_horizontal:
|
||||||
|
# Tile horizontally (to the right of existing images)
|
||||||
|
w_offset = canvas_w
|
||||||
|
canvas_w = canvas_w + latent_width
|
||||||
|
canvas_h = max(canvas_h, latent_height)
|
||||||
|
else:
|
||||||
|
# Tile vertically (below existing images)
|
||||||
|
h_offset = canvas_h
|
||||||
|
canvas_h = canvas_h + latent_height
|
||||||
|
canvas_w = max(canvas_w, latent_width)
|
||||||
|
else:
|
||||||
|
# First image - just set canvas dimensions
|
||||||
|
canvas_h = latent_height
|
||||||
|
canvas_w = latent_width
|
||||||
|
|
||||||
|
# Generate IDs with both index offset and spatial offsets
|
||||||
|
kontext_ids = generate_img_ids_with_offset(
|
||||||
|
latent_height=latent_height,
|
||||||
|
latent_width=latent_width,
|
||||||
|
batch_size=batch_size,
|
||||||
|
device=self._device,
|
||||||
|
dtype=self._dtype,
|
||||||
|
idx_offset=1, # All reference images use index=1 (matching ComfyUI implementation)
|
||||||
|
h_offset=h_offset,
|
||||||
|
w_offset=w_offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
all_latents.append(kontext_latents_packed)
|
||||||
|
all_ids.append(kontext_ids)
|
||||||
|
|
||||||
|
# Concatenate all latents and IDs along the sequence dimension
|
||||||
|
concatenated_latents = torch.cat(all_latents, dim=1) # Concatenate along sequence dimension
|
||||||
|
concatenated_ids = torch.cat(all_ids, dim=1) # Concatenate along sequence dimension
|
||||||
|
|
||||||
|
return concatenated_latents, concatenated_ids
|
||||||
|
|
||||||
def ensure_batch_size(self, target_batch_size: int) -> None:
|
def ensure_batch_size(self, target_batch_size: int) -> None:
|
||||||
"""Ensures the kontext latents and IDs match the target batch size by repeating if necessary."""
|
"""Ensures the kontext latents and IDs match the target batch size by repeating if necessary."""
|
||||||
|
|||||||
304
invokeai/backend/image_util/imwatermark/vendor.py
Normal file
304
invokeai/backend/image_util/imwatermark/vendor.py
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
# This file is vendored from https://github.com/ShieldMnt/invisible-watermark
|
||||||
|
#
|
||||||
|
# `invisible-watermark` is MIT licensed as of August 23, 2025, when the code was copied into this repo.
|
||||||
|
#
|
||||||
|
# Why we vendored it in:
|
||||||
|
# `invisible-watermark` has a dependency on `opencv-python`, which conflicts with Invoke's dependency on
|
||||||
|
# `opencv-contrib-python`. It's easier to copy the code over than complicate the installation process by
|
||||||
|
# requiring an extra post-install step of removing `opencv-python` and installing `opencv-contrib-python`.
|
||||||
|
|
||||||
|
import struct
|
||||||
|
import uuid
|
||||||
|
import base64
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
import pywt
|
||||||
|
|
||||||
|
|
||||||
|
class WatermarkEncoder(object):
|
||||||
|
def __init__(self, content=b""):
|
||||||
|
seq = np.array([n for n in content], dtype=np.uint8)
|
||||||
|
self._watermarks = list(np.unpackbits(seq))
|
||||||
|
self._wmLen = len(self._watermarks)
|
||||||
|
self._wmType = "bytes"
|
||||||
|
|
||||||
|
def set_by_ipv4(self, addr):
|
||||||
|
bits = []
|
||||||
|
ips = addr.split(".")
|
||||||
|
for ip in ips:
|
||||||
|
bits += list(np.unpackbits(np.array([ip % 255], dtype=np.uint8)))
|
||||||
|
self._watermarks = bits
|
||||||
|
self._wmLen = len(self._watermarks)
|
||||||
|
self._wmType = "ipv4"
|
||||||
|
assert self._wmLen == 32
|
||||||
|
|
||||||
|
def set_by_uuid(self, uid):
|
||||||
|
u = uuid.UUID(uid)
|
||||||
|
self._wmType = "uuid"
|
||||||
|
seq = np.array([n for n in u.bytes], dtype=np.uint8)
|
||||||
|
self._watermarks = list(np.unpackbits(seq))
|
||||||
|
self._wmLen = len(self._watermarks)
|
||||||
|
|
||||||
|
def set_by_bytes(self, content):
|
||||||
|
self._wmType = "bytes"
|
||||||
|
seq = np.array([n for n in content], dtype=np.uint8)
|
||||||
|
self._watermarks = list(np.unpackbits(seq))
|
||||||
|
self._wmLen = len(self._watermarks)
|
||||||
|
|
||||||
|
def set_by_b16(self, b16):
|
||||||
|
content = base64.b16decode(b16)
|
||||||
|
self.set_by_bytes(content)
|
||||||
|
self._wmType = "b16"
|
||||||
|
|
||||||
|
def set_by_bits(self, bits=[]):
|
||||||
|
self._watermarks = [int(bit) % 2 for bit in bits]
|
||||||
|
self._wmLen = len(self._watermarks)
|
||||||
|
self._wmType = "bits"
|
||||||
|
|
||||||
|
def set_watermark(self, wmType="bytes", content=""):
|
||||||
|
if wmType == "ipv4":
|
||||||
|
self.set_by_ipv4(content)
|
||||||
|
elif wmType == "uuid":
|
||||||
|
self.set_by_uuid(content)
|
||||||
|
elif wmType == "bits":
|
||||||
|
self.set_by_bits(content)
|
||||||
|
elif wmType == "bytes":
|
||||||
|
self.set_by_bytes(content)
|
||||||
|
elif wmType == "b16":
|
||||||
|
self.set_by_b16(content)
|
||||||
|
else:
|
||||||
|
raise NameError("%s is not supported" % wmType)
|
||||||
|
|
||||||
|
def get_length(self):
|
||||||
|
return self._wmLen
|
||||||
|
|
||||||
|
# @classmethod
|
||||||
|
# def loadModel(cls):
|
||||||
|
# RivaWatermark.loadModel()
|
||||||
|
|
||||||
|
def encode(self, cv2Image, method="dwtDct", **configs):
|
||||||
|
(r, c, channels) = cv2Image.shape
|
||||||
|
if r * c < 256 * 256:
|
||||||
|
raise RuntimeError("image too small, should be larger than 256x256")
|
||||||
|
|
||||||
|
if method == "dwtDct":
|
||||||
|
embed = EmbedMaxDct(self._watermarks, wmLen=self._wmLen, **configs)
|
||||||
|
return embed.encode(cv2Image)
|
||||||
|
# elif method == 'dwtDctSvd':
|
||||||
|
# embed = EmbedDwtDctSvd(self._watermarks, wmLen=self._wmLen, **configs)
|
||||||
|
# return embed.encode(cv2Image)
|
||||||
|
# elif method == 'rivaGan':
|
||||||
|
# embed = RivaWatermark(self._watermarks, self._wmLen)
|
||||||
|
# return embed.encode(cv2Image)
|
||||||
|
else:
|
||||||
|
raise NameError("%s is not supported" % method)
|
||||||
|
|
||||||
|
|
||||||
|
class WatermarkDecoder(object):
|
||||||
|
def __init__(self, wm_type="bytes", length=0):
|
||||||
|
self._wmType = wm_type
|
||||||
|
if wm_type == "ipv4":
|
||||||
|
self._wmLen = 32
|
||||||
|
elif wm_type == "uuid":
|
||||||
|
self._wmLen = 128
|
||||||
|
elif wm_type == "bytes":
|
||||||
|
self._wmLen = length
|
||||||
|
elif wm_type == "bits":
|
||||||
|
self._wmLen = length
|
||||||
|
elif wm_type == "b16":
|
||||||
|
self._wmLen = length
|
||||||
|
else:
|
||||||
|
raise NameError("%s is unsupported" % wm_type)
|
||||||
|
|
||||||
|
def reconstruct_ipv4(self, bits):
|
||||||
|
ips = [str(ip) for ip in list(np.packbits(bits))]
|
||||||
|
return ".".join(ips)
|
||||||
|
|
||||||
|
def reconstruct_uuid(self, bits):
|
||||||
|
nums = np.packbits(bits)
|
||||||
|
bstr = b""
|
||||||
|
for i in range(16):
|
||||||
|
bstr += struct.pack(">B", nums[i])
|
||||||
|
|
||||||
|
return str(uuid.UUID(bytes=bstr))
|
||||||
|
|
||||||
|
def reconstruct_bits(self, bits):
|
||||||
|
# return ''.join([str(b) for b in bits])
|
||||||
|
return bits
|
||||||
|
|
||||||
|
def reconstruct_b16(self, bits):
|
||||||
|
bstr = self.reconstruct_bytes(bits)
|
||||||
|
return base64.b16encode(bstr)
|
||||||
|
|
||||||
|
def reconstruct_bytes(self, bits):
|
||||||
|
nums = np.packbits(bits)
|
||||||
|
bstr = b""
|
||||||
|
for i in range(self._wmLen // 8):
|
||||||
|
bstr += struct.pack(">B", nums[i])
|
||||||
|
return bstr
|
||||||
|
|
||||||
|
def reconstruct(self, bits):
|
||||||
|
if len(bits) != self._wmLen:
|
||||||
|
raise RuntimeError("bits are not matched with watermark length")
|
||||||
|
|
||||||
|
if self._wmType == "ipv4":
|
||||||
|
return self.reconstruct_ipv4(bits)
|
||||||
|
elif self._wmType == "uuid":
|
||||||
|
return self.reconstruct_uuid(bits)
|
||||||
|
elif self._wmType == "bits":
|
||||||
|
return self.reconstruct_bits(bits)
|
||||||
|
elif self._wmType == "b16":
|
||||||
|
return self.reconstruct_b16(bits)
|
||||||
|
else:
|
||||||
|
return self.reconstruct_bytes(bits)
|
||||||
|
|
||||||
|
def decode(self, cv2Image, method="dwtDct", **configs):
|
||||||
|
(r, c, channels) = cv2Image.shape
|
||||||
|
if r * c < 256 * 256:
|
||||||
|
raise RuntimeError("image too small, should be larger than 256x256")
|
||||||
|
|
||||||
|
bits = []
|
||||||
|
if method == "dwtDct":
|
||||||
|
embed = EmbedMaxDct(watermarks=[], wmLen=self._wmLen, **configs)
|
||||||
|
bits = embed.decode(cv2Image)
|
||||||
|
# elif method == 'dwtDctSvd':
|
||||||
|
# embed = EmbedDwtDctSvd(watermarks=[], wmLen=self._wmLen, **configs)
|
||||||
|
# bits = embed.decode(cv2Image)
|
||||||
|
# elif method == 'rivaGan':
|
||||||
|
# embed = RivaWatermark(watermarks=[], wmLen=self._wmLen, **configs)
|
||||||
|
# bits = embed.decode(cv2Image)
|
||||||
|
else:
|
||||||
|
raise NameError("%s is not supported" % method)
|
||||||
|
return self.reconstruct(bits)
|
||||||
|
|
||||||
|
# @classmethod
|
||||||
|
# def loadModel(cls):
|
||||||
|
# RivaWatermark.loadModel()
|
||||||
|
|
||||||
|
|
||||||
|
class EmbedMaxDct(object):
|
||||||
|
def __init__(self, watermarks=[], wmLen=8, scales=[0, 36, 36], block=4):
|
||||||
|
self._watermarks = watermarks
|
||||||
|
self._wmLen = wmLen
|
||||||
|
self._scales = scales
|
||||||
|
self._block = block
|
||||||
|
|
||||||
|
def encode(self, bgr):
|
||||||
|
(row, col, channels) = bgr.shape
|
||||||
|
|
||||||
|
yuv = cv2.cvtColor(bgr, cv2.COLOR_BGR2YUV)
|
||||||
|
|
||||||
|
for channel in range(2):
|
||||||
|
if self._scales[channel] <= 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
ca1, (h1, v1, d1) = pywt.dwt2(yuv[: row // 4 * 4, : col // 4 * 4, channel], "haar")
|
||||||
|
self.encode_frame(ca1, self._scales[channel])
|
||||||
|
|
||||||
|
yuv[: row // 4 * 4, : col // 4 * 4, channel] = pywt.idwt2((ca1, (v1, h1, d1)), "haar")
|
||||||
|
|
||||||
|
bgr_encoded = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR)
|
||||||
|
return bgr_encoded
|
||||||
|
|
||||||
|
def decode(self, bgr):
|
||||||
|
(row, col, channels) = bgr.shape
|
||||||
|
|
||||||
|
yuv = cv2.cvtColor(bgr, cv2.COLOR_BGR2YUV)
|
||||||
|
|
||||||
|
scores = [[] for i in range(self._wmLen)]
|
||||||
|
for channel in range(2):
|
||||||
|
if self._scales[channel] <= 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
ca1, (h1, v1, d1) = pywt.dwt2(yuv[: row // 4 * 4, : col // 4 * 4, channel], "haar")
|
||||||
|
|
||||||
|
scores = self.decode_frame(ca1, self._scales[channel], scores)
|
||||||
|
|
||||||
|
avgScores = list(map(lambda l: np.array(l).mean(), scores))
|
||||||
|
|
||||||
|
bits = np.array(avgScores) * 255 > 127
|
||||||
|
return bits
|
||||||
|
|
||||||
|
def decode_frame(self, frame, scale, scores):
|
||||||
|
(row, col) = frame.shape
|
||||||
|
num = 0
|
||||||
|
|
||||||
|
for i in range(row // self._block):
|
||||||
|
for j in range(col // self._block):
|
||||||
|
block = frame[
|
||||||
|
i * self._block : i * self._block + self._block, j * self._block : j * self._block + self._block
|
||||||
|
]
|
||||||
|
|
||||||
|
score = self.infer_dct_matrix(block, scale)
|
||||||
|
# score = self.infer_dct_svd(block, scale)
|
||||||
|
wmBit = num % self._wmLen
|
||||||
|
scores[wmBit].append(score)
|
||||||
|
num = num + 1
|
||||||
|
|
||||||
|
return scores
|
||||||
|
|
||||||
|
def diffuse_dct_svd(self, block, wmBit, scale):
|
||||||
|
u, s, v = np.linalg.svd(cv2.dct(block))
|
||||||
|
|
||||||
|
s[0] = (s[0] // scale + 0.25 + 0.5 * wmBit) * scale
|
||||||
|
return cv2.idct(np.dot(u, np.dot(np.diag(s), v)))
|
||||||
|
|
||||||
|
def infer_dct_svd(self, block, scale):
|
||||||
|
u, s, v = np.linalg.svd(cv2.dct(block))
|
||||||
|
|
||||||
|
score = 0
|
||||||
|
score = int((s[0] % scale) > scale * 0.5)
|
||||||
|
return score
|
||||||
|
if score >= 0.5:
|
||||||
|
return 1.0
|
||||||
|
else:
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
def diffuse_dct_matrix(self, block, wmBit, scale):
|
||||||
|
pos = np.argmax(abs(block.flatten()[1:])) + 1
|
||||||
|
i, j = pos // self._block, pos % self._block
|
||||||
|
val = block[i][j]
|
||||||
|
if val >= 0.0:
|
||||||
|
block[i][j] = (val // scale + 0.25 + 0.5 * wmBit) * scale
|
||||||
|
else:
|
||||||
|
val = abs(val)
|
||||||
|
block[i][j] = -1.0 * (val // scale + 0.25 + 0.5 * wmBit) * scale
|
||||||
|
return block
|
||||||
|
|
||||||
|
def infer_dct_matrix(self, block, scale):
|
||||||
|
pos = np.argmax(abs(block.flatten()[1:])) + 1
|
||||||
|
i, j = pos // self._block, pos % self._block
|
||||||
|
|
||||||
|
val = block[i][j]
|
||||||
|
if val < 0:
|
||||||
|
val = abs(val)
|
||||||
|
|
||||||
|
if (val % scale) > 0.5 * scale:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def encode_frame(self, frame, scale):
|
||||||
|
"""
|
||||||
|
frame is a matrix (M, N)
|
||||||
|
|
||||||
|
we get K (watermark bits size) blocks (self._block x self._block)
|
||||||
|
|
||||||
|
For i-th block, we encode watermark[i] bit into it
|
||||||
|
"""
|
||||||
|
(row, col) = frame.shape
|
||||||
|
num = 0
|
||||||
|
for i in range(row // self._block):
|
||||||
|
for j in range(col // self._block):
|
||||||
|
block = frame[
|
||||||
|
i * self._block : i * self._block + self._block, j * self._block : j * self._block + self._block
|
||||||
|
]
|
||||||
|
wmBit = self._watermarks[(num % self._wmLen)]
|
||||||
|
|
||||||
|
diffusedBlock = self.diffuse_dct_matrix(block, wmBit, scale)
|
||||||
|
# diffusedBlock = self.diffuse_dct_svd(block, wmBit, scale)
|
||||||
|
frame[
|
||||||
|
i * self._block : i * self._block + self._block, j * self._block : j * self._block + self._block
|
||||||
|
] = diffusedBlock
|
||||||
|
|
||||||
|
num = num + 1
|
||||||
@@ -6,13 +6,10 @@ configuration variable, that allows the watermarking to be supressed.
|
|||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from imwatermark import WatermarkEncoder
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
import invokeai.backend.util.logging as logger
|
import invokeai.backend.util.logging as logger
|
||||||
from invokeai.app.services.config.config_default import get_config
|
from invokeai.backend.image_util.imwatermark.vendor import WatermarkEncoder
|
||||||
|
|
||||||
config = get_config()
|
|
||||||
|
|
||||||
|
|
||||||
class InvisibleWatermark:
|
class InvisibleWatermark:
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import torch
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
# Import SAM2 components - these should be available in transformers 4.56.0+
|
||||||
|
from transformers.models.sam2 import Sam2Model
|
||||||
|
from transformers.models.sam2.processing_sam2 import Sam2Processor
|
||||||
|
|
||||||
|
from invokeai.backend.image_util.segment_anything.shared import SAMInput
|
||||||
|
from invokeai.backend.raw_model import RawModel
|
||||||
|
|
||||||
|
|
||||||
|
class SegmentAnything2Pipeline(RawModel):
|
||||||
|
"""A wrapper class for the transformers SAM2 model and processor that makes it compatible with the model manager."""
|
||||||
|
|
||||||
|
def __init__(self, sam2_model: Sam2Model, sam2_processor: Sam2Processor):
|
||||||
|
"""Initialize the SAM2 pipeline.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sam2_model: The SAM2 model
|
||||||
|
sam2_processor: The SAM2 processor (can be Sam2Processor or Sam2VideoProcessor)
|
||||||
|
"""
|
||||||
|
self._sam2_model = sam2_model
|
||||||
|
self._sam2_processor = sam2_processor
|
||||||
|
|
||||||
|
def to(self, device: Optional[torch.device] = None, dtype: Optional[torch.dtype] = None):
|
||||||
|
# HACK: The SAM2 pipeline may not work on MPS devices. We only allow it to be moved to CPU or CUDA.
|
||||||
|
if device is not None and device.type not in {"cpu", "cuda"}:
|
||||||
|
device = None
|
||||||
|
self._sam2_model.to(device=device, dtype=dtype)
|
||||||
|
|
||||||
|
def calc_size(self) -> int:
|
||||||
|
# HACK: Fix the circular import issue.
|
||||||
|
from invokeai.backend.model_manager.load.model_util import calc_module_size
|
||||||
|
|
||||||
|
return calc_module_size(self._sam2_model)
|
||||||
|
|
||||||
|
def segment(
|
||||||
|
self,
|
||||||
|
image: Image.Image,
|
||||||
|
inputs: list[SAMInput],
|
||||||
|
) -> torch.Tensor:
|
||||||
|
"""Segment the image using the provided inputs.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
image: The image to segment.
|
||||||
|
inputs: A list of SAMInput objects containing bounding boxes and/or point lists.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
torch.Tensor: The segmentation masks. dtype: torch.bool. shape: [num_masks, channels, height, width].
|
||||||
|
"""
|
||||||
|
|
||||||
|
input_boxes: list[list[float]] = []
|
||||||
|
input_points: list[list[list[float]]] = []
|
||||||
|
input_labels: list[list[int]] = []
|
||||||
|
|
||||||
|
for i in inputs:
|
||||||
|
box: list[float] | None = None
|
||||||
|
points: list[list[float]] | None = None
|
||||||
|
labels: list[int] | None = None
|
||||||
|
|
||||||
|
if i.bounding_box is not None:
|
||||||
|
box: list[float] | None = [
|
||||||
|
i.bounding_box.x_min,
|
||||||
|
i.bounding_box.y_min,
|
||||||
|
i.bounding_box.x_max,
|
||||||
|
i.bounding_box.y_max,
|
||||||
|
]
|
||||||
|
|
||||||
|
if i.points is not None:
|
||||||
|
points = []
|
||||||
|
labels = []
|
||||||
|
for point in i.points:
|
||||||
|
points.append([point.x, point.y])
|
||||||
|
labels.append(point.label.value)
|
||||||
|
|
||||||
|
if box is not None:
|
||||||
|
input_boxes.append(box)
|
||||||
|
if points is not None:
|
||||||
|
input_points.append(points)
|
||||||
|
if labels is not None:
|
||||||
|
input_labels.append(labels)
|
||||||
|
|
||||||
|
batched_input_boxes = [input_boxes] if input_boxes else None
|
||||||
|
batched_input_points = [input_points] if input_points else None
|
||||||
|
batched_input_labels = [input_labels] if input_labels else None
|
||||||
|
|
||||||
|
processed_inputs = self._sam2_processor(
|
||||||
|
images=image,
|
||||||
|
input_boxes=batched_input_boxes,
|
||||||
|
input_points=batched_input_points,
|
||||||
|
input_labels=batched_input_labels,
|
||||||
|
return_tensors="pt",
|
||||||
|
).to(self._sam2_model.device)
|
||||||
|
|
||||||
|
# Generate masks using the SAM2 model
|
||||||
|
outputs = self._sam2_model(**processed_inputs)
|
||||||
|
|
||||||
|
# Post-process the masks to get the final segmentation
|
||||||
|
masks = self._sam2_processor.post_process_masks(
|
||||||
|
masks=outputs.pred_masks,
|
||||||
|
original_sizes=processed_inputs.original_sizes,
|
||||||
|
reshaped_input_sizes=processed_inputs.reshaped_input_sizes,
|
||||||
|
)
|
||||||
|
|
||||||
|
# There should be only one batch.
|
||||||
|
assert len(masks) == 1
|
||||||
|
return masks[0]
|
||||||
@@ -1,20 +1,13 @@
|
|||||||
from typing import Optional, TypeAlias
|
from typing import Optional
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from transformers.models.sam import SamModel
|
from transformers.models.sam import SamModel
|
||||||
from transformers.models.sam.processing_sam import SamProcessor
|
from transformers.models.sam.processing_sam import SamProcessor
|
||||||
|
|
||||||
|
from invokeai.backend.image_util.segment_anything.shared import SAMInput
|
||||||
from invokeai.backend.raw_model import RawModel
|
from invokeai.backend.raw_model import RawModel
|
||||||
|
|
||||||
# Type aliases for the inputs to the SAM model.
|
|
||||||
ListOfBoundingBoxes: TypeAlias = list[list[int]]
|
|
||||||
"""A list of bounding boxes. Each bounding box is in the format [xmin, ymin, xmax, ymax]."""
|
|
||||||
ListOfPoints: TypeAlias = list[list[int]]
|
|
||||||
"""A list of points. Each point is in the format [x, y]."""
|
|
||||||
ListOfPointLabels: TypeAlias = list[int]
|
|
||||||
"""A list of SAM point labels. Each label is an integer where -1 is background, 0 is neutral, and 1 is foreground."""
|
|
||||||
|
|
||||||
|
|
||||||
class SegmentAnythingPipeline(RawModel):
|
class SegmentAnythingPipeline(RawModel):
|
||||||
"""A wrapper class for the transformers SAM model and processor that makes it compatible with the model manager."""
|
"""A wrapper class for the transformers SAM model and processor that makes it compatible with the model manager."""
|
||||||
@@ -38,55 +31,65 @@ class SegmentAnythingPipeline(RawModel):
|
|||||||
def segment(
|
def segment(
|
||||||
self,
|
self,
|
||||||
image: Image.Image,
|
image: Image.Image,
|
||||||
bounding_boxes: list[list[int]] | None = None,
|
inputs: list[SAMInput],
|
||||||
point_lists: list[list[list[int]]] | None = None,
|
|
||||||
) -> torch.Tensor:
|
) -> torch.Tensor:
|
||||||
"""Run the SAM model.
|
"""Segment the image using the provided inputs.
|
||||||
|
|
||||||
Either bounding_boxes or point_lists must be provided. If both are provided, bounding_boxes will be used and
|
|
||||||
point_lists will be ignored.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
image (Image.Image): The image to segment.
|
image: The image to segment.
|
||||||
bounding_boxes (list[list[int]]): The bounding box prompts. Each bounding box is in the format
|
inputs: A list of SAMInput objects containing bounding boxes and/or point lists.
|
||||||
[xmin, ymin, xmax, ymax].
|
|
||||||
point_lists (list[list[list[int]]]): The points prompts. Each point is in the format [x, y, label].
|
|
||||||
`label` is an integer where -1 is background, 0 is neutral, and 1 is foreground.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
torch.Tensor: The segmentation masks. dtype: torch.bool. shape: [num_masks, channels, height, width].
|
torch.Tensor: The segmentation masks. dtype: torch.bool. shape: [num_masks, channels, height, width].
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Prep the inputs:
|
input_boxes: list[list[float]] = []
|
||||||
# - Create a list of bounding boxes or points and labels.
|
input_points: list[list[list[float]]] = []
|
||||||
# - Add a batch dimension of 1 to the inputs.
|
input_labels: list[list[int]] = []
|
||||||
if bounding_boxes:
|
|
||||||
input_boxes: list[ListOfBoundingBoxes] | None = [bounding_boxes]
|
|
||||||
input_points: list[ListOfPoints] | None = None
|
|
||||||
input_labels: list[ListOfPointLabels] | None = None
|
|
||||||
elif point_lists:
|
|
||||||
input_boxes: list[ListOfBoundingBoxes] | None = None
|
|
||||||
input_points: list[ListOfPoints] | None = []
|
|
||||||
input_labels: list[ListOfPointLabels] | None = []
|
|
||||||
for point_list in point_lists:
|
|
||||||
input_points.append([[p[0], p[1]] for p in point_list])
|
|
||||||
input_labels.append([p[2] for p in point_list])
|
|
||||||
|
|
||||||
else:
|
for i in inputs:
|
||||||
raise ValueError("Either bounding_boxes or points and labels must be provided.")
|
box: list[float] | None = None
|
||||||
|
points: list[list[float]] | None = None
|
||||||
|
labels: list[int] | None = None
|
||||||
|
|
||||||
inputs = self._sam_processor(
|
if i.bounding_box is not None:
|
||||||
|
box: list[float] | None = [
|
||||||
|
i.bounding_box.x_min,
|
||||||
|
i.bounding_box.y_min,
|
||||||
|
i.bounding_box.x_max,
|
||||||
|
i.bounding_box.y_max,
|
||||||
|
]
|
||||||
|
|
||||||
|
if i.points is not None:
|
||||||
|
points = []
|
||||||
|
labels = []
|
||||||
|
for point in i.points:
|
||||||
|
points.append([point.x, point.y])
|
||||||
|
labels.append(point.label.value)
|
||||||
|
|
||||||
|
if box is not None:
|
||||||
|
input_boxes.append(box)
|
||||||
|
if points is not None:
|
||||||
|
input_points.append(points)
|
||||||
|
if labels is not None:
|
||||||
|
input_labels.append(labels)
|
||||||
|
|
||||||
|
batched_input_boxes = [input_boxes] if input_boxes else None
|
||||||
|
batched_input_points = input_points if input_points else None
|
||||||
|
batched_input_labels = input_labels if input_labels else None
|
||||||
|
|
||||||
|
processed_inputs = self._sam_processor(
|
||||||
images=image,
|
images=image,
|
||||||
input_boxes=input_boxes,
|
input_boxes=batched_input_boxes,
|
||||||
input_points=input_points,
|
input_points=batched_input_points,
|
||||||
input_labels=input_labels,
|
input_labels=batched_input_labels,
|
||||||
return_tensors="pt",
|
return_tensors="pt",
|
||||||
).to(self._sam_model.device)
|
).to(self._sam_model.device)
|
||||||
outputs = self._sam_model(**inputs)
|
outputs = self._sam_model(**processed_inputs)
|
||||||
masks = self._sam_processor.post_process_masks(
|
masks = self._sam_processor.post_process_masks(
|
||||||
masks=outputs.pred_masks,
|
masks=outputs.pred_masks,
|
||||||
original_sizes=inputs.original_sizes,
|
original_sizes=processed_inputs.original_sizes,
|
||||||
reshaped_input_sizes=inputs.reshaped_input_sizes,
|
reshaped_input_sizes=processed_inputs.reshaped_input_sizes,
|
||||||
)
|
)
|
||||||
|
|
||||||
# There should be only one batch.
|
# There should be only one batch.
|
||||||
|
|||||||
49
invokeai/backend/image_util/segment_anything/shared.py
Normal file
49
invokeai/backend/image_util/segment_anything/shared.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
from pydantic import BaseModel, model_validator
|
||||||
|
from pydantic.fields import Field
|
||||||
|
|
||||||
|
|
||||||
|
class BoundingBox(BaseModel):
|
||||||
|
x_min: int = Field(..., description="The minimum x-coordinate of the bounding box (inclusive).")
|
||||||
|
x_max: int = Field(..., description="The maximum x-coordinate of the bounding box (exclusive).")
|
||||||
|
y_min: int = Field(..., description="The minimum y-coordinate of the bounding box (inclusive).")
|
||||||
|
y_max: int = Field(..., description="The maximum y-coordinate of the bounding box (exclusive).")
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def check_coords(self):
|
||||||
|
if self.x_min > self.x_max:
|
||||||
|
raise ValueError(f"x_min ({self.x_min}) is greater than x_max ({self.x_max}).")
|
||||||
|
if self.y_min > self.y_max:
|
||||||
|
raise ValueError(f"y_min ({self.y_min}) is greater than y_max ({self.y_max}).")
|
||||||
|
return self
|
||||||
|
|
||||||
|
def tuple(self) -> tuple[int, int, int, int]:
|
||||||
|
"""
|
||||||
|
Returns the bounding box as a tuple suitable for use with PIL's `Image.crop()` method.
|
||||||
|
This method returns a tuple of the form (left, upper, right, lower) == (x_min, y_min, x_max, y_max).
|
||||||
|
"""
|
||||||
|
return (self.x_min, self.y_min, self.x_max, self.y_max)
|
||||||
|
|
||||||
|
|
||||||
|
class SAMPointLabel(Enum):
|
||||||
|
negative = -1
|
||||||
|
neutral = 0
|
||||||
|
positive = 1
|
||||||
|
|
||||||
|
|
||||||
|
class SAMPoint(BaseModel):
|
||||||
|
x: int = Field(..., description="The x-coordinate of the point")
|
||||||
|
y: int = Field(..., description="The y-coordinate of the point")
|
||||||
|
label: SAMPointLabel = Field(..., description="The label of the point")
|
||||||
|
|
||||||
|
|
||||||
|
class SAMInput(BaseModel):
|
||||||
|
bounding_box: BoundingBox | None = Field(None, description="The bounding box to use for segmentation")
|
||||||
|
points: list[SAMPoint] | None = Field(None, description="The points to use for segmentation")
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def check_input(self):
|
||||||
|
if not self.bounding_box and not self.points:
|
||||||
|
raise ValueError("Either bounding_box or points must be provided")
|
||||||
|
return self
|
||||||
@@ -90,6 +90,11 @@ class MainModelDefaultSettings(BaseModel):
|
|||||||
model_config = ConfigDict(extra="forbid")
|
model_config = ConfigDict(extra="forbid")
|
||||||
|
|
||||||
|
|
||||||
|
class LoraModelDefaultSettings(BaseModel):
|
||||||
|
weight: float | None = Field(default=None, ge=-1, le=2, description="Default weight for this model")
|
||||||
|
model_config = ConfigDict(extra="forbid")
|
||||||
|
|
||||||
|
|
||||||
class ControlAdapterDefaultSettings(BaseModel):
|
class ControlAdapterDefaultSettings(BaseModel):
|
||||||
# This could be narrowed to controlnet processor nodes, but they change. Leaving this a string is safer.
|
# This could be narrowed to controlnet processor nodes, but they change. Leaving this a string is safer.
|
||||||
preprocessor: str | None
|
preprocessor: str | None
|
||||||
@@ -287,6 +292,9 @@ class LoRAConfigBase(ABC, BaseModel):
|
|||||||
|
|
||||||
type: Literal[ModelType.LoRA] = ModelType.LoRA
|
type: Literal[ModelType.LoRA] = ModelType.LoRA
|
||||||
trigger_phrases: Optional[set[str]] = Field(description="Set of trigger phrases for this model", default=None)
|
trigger_phrases: Optional[set[str]] = Field(description="Set of trigger phrases for this model", default=None)
|
||||||
|
default_settings: Optional[LoraModelDefaultSettings] = Field(
|
||||||
|
description="Default settings for this model", default=None
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def flux_lora_format(cls, mod: ModelOnDisk):
|
def flux_lora_format(cls, mod: ModelOnDisk):
|
||||||
@@ -492,6 +500,15 @@ class MainConfigBase(ABC, BaseModel):
|
|||||||
variant: AnyVariant = ModelVariantType.Normal
|
variant: AnyVariant = ModelVariantType.Normal
|
||||||
|
|
||||||
|
|
||||||
|
class VideoConfigBase(ABC, BaseModel):
|
||||||
|
type: Literal[ModelType.Video] = ModelType.Video
|
||||||
|
trigger_phrases: Optional[set[str]] = Field(description="Set of trigger phrases for this model", default=None)
|
||||||
|
default_settings: Optional[MainModelDefaultSettings] = Field(
|
||||||
|
description="Default settings for this model", default=None
|
||||||
|
)
|
||||||
|
variant: AnyVariant = ModelVariantType.Normal
|
||||||
|
|
||||||
|
|
||||||
class MainCheckpointConfig(CheckpointConfigBase, MainConfigBase, LegacyProbeMixin, ModelConfigBase):
|
class MainCheckpointConfig(CheckpointConfigBase, MainConfigBase, LegacyProbeMixin, ModelConfigBase):
|
||||||
"""Model config for main checkpoint models."""
|
"""Model config for main checkpoint models."""
|
||||||
|
|
||||||
@@ -649,6 +666,21 @@ class ApiModelConfig(MainConfigBase, ModelConfigBase):
|
|||||||
raise NotImplementedError("API models are not parsed from disk.")
|
raise NotImplementedError("API models are not parsed from disk.")
|
||||||
|
|
||||||
|
|
||||||
|
class VideoApiModelConfig(VideoConfigBase, ModelConfigBase):
|
||||||
|
"""Model config for API-based video models."""
|
||||||
|
|
||||||
|
format: Literal[ModelFormat.Api] = ModelFormat.Api
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def matches(cls, mod: ModelOnDisk) -> bool:
|
||||||
|
# API models are not stored on disk, so we can't match them.
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse(cls, mod: ModelOnDisk) -> dict[str, Any]:
|
||||||
|
raise NotImplementedError("API models are not parsed from disk.")
|
||||||
|
|
||||||
|
|
||||||
def get_model_discriminator_value(v: Any) -> str:
|
def get_model_discriminator_value(v: Any) -> str:
|
||||||
"""
|
"""
|
||||||
Computes the discriminator value for a model config.
|
Computes the discriminator value for a model config.
|
||||||
@@ -718,12 +750,13 @@ AnyModelConfig = Annotated[
|
|||||||
Annotated[FluxReduxConfig, FluxReduxConfig.get_tag()],
|
Annotated[FluxReduxConfig, FluxReduxConfig.get_tag()],
|
||||||
Annotated[LlavaOnevisionConfig, LlavaOnevisionConfig.get_tag()],
|
Annotated[LlavaOnevisionConfig, LlavaOnevisionConfig.get_tag()],
|
||||||
Annotated[ApiModelConfig, ApiModelConfig.get_tag()],
|
Annotated[ApiModelConfig, ApiModelConfig.get_tag()],
|
||||||
|
Annotated[VideoApiModelConfig, VideoApiModelConfig.get_tag()],
|
||||||
],
|
],
|
||||||
Discriminator(get_model_discriminator_value),
|
Discriminator(get_model_discriminator_value),
|
||||||
]
|
]
|
||||||
|
|
||||||
AnyModelConfigValidator = TypeAdapter(AnyModelConfig)
|
AnyModelConfigValidator = TypeAdapter(AnyModelConfig)
|
||||||
AnyDefaultSettings: TypeAlias = Union[MainModelDefaultSettings, ControlAdapterDefaultSettings]
|
AnyDefaultSettings: TypeAlias = Union[MainModelDefaultSettings, LoraModelDefaultSettings, ControlAdapterDefaultSettings]
|
||||||
|
|
||||||
|
|
||||||
class ModelConfigFactory:
|
class ModelConfigFactory:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import spandrel
|
|||||||
import torch
|
import torch
|
||||||
|
|
||||||
import invokeai.backend.util.logging as logger
|
import invokeai.backend.util.logging as logger
|
||||||
|
from invokeai.app.services.config.config_default import get_config
|
||||||
from invokeai.app.util.misc import uuid_string
|
from invokeai.app.util.misc import uuid_string
|
||||||
from invokeai.backend.flux.controlnet.state_dict_utils import (
|
from invokeai.backend.flux.controlnet.state_dict_utils import (
|
||||||
is_state_dict_instantx_controlnet,
|
is_state_dict_instantx_controlnet,
|
||||||
@@ -22,6 +23,7 @@ from invokeai.backend.model_manager.config import (
|
|||||||
AnyModelConfig,
|
AnyModelConfig,
|
||||||
ControlAdapterDefaultSettings,
|
ControlAdapterDefaultSettings,
|
||||||
InvalidModelConfigException,
|
InvalidModelConfigException,
|
||||||
|
LoraModelDefaultSettings,
|
||||||
MainModelDefaultSettings,
|
MainModelDefaultSettings,
|
||||||
ModelConfigFactory,
|
ModelConfigFactory,
|
||||||
SubmodelDefinition,
|
SubmodelDefinition,
|
||||||
@@ -216,6 +218,8 @@ class ModelProbe(object):
|
|||||||
if not fields["default_settings"]:
|
if not fields["default_settings"]:
|
||||||
if fields["type"] in {ModelType.ControlNet, ModelType.T2IAdapter, ModelType.ControlLoRa}:
|
if fields["type"] in {ModelType.ControlNet, ModelType.T2IAdapter, ModelType.ControlLoRa}:
|
||||||
fields["default_settings"] = get_default_settings_control_adapters(fields["name"])
|
fields["default_settings"] = get_default_settings_control_adapters(fields["name"])
|
||||||
|
if fields["type"] in {ModelType.LoRA}:
|
||||||
|
fields["default_settings"] = get_default_settings_lora()
|
||||||
elif fields["type"] is ModelType.Main:
|
elif fields["type"] is ModelType.Main:
|
||||||
fields["default_settings"] = get_default_settings_main(fields["base"])
|
fields["default_settings"] = get_default_settings_main(fields["base"])
|
||||||
|
|
||||||
@@ -493,9 +497,21 @@ class ModelProbe(object):
|
|||||||
# scan model
|
# scan model
|
||||||
scan_result = pscan.scan_file_path(checkpoint)
|
scan_result = pscan.scan_file_path(checkpoint)
|
||||||
if scan_result.infected_files != 0:
|
if scan_result.infected_files != 0:
|
||||||
raise Exception(f"The model {model_name} is potentially infected by malware. Aborting import.")
|
if get_config().unsafe_disable_picklescan:
|
||||||
|
logger.warning(
|
||||||
|
f"The model {model_name} is potentially infected by malware, but picklescan is disabled. "
|
||||||
|
"Proceeding with caution."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"The model {model_name} is potentially infected by malware. Aborting import.")
|
||||||
if scan_result.scan_err:
|
if scan_result.scan_err:
|
||||||
raise Exception(f"Error scanning model {model_name} for malware. Aborting import.")
|
if get_config().unsafe_disable_picklescan:
|
||||||
|
logger.warning(
|
||||||
|
f"Error scanning the model at {model_name} for malware, but picklescan is disabled. "
|
||||||
|
"Proceeding with caution."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"Error scanning the model at {model_name} for malware. Aborting import.")
|
||||||
|
|
||||||
|
|
||||||
# Probing utilities
|
# Probing utilities
|
||||||
@@ -530,6 +546,10 @@ def get_default_settings_control_adapters(model_name: str) -> Optional[ControlAd
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_settings_lora() -> LoraModelDefaultSettings:
|
||||||
|
return LoraModelDefaultSettings()
|
||||||
|
|
||||||
|
|
||||||
def get_default_settings_main(model_base: BaseModelType) -> Optional[MainModelDefaultSettings]:
|
def get_default_settings_main(model_base: BaseModelType) -> Optional[MainModelDefaultSettings]:
|
||||||
if model_base is BaseModelType.StableDiffusion1 or model_base is BaseModelType.StableDiffusion2:
|
if model_base is BaseModelType.StableDiffusion1 or model_base is BaseModelType.StableDiffusion2:
|
||||||
return MainModelDefaultSettings(width=512, height=512)
|
return MainModelDefaultSettings(width=512, height=512)
|
||||||
|
|||||||
@@ -6,13 +6,17 @@ import torch
|
|||||||
from picklescan.scanner import scan_file_path
|
from picklescan.scanner import scan_file_path
|
||||||
from safetensors import safe_open
|
from safetensors import safe_open
|
||||||
|
|
||||||
|
from invokeai.app.services.config.config_default import get_config
|
||||||
from invokeai.backend.model_hash.model_hash import HASHING_ALGORITHMS, ModelHash
|
from invokeai.backend.model_hash.model_hash import HASHING_ALGORITHMS, ModelHash
|
||||||
from invokeai.backend.model_manager.taxonomy import ModelRepoVariant
|
from invokeai.backend.model_manager.taxonomy import ModelRepoVariant
|
||||||
from invokeai.backend.quantization.gguf.loaders import gguf_sd_loader
|
from invokeai.backend.quantization.gguf.loaders import gguf_sd_loader
|
||||||
|
from invokeai.backend.util.logging import InvokeAILogger
|
||||||
from invokeai.backend.util.silence_warnings import SilenceWarnings
|
from invokeai.backend.util.silence_warnings import SilenceWarnings
|
||||||
|
|
||||||
StateDict: TypeAlias = dict[str | int, Any] # When are the keys int?
|
StateDict: TypeAlias = dict[str | int, Any] # When are the keys int?
|
||||||
|
|
||||||
|
logger = InvokeAILogger.get_logger()
|
||||||
|
|
||||||
|
|
||||||
class ModelOnDisk:
|
class ModelOnDisk:
|
||||||
"""A utility class representing a model stored on disk."""
|
"""A utility class representing a model stored on disk."""
|
||||||
@@ -79,8 +83,24 @@ class ModelOnDisk:
|
|||||||
with SilenceWarnings():
|
with SilenceWarnings():
|
||||||
if path.suffix.endswith((".ckpt", ".pt", ".pth", ".bin")):
|
if path.suffix.endswith((".ckpt", ".pt", ".pth", ".bin")):
|
||||||
scan_result = scan_file_path(path)
|
scan_result = scan_file_path(path)
|
||||||
if scan_result.infected_files != 0 or scan_result.scan_err:
|
if scan_result.infected_files != 0:
|
||||||
raise RuntimeError(f"The model {path.stem} is potentially infected by malware. Aborting import.")
|
if get_config().unsafe_disable_picklescan:
|
||||||
|
logger.warning(
|
||||||
|
f"The model {path.stem} is potentially infected by malware, but picklescan is disabled. "
|
||||||
|
"Proceeding with caution."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"The model {path.stem} is potentially infected by malware. Aborting import."
|
||||||
|
)
|
||||||
|
if scan_result.scan_err:
|
||||||
|
if get_config().unsafe_disable_picklescan:
|
||||||
|
logger.warning(
|
||||||
|
f"Error scanning the model at {path.stem} for malware, but picklescan is disabled. "
|
||||||
|
"Proceeding with caution."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"Error scanning the model at {path.stem} for malware. Aborting import.")
|
||||||
checkpoint = torch.load(path, map_location="cpu")
|
checkpoint = torch.load(path, map_location="cpu")
|
||||||
assert isinstance(checkpoint, dict)
|
assert isinstance(checkpoint, dict)
|
||||||
elif path.suffix.endswith(".gguf"):
|
elif path.suffix.endswith(".gguf"):
|
||||||
|
|||||||
@@ -149,13 +149,29 @@ flux_kontext = StarterModel(
|
|||||||
dependencies=[t5_base_encoder, flux_vae, clip_l_encoder],
|
dependencies=[t5_base_encoder, flux_vae, clip_l_encoder],
|
||||||
)
|
)
|
||||||
flux_kontext_quantized = StarterModel(
|
flux_kontext_quantized = StarterModel(
|
||||||
name="FLUX.1 Kontext dev (Quantized)",
|
name="FLUX.1 Kontext dev (quantized)",
|
||||||
base=BaseModelType.Flux,
|
base=BaseModelType.Flux,
|
||||||
source="https://huggingface.co/unsloth/FLUX.1-Kontext-dev-GGUF/resolve/main/flux1-kontext-dev-Q4_K_M.gguf",
|
source="https://huggingface.co/unsloth/FLUX.1-Kontext-dev-GGUF/resolve/main/flux1-kontext-dev-Q4_K_M.gguf",
|
||||||
description="FLUX.1 Kontext dev quantized (q4_k_m). Total size with dependencies: ~14GB",
|
description="FLUX.1 Kontext dev quantized (q4_k_m). Total size with dependencies: ~14GB",
|
||||||
type=ModelType.Main,
|
type=ModelType.Main,
|
||||||
dependencies=[t5_8b_quantized_encoder, flux_vae, clip_l_encoder],
|
dependencies=[t5_8b_quantized_encoder, flux_vae, clip_l_encoder],
|
||||||
)
|
)
|
||||||
|
flux_krea = StarterModel(
|
||||||
|
name="FLUX.1 Krea dev",
|
||||||
|
base=BaseModelType.Flux,
|
||||||
|
source="https://huggingface.co/InvokeAI/FLUX.1-Krea-dev/resolve/main/flux1-krea-dev.safetensors",
|
||||||
|
description="FLUX.1 Krea dev. Total size with dependencies: ~33GB",
|
||||||
|
type=ModelType.Main,
|
||||||
|
dependencies=[t5_8b_quantized_encoder, flux_vae, clip_l_encoder],
|
||||||
|
)
|
||||||
|
flux_krea_quantized = StarterModel(
|
||||||
|
name="FLUX.1 Krea dev (quantized)",
|
||||||
|
base=BaseModelType.Flux,
|
||||||
|
source="https://huggingface.co/InvokeAI/FLUX.1-Krea-dev-GGUF/resolve/main/flux1-krea-dev-Q4_K_M.gguf",
|
||||||
|
description="FLUX.1 Krea dev quantized (q4_k_m). Total size with dependencies: ~14GB",
|
||||||
|
type=ModelType.Main,
|
||||||
|
dependencies=[t5_8b_quantized_encoder, flux_vae, clip_l_encoder],
|
||||||
|
)
|
||||||
sd35_medium = StarterModel(
|
sd35_medium = StarterModel(
|
||||||
name="SD3.5 Medium",
|
name="SD3.5 Medium",
|
||||||
base=BaseModelType.StableDiffusion3,
|
base=BaseModelType.StableDiffusion3,
|
||||||
@@ -580,13 +596,14 @@ t2i_sketch_sdxl = StarterModel(
|
|||||||
)
|
)
|
||||||
# endregion
|
# endregion
|
||||||
# region SpandrelImageToImage
|
# region SpandrelImageToImage
|
||||||
realesrgan_anime = StarterModel(
|
animesharp_v4_rcan = StarterModel(
|
||||||
name="RealESRGAN_x4plus_anime_6B",
|
name="2x-AnimeSharpV4_RCAN",
|
||||||
base=BaseModelType.Any,
|
base=BaseModelType.Any,
|
||||||
source="https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth",
|
source="https://github.com/Kim2091/Kim2091-Models/releases/download/2x-AnimeSharpV4/2x-AnimeSharpV4_RCAN.safetensors",
|
||||||
description="A Real-ESRGAN 4x upscaling model (optimized for anime images).",
|
description="A 2x upscaling model (optimized for anime images).",
|
||||||
type=ModelType.SpandrelImageToImage,
|
type=ModelType.SpandrelImageToImage,
|
||||||
)
|
)
|
||||||
|
|
||||||
realesrgan_x4 = StarterModel(
|
realesrgan_x4 = StarterModel(
|
||||||
name="RealESRGAN_x4plus",
|
name="RealESRGAN_x4plus",
|
||||||
base=BaseModelType.Any,
|
base=BaseModelType.Any,
|
||||||
@@ -732,7 +749,7 @@ STARTER_MODELS: list[StarterModel] = [
|
|||||||
t2i_lineart_sdxl,
|
t2i_lineart_sdxl,
|
||||||
t2i_sketch_sdxl,
|
t2i_sketch_sdxl,
|
||||||
realesrgan_x4,
|
realesrgan_x4,
|
||||||
realesrgan_anime,
|
animesharp_v4_rcan,
|
||||||
realesrgan_x2,
|
realesrgan_x2,
|
||||||
swinir,
|
swinir,
|
||||||
t5_base_encoder,
|
t5_base_encoder,
|
||||||
@@ -743,6 +760,8 @@ STARTER_MODELS: list[StarterModel] = [
|
|||||||
llava_onevision,
|
llava_onevision,
|
||||||
flux_fill,
|
flux_fill,
|
||||||
cogview4,
|
cogview4,
|
||||||
|
flux_krea,
|
||||||
|
flux_krea_quantized,
|
||||||
]
|
]
|
||||||
|
|
||||||
sd1_bundle: list[StarterModel] = [
|
sd1_bundle: list[StarterModel] = [
|
||||||
@@ -794,6 +813,7 @@ flux_bundle: list[StarterModel] = [
|
|||||||
flux_redux,
|
flux_redux,
|
||||||
flux_fill,
|
flux_fill,
|
||||||
flux_kontext_quantized,
|
flux_kontext_quantized,
|
||||||
|
flux_krea_quantized,
|
||||||
]
|
]
|
||||||
|
|
||||||
STARTER_BUNDLES: dict[str, StarterModelBundle] = {
|
STARTER_BUNDLES: dict[str, StarterModelBundle] = {
|
||||||
|
|||||||
@@ -28,8 +28,11 @@ class BaseModelType(str, Enum):
|
|||||||
CogView4 = "cogview4"
|
CogView4 = "cogview4"
|
||||||
Imagen3 = "imagen3"
|
Imagen3 = "imagen3"
|
||||||
Imagen4 = "imagen4"
|
Imagen4 = "imagen4"
|
||||||
|
Gemini2_5 = "gemini-2.5"
|
||||||
ChatGPT4o = "chatgpt-4o"
|
ChatGPT4o = "chatgpt-4o"
|
||||||
FluxKontext = "flux-kontext"
|
FluxKontext = "flux-kontext"
|
||||||
|
Veo3 = "veo3"
|
||||||
|
Runway = "runway"
|
||||||
|
|
||||||
|
|
||||||
class ModelType(str, Enum):
|
class ModelType(str, Enum):
|
||||||
@@ -51,6 +54,7 @@ class ModelType(str, Enum):
|
|||||||
SigLIP = "siglip"
|
SigLIP = "siglip"
|
||||||
FluxRedux = "flux_redux"
|
FluxRedux = "flux_redux"
|
||||||
LlavaOnevision = "llava_onevision"
|
LlavaOnevision = "llava_onevision"
|
||||||
|
Video = "video"
|
||||||
|
|
||||||
|
|
||||||
class SubModelType(str, Enum):
|
class SubModelType(str, Enum):
|
||||||
|
|||||||
@@ -8,8 +8,12 @@ import picklescan.scanner as pscan
|
|||||||
import safetensors
|
import safetensors
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
|
from invokeai.app.services.config.config_default import get_config
|
||||||
from invokeai.backend.model_manager.taxonomy import ClipVariantType
|
from invokeai.backend.model_manager.taxonomy import ClipVariantType
|
||||||
from invokeai.backend.quantization.gguf.loaders import gguf_sd_loader
|
from invokeai.backend.quantization.gguf.loaders import gguf_sd_loader
|
||||||
|
from invokeai.backend.util.logging import InvokeAILogger
|
||||||
|
|
||||||
|
logger = InvokeAILogger.get_logger()
|
||||||
|
|
||||||
|
|
||||||
def _fast_safetensors_reader(path: str) -> Dict[str, torch.Tensor]:
|
def _fast_safetensors_reader(path: str) -> Dict[str, torch.Tensor]:
|
||||||
@@ -59,9 +63,21 @@ def read_checkpoint_meta(path: Union[str, Path], scan: bool = True) -> Dict[str,
|
|||||||
if scan:
|
if scan:
|
||||||
scan_result = pscan.scan_file_path(path)
|
scan_result = pscan.scan_file_path(path)
|
||||||
if scan_result.infected_files != 0:
|
if scan_result.infected_files != 0:
|
||||||
raise Exception(f"The model at {path} is potentially infected by malware. Aborting import.")
|
if get_config().unsafe_disable_picklescan:
|
||||||
|
logger.warning(
|
||||||
|
f"The model {path} is potentially infected by malware, but picklescan is disabled. "
|
||||||
|
"Proceeding with caution."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"The model {path} is potentially infected by malware. Aborting import.")
|
||||||
if scan_result.scan_err:
|
if scan_result.scan_err:
|
||||||
raise Exception(f"Error scanning model at {path} for malware. Aborting import.")
|
if get_config().unsafe_disable_picklescan:
|
||||||
|
logger.warning(
|
||||||
|
f"Error scanning the model at {path} for malware, but picklescan is disabled. "
|
||||||
|
"Proceeding with caution."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"Error scanning the model at {path} for malware. Aborting import.")
|
||||||
|
|
||||||
checkpoint = torch.load(path, map_location=torch.device("meta"))
|
checkpoint = torch.load(path, map_location=torch.device("meta"))
|
||||||
return checkpoint
|
return checkpoint
|
||||||
|
|||||||
@@ -18,16 +18,25 @@ def is_state_dict_likely_in_flux_diffusers_format(state_dict: Dict[str, torch.Te
|
|||||||
# First, check that all keys end in "lora_A.weight" or "lora_B.weight" (i.e. are in PEFT format).
|
# First, check that all keys end in "lora_A.weight" or "lora_B.weight" (i.e. are in PEFT format).
|
||||||
all_keys_in_peft_format = all(k.endswith(("lora_A.weight", "lora_B.weight")) for k in state_dict.keys())
|
all_keys_in_peft_format = all(k.endswith(("lora_A.weight", "lora_B.weight")) for k in state_dict.keys())
|
||||||
|
|
||||||
# Next, check that this is likely a FLUX model by spot-checking a few keys.
|
# Check if keys use transformer prefix
|
||||||
expected_keys = [
|
transformer_prefix_keys = [
|
||||||
"transformer.single_transformer_blocks.0.attn.to_q.lora_A.weight",
|
"transformer.single_transformer_blocks.0.attn.to_q.lora_A.weight",
|
||||||
"transformer.single_transformer_blocks.0.attn.to_q.lora_B.weight",
|
"transformer.single_transformer_blocks.0.attn.to_q.lora_B.weight",
|
||||||
"transformer.transformer_blocks.0.attn.add_q_proj.lora_A.weight",
|
"transformer.transformer_blocks.0.attn.add_q_proj.lora_A.weight",
|
||||||
"transformer.transformer_blocks.0.attn.add_q_proj.lora_B.weight",
|
"transformer.transformer_blocks.0.attn.add_q_proj.lora_B.weight",
|
||||||
]
|
]
|
||||||
all_expected_keys_present = all(k in state_dict for k in expected_keys)
|
transformer_keys_present = all(k in state_dict for k in transformer_prefix_keys)
|
||||||
|
|
||||||
return all_keys_in_peft_format and all_expected_keys_present
|
# Check if keys use base_model.model prefix
|
||||||
|
base_model_prefix_keys = [
|
||||||
|
"base_model.model.single_transformer_blocks.0.attn.to_q.lora_A.weight",
|
||||||
|
"base_model.model.single_transformer_blocks.0.attn.to_q.lora_B.weight",
|
||||||
|
"base_model.model.transformer_blocks.0.attn.add_q_proj.lora_A.weight",
|
||||||
|
"base_model.model.transformer_blocks.0.attn.add_q_proj.lora_B.weight",
|
||||||
|
]
|
||||||
|
base_model_keys_present = all(k in state_dict for k in base_model_prefix_keys)
|
||||||
|
|
||||||
|
return all_keys_in_peft_format and (transformer_keys_present or base_model_keys_present)
|
||||||
|
|
||||||
|
|
||||||
def lora_model_from_flux_diffusers_state_dict(
|
def lora_model_from_flux_diffusers_state_dict(
|
||||||
@@ -49,8 +58,16 @@ def lora_layers_from_flux_diffusers_grouped_state_dict(
|
|||||||
https://github.com/huggingface/diffusers/blob/55ac421f7bb12fd00ccbef727be4dc2f3f920abb/scripts/convert_flux_to_diffusers.py
|
https://github.com/huggingface/diffusers/blob/55ac421f7bb12fd00ccbef727be4dc2f3f920abb/scripts/convert_flux_to_diffusers.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Remove the "transformer." prefix from all keys.
|
# Determine which prefix is used and remove it from all keys.
|
||||||
grouped_state_dict = {k.replace("transformer.", ""): v for k, v in grouped_state_dict.items()}
|
# Check if any key starts with "base_model.model." prefix
|
||||||
|
has_base_model_prefix = any(k.startswith("base_model.model.") for k in grouped_state_dict.keys())
|
||||||
|
|
||||||
|
if has_base_model_prefix:
|
||||||
|
# Remove the "base_model.model." prefix from all keys.
|
||||||
|
grouped_state_dict = {k.replace("base_model.model.", ""): v for k, v in grouped_state_dict.items()}
|
||||||
|
else:
|
||||||
|
# Remove the "transformer." prefix from all keys.
|
||||||
|
grouped_state_dict = {k.replace("transformer.", ""): v for k, v in grouped_state_dict.items()}
|
||||||
|
|
||||||
# Constants for FLUX.1
|
# Constants for FLUX.1
|
||||||
num_double_layers = 19
|
num_double_layers = 19
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ def main():
|
|||||||
"/data/invokeai/models/.download_cache/https__huggingface.co_black-forest-labs_flux.1-schnell_resolve_main_flux1-schnell.safetensors/flux1-schnell.safetensors"
|
"/data/invokeai/models/.download_cache/https__huggingface.co_black-forest-labs_flux.1-schnell_resolve_main_flux1-schnell.safetensors/flux1-schnell.safetensors"
|
||||||
)
|
)
|
||||||
|
|
||||||
with log_time("Intialize FLUX transformer on meta device"):
|
with log_time("Initialize FLUX transformer on meta device"):
|
||||||
# TODO(ryand): Determine if this is a schnell model or a dev model and load the appropriate config.
|
# TODO(ryand): Determine if this is a schnell model or a dev model and load the appropriate config.
|
||||||
p = params["flux-schnell"]
|
p = params["flux-schnell"]
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ def main():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# inference_dtype = torch.bfloat16
|
# inference_dtype = torch.bfloat16
|
||||||
with log_time("Intialize FLUX transformer on meta device"):
|
with log_time("Initialize FLUX transformer on meta device"):
|
||||||
# TODO(ryand): Determine if this is a schnell model or a dev model and load the appropriate config.
|
# TODO(ryand): Determine if this is a schnell model or a dev model and load the appropriate config.
|
||||||
p = params["flux-schnell"]
|
p = params["flux-schnell"]
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ def main():
|
|||||||
"""
|
"""
|
||||||
model_path = Path("/data/misc/text_encoder_2")
|
model_path = Path("/data/misc/text_encoder_2")
|
||||||
|
|
||||||
with log_time("Intialize T5 on meta device"):
|
with log_time("Initialize T5 on meta device"):
|
||||||
model_config = AutoConfig.from_pretrained(model_path)
|
model_config = AutoConfig.from_pretrained(model_path)
|
||||||
with accelerate.init_empty_weights():
|
with accelerate.init_empty_weights():
|
||||||
model = AutoModelForTextEncoding.from_config(model_config)
|
model = AutoModelForTextEncoding.from_config(model_config)
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ import torch
|
|||||||
from diffusers.configuration_utils import ConfigMixin, register_to_config
|
from diffusers.configuration_utils import ConfigMixin, register_to_config
|
||||||
from diffusers.loaders.single_file_model import FromOriginalModelMixin
|
from diffusers.loaders.single_file_model import FromOriginalModelMixin
|
||||||
from diffusers.models.attention_processor import AttentionProcessor, AttnProcessor
|
from diffusers.models.attention_processor import AttentionProcessor, AttnProcessor
|
||||||
from diffusers.models.controlnet import ControlNetConditioningEmbedding, ControlNetOutput, zero_module
|
from diffusers.models.controlnets.controlnet import (
|
||||||
|
ControlNetConditioningEmbedding,
|
||||||
|
ControlNetOutput,
|
||||||
|
zero_module,
|
||||||
|
)
|
||||||
from diffusers.models.embeddings import (
|
from diffusers.models.embeddings import (
|
||||||
TextImageProjection,
|
TextImageProjection,
|
||||||
TextImageTimeEmbedding,
|
TextImageTimeEmbedding,
|
||||||
@@ -775,7 +779,15 @@ class ControlNetModel(ModelMixin, ConfigMixin, FromOriginalModelMixin):
|
|||||||
|
|
||||||
|
|
||||||
diffusers.ControlNetModel = ControlNetModel
|
diffusers.ControlNetModel = ControlNetModel
|
||||||
diffusers.models.controlnet.ControlNetModel = ControlNetModel
|
# Patch both the new and legacy module paths for compatibility
|
||||||
|
try:
|
||||||
|
diffusers.models.controlnets.controlnet.ControlNetModel = ControlNetModel
|
||||||
|
except Exception:
|
||||||
|
# Fallback for environments still exposing the legacy path
|
||||||
|
try:
|
||||||
|
diffusers.models.controlnet.ControlNetModel = ControlNetModel
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# patch LoRACompatibleConv to use original Conv2D forward function
|
# patch LoRACompatibleConv to use original Conv2D forward function
|
||||||
|
|||||||
117
invokeai/backend/util/vae_working_memory.py
Normal file
117
invokeai/backend/util/vae_working_memory.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
import torch
|
||||||
|
from diffusers.models.autoencoders.autoencoder_kl import AutoencoderKL
|
||||||
|
from diffusers.models.autoencoders.autoencoder_tiny import AutoencoderTiny
|
||||||
|
|
||||||
|
from invokeai.app.invocations.constants import LATENT_SCALE_FACTOR
|
||||||
|
from invokeai.backend.flux.modules.autoencoder import AutoEncoder
|
||||||
|
|
||||||
|
|
||||||
|
def estimate_vae_working_memory_sd15_sdxl(
|
||||||
|
operation: Literal["encode", "decode"],
|
||||||
|
image_tensor: torch.Tensor,
|
||||||
|
vae: AutoencoderKL | AutoencoderTiny,
|
||||||
|
tile_size: int | None,
|
||||||
|
fp32: bool,
|
||||||
|
) -> int:
|
||||||
|
"""Estimate the working memory required to encode or decode the given tensor."""
|
||||||
|
# It was found experimentally that the peak working memory scales linearly with the number of pixels and the
|
||||||
|
# element size (precision). This estimate is accurate for both SD1 and SDXL.
|
||||||
|
element_size = 4 if fp32 else 2
|
||||||
|
|
||||||
|
# This constant is determined experimentally and takes into consideration both allocated and reserved memory. See #8414
|
||||||
|
# Encoding uses ~45% the working memory as decoding.
|
||||||
|
scaling_constant = 2200 if operation == "decode" else 1100
|
||||||
|
|
||||||
|
latent_scale_factor_for_operation = LATENT_SCALE_FACTOR if operation == "decode" else 1
|
||||||
|
|
||||||
|
if tile_size is not None:
|
||||||
|
if tile_size == 0:
|
||||||
|
tile_size = vae.tile_sample_min_size
|
||||||
|
assert isinstance(tile_size, int)
|
||||||
|
h = tile_size
|
||||||
|
w = tile_size
|
||||||
|
working_memory = h * w * element_size * scaling_constant
|
||||||
|
|
||||||
|
# We add 25% to the working memory estimate when tiling is enabled to account for factors like tile overlap
|
||||||
|
# and number of tiles. We could make this more precise in the future, but this should be good enough for
|
||||||
|
# most use cases.
|
||||||
|
working_memory = working_memory * 1.25
|
||||||
|
else:
|
||||||
|
h = latent_scale_factor_for_operation * image_tensor.shape[-2]
|
||||||
|
w = latent_scale_factor_for_operation * image_tensor.shape[-1]
|
||||||
|
working_memory = h * w * element_size * scaling_constant
|
||||||
|
|
||||||
|
if fp32:
|
||||||
|
# If we are running in FP32, then we should account for the likely increase in model size (~250MB).
|
||||||
|
working_memory += 250 * 2**20
|
||||||
|
|
||||||
|
print(f"estimate_vae_working_memory_sd15_sdxl: {int(working_memory)}")
|
||||||
|
|
||||||
|
return int(working_memory)
|
||||||
|
|
||||||
|
|
||||||
|
def estimate_vae_working_memory_cogview4(
|
||||||
|
operation: Literal["encode", "decode"], image_tensor: torch.Tensor, vae: AutoencoderKL
|
||||||
|
) -> int:
|
||||||
|
"""Estimate the working memory required by the invocation in bytes."""
|
||||||
|
latent_scale_factor_for_operation = LATENT_SCALE_FACTOR if operation == "decode" else 1
|
||||||
|
|
||||||
|
h = latent_scale_factor_for_operation * image_tensor.shape[-2]
|
||||||
|
w = latent_scale_factor_for_operation * image_tensor.shape[-1]
|
||||||
|
element_size = next(vae.parameters()).element_size()
|
||||||
|
|
||||||
|
# This constant is determined experimentally and takes into consideration both allocated and reserved memory. See #8414
|
||||||
|
# Encoding uses ~45% the working memory as decoding.
|
||||||
|
scaling_constant = 2200 if operation == "decode" else 1100
|
||||||
|
working_memory = h * w * element_size * scaling_constant
|
||||||
|
|
||||||
|
print(f"estimate_vae_working_memory_cogview4: {int(working_memory)}")
|
||||||
|
|
||||||
|
return int(working_memory)
|
||||||
|
|
||||||
|
|
||||||
|
def estimate_vae_working_memory_flux(
|
||||||
|
operation: Literal["encode", "decode"], image_tensor: torch.Tensor, vae: AutoEncoder
|
||||||
|
) -> int:
|
||||||
|
"""Estimate the working memory required by the invocation in bytes."""
|
||||||
|
|
||||||
|
latent_scale_factor_for_operation = LATENT_SCALE_FACTOR if operation == "decode" else 1
|
||||||
|
|
||||||
|
out_h = latent_scale_factor_for_operation * image_tensor.shape[-2]
|
||||||
|
out_w = latent_scale_factor_for_operation * image_tensor.shape[-1]
|
||||||
|
element_size = next(vae.parameters()).element_size()
|
||||||
|
|
||||||
|
# This constant is determined experimentally and takes into consideration both allocated and reserved memory. See #8414
|
||||||
|
# Encoding uses ~45% the working memory as decoding.
|
||||||
|
scaling_constant = 2200 if operation == "decode" else 1100
|
||||||
|
|
||||||
|
working_memory = out_h * out_w * element_size * scaling_constant
|
||||||
|
|
||||||
|
print(f"estimate_vae_working_memory_flux: {int(working_memory)}")
|
||||||
|
|
||||||
|
return int(working_memory)
|
||||||
|
|
||||||
|
|
||||||
|
def estimate_vae_working_memory_sd3(
|
||||||
|
operation: Literal["encode", "decode"], image_tensor: torch.Tensor, vae: AutoencoderKL
|
||||||
|
) -> int:
|
||||||
|
"""Estimate the working memory required by the invocation in bytes."""
|
||||||
|
# Encode operations use approximately 50% of the memory required for decode operations
|
||||||
|
|
||||||
|
latent_scale_factor_for_operation = LATENT_SCALE_FACTOR if operation == "decode" else 1
|
||||||
|
|
||||||
|
h = latent_scale_factor_for_operation * image_tensor.shape[-2]
|
||||||
|
w = latent_scale_factor_for_operation * image_tensor.shape[-1]
|
||||||
|
element_size = next(vae.parameters()).element_size()
|
||||||
|
|
||||||
|
# This constant is determined experimentally and takes into consideration both allocated and reserved memory. See #8414
|
||||||
|
# Encoding uses ~45% the working memory as decoding.
|
||||||
|
scaling_constant = 2200 if operation == "decode" else 1100
|
||||||
|
|
||||||
|
working_memory = h * w * element_size * scaling_constant
|
||||||
|
|
||||||
|
print(f"estimate_vae_working_memory_sd3: {int(working_memory)}")
|
||||||
|
|
||||||
|
return int(working_memory)
|
||||||
3
invokeai/frontend/web/.gitignore
vendored
3
invokeai/frontend/web/.gitignore
vendored
@@ -44,4 +44,5 @@ yalc.lock
|
|||||||
|
|
||||||
# vitest
|
# vitest
|
||||||
tsconfig.vitest-temp.json
|
tsconfig.vitest-temp.json
|
||||||
coverage/
|
coverage/
|
||||||
|
*.tgz
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ i18n.use(initReactI18next).init({
|
|||||||
returnNull: false,
|
returnNull: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const store = createStore(undefined, false);
|
const store = createStore();
|
||||||
$store.set(store);
|
$store.set(store);
|
||||||
$baseUrl.set('http://localhost:9090');
|
$baseUrl.set('http://localhost:9090');
|
||||||
|
|
||||||
|
|||||||
39
invokeai/frontend/web/CLAUDE.md
Normal file
39
invokeai/frontend/web/CLAUDE.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Bash commands
|
||||||
|
|
||||||
|
All commands should be run from `<REPO_ROOT>/invokeai/frontend/web/`.
|
||||||
|
|
||||||
|
- `pnpm lint:prettier`: check formatting
|
||||||
|
- `pnpm lint:eslint`: check for linting issues
|
||||||
|
- `pnpm lint:knip`: check for unused dependencies
|
||||||
|
- `pnpm lint:dpdm`: check for dependency cycles
|
||||||
|
- `pnpm lint:tsc`: check for TypeScript issues
|
||||||
|
- `pnpm lint`: run all checks
|
||||||
|
- `pnpm fix`: automatically fix issues where possible
|
||||||
|
- `pnpm test:no-watch`: run the test suite
|
||||||
|
|
||||||
|
# Writing Tests
|
||||||
|
|
||||||
|
This repo uses `vitest` for unit tests.
|
||||||
|
|
||||||
|
Tests should be colocated with the code they test, and should use the `.test.ts` suffix.
|
||||||
|
|
||||||
|
Tests do not need to be written for code that is trivial or has no logic (e.g. simple type definitions, re-exports, etc.). We currently do not do UI tests.
|
||||||
|
|
||||||
|
# Agents
|
||||||
|
|
||||||
|
- Use @agent-javascript-pro and @agent-typescript-pro for JavaScript and TypeScript code generation and assistance.
|
||||||
|
- Use @frontend-developer for general frontend development tasks.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
Split up tasks into smaller subtasks and handle them one at a time using an agent. Ensure each subtask is completed before moving on to the next.
|
||||||
|
|
||||||
|
Each agent should maintain a work log in a markdown file.
|
||||||
|
|
||||||
|
When an agent completes a task, it should:
|
||||||
|
|
||||||
|
1. Summarize the changes made.
|
||||||
|
2. List any files that were added, modified, or deleted.
|
||||||
|
3. Commit the changes with a descriptive commit message.
|
||||||
|
|
||||||
|
DO NOT PUSH ANY CHANGES TO THE REMOTE REPOSITORY.
|
||||||
@@ -197,6 +197,10 @@ export default [
|
|||||||
importNames: ['isEqual'],
|
importNames: ['isEqual'],
|
||||||
message: 'Please use objectEquals from @observ33r/object-equals instead.',
|
message: 'Please use objectEquals from @observ33r/object-equals instead.',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'zod/v3',
|
||||||
|
message: 'Import from zod instead.',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const config: KnipConfig = {
|
|||||||
'src/app/store/use-debounced-app-selector.ts',
|
'src/app/store/use-debounced-app-selector.ts',
|
||||||
],
|
],
|
||||||
ignoreBinaries: ['only-allow'],
|
ignoreBinaries: ['only-allow'],
|
||||||
|
ignoreDependencies: ['magic-string'],
|
||||||
paths: {
|
paths: {
|
||||||
'public/*': ['public/*'],
|
'public/*': ['public/*'],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
"@dagrejs/dagre": "^1.1.5",
|
"@dagrejs/dagre": "^1.1.5",
|
||||||
"@dagrejs/graphlib": "^2.2.4",
|
"@dagrejs/graphlib": "^2.2.4",
|
||||||
"@fontsource-variable/inter": "^5.2.6",
|
"@fontsource-variable/inter": "^5.2.6",
|
||||||
"@invoke-ai/ui-library": "^0.0.46",
|
"@invoke-ai/ui-library": "^0.0.47",
|
||||||
"@nanostores/react": "^1.0.0",
|
"@nanostores/react": "^1.0.0",
|
||||||
"@observ33r/object-equals": "^1.1.5",
|
"@observ33r/object-equals": "^1.1.5",
|
||||||
"@reduxjs/toolkit": "2.8.2",
|
"@reduxjs/toolkit": "2.8.2",
|
||||||
@@ -56,19 +56,20 @@
|
|||||||
"chakra-react-select": "^4.9.2",
|
"chakra-react-select": "^4.9.2",
|
||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
"compare-versions": "^6.1.1",
|
"compare-versions": "^6.1.1",
|
||||||
"dockview": "^4.4.1",
|
"dockview": "^4.7.1",
|
||||||
"es-toolkit": "^1.39.7",
|
"es-toolkit": "^1.39.7",
|
||||||
"filesize": "^10.1.6",
|
"filesize": "^10.1.6",
|
||||||
"fracturedjsonjs": "^4.1.0",
|
"fracturedjsonjs": "^4.1.0",
|
||||||
"framer-motion": "^11.10.0",
|
"framer-motion": "^11.10.0",
|
||||||
"i18next": "^25.3.2",
|
"i18next": "^25.3.2",
|
||||||
"i18next-http-backend": "^3.0.2",
|
"i18next-http-backend": "^3.0.2",
|
||||||
"idb-keyval": "6.2.2",
|
"idb-keyval": "6.2.1",
|
||||||
"jsondiffpatch": "^0.7.3",
|
"jsondiffpatch": "^0.7.3",
|
||||||
"konva": "^9.3.22",
|
"konva": "^9.3.22",
|
||||||
"linkify-react": "^4.3.1",
|
"linkify-react": "^4.3.1",
|
||||||
"linkifyjs": "^4.3.1",
|
"linkifyjs": "^4.3.1",
|
||||||
"lru-cache": "^11.1.0",
|
"lru-cache": "^11.1.0",
|
||||||
|
"media-chrome": "^4.13.0",
|
||||||
"mtwist": "^1.0.2",
|
"mtwist": "^1.0.2",
|
||||||
"nanoid": "^5.1.5",
|
"nanoid": "^5.1.5",
|
||||||
"nanostores": "^1.0.1",
|
"nanostores": "^1.0.1",
|
||||||
@@ -87,6 +88,7 @@
|
|||||||
"react-hotkeys-hook": "4.5.0",
|
"react-hotkeys-hook": "4.5.0",
|
||||||
"react-i18next": "^15.5.3",
|
"react-i18next": "^15.5.3",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
|
"react-player": "^3.3.1",
|
||||||
"react-redux": "9.2.0",
|
"react-redux": "9.2.0",
|
||||||
"react-resizable-panels": "^3.0.3",
|
"react-resizable-panels": "^3.0.3",
|
||||||
"react-textarea-autosize": "^8.5.9",
|
"react-textarea-autosize": "^8.5.9",
|
||||||
@@ -103,7 +105,7 @@
|
|||||||
"use-debounce": "^10.0.5",
|
"use-debounce": "^10.0.5",
|
||||||
"use-device-pixel-ratio": "^1.1.2",
|
"use-device-pixel-ratio": "^1.1.2",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"zod": "^4.0.5",
|
"zod": "^4.0.10",
|
||||||
"zod-validation-error": "^3.5.2"
|
"zod-validation-error": "^3.5.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@@ -139,6 +141,7 @@
|
|||||||
"eslint-plugin-unused-imports": "^4.1.4",
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
"globals": "^16.3.0",
|
"globals": "^16.3.0",
|
||||||
"knip": "^5.61.3",
|
"knip": "^5.61.3",
|
||||||
|
"magic-string": "^0.30.17",
|
||||||
"openapi-types": "^12.1.3",
|
"openapi-types": "^12.1.3",
|
||||||
"openapi-typescript": "^7.6.1",
|
"openapi-typescript": "^7.6.1",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
|
|||||||
516
invokeai/frontend/web/pnpm-lock.yaml
generated
516
invokeai/frontend/web/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,7 @@
|
|||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "حجم الصورة",
|
"galleryImageSize": "حجم الصورة",
|
||||||
"gallerySettings": "إعدادات المعرض",
|
"gallerySettings": "إعدادات المعرض",
|
||||||
"autoSwitchNewImages": "التبديل التلقائي إلى الصور الجديدة",
|
"autoSwitchNewImages": "التبديل التلقائي إلى الصور الجديدة"
|
||||||
"noImagesInGallery": "لا توجد صور في المعرض"
|
|
||||||
},
|
},
|
||||||
"modelManager": {
|
"modelManager": {
|
||||||
"modelManager": "مدير النموذج",
|
"modelManager": "مدير النموذج",
|
||||||
@@ -62,12 +61,10 @@
|
|||||||
"infillMethod": "طريقة التعبئة",
|
"infillMethod": "طريقة التعبئة",
|
||||||
"tileSize": "حجم البلاطة",
|
"tileSize": "حجم البلاطة",
|
||||||
"copyImage": "نسخ الصورة",
|
"copyImage": "نسخ الصورة",
|
||||||
"downloadImage": "تحميل الصورة",
|
|
||||||
"usePrompt": "استخدم المحث",
|
"usePrompt": "استخدم المحث",
|
||||||
"useSeed": "استخدام البذور",
|
"useSeed": "استخدام البذور",
|
||||||
"useAll": "استخدام الكل",
|
"useAll": "استخدام الكل",
|
||||||
"info": "معلومات",
|
"info": "معلومات"
|
||||||
"showOptionsPanel": "إظهار لوحة الخيارات"
|
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"models": "موديلات",
|
"models": "موديلات",
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
"ipAdapter": "IP Adapter",
|
"ipAdapter": "IP Adapter",
|
||||||
"auto": "Auto",
|
"auto": "Auto",
|
||||||
"controlNet": "ControlNet",
|
"controlNet": "ControlNet",
|
||||||
"imageFailedToLoad": "Kann Bild nicht laden",
|
|
||||||
"modelManager": "Model Manager",
|
"modelManager": "Model Manager",
|
||||||
"learnMore": "Mehr erfahren",
|
"learnMore": "Mehr erfahren",
|
||||||
"loading": "Lade",
|
"loading": "Lade",
|
||||||
@@ -52,7 +51,6 @@
|
|||||||
"somethingWentWrong": "Etwas ist schief gelaufen",
|
"somethingWentWrong": "Etwas ist schief gelaufen",
|
||||||
"copyError": "$t(gallery.copy) Fehler",
|
"copyError": "$t(gallery.copy) Fehler",
|
||||||
"input": "Eingabe",
|
"input": "Eingabe",
|
||||||
"notInstalled": "Nicht $t(common.installed)",
|
|
||||||
"alpha": "Alpha",
|
"alpha": "Alpha",
|
||||||
"red": "Rot",
|
"red": "Rot",
|
||||||
"green": "Grün",
|
"green": "Grün",
|
||||||
@@ -62,11 +60,8 @@
|
|||||||
"direction": "Richtung",
|
"direction": "Richtung",
|
||||||
"save": "Speichern",
|
"save": "Speichern",
|
||||||
"created": "Erstellt",
|
"created": "Erstellt",
|
||||||
"prevPage": "Vorherige Seite",
|
|
||||||
"nextPage": "Nächste Seite",
|
|
||||||
"unknownError": "Unbekannter Fehler",
|
"unknownError": "Unbekannter Fehler",
|
||||||
"aboutDesc": "Verwenden Sie Invoke für die Arbeit? Siehe hier:",
|
"aboutDesc": "Verwenden Sie Invoke für die Arbeit? Siehe hier:",
|
||||||
"localSystem": "Lokales System",
|
|
||||||
"orderBy": "Ordnen nach",
|
"orderBy": "Ordnen nach",
|
||||||
"saveAs": "Speichern als",
|
"saveAs": "Speichern als",
|
||||||
"updated": "Aktualisiert",
|
"updated": "Aktualisiert",
|
||||||
@@ -77,7 +72,6 @@
|
|||||||
"selected": "Ausgewählt",
|
"selected": "Ausgewählt",
|
||||||
"beta": "Beta",
|
"beta": "Beta",
|
||||||
"editor": "Editor",
|
"editor": "Editor",
|
||||||
"goTo": "Gehe zu",
|
|
||||||
"positivePrompt": "Positiv-Prompt",
|
"positivePrompt": "Positiv-Prompt",
|
||||||
"negativePrompt": "Negativ-Prompt",
|
"negativePrompt": "Negativ-Prompt",
|
||||||
"tab": "Tabulator",
|
"tab": "Tabulator",
|
||||||
@@ -106,7 +100,6 @@
|
|||||||
"values": "Werte",
|
"values": "Werte",
|
||||||
"min": "Min",
|
"min": "Min",
|
||||||
"max": "Max",
|
"max": "Max",
|
||||||
"resetToDefaults": "Auf Standard zurücksetzen",
|
|
||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
"row": "Reihe",
|
"row": "Reihe",
|
||||||
"column": "Spalte",
|
"column": "Spalte",
|
||||||
@@ -135,14 +128,12 @@
|
|||||||
"galleryImageSize": "Bildgröße",
|
"galleryImageSize": "Bildgröße",
|
||||||
"gallerySettings": "Galerie-Einstellungen",
|
"gallerySettings": "Galerie-Einstellungen",
|
||||||
"autoSwitchNewImages": "Auto-Wechsel zu neuen Bildern",
|
"autoSwitchNewImages": "Auto-Wechsel zu neuen Bildern",
|
||||||
"noImagesInGallery": "Keine Bilder in der Galerie",
|
|
||||||
"loading": "Lade",
|
"loading": "Lade",
|
||||||
"deleteImage_one": "Lösche Bild",
|
"deleteImage_one": "Lösche Bild",
|
||||||
"deleteImage_other": "Lösche {{count}} Bilder",
|
"deleteImage_other": "Lösche {{count}} Bilder",
|
||||||
"copy": "Kopieren",
|
"copy": "Kopieren",
|
||||||
"download": "Runterladen",
|
"download": "Runterladen",
|
||||||
"featuresWillReset": "Wenn Sie dieses Bild löschen, werden diese Funktionen sofort zurückgesetzt.",
|
"featuresWillReset": "Wenn Sie dieses Bild löschen, werden diese Funktionen sofort zurückgesetzt.",
|
||||||
"unableToLoad": "Galerie kann nicht geladen werden",
|
|
||||||
"downloadSelection": "Auswahl herunterladen",
|
"downloadSelection": "Auswahl herunterladen",
|
||||||
"currentlyInUse": "Dieses Bild wird derzeit in den folgenden Funktionen verwendet:",
|
"currentlyInUse": "Dieses Bild wird derzeit in den folgenden Funktionen verwendet:",
|
||||||
"deleteImagePermanent": "Gelöschte Bilder können nicht wiederhergestellt werden.",
|
"deleteImagePermanent": "Gelöschte Bilder können nicht wiederhergestellt werden.",
|
||||||
@@ -182,16 +173,12 @@
|
|||||||
"gallery": "Galerie",
|
"gallery": "Galerie",
|
||||||
"sortDirection": "Sortierreihenfolge",
|
"sortDirection": "Sortierreihenfolge",
|
||||||
"sideBySide": "Nebeneinander",
|
"sideBySide": "Nebeneinander",
|
||||||
"openViewer": "Viewer öffnen",
|
|
||||||
"viewerImage": "Viewer-Bild",
|
"viewerImage": "Viewer-Bild",
|
||||||
"exitCompare": "Vergleichen beenden",
|
"exitCompare": "Vergleichen beenden",
|
||||||
"closeViewer": "Viewer schließen",
|
|
||||||
"selectAnImageToCompare": "Wählen Sie ein Bild zum Vergleichen",
|
|
||||||
"stretchToFit": "Strecken bis es passt",
|
"stretchToFit": "Strecken bis es passt",
|
||||||
"displayBoardSearch": "Board durchsuchen",
|
"displayBoardSearch": "Board durchsuchen",
|
||||||
"displaySearch": "Bild suchen",
|
"displaySearch": "Bild suchen",
|
||||||
"go": "Los",
|
"go": "Los",
|
||||||
"jump": "Springen",
|
|
||||||
"assetsTab": "Dateien, die Sie zur Verwendung in Ihren Projekten hochgeladen haben.",
|
"assetsTab": "Dateien, die Sie zur Verwendung in Ihren Projekten hochgeladen haben.",
|
||||||
"imagesTab": "Bilder, die Sie in Invoke erstellt und gespeichert haben.",
|
"imagesTab": "Bilder, die Sie in Invoke erstellt und gespeichert haben.",
|
||||||
"boardsSettings": "Ordnereinstellungen",
|
"boardsSettings": "Ordnereinstellungen",
|
||||||
@@ -210,10 +197,6 @@
|
|||||||
"title": "Bbox Werkzeug",
|
"title": "Bbox Werkzeug",
|
||||||
"desc": "Bbox Werkzeug auswählen."
|
"desc": "Bbox Werkzeug auswählen."
|
||||||
},
|
},
|
||||||
"setFillToWhite": {
|
|
||||||
"title": "Farbe auf Weiß einstellen",
|
|
||||||
"desc": "Setzt die aktuelle Werkzeugfarbe auf weiß."
|
|
||||||
},
|
|
||||||
"title": "Leinwand",
|
"title": "Leinwand",
|
||||||
"selectBrushTool": {
|
"selectBrushTool": {
|
||||||
"title": "Pinselwerkzeug",
|
"title": "Pinselwerkzeug",
|
||||||
@@ -578,7 +561,6 @@
|
|||||||
"urlOrLocalPath": "URL oder lokaler Pfad",
|
"urlOrLocalPath": "URL oder lokaler Pfad",
|
||||||
"install": "Installieren",
|
"install": "Installieren",
|
||||||
"textualInversions": "Textuelle Inversionen",
|
"textualInversions": "Textuelle Inversionen",
|
||||||
"ipAdapters": "IP-Adapter",
|
|
||||||
"modelImageUpdated": "Modellbild aktualisiert",
|
"modelImageUpdated": "Modellbild aktualisiert",
|
||||||
"path": "Pfad",
|
"path": "Pfad",
|
||||||
"pathToConfig": "Pfad zur Konfiguration",
|
"pathToConfig": "Pfad zur Konfiguration",
|
||||||
@@ -601,7 +583,6 @@
|
|||||||
"repoVariant": "Repo Variante",
|
"repoVariant": "Repo Variante",
|
||||||
"learnMoreAboutSupportedModels": "Erfahren Sie mehr über die Modelle, die wir unterstützen",
|
"learnMoreAboutSupportedModels": "Erfahren Sie mehr über die Modelle, die wir unterstützen",
|
||||||
"clipEmbed": "CLIP einbetten",
|
"clipEmbed": "CLIP einbetten",
|
||||||
"starterModelsInModelManager": "Modelle für Ihren Start finden Sie im Modell-Manager",
|
|
||||||
"noModelsInstalledDesc1": "Installiere Modelle mit dem",
|
"noModelsInstalledDesc1": "Installiere Modelle mit dem",
|
||||||
"modelImageUpdateFailed": "Modellbild-Update fehlgeschlagen",
|
"modelImageUpdateFailed": "Modellbild-Update fehlgeschlagen",
|
||||||
"prune": "Bereinigen",
|
"prune": "Bereinigen",
|
||||||
@@ -661,11 +642,9 @@
|
|||||||
"scaledHeight": "Skaliert H",
|
"scaledHeight": "Skaliert H",
|
||||||
"infillMethod": "Infill-Methode",
|
"infillMethod": "Infill-Methode",
|
||||||
"tileSize": "Kachelgröße",
|
"tileSize": "Kachelgröße",
|
||||||
"downloadImage": "Bild herunterladen",
|
|
||||||
"usePrompt": "Prompt verwenden",
|
"usePrompt": "Prompt verwenden",
|
||||||
"useSeed": "Seed verwenden",
|
"useSeed": "Seed verwenden",
|
||||||
"useAll": "Alle verwenden",
|
"useAll": "Alle verwenden",
|
||||||
"showOptionsPanel": "Optionsleiste zeigen",
|
|
||||||
"copyImage": "Bild kopieren",
|
"copyImage": "Bild kopieren",
|
||||||
"denoisingStrength": "Stärke der Entrauschung",
|
"denoisingStrength": "Stärke der Entrauschung",
|
||||||
"symmetry": "Symmetrie",
|
"symmetry": "Symmetrie",
|
||||||
@@ -681,10 +660,6 @@
|
|||||||
"remixImage": "Remix des Bilds erstellen",
|
"remixImage": "Remix des Bilds erstellen",
|
||||||
"imageActions": "Weitere Bildaktionen",
|
"imageActions": "Weitere Bildaktionen",
|
||||||
"invoke": {
|
"invoke": {
|
||||||
"fluxModelIncompatibleScaledBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), Skalierte Bbox-Breite ist {{width}}",
|
|
||||||
"fluxModelIncompatibleScaledBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), Skalierte Bbox-Höhe ist {{height}}",
|
|
||||||
"fluxModelIncompatibleBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), Bbox-Breite ist {{width}}",
|
|
||||||
"fluxModelIncompatibleBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), Bbox-Höhe ist {{height}}",
|
|
||||||
"noNodesInGraph": "Keine Knoten im Graphen",
|
"noNodesInGraph": "Keine Knoten im Graphen",
|
||||||
"canvasIsTransforming": "Leinwand ist beschäftigt (wird transformiert)",
|
"canvasIsTransforming": "Leinwand ist beschäftigt (wird transformiert)",
|
||||||
"canvasIsRasterizing": "Leinwand ist beschäftigt (wird gerastert)",
|
"canvasIsRasterizing": "Leinwand ist beschäftigt (wird gerastert)",
|
||||||
@@ -750,7 +725,6 @@
|
|||||||
"parametersNotSet": "Parameter nicht zurückgerufen",
|
"parametersNotSet": "Parameter nicht zurückgerufen",
|
||||||
"addedToBoard": "Dem Board hinzugefügt",
|
"addedToBoard": "Dem Board hinzugefügt",
|
||||||
"loadedWithWarnings": "Workflow mit Warnungen geladen",
|
"loadedWithWarnings": "Workflow mit Warnungen geladen",
|
||||||
"imageSaved": "Bild gespeichert",
|
|
||||||
"linkCopied": "Link kopiert",
|
"linkCopied": "Link kopiert",
|
||||||
"problemCopyingLayer": "Ebene kann nicht kopiert werden",
|
"problemCopyingLayer": "Ebene kann nicht kopiert werden",
|
||||||
"problemSavingLayer": "Ebene kann nicht gespeichert werden",
|
"problemSavingLayer": "Ebene kann nicht gespeichert werden",
|
||||||
@@ -761,8 +735,6 @@
|
|||||||
"prunedQueue": "Warteschlange bereinigt",
|
"prunedQueue": "Warteschlange bereinigt",
|
||||||
"modelAddedSimple": "Modell zur Warteschlange hinzugefügt",
|
"modelAddedSimple": "Modell zur Warteschlange hinzugefügt",
|
||||||
"parametersSet": "Parameter zurückgerufen",
|
"parametersSet": "Parameter zurückgerufen",
|
||||||
"imageNotLoadedDesc": "Bild konnte nicht gefunden werden",
|
|
||||||
"setControlImage": "Als Kontrollbild festlegen",
|
|
||||||
"sentToUpscale": "An Vergrößerung gesendet",
|
"sentToUpscale": "An Vergrößerung gesendet",
|
||||||
"parameterNotSetDescWithMessage": "{{parameter}} kann nicht zurückgerufen werden: {{message}}",
|
"parameterNotSetDescWithMessage": "{{parameter}} kann nicht zurückgerufen werden: {{message}}",
|
||||||
"unableToLoadImageMetadata": "Bildmetadaten können nicht geladen werden",
|
"unableToLoadImageMetadata": "Bildmetadaten können nicht geladen werden",
|
||||||
@@ -775,7 +747,6 @@
|
|||||||
"parameterSet": "Parameter zurückgerufen",
|
"parameterSet": "Parameter zurückgerufen",
|
||||||
"importFailed": "Import fehlgeschlagen",
|
"importFailed": "Import fehlgeschlagen",
|
||||||
"importSuccessful": "Import erfolgreich",
|
"importSuccessful": "Import erfolgreich",
|
||||||
"setNodeField": "Als Knotenfeld festlegen",
|
|
||||||
"somethingWentWrong": "Etwas ist schief gelaufen",
|
"somethingWentWrong": "Etwas ist schief gelaufen",
|
||||||
"workflowLoaded": "Arbeitsablauf geladen",
|
"workflowLoaded": "Arbeitsablauf geladen",
|
||||||
"workflowDeleted": "Arbeitsablauf gelöscht",
|
"workflowDeleted": "Arbeitsablauf gelöscht",
|
||||||
@@ -783,16 +754,12 @@
|
|||||||
"layerCopiedToClipboard": "Ebene in die Zwischenablage kopiert",
|
"layerCopiedToClipboard": "Ebene in die Zwischenablage kopiert",
|
||||||
"sentToCanvas": "An Leinwand gesendet",
|
"sentToCanvas": "An Leinwand gesendet",
|
||||||
"problemDeletingWorkflow": "Problem beim Löschen des Arbeitsablaufs",
|
"problemDeletingWorkflow": "Problem beim Löschen des Arbeitsablaufs",
|
||||||
"uploadFailedInvalidUploadDesc_withCount_one": "Darf maximal 1 PNG-, JPEG- oder WEBP-Bild sein.",
|
|
||||||
"uploadFailedInvalidUploadDesc_withCount_other": "Dürfen maximal {{count}} PNG-, JPEG- oder WEBP-Bild sein.",
|
|
||||||
"problemRetrievingWorkflow": "Problem beim Abrufen des Arbeitsablaufs",
|
"problemRetrievingWorkflow": "Problem beim Abrufen des Arbeitsablaufs",
|
||||||
"uploadFailedInvalidUploadDesc": "Müssen PNG-, JPEG- oder WEBP-Bilder sein.",
|
"uploadFailedInvalidUploadDesc": "Müssen PNG-, JPEG- oder WEBP-Bilder sein.",
|
||||||
"pasteSuccess": "Eingefügt in {{destination}}",
|
"pasteSuccess": "Eingefügt in {{destination}}",
|
||||||
"pasteFailed": "Einfügen fehlgeschlagen",
|
"pasteFailed": "Einfügen fehlgeschlagen",
|
||||||
"unableToCopy": "Kopieren nicht möglich",
|
"unableToCopy": "Kopieren nicht möglich",
|
||||||
"unableToCopyDesc_theseSteps": "diese Schritte",
|
"unableToCopyDesc_theseSteps": "diese Schritte",
|
||||||
"noRasterLayers": "Keine Rasterebenen gefunden",
|
|
||||||
"noActiveRasterLayers": "Keine aktiven Rasterebenen",
|
|
||||||
"noVisibleRasterLayers": "Keine sichtbaren Rasterebenen"
|
"noVisibleRasterLayers": "Keine sichtbaren Rasterebenen"
|
||||||
},
|
},
|
||||||
"accessibility": {
|
"accessibility": {
|
||||||
@@ -845,16 +812,13 @@
|
|||||||
"archiveBoard": "Ordner archivieren",
|
"archiveBoard": "Ordner archivieren",
|
||||||
"archived": "Archiviert",
|
"archived": "Archiviert",
|
||||||
"noBoards": "Kein {{boardType}} Ordner",
|
"noBoards": "Kein {{boardType}} Ordner",
|
||||||
"hideBoards": "Ordner verstecken",
|
|
||||||
"viewBoards": "Ordner ansehen",
|
|
||||||
"deletedPrivateBoardsCannotbeRestored": "Gelöschte Boards können nicht wiederhergestellt werden. Wenn Sie „Nur Board löschen“ wählen, werden die Bilder in einen privaten, nicht kategorisierten Status für den Ersteller des Bildes versetzt.",
|
"deletedPrivateBoardsCannotbeRestored": "Gelöschte Boards können nicht wiederhergestellt werden. Wenn Sie „Nur Board löschen“ wählen, werden die Bilder in einen privaten, nicht kategorisierten Status für den Ersteller des Bildes versetzt.",
|
||||||
"assetsWithCount_one": "{{count}} in der Sammlung",
|
"assetsWithCount_one": "{{count}} in der Sammlung",
|
||||||
"assetsWithCount_other": "{{count}} in der Sammlung",
|
"assetsWithCount_other": "{{count}} in der Sammlung",
|
||||||
"deletedBoardsCannotbeRestored": "Gelöschte Ordner können nicht wiederhergestellt werden. Die Auswahl von \"Nur Ordner löschen\" verschiebt Bilder in einen unkategorisierten Zustand.",
|
"deletedBoardsCannotbeRestored": "Gelöschte Ordner können nicht wiederhergestellt werden. Die Auswahl von \"Nur Ordner löschen\" verschiebt Bilder in einen unkategorisierten Zustand.",
|
||||||
"updateBoardError": "Fehler beim Aktualisieren des Ordners",
|
"updateBoardError": "Fehler beim Aktualisieren des Ordners",
|
||||||
"uncategorizedImages": "Nicht kategorisierte Bilder",
|
"uncategorizedImages": "Nicht kategorisierte Bilder",
|
||||||
"deleteAllUncategorizedImages": "Alle nicht kategorisierten Bilder löschen",
|
"deleteAllUncategorizedImages": "Alle nicht kategorisierten Bilder löschen"
|
||||||
"deletedImagesCannotBeRestored": "Gelöschte Bilder können nicht wiederhergestellt werden."
|
|
||||||
},
|
},
|
||||||
"queue": {
|
"queue": {
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
@@ -909,7 +873,6 @@
|
|||||||
"batchQueuedDesc_other": "{{count}} Einträge an {{direction}} der Wartschlange hinzugefügt",
|
"batchQueuedDesc_other": "{{count}} Einträge an {{direction}} der Wartschlange hinzugefügt",
|
||||||
"openQueue": "Warteschlange öffnen",
|
"openQueue": "Warteschlange öffnen",
|
||||||
"batchFailedToQueue": "Fehler beim Einreihen in die Stapelverarbeitung",
|
"batchFailedToQueue": "Fehler beim Einreihen in die Stapelverarbeitung",
|
||||||
"batchFieldValues": "Stapelverarbeitungswerte",
|
|
||||||
"batchQueued": "Stapelverarbeitung eingereiht",
|
"batchQueued": "Stapelverarbeitung eingereiht",
|
||||||
"graphQueued": "Graph eingereiht",
|
"graphQueued": "Graph eingereiht",
|
||||||
"graphFailedToQueue": "Fehler beim Einreihen des Graphen",
|
"graphFailedToQueue": "Fehler beim Einreihen des Graphen",
|
||||||
@@ -956,8 +919,6 @@
|
|||||||
"allPrompts": "Alle Prompts",
|
"allPrompts": "Alle Prompts",
|
||||||
"imageDimensions": "Bilder Auslösungen",
|
"imageDimensions": "Bilder Auslösungen",
|
||||||
"parameterSet": "Parameter {{parameter}} setzen",
|
"parameterSet": "Parameter {{parameter}} setzen",
|
||||||
"recallParameter": "{{label}} Abrufen",
|
|
||||||
"parsingFailed": "Parsing Fehlgeschlagen",
|
|
||||||
"canvasV2Metadata": "Leinwand",
|
"canvasV2Metadata": "Leinwand",
|
||||||
"guidance": "Führung",
|
"guidance": "Führung",
|
||||||
"seamlessXAxis": "Nahtlose X Achse",
|
"seamlessXAxis": "Nahtlose X Achse",
|
||||||
@@ -1240,9 +1201,7 @@
|
|||||||
"collectionFieldType": "{{name}} (Sammlung)",
|
"collectionFieldType": "{{name}} (Sammlung)",
|
||||||
"connectionWouldCreateCycle": "Verbindung würde einen Kreislauf/cycle schaffen",
|
"connectionWouldCreateCycle": "Verbindung würde einen Kreislauf/cycle schaffen",
|
||||||
"inputMayOnlyHaveOneConnection": "Eingang darf nur eine Verbindung haben",
|
"inputMayOnlyHaveOneConnection": "Eingang darf nur eine Verbindung haben",
|
||||||
"hideLegendNodes": "Feldtyp-Legende ausblenden",
|
|
||||||
"integer": "Ganze Zahl",
|
"integer": "Ganze Zahl",
|
||||||
"addLinearView": "Zur linearen Ansicht hinzufügen",
|
|
||||||
"currentImageDescription": "Zeigt das aktuelle Bild im Node-Editor an",
|
"currentImageDescription": "Zeigt das aktuelle Bild im Node-Editor an",
|
||||||
"ipAdapter": "IP-Adapter",
|
"ipAdapter": "IP-Adapter",
|
||||||
"hideMinimapnodes": "Miniatur-Kartenansicht ausblenden",
|
"hideMinimapnodes": "Miniatur-Kartenansicht ausblenden",
|
||||||
@@ -1251,7 +1210,6 @@
|
|||||||
"reloadNodeTemplates": "Knoten-Vorlagen neu laden",
|
"reloadNodeTemplates": "Knoten-Vorlagen neu laden",
|
||||||
"newWorkflow": "Neuer Arbeitsablauf / Workflow",
|
"newWorkflow": "Neuer Arbeitsablauf / Workflow",
|
||||||
"newWorkflowDesc": "Einen neuen Arbeitsablauf erstellen?",
|
"newWorkflowDesc": "Einen neuen Arbeitsablauf erstellen?",
|
||||||
"noFieldsLinearview": "Keine Felder zur linearen Ansicht hinzugefügt",
|
|
||||||
"clearWorkflow": "Workflow löschen",
|
"clearWorkflow": "Workflow löschen",
|
||||||
"clearWorkflowDesc": "Diesen Arbeitsablauf löschen und neu starten?",
|
"clearWorkflowDesc": "Diesen Arbeitsablauf löschen und neu starten?",
|
||||||
"noConnectionInProgress": "Es besteht keine Verbindung",
|
"noConnectionInProgress": "Es besteht keine Verbindung",
|
||||||
@@ -1259,7 +1217,6 @@
|
|||||||
"nodeVersion": "Knoten Version",
|
"nodeVersion": "Knoten Version",
|
||||||
"node": "Knoten",
|
"node": "Knoten",
|
||||||
"nodeSearch": "Knoten suchen",
|
"nodeSearch": "Knoten suchen",
|
||||||
"removeLinearView": "Entfernen aus Linear View",
|
|
||||||
"nodeOutputs": "Knoten-Ausgänge",
|
"nodeOutputs": "Knoten-Ausgänge",
|
||||||
"nodeTemplate": "Knoten-Vorlage",
|
"nodeTemplate": "Knoten-Vorlage",
|
||||||
"nodeType": "Knotentyp",
|
"nodeType": "Knotentyp",
|
||||||
@@ -1270,7 +1227,6 @@
|
|||||||
"clearWorkflowDesc2": "Ihr aktueller Arbeitsablauf hat ungespeicherte Änderungen.",
|
"clearWorkflowDesc2": "Ihr aktueller Arbeitsablauf hat ungespeicherte Änderungen.",
|
||||||
"scheduler": "Planer",
|
"scheduler": "Planer",
|
||||||
"showMinimapnodes": "MiniMap anzeigen",
|
"showMinimapnodes": "MiniMap anzeigen",
|
||||||
"showLegendNodes": "Feldtyp-Legende anzeigen",
|
|
||||||
"executionStateCompleted": "Erledigt",
|
"executionStateCompleted": "Erledigt",
|
||||||
"downloadWorkflow": "Workflow JSON herunterladen",
|
"downloadWorkflow": "Workflow JSON herunterladen",
|
||||||
"executionStateInProgress": "In Bearbeitung",
|
"executionStateInProgress": "In Bearbeitung",
|
||||||
@@ -1280,7 +1236,6 @@
|
|||||||
"fieldTypesMustMatch": "Feldtypen müssen übereinstimmen",
|
"fieldTypesMustMatch": "Feldtypen müssen übereinstimmen",
|
||||||
"fitViewportNodes": "An Ansichtsgröße anpassen",
|
"fitViewportNodes": "An Ansichtsgröße anpassen",
|
||||||
"loadingNodes": "Lade Nodes...",
|
"loadingNodes": "Lade Nodes...",
|
||||||
"mismatchedVersion": "Ungültiger Knoten: Knoten {{node}} vom Typ {{type}} hat keine passende Version (Update versuchen?)",
|
|
||||||
"fullyContainNodesHelp": "Nodes müssen vollständig innerhalb der Auswahlbox sein, um ausgewählt werden zu können",
|
"fullyContainNodesHelp": "Nodes müssen vollständig innerhalb der Auswahlbox sein, um ausgewählt werden zu können",
|
||||||
"noWorkflow": "Kein Workflow",
|
"noWorkflow": "Kein Workflow",
|
||||||
"executionStateError": "Fehler",
|
"executionStateError": "Fehler",
|
||||||
@@ -1292,9 +1247,7 @@
|
|||||||
"sourceNodeDoesNotExist": "Ungültiger Rand: Quell- / Ausgabe-Knoten {{node}} existiert nicht",
|
"sourceNodeDoesNotExist": "Ungültiger Rand: Quell- / Ausgabe-Knoten {{node}} existiert nicht",
|
||||||
"updateAllNodes": "Update Knoten",
|
"updateAllNodes": "Update Knoten",
|
||||||
"allNodesUpdated": "Alle Knoten aktualisiert",
|
"allNodesUpdated": "Alle Knoten aktualisiert",
|
||||||
"unknownTemplate": "Unbekannte Vorlage",
|
|
||||||
"updateApp": "Update App",
|
"updateApp": "Update App",
|
||||||
"unknownInput": "Unbekannte Eingabe: {{name}}",
|
|
||||||
"unknownNodeType": "Unbekannter Knotentyp",
|
"unknownNodeType": "Unbekannter Knotentyp",
|
||||||
"float": "Kommazahlen",
|
"float": "Kommazahlen",
|
||||||
"enum": "Aufzählung",
|
"enum": "Aufzählung",
|
||||||
@@ -1310,7 +1263,6 @@
|
|||||||
"workflowAuthor": "Autor",
|
"workflowAuthor": "Autor",
|
||||||
"graph": "Graph",
|
"graph": "Graph",
|
||||||
"workflowDescription": "Kurze Beschreibung",
|
"workflowDescription": "Kurze Beschreibung",
|
||||||
"versionUnknown": " Version unbekannt",
|
|
||||||
"workflow": "Arbeitsablauf",
|
"workflow": "Arbeitsablauf",
|
||||||
"noGraph": "Kein Graph",
|
"noGraph": "Kein Graph",
|
||||||
"version": "Version",
|
"version": "Version",
|
||||||
@@ -1328,7 +1280,6 @@
|
|||||||
"unknownErrorValidatingWorkflow": "Unbekannter Fehler beim Validieren des Arbeitsablaufes",
|
"unknownErrorValidatingWorkflow": "Unbekannter Fehler beim Validieren des Arbeitsablaufes",
|
||||||
"inputFieldTypeParseError": "Typ des Eingabefelds {{node}}.{{field}} kann nicht analysiert werden ({{message}})",
|
"inputFieldTypeParseError": "Typ des Eingabefelds {{node}}.{{field}} kann nicht analysiert werden ({{message}})",
|
||||||
"workflowSettings": "Arbeitsablauf Editor Einstellungen",
|
"workflowSettings": "Arbeitsablauf Editor Einstellungen",
|
||||||
"unableToLoadWorkflow": "Arbeitsablauf kann nicht geladen werden",
|
|
||||||
"viewMode": "In linearen Ansicht verwenden",
|
"viewMode": "In linearen Ansicht verwenden",
|
||||||
"unableToValidateWorkflow": "Arbeitsablauf kann nicht validiert werden",
|
"unableToValidateWorkflow": "Arbeitsablauf kann nicht validiert werden",
|
||||||
"outputFieldTypeParseError": "Typ des Ausgabefelds {{node}}.{{field}} kann nicht analysiert werden ({{message}})",
|
"outputFieldTypeParseError": "Typ des Ausgabefelds {{node}}.{{field}} kann nicht analysiert werden ({{message}})",
|
||||||
@@ -1344,7 +1295,6 @@
|
|||||||
"arithmeticSequence": "Arithmetische Folge",
|
"arithmeticSequence": "Arithmetische Folge",
|
||||||
"noBatchGroup": "keine Gruppe",
|
"noBatchGroup": "keine Gruppe",
|
||||||
"generatorNoValues": "leer",
|
"generatorNoValues": "leer",
|
||||||
"generatorLoading": "wird geladen",
|
|
||||||
"generatorLoadFromFile": "Aus Datei laden",
|
"generatorLoadFromFile": "Aus Datei laden",
|
||||||
"showEdgeLabels": "Kantenbeschriftungen anzeigen",
|
"showEdgeLabels": "Kantenbeschriftungen anzeigen",
|
||||||
"downloadWorkflowError": "Fehler beim Herunterladen des Arbeitsablaufs",
|
"downloadWorkflowError": "Fehler beim Herunterladen des Arbeitsablaufs",
|
||||||
@@ -1352,14 +1302,11 @@
|
|||||||
"description": "Beschreibung",
|
"description": "Beschreibung",
|
||||||
"loadWorkflowDesc": "Arbeitsablauf laden?",
|
"loadWorkflowDesc": "Arbeitsablauf laden?",
|
||||||
"loadWorkflowDesc2": "Ihr aktueller Arbeitsablauf enthält nicht gespeicherte Änderungen.",
|
"loadWorkflowDesc2": "Ihr aktueller Arbeitsablauf enthält nicht gespeicherte Änderungen.",
|
||||||
"loadingTemplates": "Lade {{name}}",
|
|
||||||
"missingSourceOrTargetHandle": "Fehlender Quell- oder Zielgriff",
|
"missingSourceOrTargetHandle": "Fehlender Quell- oder Zielgriff",
|
||||||
"missingSourceOrTargetNode": "Fehlender Quell- oder Zielknoten",
|
"missingSourceOrTargetNode": "Fehlender Quell- oder Zielknoten",
|
||||||
"showEdgeLabelsHelp": "Beschriftungen an Kanten anzeigen, um die verknüpften Knoten zu kennzeichnen"
|
"showEdgeLabelsHelp": "Beschriftungen an Kanten anzeigen, um die verknüpften Knoten zu kennzeichnen"
|
||||||
},
|
},
|
||||||
"hrf": {
|
"hrf": {
|
||||||
"enableHrf": "Korrektur für hohe Auflösungen",
|
|
||||||
"upscaleMethod": "Vergrößerungsmethode",
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"strength": "Auflösungs-Fix Stärke",
|
"strength": "Auflösungs-Fix Stärke",
|
||||||
"enabled": "Auflösungs-Fix aktiviert",
|
"enabled": "Auflösungs-Fix aktiviert",
|
||||||
@@ -1370,11 +1317,9 @@
|
|||||||
"models": {
|
"models": {
|
||||||
"noMatchingModels": "Keine passenden Modelle",
|
"noMatchingModels": "Keine passenden Modelle",
|
||||||
"loading": "lade",
|
"loading": "lade",
|
||||||
"noMatchingLoRAs": "Keine passenden LoRAs",
|
|
||||||
"noModelsAvailable": "Keine Modelle verfügbar",
|
"noModelsAvailable": "Keine Modelle verfügbar",
|
||||||
"selectModel": "Wählen ein Modell aus",
|
"selectModel": "Wählen ein Modell aus",
|
||||||
"noRefinerModelsInstalled": "Keine SDXL Refiner-Modelle installiert",
|
"noRefinerModelsInstalled": "Keine SDXL Refiner-Modelle installiert",
|
||||||
"noLoRAsInstalled": "Keine LoRAs installiert",
|
|
||||||
"addLora": "LoRA hinzufügen",
|
"addLora": "LoRA hinzufügen",
|
||||||
"defaultVAE": "Standard VAE",
|
"defaultVAE": "Standard VAE",
|
||||||
"lora": "LoRA",
|
"lora": "LoRA",
|
||||||
@@ -1404,31 +1349,23 @@
|
|||||||
"workflows": "Arbeitsabläufe",
|
"workflows": "Arbeitsabläufe",
|
||||||
"workflowName": "Arbeitsablauf-Name",
|
"workflowName": "Arbeitsablauf-Name",
|
||||||
"saveWorkflowAs": "Arbeitsablauf speichern als",
|
"saveWorkflowAs": "Arbeitsablauf speichern als",
|
||||||
"searchWorkflows": "Suche Arbeitsabläufe",
|
|
||||||
"newWorkflowCreated": "Neuer Arbeitsablauf erstellt",
|
"newWorkflowCreated": "Neuer Arbeitsablauf erstellt",
|
||||||
"problemSavingWorkflow": "Problem beim Speichern des Arbeitsablaufs",
|
"problemSavingWorkflow": "Problem beim Speichern des Arbeitsablaufs",
|
||||||
"problemLoading": "Problem beim Laden von Arbeitsabläufen",
|
|
||||||
"downloadWorkflow": "Speichern als",
|
"downloadWorkflow": "Speichern als",
|
||||||
"savingWorkflow": "Speichere Arbeitsablauf...",
|
"savingWorkflow": "Speichere Arbeitsablauf...",
|
||||||
"saveWorkflow": "Arbeitsablauf speichern",
|
"saveWorkflow": "Arbeitsablauf speichern",
|
||||||
"noWorkflows": "Keine Arbeitsabläufe",
|
"noWorkflows": "Keine Arbeitsabläufe",
|
||||||
"workflowLibrary": "Bibliothek",
|
"workflowLibrary": "Bibliothek",
|
||||||
"unnamedWorkflow": "Unbenannter Arbeitsablauf",
|
"unnamedWorkflow": "Unbenannter Arbeitsablauf",
|
||||||
"noDescription": "Keine Beschreibung",
|
|
||||||
"clearWorkflowSearchFilter": "Suchfilter zurücksetzen",
|
|
||||||
"workflowEditorMenu": "Arbeitsablauf-Editor Menü",
|
"workflowEditorMenu": "Arbeitsablauf-Editor Menü",
|
||||||
"deleteWorkflow": "Arbeitsablauf löschen",
|
"deleteWorkflow": "Arbeitsablauf löschen",
|
||||||
"workflowSaved": "Arbeitsablauf gespeichert",
|
"workflowSaved": "Arbeitsablauf gespeichert",
|
||||||
"uploadWorkflow": "Aus Datei laden",
|
"uploadWorkflow": "Aus Datei laden",
|
||||||
"openWorkflow": "Arbeitsablauf öffnen",
|
|
||||||
"saveWorkflowToProject": "Arbeitsablauf in Projekt speichern",
|
"saveWorkflowToProject": "Arbeitsablauf in Projekt speichern",
|
||||||
"workflowCleared": "Arbeitsablauf gelöscht",
|
"workflowCleared": "Arbeitsablauf gelöscht",
|
||||||
"loading": "Lade Arbeitsabläufe",
|
"loading": "Lade Arbeitsabläufe",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"ascending": "Aufsteigend",
|
"ascending": "Aufsteigend",
|
||||||
"defaultWorkflows": "Standard Arbeitsabläufe",
|
|
||||||
"userWorkflows": "Benutzer Arbeitsabläufe",
|
|
||||||
"projectWorkflows": "Projekt Arbeitsabläufe",
|
|
||||||
"opened": "Geöffnet",
|
"opened": "Geöffnet",
|
||||||
"loadWorkflow": "Arbeitsablauf $t(common.load)",
|
"loadWorkflow": "Arbeitsablauf $t(common.load)",
|
||||||
"updated": "Aktualisiert",
|
"updated": "Aktualisiert",
|
||||||
@@ -1442,12 +1379,10 @@
|
|||||||
"copyShareLink": "Teilen-Link kopieren",
|
"copyShareLink": "Teilen-Link kopieren",
|
||||||
"download": "Herunterladen",
|
"download": "Herunterladen",
|
||||||
"convertGraph": "Graph konvertieren",
|
"convertGraph": "Graph konvertieren",
|
||||||
"filterByTags": "Nach Tags filtern",
|
|
||||||
"yourWorkflows": "Ihre Arbeitsabläufe",
|
"yourWorkflows": "Ihre Arbeitsabläufe",
|
||||||
"recentlyOpened": "Kürzlich geöffnet"
|
"recentlyOpened": "Kürzlich geöffnet"
|
||||||
},
|
},
|
||||||
"sdxl": {
|
"sdxl": {
|
||||||
"concatPromptStyle": "Verknüpfen von Prompt & Stil",
|
|
||||||
"scheduler": "Planer",
|
"scheduler": "Planer",
|
||||||
"steps": "Schritte"
|
"steps": "Schritte"
|
||||||
},
|
},
|
||||||
@@ -1459,18 +1394,15 @@
|
|||||||
"addPromptTrigger": "Prompt-Trigger hinzufügen",
|
"addPromptTrigger": "Prompt-Trigger hinzufügen",
|
||||||
"compatibleEmbeddings": "Kompatible Einbettungen",
|
"compatibleEmbeddings": "Kompatible Einbettungen",
|
||||||
"replace": "Ersetzen",
|
"replace": "Ersetzen",
|
||||||
"insert": "Einfügen",
|
|
||||||
"discard": "Verwerfen",
|
"discard": "Verwerfen",
|
||||||
"generateFromImage": "Prompt aus Bild generieren",
|
"generateFromImage": "Prompt aus Bild generieren",
|
||||||
"expandCurrentPrompt": "Aktuelle Prompt erweitern",
|
"expandCurrentPrompt": "Aktuelle Prompt erweitern",
|
||||||
"uploadImageForPromptGeneration": "Bild zur Prompt-Generierung hochladen",
|
"uploadImageForPromptGeneration": "Bild zur Prompt-Generierung hochladen",
|
||||||
"expandingPrompt": "Prompt wird erweitert...",
|
"expandingPrompt": "Prompt wird erweitert..."
|
||||||
"resultTitle": "Prompt-Erweiterung abgeschlossen"
|
|
||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"queue": "Warteschlange",
|
"queue": "Warteschlange",
|
||||||
"generation": "Erzeugung",
|
|
||||||
"gallery": "Galerie",
|
"gallery": "Galerie",
|
||||||
"models": "Modelle",
|
"models": "Modelle",
|
||||||
"upscaling": "Hochskalierung",
|
"upscaling": "Hochskalierung",
|
||||||
@@ -1605,8 +1537,6 @@
|
|||||||
"opacity": "Opazität",
|
"opacity": "Opazität",
|
||||||
"removeBookmark": "Lesezeichen entfernen",
|
"removeBookmark": "Lesezeichen entfernen",
|
||||||
"rasterLayer": "Rasterebene",
|
"rasterLayer": "Rasterebene",
|
||||||
"rasterLayers_withCount_visible": "Rasterebenen ({{count}})",
|
|
||||||
"controlLayers_withCount_visible": "Kontroll-Ebenen ({{count}})",
|
|
||||||
"deleteSelected": "Ausgewählte löschen",
|
"deleteSelected": "Ausgewählte löschen",
|
||||||
"newRegionalReferenceImageError": "Problem beim Erstellen eines regionalen Referenzbilds",
|
"newRegionalReferenceImageError": "Problem beim Erstellen eines regionalen Referenzbilds",
|
||||||
"newControlLayerOk": "Kontroll-Ebene erstellt",
|
"newControlLayerOk": "Kontroll-Ebene erstellt",
|
||||||
@@ -1614,10 +1544,8 @@
|
|||||||
"newRasterLayerOk": "Rasterebene erstellt",
|
"newRasterLayerOk": "Rasterebene erstellt",
|
||||||
"moveToFront": "Nach vorne bringen",
|
"moveToFront": "Nach vorne bringen",
|
||||||
"copyToClipboard": "In die Zwischenablage kopieren",
|
"copyToClipboard": "In die Zwischenablage kopieren",
|
||||||
"controlLayers_withCount_hidden": "Kontroll-Ebenen ({{count}} ausgeblendet)",
|
|
||||||
"clearCaches": "Cache leeren",
|
"clearCaches": "Cache leeren",
|
||||||
"controlLayer": "Kontroll-Ebene",
|
"controlLayer": "Kontroll-Ebene",
|
||||||
"rasterLayers_withCount_hidden": "Rasterebenen ({{count}} ausgeblendet)",
|
|
||||||
"transparency": "Transparenz",
|
"transparency": "Transparenz",
|
||||||
"canvas": "Leinwand",
|
"canvas": "Leinwand",
|
||||||
"global": "Global",
|
"global": "Global",
|
||||||
@@ -1640,9 +1568,7 @@
|
|||||||
"weight": "Gewichtung",
|
"weight": "Gewichtung",
|
||||||
"addReferenceImage": "$t(controlLayers.referenceImage) hinzufügen",
|
"addReferenceImage": "$t(controlLayers.referenceImage) hinzufügen",
|
||||||
"addInpaintMask": "$t(controlLayers.inpaintMask) hinzufügen",
|
"addInpaintMask": "$t(controlLayers.inpaintMask) hinzufügen",
|
||||||
"addGlobalReferenceImage": "$t(controlLayers.globalReferenceImage) hinzufügen",
|
|
||||||
"regionalGuidance": "Regionale Führung",
|
"regionalGuidance": "Regionale Führung",
|
||||||
"globalReferenceImages_withCount_visible": "Globale Referenzbilder ({{count}})",
|
|
||||||
"addPositivePrompt": "$t(controlLayers.prompt) hinzufügen",
|
"addPositivePrompt": "$t(controlLayers.prompt) hinzufügen",
|
||||||
"locked": "Gesperrt",
|
"locked": "Gesperrt",
|
||||||
"showHUD": "HUD anzeigen",
|
"showHUD": "HUD anzeigen",
|
||||||
@@ -1650,16 +1576,12 @@
|
|||||||
"addRasterLayer": "$t(controlLayers.rasterLayer) hinzufügen",
|
"addRasterLayer": "$t(controlLayers.rasterLayer) hinzufügen",
|
||||||
"addRegionalGuidance": "$t(controlLayers.regionalGuidance) hinzufügen",
|
"addRegionalGuidance": "$t(controlLayers.regionalGuidance) hinzufügen",
|
||||||
"addControlLayer": "$t(controlLayers.controlLayer) hinzufügen",
|
"addControlLayer": "$t(controlLayers.controlLayer) hinzufügen",
|
||||||
"newCanvasSession": "Neue Leinwand-Sitzung",
|
|
||||||
"replaceLayer": "Ebene ersetzen",
|
"replaceLayer": "Ebene ersetzen",
|
||||||
"newGallerySession": "Neue Galerie-Sitzung",
|
|
||||||
"unlocked": "Entsperrt",
|
"unlocked": "Entsperrt",
|
||||||
"showProgressOnCanvas": "Fortschritt auf Leinwand anzeigen",
|
"showProgressOnCanvas": "Fortschritt auf Leinwand anzeigen",
|
||||||
"controlMode": {
|
"controlMode": {
|
||||||
"balanced": "Ausgewogen"
|
"balanced": "Ausgewogen"
|
||||||
},
|
},
|
||||||
"globalReferenceImages_withCount_hidden": "Globale Referenzbilder ({{count}} ausgeblendet)",
|
|
||||||
"sendToGallery": "An Galerie senden",
|
|
||||||
"stagingArea": {
|
"stagingArea": {
|
||||||
"accept": "Annehmen",
|
"accept": "Annehmen",
|
||||||
"next": "Nächste",
|
"next": "Nächste",
|
||||||
@@ -1667,8 +1589,6 @@
|
|||||||
"discard": "Verwerfen",
|
"discard": "Verwerfen",
|
||||||
"previous": "Vorherige"
|
"previous": "Vorherige"
|
||||||
},
|
},
|
||||||
"regionalGuidance_withCount_visible": "Regionale Führung ({{count}})",
|
|
||||||
"regionalGuidance_withCount_hidden": "Regionale Führung ({{count}} ausgeblendet)",
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"snapToGrid": {
|
"snapToGrid": {
|
||||||
"on": "Ein",
|
"on": "Ein",
|
||||||
@@ -1678,8 +1598,6 @@
|
|||||||
},
|
},
|
||||||
"layer_one": "Ebene",
|
"layer_one": "Ebene",
|
||||||
"layer_other": "Ebenen",
|
"layer_other": "Ebenen",
|
||||||
"layer_withCount_one": "Ebene ({{count}})",
|
|
||||||
"layer_withCount_other": "Ebenen ({{count}})",
|
|
||||||
"fill": {
|
"fill": {
|
||||||
"fillStyle": "Füllstil",
|
"fillStyle": "Füllstil",
|
||||||
"diagonal": "Diagonal",
|
"diagonal": "Diagonal",
|
||||||
|
|||||||
@@ -38,10 +38,13 @@
|
|||||||
"deletedImagesCannotBeRestored": "Deleted images cannot be restored.",
|
"deletedImagesCannotBeRestored": "Deleted images cannot be restored.",
|
||||||
"hideBoards": "Hide Boards",
|
"hideBoards": "Hide Boards",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
|
"locateInGalery": "Locate in Gallery",
|
||||||
"menuItemAutoAdd": "Auto-add to this Board",
|
"menuItemAutoAdd": "Auto-add to this Board",
|
||||||
"move": "Move",
|
"move": "Move",
|
||||||
"movingImagesToBoard_one": "Moving {{count}} image to board:",
|
"movingImagesToBoard_one": "Moving {{count}} image to board:",
|
||||||
"movingImagesToBoard_other": "Moving {{count}} images to board:",
|
"movingImagesToBoard_other": "Moving {{count}} images to board:",
|
||||||
|
"movingVideosToBoard_one": "Moving {{count}} video to board:",
|
||||||
|
"movingVideosToBoard_other": "Moving {{count}} videos to board:",
|
||||||
"myBoard": "My Board",
|
"myBoard": "My Board",
|
||||||
"noBoards": "No {{boardType}} Boards",
|
"noBoards": "No {{boardType}} Boards",
|
||||||
"noMatching": "No matching Boards",
|
"noMatching": "No matching Boards",
|
||||||
@@ -58,6 +61,8 @@
|
|||||||
"imagesWithCount_other": "{{count}} images",
|
"imagesWithCount_other": "{{count}} images",
|
||||||
"assetsWithCount_one": "{{count}} asset",
|
"assetsWithCount_one": "{{count}} asset",
|
||||||
"assetsWithCount_other": "{{count}} assets",
|
"assetsWithCount_other": "{{count}} assets",
|
||||||
|
"videosWithCount_one": "{{count}} video",
|
||||||
|
"videosWithCount_other": "{{count}} videos",
|
||||||
"updateBoardError": "Error updating board"
|
"updateBoardError": "Error updating board"
|
||||||
},
|
},
|
||||||
"accordions": {
|
"accordions": {
|
||||||
@@ -99,6 +104,7 @@
|
|||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
"copyError": "$t(gallery.copy) Error",
|
"copyError": "$t(gallery.copy) Error",
|
||||||
"clipboard": "Clipboard",
|
"clipboard": "Clipboard",
|
||||||
|
"crop": "Crop",
|
||||||
"on": "On",
|
"on": "On",
|
||||||
"off": "Off",
|
"off": "Off",
|
||||||
"or": "or",
|
"or": "or",
|
||||||
@@ -114,6 +120,9 @@
|
|||||||
"t2iAdapter": "T2I Adapter",
|
"t2iAdapter": "T2I Adapter",
|
||||||
"positivePrompt": "Positive Prompt",
|
"positivePrompt": "Positive Prompt",
|
||||||
"negativePrompt": "Negative Prompt",
|
"negativePrompt": "Negative Prompt",
|
||||||
|
"removeNegativePrompt": "Remove Negative Prompt",
|
||||||
|
"addNegativePrompt": "Add Negative Prompt",
|
||||||
|
"selectYourModel": "Select Your Model",
|
||||||
"discordLabel": "Discord",
|
"discordLabel": "Discord",
|
||||||
"dontAskMeAgain": "Don't ask me again",
|
"dontAskMeAgain": "Don't ask me again",
|
||||||
"dontShowMeThese": "Don't show me these",
|
"dontShowMeThese": "Don't show me these",
|
||||||
@@ -234,7 +243,10 @@
|
|||||||
"resultSubtitle": "Choose how to handle the expanded prompt:",
|
"resultSubtitle": "Choose how to handle the expanded prompt:",
|
||||||
"replace": "Replace",
|
"replace": "Replace",
|
||||||
"insert": "Insert",
|
"insert": "Insert",
|
||||||
"discard": "Discard"
|
"discard": "Discard",
|
||||||
|
"noPromptHistory": "No prompt history recorded.",
|
||||||
|
"noMatchingPrompts": "No matching prompts in history.",
|
||||||
|
"toSwitchBetweenPrompts": "to switch between prompts."
|
||||||
},
|
},
|
||||||
"queue": {
|
"queue": {
|
||||||
"queue": "Queue",
|
"queue": "Queue",
|
||||||
@@ -290,7 +302,7 @@
|
|||||||
"completedIn": "Completed in",
|
"completedIn": "Completed in",
|
||||||
"batch": "Batch",
|
"batch": "Batch",
|
||||||
"origin": "Origin",
|
"origin": "Origin",
|
||||||
"destination": "Destination",
|
"destination": "Dest",
|
||||||
"upscaling": "Upscaling",
|
"upscaling": "Upscaling",
|
||||||
"canvas": "Canvas",
|
"canvas": "Canvas",
|
||||||
"generation": "Generation",
|
"generation": "Generation",
|
||||||
@@ -316,7 +328,13 @@
|
|||||||
"iterations_other": "Iterations",
|
"iterations_other": "Iterations",
|
||||||
"generations_one": "Generation",
|
"generations_one": "Generation",
|
||||||
"generations_other": "Generations",
|
"generations_other": "Generations",
|
||||||
"batchSize": "Batch Size"
|
"batchSize": "Batch Size",
|
||||||
|
"createdAt": "Created At",
|
||||||
|
"completedAt": "Completed At",
|
||||||
|
"sortColumn": "Sort Column",
|
||||||
|
"sortBy": "Sort by {{column}}",
|
||||||
|
"sortOrderAscending": "Ascending",
|
||||||
|
"sortOrderDescending": "Descending"
|
||||||
},
|
},
|
||||||
"invocationCache": {
|
"invocationCache": {
|
||||||
"invocationCache": "Invocation Cache",
|
"invocationCache": "Invocation Cache",
|
||||||
@@ -357,6 +375,9 @@
|
|||||||
"deleteImage_one": "Delete Image",
|
"deleteImage_one": "Delete Image",
|
||||||
"deleteImage_other": "Delete {{count}} Images",
|
"deleteImage_other": "Delete {{count}} Images",
|
||||||
"deleteImagePermanent": "Deleted images cannot be restored.",
|
"deleteImagePermanent": "Deleted images cannot be restored.",
|
||||||
|
"deleteVideo_one": "Delete Video",
|
||||||
|
"deleteVideo_other": "Delete {{count}} Videos",
|
||||||
|
"deleteVideoPermanent": "Deleted videos cannot be restored.",
|
||||||
"displayBoardSearch": "Board Search",
|
"displayBoardSearch": "Board Search",
|
||||||
"displaySearch": "Image Search",
|
"displaySearch": "Image Search",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
@@ -376,9 +397,10 @@
|
|||||||
"sortDirection": "Sort Direction",
|
"sortDirection": "Sort Direction",
|
||||||
"showStarredImagesFirst": "Show Starred Images First",
|
"showStarredImagesFirst": "Show Starred Images First",
|
||||||
"noImageSelected": "No Image Selected",
|
"noImageSelected": "No Image Selected",
|
||||||
|
"noVideoSelected": "No Video Selected",
|
||||||
"noImagesInGallery": "No Images to Display",
|
"noImagesInGallery": "No Images to Display",
|
||||||
"starImage": "Star Image",
|
"starImage": "Star",
|
||||||
"unstarImage": "Unstar Image",
|
"unstarImage": "Unstar",
|
||||||
"unableToLoad": "Unable to load Gallery",
|
"unableToLoad": "Unable to load Gallery",
|
||||||
"deleteSelection": "Delete Selection",
|
"deleteSelection": "Delete Selection",
|
||||||
"downloadSelection": "Download Selection",
|
"downloadSelection": "Download Selection",
|
||||||
@@ -407,7 +429,9 @@
|
|||||||
"openViewer": "Open Viewer",
|
"openViewer": "Open Viewer",
|
||||||
"closeViewer": "Close Viewer",
|
"closeViewer": "Close Viewer",
|
||||||
"move": "Move",
|
"move": "Move",
|
||||||
"useForPromptGeneration": "Use for Prompt Generation"
|
"useForPromptGeneration": "Use for Prompt Generation",
|
||||||
|
"videos": "Videos",
|
||||||
|
"videosTab": "Videos you've created and saved within Invoke."
|
||||||
},
|
},
|
||||||
"hotkeys": {
|
"hotkeys": {
|
||||||
"hotkeys": "Hotkeys",
|
"hotkeys": "Hotkeys",
|
||||||
@@ -452,10 +476,22 @@
|
|||||||
"title": "Select the Queue Tab",
|
"title": "Select the Queue Tab",
|
||||||
"desc": "Selects the Queue tab."
|
"desc": "Selects the Queue tab."
|
||||||
},
|
},
|
||||||
|
"selectVideoTab": {
|
||||||
|
"title": "Select the Video Tab",
|
||||||
|
"desc": "Selects the Video tab."
|
||||||
|
},
|
||||||
"focusPrompt": {
|
"focusPrompt": {
|
||||||
"title": "Focus Prompt",
|
"title": "Focus Prompt",
|
||||||
"desc": "Move cursor focus to the positive prompt."
|
"desc": "Move cursor focus to the positive prompt."
|
||||||
},
|
},
|
||||||
|
"promptHistoryPrev": {
|
||||||
|
"title": "Previous Prompt in History",
|
||||||
|
"desc": "When the prompt is focused, move to the previous (older) prompt in your history."
|
||||||
|
},
|
||||||
|
"promptHistoryNext": {
|
||||||
|
"title": "Next Prompt in History",
|
||||||
|
"desc": "When the prompt is focused, move to the next (newer) prompt in your history."
|
||||||
|
},
|
||||||
"toggleLeftPanel": {
|
"toggleLeftPanel": {
|
||||||
"title": "Toggle Left Panel",
|
"title": "Toggle Left Panel",
|
||||||
"desc": "Show or hide the left panel."
|
"desc": "Show or hide the left panel."
|
||||||
@@ -478,6 +514,9 @@
|
|||||||
"key": "1"
|
"key": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"video": {
|
||||||
|
"title": "Video"
|
||||||
|
},
|
||||||
"canvas": {
|
"canvas": {
|
||||||
"title": "Canvas",
|
"title": "Canvas",
|
||||||
"selectBrushTool": {
|
"selectBrushTool": {
|
||||||
@@ -568,9 +607,13 @@
|
|||||||
"title": "Prev Layer",
|
"title": "Prev Layer",
|
||||||
"desc": "Select the previous layer in the list."
|
"desc": "Select the previous layer in the list."
|
||||||
},
|
},
|
||||||
"setFillToWhite": {
|
"setFillColorsToDefault": {
|
||||||
"title": "Set Color to White",
|
"title": "Set Colors to Default",
|
||||||
"desc": "Set the current tool color to white."
|
"desc": "Set the current tool colors to default."
|
||||||
|
},
|
||||||
|
"toggleFillColor": {
|
||||||
|
"title": "Toggle Fill Color",
|
||||||
|
"desc": "Toggle the current tool fill color."
|
||||||
},
|
},
|
||||||
"filterSelected": {
|
"filterSelected": {
|
||||||
"title": "Filter",
|
"title": "Filter",
|
||||||
@@ -610,10 +653,18 @@
|
|||||||
"title": "Toggle Non-Raster Layers",
|
"title": "Toggle Non-Raster Layers",
|
||||||
"desc": "Show or hide all non-raster layer categories (Control Layers, Inpaint Masks, Regional Guidance)."
|
"desc": "Show or hide all non-raster layer categories (Control Layers, Inpaint Masks, Regional Guidance)."
|
||||||
},
|
},
|
||||||
|
"fitBboxToLayers": {
|
||||||
|
"title": "Fit Bbox To Layers",
|
||||||
|
"desc": "Automatically adjust the generation bounding box to fit visible layers"
|
||||||
|
},
|
||||||
"fitBboxToMasks": {
|
"fitBboxToMasks": {
|
||||||
"title": "Fit Bbox To Masks",
|
"title": "Fit Bbox To Masks",
|
||||||
"desc": "Automatically adjust the generation bounding box to fit visible inpaint masks"
|
"desc": "Automatically adjust the generation bounding box to fit visible inpaint masks"
|
||||||
},
|
},
|
||||||
|
"toggleBbox": {
|
||||||
|
"title": "Toggle Bbox Visibility",
|
||||||
|
"desc": "Hide or show the generation bounding box"
|
||||||
|
},
|
||||||
"applySegmentAnything": {
|
"applySegmentAnything": {
|
||||||
"title": "Apply Segment Anything",
|
"title": "Apply Segment Anything",
|
||||||
"desc": "Apply the current Segment Anything mask.",
|
"desc": "Apply the current Segment Anything mask.",
|
||||||
@@ -759,20 +810,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lora": {
|
||||||
|
"weight": "Weight"
|
||||||
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"allPrompts": "All Prompts",
|
"allPrompts": "All Prompts",
|
||||||
"cfgScale": "CFG scale",
|
"cfgScale": "CFG scale",
|
||||||
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
||||||
|
"clipSkip": "$t(parameters.clipSkip)",
|
||||||
"createdBy": "Created By",
|
"createdBy": "Created By",
|
||||||
"generationMode": "Generation Mode",
|
"generationMode": "Generation Mode",
|
||||||
"guidance": "Guidance",
|
"guidance": "Guidance",
|
||||||
"height": "Height",
|
"height": "Height",
|
||||||
"imageDetails": "Image Details",
|
"imageDetails": "Image Details",
|
||||||
|
"videoDetails": "Video Details",
|
||||||
"imageDimensions": "Image Dimensions",
|
"imageDimensions": "Image Dimensions",
|
||||||
"metadata": "Metadata",
|
"metadata": "Metadata",
|
||||||
"model": "Model",
|
"model": "Model",
|
||||||
"negativePrompt": "Negative Prompt",
|
"negativePrompt": "Negative Prompt",
|
||||||
"noImageDetails": "No image details found",
|
"noImageDetails": "No image details found",
|
||||||
|
"noVideoDetails": "No video details found",
|
||||||
"noMetaData": "No metadata found",
|
"noMetaData": "No metadata found",
|
||||||
"noRecallParameters": "No parameters to recall found",
|
"noRecallParameters": "No parameters to recall found",
|
||||||
"parameterSet": "Parameter {{parameter}} set",
|
"parameterSet": "Parameter {{parameter}} set",
|
||||||
@@ -790,7 +847,11 @@
|
|||||||
"vae": "VAE",
|
"vae": "VAE",
|
||||||
"width": "Width",
|
"width": "Width",
|
||||||
"workflow": "Workflow",
|
"workflow": "Workflow",
|
||||||
"canvasV2Metadata": "Canvas Layers"
|
"canvasV2Metadata": "Canvas Layers",
|
||||||
|
"videoModel": "Model",
|
||||||
|
"videoDuration": "Duration",
|
||||||
|
"videoAspectRatio": "Aspect Ratio",
|
||||||
|
"videoResolution": "Resolution"
|
||||||
},
|
},
|
||||||
"modelManager": {
|
"modelManager": {
|
||||||
"active": "active",
|
"active": "active",
|
||||||
@@ -865,6 +926,9 @@
|
|||||||
"install": "Install",
|
"install": "Install",
|
||||||
"installAll": "Install All",
|
"installAll": "Install All",
|
||||||
"installRepo": "Install Repo",
|
"installRepo": "Install Repo",
|
||||||
|
"installBundle": "Install Bundle",
|
||||||
|
"installBundleMsg1": "Are you sure you want to install the {{bundleName}} bundle?",
|
||||||
|
"installBundleMsg2": "This bundle will install the following {{count}} models:",
|
||||||
"ipAdapters": "IP Adapters",
|
"ipAdapters": "IP Adapters",
|
||||||
"learnMoreAboutSupportedModels": "Learn more about the models we support",
|
"learnMoreAboutSupportedModels": "Learn more about the models we support",
|
||||||
"load": "Load",
|
"load": "Load",
|
||||||
@@ -1173,6 +1237,7 @@
|
|||||||
},
|
},
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"aspect": "Aspect",
|
"aspect": "Aspect",
|
||||||
|
"duration": "Duration",
|
||||||
"lockAspectRatio": "Lock Aspect Ratio",
|
"lockAspectRatio": "Lock Aspect Ratio",
|
||||||
"swapDimensions": "Swap Dimensions",
|
"swapDimensions": "Swap Dimensions",
|
||||||
"setToOptimalSize": "Optimize size for model",
|
"setToOptimalSize": "Optimize size for model",
|
||||||
@@ -1197,9 +1262,15 @@
|
|||||||
"height": "Height",
|
"height": "Height",
|
||||||
"imageFit": "Fit Initial Image To Output Size",
|
"imageFit": "Fit Initial Image To Output Size",
|
||||||
"images": "Images",
|
"images": "Images",
|
||||||
|
"images_withCount_one": "Image",
|
||||||
|
"images_withCount_other": "Images",
|
||||||
|
"videos_withCount_one": "Video",
|
||||||
|
"videos_withCount_other": "Videos",
|
||||||
"infillMethod": "Infill Method",
|
"infillMethod": "Infill Method",
|
||||||
"infillColorValue": "Fill Color",
|
"infillColorValue": "Fill Color",
|
||||||
"info": "Info",
|
"info": "Info",
|
||||||
|
"startingFrameImage": "Start Frame",
|
||||||
|
"startingFrameImageAspectRatioWarning": "Image aspect ratio does not match the video aspect ratio ({{videoAspectRatio}}). This could lead to unexpected cropping during video generation.",
|
||||||
"invoke": {
|
"invoke": {
|
||||||
"addingImagesTo": "Adding images to",
|
"addingImagesTo": "Adding images to",
|
||||||
"modelDisabledForTrial": "Generating with {{modelName}} is not available on trial accounts. Visit your account settings to upgrade.",
|
"modelDisabledForTrial": "Generating with {{modelName}} is not available on trial accounts. Visit your account settings to upgrade.",
|
||||||
@@ -1223,6 +1294,7 @@
|
|||||||
"batchNodeCollectionSizeMismatchNoGroupId": "Batch group collection size mismatch",
|
"batchNodeCollectionSizeMismatchNoGroupId": "Batch group collection size mismatch",
|
||||||
"batchNodeCollectionSizeMismatch": "Collection size mismatch on Batch {{batchGroupId}}",
|
"batchNodeCollectionSizeMismatch": "Collection size mismatch on Batch {{batchGroupId}}",
|
||||||
"noModelSelected": "No model selected",
|
"noModelSelected": "No model selected",
|
||||||
|
"noStartingFrameImage": "No starting frame image",
|
||||||
"noT5EncoderModelSelected": "No T5 Encoder model selected for FLUX generation",
|
"noT5EncoderModelSelected": "No T5 Encoder model selected for FLUX generation",
|
||||||
"noFLUXVAEModelSelected": "No VAE model selected for FLUX generation",
|
"noFLUXVAEModelSelected": "No VAE model selected for FLUX generation",
|
||||||
"noCLIPEmbedModelSelected": "No CLIP Embed model selected for FLUX generation",
|
"noCLIPEmbedModelSelected": "No CLIP Embed model selected for FLUX generation",
|
||||||
@@ -1235,7 +1307,7 @@
|
|||||||
"modelIncompatibleScaledBboxWidth": "Scaled bbox width is {{width}} but {{model}} requires multiple of {{multiple}}",
|
"modelIncompatibleScaledBboxWidth": "Scaled bbox width is {{width}} but {{model}} requires multiple of {{multiple}}",
|
||||||
"modelIncompatibleScaledBboxHeight": "Scaled bbox height is {{height}} but {{model}} requires multiple of {{multiple}}",
|
"modelIncompatibleScaledBboxHeight": "Scaled bbox height is {{height}} but {{model}} requires multiple of {{multiple}}",
|
||||||
"fluxModelMultipleControlLoRAs": "Can only use 1 Control LoRA at a time",
|
"fluxModelMultipleControlLoRAs": "Can only use 1 Control LoRA at a time",
|
||||||
"fluxKontextMultipleReferenceImages": "Can only use 1 Reference Image at a time with Flux Kontext",
|
"incompatibleLoRAs": "Incompatible LoRA(s) added",
|
||||||
"canvasIsFiltering": "Canvas is busy (filtering)",
|
"canvasIsFiltering": "Canvas is busy (filtering)",
|
||||||
"canvasIsTransforming": "Canvas is busy (transforming)",
|
"canvasIsTransforming": "Canvas is busy (transforming)",
|
||||||
"canvasIsRasterizing": "Canvas is busy (rasterizing)",
|
"canvasIsRasterizing": "Canvas is busy (rasterizing)",
|
||||||
@@ -1245,7 +1317,8 @@
|
|||||||
"noNodesInGraph": "No nodes in graph",
|
"noNodesInGraph": "No nodes in graph",
|
||||||
"systemDisconnected": "System disconnected",
|
"systemDisconnected": "System disconnected",
|
||||||
"promptExpansionPending": "Prompt expansion in progress",
|
"promptExpansionPending": "Prompt expansion in progress",
|
||||||
"promptExpansionResultPending": "Please accept or discard your prompt expansion result"
|
"promptExpansionResultPending": "Please accept or discard your prompt expansion result",
|
||||||
|
"videoIsDisabled": "Video generation is not enabled for {{accountType}} accounts."
|
||||||
},
|
},
|
||||||
"maskBlur": "Mask Blur",
|
"maskBlur": "Mask Blur",
|
||||||
"negativePromptPlaceholder": "Negative Prompt",
|
"negativePromptPlaceholder": "Negative Prompt",
|
||||||
@@ -1263,9 +1336,11 @@
|
|||||||
"seamlessXAxis": "Seamless X Axis",
|
"seamlessXAxis": "Seamless X Axis",
|
||||||
"seamlessYAxis": "Seamless Y Axis",
|
"seamlessYAxis": "Seamless Y Axis",
|
||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
|
"videoActions": "Video Actions",
|
||||||
"imageActions": "Image Actions",
|
"imageActions": "Image Actions",
|
||||||
"sendToCanvas": "Send To Canvas",
|
"sendToCanvas": "Send To Canvas",
|
||||||
"sendToUpscale": "Send To Upscale",
|
"sendToUpscale": "Send To Upscale",
|
||||||
|
"sendToVideo": "Send To Video",
|
||||||
"showOptionsPanel": "Show Side Panel (O or T)",
|
"showOptionsPanel": "Show Side Panel (O or T)",
|
||||||
"shuffle": "Shuffle Seed",
|
"shuffle": "Shuffle Seed",
|
||||||
"steps": "Steps",
|
"steps": "Steps",
|
||||||
@@ -1277,16 +1352,19 @@
|
|||||||
"postProcessing": "Post-Processing (Shift + U)",
|
"postProcessing": "Post-Processing (Shift + U)",
|
||||||
"processImage": "Process Image",
|
"processImage": "Process Image",
|
||||||
"upscaling": "Upscaling",
|
"upscaling": "Upscaling",
|
||||||
|
"video": "Video",
|
||||||
"useAll": "Use All",
|
"useAll": "Use All",
|
||||||
"useSize": "Use Size",
|
"useSize": "Use Size",
|
||||||
"useCpuNoise": "Use CPU Noise",
|
"useCpuNoise": "Use CPU Noise",
|
||||||
"remixImage": "Remix Image",
|
"remixImage": "Remix Image",
|
||||||
"usePrompt": "Use Prompt",
|
"usePrompt": "Use Prompt",
|
||||||
"useSeed": "Use Seed",
|
"useSeed": "Use Seed",
|
||||||
|
"useClipSkip": "Use CLIP Skip",
|
||||||
"width": "Width",
|
"width": "Width",
|
||||||
"gaussianBlur": "Gaussian Blur",
|
"gaussianBlur": "Gaussian Blur",
|
||||||
"boxBlur": "Box Blur",
|
"boxBlur": "Box Blur",
|
||||||
"staged": "Staged",
|
"staged": "Staged",
|
||||||
|
"resolution": "Resolution",
|
||||||
"modelDisabledForTrial": "Generating with {{modelName}} is not available on trial accounts. Visit your <LinkComponent>account settings</LinkComponent> to upgrade."
|
"modelDisabledForTrial": "Generating with {{modelName}} is not available on trial accounts. Visit your <LinkComponent>account settings</LinkComponent> to upgrade."
|
||||||
},
|
},
|
||||||
"dynamicPrompts": {
|
"dynamicPrompts": {
|
||||||
@@ -1364,8 +1442,8 @@
|
|||||||
"addedToBoard": "Added to board {{name}}'s assets",
|
"addedToBoard": "Added to board {{name}}'s assets",
|
||||||
"addedToUncategorized": "Added to board $t(boards.uncategorized)'s assets",
|
"addedToUncategorized": "Added to board $t(boards.uncategorized)'s assets",
|
||||||
"baseModelChanged": "Base Model Changed",
|
"baseModelChanged": "Base Model Changed",
|
||||||
"baseModelChangedCleared_one": "Cleared or disabled {{count}} incompatible submodel",
|
"baseModelChangedCleared_one": "Updated, cleared or disabled {{count}} incompatible submodel",
|
||||||
"baseModelChangedCleared_other": "Cleared or disabled {{count}} incompatible submodels",
|
"baseModelChangedCleared_other": "Updated, cleared or disabled {{count}} incompatible submodels",
|
||||||
"canceled": "Processing Canceled",
|
"canceled": "Processing Canceled",
|
||||||
"connected": "Connected to Server",
|
"connected": "Connected to Server",
|
||||||
"imageCopied": "Image Copied",
|
"imageCopied": "Image Copied",
|
||||||
@@ -1933,8 +2011,11 @@
|
|||||||
"zoomToNode": "Zoom to Node",
|
"zoomToNode": "Zoom to Node",
|
||||||
"nodeFieldTooltip": "To add a node field, click the small plus sign button on the field in the Workflow Editor, or drag the field by its name into the form.",
|
"nodeFieldTooltip": "To add a node field, click the small plus sign button on the field in the Workflow Editor, or drag the field by its name into the form.",
|
||||||
"addToForm": "Add to Form",
|
"addToForm": "Add to Form",
|
||||||
|
"removeFromForm": "Remove from Form",
|
||||||
"label": "Label",
|
"label": "Label",
|
||||||
"showDescription": "Show Description",
|
"showDescription": "Show Description",
|
||||||
|
"showShuffle": "Show Shuffle",
|
||||||
|
"shuffle": "Shuffle",
|
||||||
"component": "Component",
|
"component": "Component",
|
||||||
"numberInput": "Number Input",
|
"numberInput": "Number Input",
|
||||||
"singleLine": "Single Line",
|
"singleLine": "Single Line",
|
||||||
@@ -2015,6 +2096,24 @@
|
|||||||
"pullBboxIntoLayerError": "Problem Pulling BBox Into Layer",
|
"pullBboxIntoLayerError": "Problem Pulling BBox Into Layer",
|
||||||
"pullBboxIntoReferenceImageOk": "Bbox Pulled Into ReferenceImage",
|
"pullBboxIntoReferenceImageOk": "Bbox Pulled Into ReferenceImage",
|
||||||
"pullBboxIntoReferenceImageError": "Problem Pulling BBox Into ReferenceImage",
|
"pullBboxIntoReferenceImageError": "Problem Pulling BBox Into ReferenceImage",
|
||||||
|
"addAdjustments": "Add Adjustments",
|
||||||
|
"removeAdjustments": "Remove Adjustments",
|
||||||
|
"adjustments": {
|
||||||
|
"simple": "Simple",
|
||||||
|
"curves": "Curves",
|
||||||
|
"heading": "Adjustments",
|
||||||
|
"expand": "Expand adjustments",
|
||||||
|
"collapse": "Collapse adjustments",
|
||||||
|
"brightness": "Brightness",
|
||||||
|
"contrast": "Contrast",
|
||||||
|
"saturation": "Saturation",
|
||||||
|
"temperature": "Temperature",
|
||||||
|
"tint": "Tint",
|
||||||
|
"sharpness": "Sharpness",
|
||||||
|
"finish": "Finish",
|
||||||
|
"reset": "Reset",
|
||||||
|
"master": "Master"
|
||||||
|
},
|
||||||
"regionIsEmpty": "Selected region is empty",
|
"regionIsEmpty": "Selected region is empty",
|
||||||
"mergeVisible": "Merge Visible",
|
"mergeVisible": "Merge Visible",
|
||||||
"mergeDown": "Merge Down",
|
"mergeDown": "Merge Down",
|
||||||
@@ -2066,6 +2165,8 @@
|
|||||||
"asControlLayer": "As $t(controlLayers.controlLayer)",
|
"asControlLayer": "As $t(controlLayers.controlLayer)",
|
||||||
"asControlLayerResize": "As $t(controlLayers.controlLayer) (Resize)",
|
"asControlLayerResize": "As $t(controlLayers.controlLayer) (Resize)",
|
||||||
"referenceImage": "Reference Image",
|
"referenceImage": "Reference Image",
|
||||||
|
"maxRefImages": "Max Ref Images",
|
||||||
|
"useAsReferenceImage": "Use as Reference Image",
|
||||||
"regionalReferenceImage": "Regional Reference Image",
|
"regionalReferenceImage": "Regional Reference Image",
|
||||||
"globalReferenceImage": "Global Reference Image",
|
"globalReferenceImage": "Global Reference Image",
|
||||||
"sendingToCanvas": "Staging Generations on Canvas",
|
"sendingToCanvas": "Staging Generations on Canvas",
|
||||||
@@ -2174,7 +2275,8 @@
|
|||||||
"rgReferenceImagesNotSupported": "regional Reference Images not supported for selected base model",
|
"rgReferenceImagesNotSupported": "regional Reference Images not supported for selected base model",
|
||||||
"rgAutoNegativeNotSupported": "Auto-Negative not supported for selected base model",
|
"rgAutoNegativeNotSupported": "Auto-Negative not supported for selected base model",
|
||||||
"rgNoRegion": "no region drawn",
|
"rgNoRegion": "no region drawn",
|
||||||
"fluxFillIncompatibleWithControlLoRA": "Control LoRA is not compatible with FLUX Fill"
|
"fluxFillIncompatibleWithControlLoRA": "Control LoRA is not compatible with FLUX Fill",
|
||||||
|
"bboxHidden": "Bounding box is hidden (shift+o to toggle)"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"unableToFindImage": "Unable to find image",
|
"unableToFindImage": "Unable to find image",
|
||||||
@@ -2210,6 +2312,8 @@
|
|||||||
},
|
},
|
||||||
"fill": {
|
"fill": {
|
||||||
"fillColor": "Fill Color",
|
"fillColor": "Fill Color",
|
||||||
|
"bgFillColor": "Background Color",
|
||||||
|
"fgFillColor": "Foreground Color",
|
||||||
"fillStyle": "Fill Style",
|
"fillStyle": "Fill Style",
|
||||||
"solid": "Solid",
|
"solid": "Solid",
|
||||||
"grid": "Grid",
|
"grid": "Grid",
|
||||||
@@ -2381,12 +2485,21 @@
|
|||||||
"saveAs": "Save As",
|
"saveAs": "Save As",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"process": "Process",
|
"process": "Process",
|
||||||
"help1": "Select a single target object. Add <Bold>Include</Bold> and <Bold>Exclude</Bold> points to indicate which parts of the layer are part of the target object.",
|
"desc": "Select a single target object. After selection is complete, click <Bold>Apply</Bold> to discard everything outside the selected area, or save the selection as a new layer.",
|
||||||
"help2": "Start with one <Bold>Include</Bold> point within the target object. Add more points to refine the selection. Fewer points typically produce better results.",
|
"visualModeDesc": "Visual mode uses box and point inputs to select an object.",
|
||||||
"help3": "Invert the selection to select everything except the target object.",
|
"visualMode1": "Click and drag to draw a box around the object you want to select. You may get better results by drawing the box a bit larger or smaller than the object.",
|
||||||
|
"visualMode2": "Click to add a green <Bold>include</Bold> point, or shift-click to add a red <Bold>exclude</Bold> point to tell the model what to include or exclude.",
|
||||||
|
"visualMode3": "Points can be used to refine a box selection or used independently.",
|
||||||
|
"promptModeDesc": "Prompt mode uses text input to select an object.",
|
||||||
|
"promptMode1": "Type a brief description of the object you want to select.",
|
||||||
|
"promptMode2": "Use simple language, avoiding complex descriptions or multiple objects.",
|
||||||
"clickToAdd": "Click on the layer to add a point",
|
"clickToAdd": "Click on the layer to add a point",
|
||||||
"dragToMove": "Drag a point to move it",
|
"dragToMove": "Drag a point to move it",
|
||||||
"clickToRemove": "Click on a point to remove it"
|
"clickToRemove": "Click on a point to remove it",
|
||||||
|
"model": "Model",
|
||||||
|
"segmentAnything1": "Segment Anything 1",
|
||||||
|
"segmentAnything2": "Segment Anything 2",
|
||||||
|
"prompt": "Selection Prompt"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"snapToGrid": {
|
"snapToGrid": {
|
||||||
@@ -2533,7 +2646,7 @@
|
|||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"generation": "Generation",
|
"generate": "Generate",
|
||||||
"canvas": "Canvas",
|
"canvas": "Canvas",
|
||||||
"workflows": "Workflows",
|
"workflows": "Workflows",
|
||||||
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
||||||
@@ -2542,15 +2655,54 @@
|
|||||||
"queue": "Queue",
|
"queue": "Queue",
|
||||||
"upscaling": "Upscaling",
|
"upscaling": "Upscaling",
|
||||||
"upscalingTab": "$t(ui.tabs.upscaling) $t(common.tab)",
|
"upscalingTab": "$t(ui.tabs.upscaling) $t(common.tab)",
|
||||||
|
"video": "Video",
|
||||||
"gallery": "Gallery"
|
"gallery": "Gallery"
|
||||||
},
|
},
|
||||||
|
"panels": {
|
||||||
|
"launchpad": "Launchpad",
|
||||||
|
"workflowEditor": "Workflow Editor",
|
||||||
|
"imageViewer": "Viewer",
|
||||||
|
"canvas": "Canvas",
|
||||||
|
"video": "Video"
|
||||||
|
},
|
||||||
"launchpad": {
|
"launchpad": {
|
||||||
"workflowsTitle": "Go deep with Workflows.",
|
"workflowsTitle": "Go deep with Workflows.",
|
||||||
"upscalingTitle": "Upscale and add detail.",
|
"upscalingTitle": "Upscale and add detail.",
|
||||||
"canvasTitle": "Edit and refine on Canvas.",
|
"canvasTitle": "Edit and refine on Canvas.",
|
||||||
"generateTitle": "Generate images from text prompts.",
|
"generateTitle": "Generate images from text prompts.",
|
||||||
|
"videoTitle": "Generate videos from text prompts.",
|
||||||
|
"video": {
|
||||||
|
"startingFrameCalloutTitle": "Add a Starting Frame",
|
||||||
|
"startingFrameCalloutDesc": "Add an image to control the first frame of your video."
|
||||||
|
},
|
||||||
|
"addStartingFrame": {
|
||||||
|
"title": "Add a Starting Frame",
|
||||||
|
"description": "Add an image to control the first frame of your video."
|
||||||
|
},
|
||||||
"modelGuideText": "Want to learn what prompts work best for each model?",
|
"modelGuideText": "Want to learn what prompts work best for each model?",
|
||||||
"modelGuideLink": "Check out our Model Guide.",
|
"modelGuideLink": "Check out our Model Guide.",
|
||||||
|
"createNewWorkflowFromScratch": "Create a new Workflow from scratch",
|
||||||
|
"browseAndLoadWorkflows": "Browse and load existing workflows",
|
||||||
|
"addStyleRef": {
|
||||||
|
"title": "Add a Style Reference",
|
||||||
|
"description": "Add an image to transfer its look."
|
||||||
|
},
|
||||||
|
"editImage": {
|
||||||
|
"title": "Edit Image",
|
||||||
|
"description": "Add an image to refine."
|
||||||
|
},
|
||||||
|
"generateFromText": {
|
||||||
|
"title": "Generate from Text",
|
||||||
|
"description": "Enter a prompt and Invoke."
|
||||||
|
},
|
||||||
|
"useALayoutImage": {
|
||||||
|
"title": "Use a Layout Image",
|
||||||
|
"description": "Add an image to control composition."
|
||||||
|
},
|
||||||
|
"generate": {
|
||||||
|
"canvasCalloutTitle": "Looking to get more control, edit, and iterate on your images?",
|
||||||
|
"canvasCalloutLink": "Navigate to Canvas for more capabilities."
|
||||||
|
},
|
||||||
"workflows": {
|
"workflows": {
|
||||||
"description": "Workflows are reusable templates that automate image generation tasks, allowing you to quickly perform complex operations and get consistent results.",
|
"description": "Workflows are reusable templates that automate image generation tasks, allowing you to quickly perform complex operations and get consistent results.",
|
||||||
"learnMoreLink": "Learn more about creating workflows",
|
"learnMoreLink": "Learn more about creating workflows",
|
||||||
@@ -2587,6 +2739,13 @@
|
|||||||
"upscaleModel": "Upscale Model",
|
"upscaleModel": "Upscale Model",
|
||||||
"model": "Model",
|
"model": "Model",
|
||||||
"scale": "Scale",
|
"scale": "Scale",
|
||||||
|
"creativityAndStructure": {
|
||||||
|
"title": "Creativity & Structure Defaults",
|
||||||
|
"conservative": "Conservative",
|
||||||
|
"balanced": "Balanced",
|
||||||
|
"creative": "Creative",
|
||||||
|
"artistic": "Artistic"
|
||||||
|
},
|
||||||
"helpText": {
|
"helpText": {
|
||||||
"promptAdvice": "When upscaling, use a prompt that describes the medium and style. Avoid describing specific content details in the image.",
|
"promptAdvice": "When upscaling, use a prompt that describes the medium and style. Avoid describing specific content details in the image.",
|
||||||
"styleAdvice": "Upscaling works best with the general style of your image."
|
"styleAdvice": "Upscaling works best with the general style of your image."
|
||||||
@@ -2594,6 +2753,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"video": {
|
||||||
|
"noVideoSelected": "No video selected",
|
||||||
|
"selectFromGallery": "Select a video from the gallery to play"
|
||||||
|
},
|
||||||
"system": {
|
"system": {
|
||||||
"enableLogging": "Enable Logging",
|
"enableLogging": "Enable Logging",
|
||||||
"logLevel": {
|
"logLevel": {
|
||||||
@@ -2631,10 +2794,9 @@
|
|||||||
"whatsNew": {
|
"whatsNew": {
|
||||||
"whatsNewInInvoke": "What's New in Invoke",
|
"whatsNewInInvoke": "What's New in Invoke",
|
||||||
"items": [
|
"items": [
|
||||||
"New setting to send all Canvas generations directly to the Gallery.",
|
"Select Object v2: Improved object selection with point and box inputs or text prompts.",
|
||||||
"New Invert Mask (Shift+V) and Fit BBox to Mask (Shift+B) capabilities.",
|
"Raster Layer Adjustments: Easily adjust layer brightness, contrast, saturation, curves and more.",
|
||||||
"Expanded support for Model Thumbnails and configurations.",
|
"Prompt History: Review and quickly recall your last 100 prompts."
|
||||||
"Various other quality of life updates and fixes"
|
|
||||||
],
|
],
|
||||||
"readReleaseNotes": "Read Release Notes",
|
"readReleaseNotes": "Read Release Notes",
|
||||||
"watchRecentReleaseVideos": "Watch Recent Release Videos",
|
"watchRecentReleaseVideos": "Watch Recent Release Videos",
|
||||||
|
|||||||
@@ -47,11 +47,8 @@
|
|||||||
"editor": "Editor",
|
"editor": "Editor",
|
||||||
"orderBy": "Ordenar por",
|
"orderBy": "Ordenar por",
|
||||||
"file": "Archivo",
|
"file": "Archivo",
|
||||||
"goTo": "Ir a",
|
|
||||||
"imageFailedToLoad": "No se puede cargar la imagen",
|
|
||||||
"saveAs": "Guardar Como",
|
"saveAs": "Guardar Como",
|
||||||
"somethingWentWrong": "Algo salió mal",
|
"somethingWentWrong": "Algo salió mal",
|
||||||
"nextPage": "Página Siguiente",
|
|
||||||
"selected": "Seleccionado",
|
"selected": "Seleccionado",
|
||||||
"tab": "Tabulador",
|
"tab": "Tabulador",
|
||||||
"positivePrompt": "Prompt Positivo",
|
"positivePrompt": "Prompt Positivo",
|
||||||
@@ -61,7 +58,6 @@
|
|||||||
"unknown": "Desconocido",
|
"unknown": "Desconocido",
|
||||||
"input": "Entrada",
|
"input": "Entrada",
|
||||||
"template": "Plantilla",
|
"template": "Plantilla",
|
||||||
"prevPage": "Página Anterior",
|
|
||||||
"red": "Rojo",
|
"red": "Rojo",
|
||||||
"alpha": "Transparencia",
|
"alpha": "Transparencia",
|
||||||
"outputs": "Resultados",
|
"outputs": "Resultados",
|
||||||
@@ -94,8 +90,6 @@
|
|||||||
"edit": "Editar",
|
"edit": "Editar",
|
||||||
"safetensors": "Safetensors",
|
"safetensors": "Safetensors",
|
||||||
"toResolve": "Para resolver",
|
"toResolve": "Para resolver",
|
||||||
"localSystem": "Sistema local",
|
|
||||||
"notInstalled": "No $t(common.installed)",
|
|
||||||
"outpaint": "outpaint",
|
"outpaint": "outpaint",
|
||||||
"simple": "Sencillo",
|
"simple": "Sencillo",
|
||||||
"close": "Cerrar"
|
"close": "Cerrar"
|
||||||
@@ -104,7 +98,6 @@
|
|||||||
"galleryImageSize": "Tamaño de la imagen",
|
"galleryImageSize": "Tamaño de la imagen",
|
||||||
"gallerySettings": "Ajustes de la galería",
|
"gallerySettings": "Ajustes de la galería",
|
||||||
"autoSwitchNewImages": "Auto seleccionar Imágenes nuevas",
|
"autoSwitchNewImages": "Auto seleccionar Imágenes nuevas",
|
||||||
"noImagesInGallery": "No hay imágenes para mostrar",
|
|
||||||
"deleteImage_one": "Eliminar Imagen",
|
"deleteImage_one": "Eliminar Imagen",
|
||||||
"deleteImage_many": "Eliminar {{count}} Imágenes",
|
"deleteImage_many": "Eliminar {{count}} Imágenes",
|
||||||
"deleteImage_other": "Eliminar {{count}} Imágenes",
|
"deleteImage_other": "Eliminar {{count}} Imágenes",
|
||||||
@@ -118,9 +111,7 @@
|
|||||||
"selectForCompare": "Seleccionar para comparar",
|
"selectForCompare": "Seleccionar para comparar",
|
||||||
"alwaysShowImageSizeBadge": "Mostrar siempre las dimensiones de la imagen",
|
"alwaysShowImageSizeBadge": "Mostrar siempre las dimensiones de la imagen",
|
||||||
"currentlyInUse": "Esta imagen se utiliza actualmente con las siguientes funciones:",
|
"currentlyInUse": "Esta imagen se utiliza actualmente con las siguientes funciones:",
|
||||||
"unableToLoad": "No se puede cargar la galería",
|
|
||||||
"selectAllOnPage": "Seleccionar todo en la página",
|
"selectAllOnPage": "Seleccionar todo en la página",
|
||||||
"selectAnImageToCompare": "Seleccione una imagen para comparar",
|
|
||||||
"bulkDownloadFailed": "Error en la descarga",
|
"bulkDownloadFailed": "Error en la descarga",
|
||||||
"compareHelp2": "Presione <Kbd> M </Kbd> para recorrer los modos de comparación.",
|
"compareHelp2": "Presione <Kbd> M </Kbd> para recorrer los modos de comparación.",
|
||||||
"move": "Mover",
|
"move": "Mover",
|
||||||
@@ -145,7 +136,6 @@
|
|||||||
"exitBoardSearch": "Finalizar búsqueda",
|
"exitBoardSearch": "Finalizar búsqueda",
|
||||||
"exitSearch": "Salir de la búsqueda de imágenes",
|
"exitSearch": "Salir de la búsqueda de imágenes",
|
||||||
"featuresWillReset": "Si elimina esta imagen, dichas funciones se restablecerán inmediatamente.",
|
"featuresWillReset": "Si elimina esta imagen, dichas funciones se restablecerán inmediatamente.",
|
||||||
"jump": "Omitir",
|
|
||||||
"loading": "Cargando",
|
"loading": "Cargando",
|
||||||
"newestFirst": "La más nueva primero",
|
"newestFirst": "La más nueva primero",
|
||||||
"unstarImage": "Dejar de ser favorita",
|
"unstarImage": "Dejar de ser favorita",
|
||||||
@@ -163,9 +153,7 @@
|
|||||||
"boardsSettings": "Ajustes de los tableros",
|
"boardsSettings": "Ajustes de los tableros",
|
||||||
"imagesSettings": "Configuración de imágenes de la galería",
|
"imagesSettings": "Configuración de imágenes de la galería",
|
||||||
"compareHelp3": "Presione <Kbd> C </Kbd> para intercambiar las imágenes comparadas.",
|
"compareHelp3": "Presione <Kbd> C </Kbd> para intercambiar las imágenes comparadas.",
|
||||||
"showArchivedBoards": "Mostrar paneles archivados",
|
"showArchivedBoards": "Mostrar paneles archivados"
|
||||||
"closeViewer": "Cerrar visor",
|
|
||||||
"openViewer": "Abrir visor"
|
|
||||||
},
|
},
|
||||||
"modelManager": {
|
"modelManager": {
|
||||||
"modelManager": "Gestor de Modelos",
|
"modelManager": "Gestor de Modelos",
|
||||||
@@ -239,12 +227,10 @@
|
|||||||
"scaledHeight": "Alto escalado",
|
"scaledHeight": "Alto escalado",
|
||||||
"infillMethod": "Método de relleno",
|
"infillMethod": "Método de relleno",
|
||||||
"tileSize": "Tamaño del mosaico",
|
"tileSize": "Tamaño del mosaico",
|
||||||
"downloadImage": "Descargar imagen",
|
|
||||||
"usePrompt": "Usar Entrada",
|
"usePrompt": "Usar Entrada",
|
||||||
"useSeed": "Usar Semilla",
|
"useSeed": "Usar Semilla",
|
||||||
"useAll": "Usar Todo",
|
"useAll": "Usar Todo",
|
||||||
"info": "Información",
|
"info": "Información",
|
||||||
"showOptionsPanel": "Mostrar panel lateral (O o T)",
|
|
||||||
"symmetry": "Simetría",
|
"symmetry": "Simetría",
|
||||||
"copyImage": "Copiar la imagen",
|
"copyImage": "Copiar la imagen",
|
||||||
"general": "General",
|
"general": "General",
|
||||||
@@ -323,8 +309,6 @@
|
|||||||
"hideMinimapnodes": "Ocultar el minimapa",
|
"hideMinimapnodes": "Ocultar el minimapa",
|
||||||
"fitViewportNodes": "Ajustar la vista",
|
"fitViewportNodes": "Ajustar la vista",
|
||||||
"zoomOutNodes": "Alejar",
|
"zoomOutNodes": "Alejar",
|
||||||
"hideLegendNodes": "Ocultar la leyenda del tipo de campo",
|
|
||||||
"showLegendNodes": "Mostrar la leyenda del tipo de campo",
|
|
||||||
"showMinimapnodes": "Mostrar el minimapa",
|
"showMinimapnodes": "Mostrar el minimapa",
|
||||||
"reloadNodeTemplates": "Recargar las plantillas de nodos",
|
"reloadNodeTemplates": "Recargar las plantillas de nodos",
|
||||||
"loadWorkflow": "Cargar el flujo de trabajo",
|
"loadWorkflow": "Cargar el flujo de trabajo",
|
||||||
@@ -361,7 +345,6 @@
|
|||||||
"assetsWithCount_one": "{{count}} activo",
|
"assetsWithCount_one": "{{count}} activo",
|
||||||
"assetsWithCount_many": "{{count}} activos",
|
"assetsWithCount_many": "{{count}} activos",
|
||||||
"assetsWithCount_other": "{{count}} activos",
|
"assetsWithCount_other": "{{count}} activos",
|
||||||
"hideBoards": "Ocultar paneles",
|
|
||||||
"addPrivateBoard": "Agregar un panel privado",
|
"addPrivateBoard": "Agregar un panel privado",
|
||||||
"addSharedBoard": "Añadir panel compartido",
|
"addSharedBoard": "Añadir panel compartido",
|
||||||
"boards": "Paneles",
|
"boards": "Paneles",
|
||||||
@@ -372,7 +355,6 @@
|
|||||||
"noBoards": "No hay paneles {{boardType}}",
|
"noBoards": "No hay paneles {{boardType}}",
|
||||||
"shared": "Paneles compartidos",
|
"shared": "Paneles compartidos",
|
||||||
"deletedPrivateBoardsCannotbeRestored": "Los paneles eliminados no se pueden restaurar. Al elegir \"Eliminar solo el panel\", las imágenes se colocan en un estado privado y sin categoría para el creador de la imagen.",
|
"deletedPrivateBoardsCannotbeRestored": "Los paneles eliminados no se pueden restaurar. Al elegir \"Eliminar solo el panel\", las imágenes se colocan en un estado privado y sin categoría para el creador de la imagen.",
|
||||||
"viewBoards": "Ver paneles",
|
|
||||||
"private": "Paneles privados",
|
"private": "Paneles privados",
|
||||||
"updateBoardError": "No se pudo actualizar el panel"
|
"updateBoardError": "No se pudo actualizar el panel"
|
||||||
},
|
},
|
||||||
@@ -399,7 +381,6 @@
|
|||||||
"ui": {
|
"ui": {
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"canvas": "Lienzo",
|
"canvas": "Lienzo",
|
||||||
"generation": "Generación",
|
|
||||||
"queue": "Cola",
|
"queue": "Cola",
|
||||||
"workflows": "Flujos de trabajo",
|
"workflows": "Flujos de trabajo",
|
||||||
"models": "Modelos",
|
"models": "Modelos",
|
||||||
@@ -462,7 +443,6 @@
|
|||||||
"other": "Otro",
|
"other": "Otro",
|
||||||
"queueFront": "Añadir al principio de la cola",
|
"queueFront": "Añadir al principio de la cola",
|
||||||
"gallery": "Galería",
|
"gallery": "Galería",
|
||||||
"batchFieldValues": "Valores de procesamiento por lotes",
|
|
||||||
"session": "Sesión",
|
"session": "Sesión",
|
||||||
"notReady": "La cola aún no está lista",
|
"notReady": "La cola aún no está lista",
|
||||||
"graphQueued": "Gráfico en cola",
|
"graphQueued": "Gráfico en cola",
|
||||||
@@ -495,15 +475,11 @@
|
|||||||
"layer_one": "Capa",
|
"layer_one": "Capa",
|
||||||
"layer_many": "Capas",
|
"layer_many": "Capas",
|
||||||
"layer_other": "Capas",
|
"layer_other": "Capas",
|
||||||
"layer_withCount_one": "({{count}}) capa",
|
|
||||||
"layer_withCount_many": "({{count}}) capas",
|
|
||||||
"layer_withCount_other": "({{count}}) capas",
|
|
||||||
"copyToClipboard": "Copiar al portapapeles"
|
"copyToClipboard": "Copiar al portapapeles"
|
||||||
},
|
},
|
||||||
"whatsNew": {
|
"whatsNew": {
|
||||||
"readReleaseNotes": "Leer las notas de la versión",
|
"readReleaseNotes": "Leer las notas de la versión",
|
||||||
"watchRecentReleaseVideos": "Ver videos de versiones recientes",
|
"watchRecentReleaseVideos": "Ver videos de versiones recientes",
|
||||||
"watchUiUpdatesOverview": "Descripción general de las actualizaciones de la interfaz de usuario de Watch",
|
|
||||||
"whatsNewInInvoke": "Novedades en Invoke",
|
"whatsNewInInvoke": "Novedades en Invoke",
|
||||||
"items": [
|
"items": [
|
||||||
"<StrongComponent>SD 3.5</StrongComponent>: compatibilidad con SD 3.5 Medium y Large."
|
"<StrongComponent>SD 3.5</StrongComponent>: compatibilidad con SD 3.5 Medium y Large."
|
||||||
@@ -528,13 +504,11 @@
|
|||||||
},
|
},
|
||||||
"hrf": {
|
"hrf": {
|
||||||
"hrf": "Solución de alta resolución",
|
"hrf": "Solución de alta resolución",
|
||||||
"enableHrf": "Activar corrección de alta resolución",
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"enabled": "Corrección de alta resolución activada",
|
"enabled": "Corrección de alta resolución activada",
|
||||||
"strength": "Forzar la corrección de alta resolución",
|
"strength": "Forzar la corrección de alta resolución",
|
||||||
"method": "Método de corrección de alta resolución"
|
"method": "Método de corrección de alta resolución"
|
||||||
},
|
}
|
||||||
"upscaleMethod": "Método de expansión"
|
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"addPromptTrigger": "Añadir activador de los avisos",
|
"addPromptTrigger": "Añadir activador de los avisos",
|
||||||
@@ -592,10 +566,6 @@
|
|||||||
"title": "Ajustar capas al lienzo",
|
"title": "Ajustar capas al lienzo",
|
||||||
"desc": "Escala y posiciona la vista para que se ajuste a todas las capas visibles."
|
"desc": "Escala y posiciona la vista para que se ajuste a todas las capas visibles."
|
||||||
},
|
},
|
||||||
"setFillToWhite": {
|
|
||||||
"title": "Establecer color en blanco",
|
|
||||||
"desc": "Establece el color actual de la herramienta en blanco."
|
|
||||||
},
|
|
||||||
"resetSelected": {
|
"resetSelected": {
|
||||||
"title": "Restablecer capa",
|
"title": "Restablecer capa",
|
||||||
"desc": "Restablecer la capa seleccionada. Solo se aplica a Máscara de retoque y Guía regional."
|
"desc": "Restablecer la capa seleccionada. Solo se aplica a Máscara de retoque y Guía regional."
|
||||||
@@ -869,10 +839,8 @@
|
|||||||
"seed": "Semilla",
|
"seed": "Semilla",
|
||||||
"strength": "Forzar imagen a imagen",
|
"strength": "Forzar imagen a imagen",
|
||||||
"recallParameters": "Parámetros de recuperación",
|
"recallParameters": "Parámetros de recuperación",
|
||||||
"recallParameter": "Recuperar {{label}}",
|
|
||||||
"steps": "Pasos",
|
"steps": "Pasos",
|
||||||
"noRecallParameters": "Sin parámetros para recuperar",
|
"noRecallParameters": "Sin parámetros para recuperar"
|
||||||
"parsingFailed": "Error al analizar"
|
|
||||||
},
|
},
|
||||||
"system": {
|
"system": {
|
||||||
"logLevel": {
|
"logLevel": {
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "Kuvan koko",
|
"galleryImageSize": "Kuvan koko",
|
||||||
"gallerySettings": "Gallerian asetukset",
|
"gallerySettings": "Gallerian asetukset",
|
||||||
"autoSwitchNewImages": "Vaihda uusiin kuviin automaattisesti",
|
"autoSwitchNewImages": "Vaihda uusiin kuviin automaattisesti"
|
||||||
"noImagesInGallery": "Ei kuvia galleriassa"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,21 +27,15 @@
|
|||||||
"error": "Erreur",
|
"error": "Erreur",
|
||||||
"installed": "Installé",
|
"installed": "Installé",
|
||||||
"format": "format",
|
"format": "format",
|
||||||
"goTo": "Aller à",
|
|
||||||
"input": "Entrée",
|
"input": "Entrée",
|
||||||
"linear": "Linéaire",
|
"linear": "Linéaire",
|
||||||
"localSystem": "Système local",
|
|
||||||
"learnMore": "En savoir plus",
|
"learnMore": "En savoir plus",
|
||||||
"modelManager": "Gestionnaire de modèle",
|
"modelManager": "Gestionnaire de modèle",
|
||||||
"notInstalled": "Non $t(common.installed)",
|
|
||||||
"openInNewTab": "Ouvrir dans un nouvel onglet",
|
"openInNewTab": "Ouvrir dans un nouvel onglet",
|
||||||
"somethingWentWrong": "Une erreur s'est produite",
|
"somethingWentWrong": "Une erreur s'est produite",
|
||||||
"created": "Créé",
|
"created": "Créé",
|
||||||
"tab": "Onglet",
|
"tab": "Onglet",
|
||||||
"folder": "Dossier",
|
"folder": "Dossier",
|
||||||
"imageFailedToLoad": "Impossible de charger l'Image",
|
|
||||||
"prevPage": "Page précédente",
|
|
||||||
"nextPage": "Page suivante",
|
|
||||||
"selected": "Sélectionné",
|
"selected": "Sélectionné",
|
||||||
"save": "Enregistrer",
|
"save": "Enregistrer",
|
||||||
"updated": "Mis à jour",
|
"updated": "Mis à jour",
|
||||||
@@ -111,7 +105,6 @@
|
|||||||
"min": "Min",
|
"min": "Min",
|
||||||
"max": "Max",
|
"max": "Max",
|
||||||
"values": "Valeurs",
|
"values": "Valeurs",
|
||||||
"resetToDefaults": "Réinitialiser par défaut",
|
|
||||||
"seed": "Graine",
|
"seed": "Graine",
|
||||||
"combinatorial": "Combinatoire"
|
"combinatorial": "Combinatoire"
|
||||||
},
|
},
|
||||||
@@ -119,11 +112,9 @@
|
|||||||
"galleryImageSize": "Taille de l'image",
|
"galleryImageSize": "Taille de l'image",
|
||||||
"gallerySettings": "Paramètres de la galerie",
|
"gallerySettings": "Paramètres de la galerie",
|
||||||
"autoSwitchNewImages": "Basculer automatiquement vers de nouvelles images",
|
"autoSwitchNewImages": "Basculer automatiquement vers de nouvelles images",
|
||||||
"noImagesInGallery": "Aucune image à afficher",
|
|
||||||
"bulkDownloadRequestedDesc": "Votre demande de téléchargement est en cours de traitement. Cela peut prendre quelques instants.",
|
"bulkDownloadRequestedDesc": "Votre demande de téléchargement est en cours de traitement. Cela peut prendre quelques instants.",
|
||||||
"deleteSelection": "Supprimer la sélection",
|
"deleteSelection": "Supprimer la sélection",
|
||||||
"selectAllOnPage": "Séléctionner toute la page",
|
"selectAllOnPage": "Séléctionner toute la page",
|
||||||
"unableToLoad": "Impossible de charger la Galerie",
|
|
||||||
"featuresWillReset": "Si vous supprimez cette image, ces fonctionnalités vont être réinitialisés.",
|
"featuresWillReset": "Si vous supprimez cette image, ces fonctionnalités vont être réinitialisés.",
|
||||||
"loading": "Chargement",
|
"loading": "Chargement",
|
||||||
"sortDirection": "Direction de tri",
|
"sortDirection": "Direction de tri",
|
||||||
@@ -149,7 +140,6 @@
|
|||||||
"openInViewer": "Ouvrir dans le Visualiseur",
|
"openInViewer": "Ouvrir dans le Visualiseur",
|
||||||
"showArchivedBoards": "Montrer les Planches archivées",
|
"showArchivedBoards": "Montrer les Planches archivées",
|
||||||
"selectForCompare": "Séléctionner pour comparaison",
|
"selectForCompare": "Séléctionner pour comparaison",
|
||||||
"selectAnImageToCompare": "Séléctionner une Image à comparer",
|
|
||||||
"exitCompare": "Sortir de la comparaison",
|
"exitCompare": "Sortir de la comparaison",
|
||||||
"compareHelp2": "Appuyez sur <Kbd>M</Kbd> pour faire défiler les modes de comparaison.",
|
"compareHelp2": "Appuyez sur <Kbd>M</Kbd> pour faire défiler les modes de comparaison.",
|
||||||
"swapImages": "Échanger les Images",
|
"swapImages": "Échanger les Images",
|
||||||
@@ -157,10 +147,7 @@
|
|||||||
"compareHelp1": "Maintenir <Kbd>Alt</Kbd> lors du clic d'une image dans la galerie ou en utilisant les flèches du clavier pour changer l'Image à comparer.",
|
"compareHelp1": "Maintenir <Kbd>Alt</Kbd> lors du clic d'une image dans la galerie ou en utilisant les flèches du clavier pour changer l'Image à comparer.",
|
||||||
"compareHelp3": "Appuyer sur <Kbd>C</Kbd> pour échanger les images à comparer.",
|
"compareHelp3": "Appuyer sur <Kbd>C</Kbd> pour échanger les images à comparer.",
|
||||||
"image": "image",
|
"image": "image",
|
||||||
"openViewer": "Ouvrir le Visualisateur",
|
|
||||||
"closeViewer": "Fermer le Visualisateur",
|
|
||||||
"currentlyInUse": "Cette image est actuellement utilisée dans ces fonctionalités :",
|
"currentlyInUse": "Cette image est actuellement utilisée dans ces fonctionalités :",
|
||||||
"jump": "Sauter",
|
|
||||||
"starImage": "Marquer l'Image",
|
"starImage": "Marquer l'Image",
|
||||||
"download": "Téléchargement",
|
"download": "Téléchargement",
|
||||||
"deleteImage_one": "Supprimer l'Image",
|
"deleteImage_one": "Supprimer l'Image",
|
||||||
@@ -247,7 +234,6 @@
|
|||||||
"metadata": "Métadonnées",
|
"metadata": "Métadonnées",
|
||||||
"scanFolder": "Scanner le dossier",
|
"scanFolder": "Scanner le dossier",
|
||||||
"inplaceInstallDesc": "Installez les modèles sans copier les fichiers. Lors de l'utilisation du modèle, il sera chargé depuis cet emplacement. Si cette option est désactivée, le(s) fichier(s) du modèle seront copiés dans le répertoire des modèles géré par Invoke lors de l'installation.",
|
"inplaceInstallDesc": "Installez les modèles sans copier les fichiers. Lors de l'utilisation du modèle, il sera chargé depuis cet emplacement. Si cette option est désactivée, le(s) fichier(s) du modèle seront copiés dans le répertoire des modèles géré par Invoke lors de l'installation.",
|
||||||
"ipAdapters": "Adaptateurs IP",
|
|
||||||
"installQueue": "File d'attente d'installation",
|
"installQueue": "File d'attente d'installation",
|
||||||
"modelImageDeleteFailed": "Échec de la suppression de l'image du modèle",
|
"modelImageDeleteFailed": "Échec de la suppression de l'image du modèle",
|
||||||
"modelName": "Nom du modèle",
|
"modelName": "Nom du modèle",
|
||||||
@@ -288,7 +274,6 @@
|
|||||||
"scanFolderHelper": "Le dossier sera analysé de manière récursive à la recherche de modèles. Cela peut prendre quelques instants pour des dossiers très volumineux.",
|
"scanFolderHelper": "Le dossier sera analysé de manière récursive à la recherche de modèles. Cela peut prendre quelques instants pour des dossiers très volumineux.",
|
||||||
"clipEmbed": "Intégration CLIP",
|
"clipEmbed": "Intégration CLIP",
|
||||||
"spandrelImageToImage": "Image vers Image (Spandrel)",
|
"spandrelImageToImage": "Image vers Image (Spandrel)",
|
||||||
"starterModelsInModelManager": "Les modèles de démarrage peuvent être trouvés dans le gestionnaire de modèles",
|
|
||||||
"t5Encoder": "Encodeur T5",
|
"t5Encoder": "Encodeur T5",
|
||||||
"learnMoreAboutSupportedModels": "En savoir plus sur les modèles que nous prenons en charge",
|
"learnMoreAboutSupportedModels": "En savoir plus sur les modèles que nous prenons en charge",
|
||||||
"includesNModels": "Contient {{n}} modèles et leurs dépendances",
|
"includesNModels": "Contient {{n}} modèles et leurs dépendances",
|
||||||
@@ -346,12 +331,10 @@
|
|||||||
"infillMethod": "Méthode de Remplissage",
|
"infillMethod": "Méthode de Remplissage",
|
||||||
"tileSize": "Taille des Tuiles",
|
"tileSize": "Taille des Tuiles",
|
||||||
"copyImage": "Copier Image",
|
"copyImage": "Copier Image",
|
||||||
"downloadImage": "Télécharger Image",
|
|
||||||
"usePrompt": "Utiliser la suggestion",
|
"usePrompt": "Utiliser la suggestion",
|
||||||
"useSeed": "Utiliser la graine",
|
"useSeed": "Utiliser la graine",
|
||||||
"useAll": "Tout utiliser",
|
"useAll": "Tout utiliser",
|
||||||
"info": "Info",
|
"info": "Info",
|
||||||
"showOptionsPanel": "Afficher le panneau latéral (O ou T)",
|
|
||||||
"invoke": {
|
"invoke": {
|
||||||
"noPrompts": "Aucun prompts généré",
|
"noPrompts": "Aucun prompts généré",
|
||||||
"missingInputForField": "entrée manquante",
|
"missingInputForField": "entrée manquante",
|
||||||
@@ -362,21 +345,16 @@
|
|||||||
"noModelSelected": "Aucun modèle sélectionné",
|
"noModelSelected": "Aucun modèle sélectionné",
|
||||||
"noNodesInGraph": "Aucun nœud dans le graphique",
|
"noNodesInGraph": "Aucun nœud dans le graphique",
|
||||||
"systemDisconnected": "Système déconnecté",
|
"systemDisconnected": "Système déconnecté",
|
||||||
"fluxModelIncompatibleBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), la hauteur de la bounding box est {{height}}",
|
|
||||||
"fluxModelIncompatibleScaledBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), la hauteur de la bounding box est {{height}}",
|
|
||||||
"noFLUXVAEModelSelected": "Aucun modèle VAE sélectionné pour la génération FLUX",
|
"noFLUXVAEModelSelected": "Aucun modèle VAE sélectionné pour la génération FLUX",
|
||||||
"canvasIsTransforming": "La Toile est occupée (en transformation)",
|
"canvasIsTransforming": "La Toile est occupée (en transformation)",
|
||||||
"canvasIsRasterizing": "La Toile est occupée (en rastérisation)",
|
"canvasIsRasterizing": "La Toile est occupée (en rastérisation)",
|
||||||
"noCLIPEmbedModelSelected": "Aucun modèle CLIP Embed sélectionné pour la génération FLUX",
|
"noCLIPEmbedModelSelected": "Aucun modèle CLIP Embed sélectionné pour la génération FLUX",
|
||||||
"canvasIsFiltering": "La Toile est occupée (en filtration)",
|
"canvasIsFiltering": "La Toile est occupée (en filtration)",
|
||||||
"fluxModelIncompatibleBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), la largeur de la bounding box est {{width}}",
|
|
||||||
"noT5EncoderModelSelected": "Aucun modèle T5 Encoder sélectionné pour la génération FLUX",
|
"noT5EncoderModelSelected": "Aucun modèle T5 Encoder sélectionné pour la génération FLUX",
|
||||||
"fluxModelIncompatibleScaledBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), la largeur de la bounding box mise à l'échelle est {{width}}",
|
|
||||||
"canvasIsCompositing": "La Toile est occupée (en composition)",
|
"canvasIsCompositing": "La Toile est occupée (en composition)",
|
||||||
"collectionTooFewItems": "trop peu d'éléments, minimum {{minItems}}",
|
"collectionTooFewItems": "trop peu d'éléments, minimum {{minItems}}",
|
||||||
"collectionTooManyItems": "trop d'éléments, maximum {{maxItems}}",
|
"collectionTooManyItems": "trop d'éléments, maximum {{maxItems}}",
|
||||||
"canvasIsSelectingObject": "La toile est occupée (sélection d'objet)",
|
"canvasIsSelectingObject": "La toile est occupée (sélection d'objet)",
|
||||||
"emptyBatches": "lots vides",
|
|
||||||
"batchNodeNotConnected": "Noeud de lots non connecté : {{label}}",
|
"batchNodeNotConnected": "Noeud de lots non connecté : {{label}}",
|
||||||
"fluxModelMultipleControlLoRAs": "Vous ne pouvez utiliser qu'un seul Control LoRA à la fois",
|
"fluxModelMultipleControlLoRAs": "Vous ne pouvez utiliser qu'un seul Control LoRA à la fois",
|
||||||
"collectionNumberLTMin": "{{value}} < {{minimum}} (incl. min)",
|
"collectionNumberLTMin": "{{value}} < {{minimum}} (incl. min)",
|
||||||
@@ -468,9 +446,7 @@
|
|||||||
"informationalPopoversDisabled": "Pop-ups d'information désactivés",
|
"informationalPopoversDisabled": "Pop-ups d'information désactivés",
|
||||||
"informationalPopoversDisabledDesc": "Les pop-ups d'information ont été désactivés. Activez-les dans les paramètres.",
|
"informationalPopoversDisabledDesc": "Les pop-ups d'information ont été désactivés. Activez-les dans les paramètres.",
|
||||||
"confirmOnNewSession": "Confirmer lors d'une nouvelle session",
|
"confirmOnNewSession": "Confirmer lors d'une nouvelle session",
|
||||||
"modelDescriptionsDisabledDesc": "Les descriptions des modèles dans les menus déroulants ont été désactivées. Activez-les dans les paramètres.",
|
|
||||||
"enableModelDescriptions": "Activer les descriptions de modèle dans les menus déroulants",
|
"enableModelDescriptions": "Activer les descriptions de modèle dans les menus déroulants",
|
||||||
"modelDescriptionsDisabled": "Descriptions de modèle dans les menus déroulants désactivés",
|
|
||||||
"showDetailedInvocationProgress": "Afficher les détails de progression"
|
"showDetailedInvocationProgress": "Afficher les détails de progression"
|
||||||
},
|
},
|
||||||
"toast": {
|
"toast": {
|
||||||
@@ -486,17 +462,14 @@
|
|||||||
"addedToBoard": "Ajouté aux ressources de la planche {{name}}",
|
"addedToBoard": "Ajouté aux ressources de la planche {{name}}",
|
||||||
"workflowLoaded": "Workflow chargé",
|
"workflowLoaded": "Workflow chargé",
|
||||||
"connected": "Connecté au serveur",
|
"connected": "Connecté au serveur",
|
||||||
"setNodeField": "Définir comme champ de nœud",
|
|
||||||
"imageUploadFailed": "Échec de l'importation de l'image",
|
"imageUploadFailed": "Échec de l'importation de l'image",
|
||||||
"loadedWithWarnings": "Workflow chargé avec des avertissements",
|
"loadedWithWarnings": "Workflow chargé avec des avertissements",
|
||||||
"imageUploaded": "Image importée",
|
"imageUploaded": "Image importée",
|
||||||
"modelAddedSimple": "Modèle ajouté à la file d'attente",
|
"modelAddedSimple": "Modèle ajouté à la file d'attente",
|
||||||
"setControlImage": "Définir comme image de contrôle",
|
|
||||||
"workflowDeleted": "Workflow supprimé",
|
"workflowDeleted": "Workflow supprimé",
|
||||||
"baseModelChangedCleared_one": "Effacé ou désactivé {{count}} sous-modèle incompatible",
|
"baseModelChangedCleared_one": "Effacé ou désactivé {{count}} sous-modèle incompatible",
|
||||||
"baseModelChangedCleared_many": "Effacé ou désactivé {{count}} sous-modèles incompatibles",
|
"baseModelChangedCleared_many": "Effacé ou désactivé {{count}} sous-modèles incompatibles",
|
||||||
"baseModelChangedCleared_other": "Effacé ou désactivé {{count}} sous-modèles incompatibles",
|
"baseModelChangedCleared_other": "Effacé ou désactivé {{count}} sous-modèles incompatibles",
|
||||||
"invalidUpload": "Importation invalide",
|
|
||||||
"problemDownloadingImage": "Impossible de télécharger l'image",
|
"problemDownloadingImage": "Impossible de télécharger l'image",
|
||||||
"problemRetrievingWorkflow": "Problème de récupération du Workflow",
|
"problemRetrievingWorkflow": "Problème de récupération du Workflow",
|
||||||
"problemDeletingWorkflow": "Problème de suppression du Workflow",
|
"problemDeletingWorkflow": "Problème de suppression du Workflow",
|
||||||
@@ -510,12 +483,10 @@
|
|||||||
"errorCopied": "Erreur copiée",
|
"errorCopied": "Erreur copiée",
|
||||||
"parametersSet": "Paramètres rappelés",
|
"parametersSet": "Paramètres rappelés",
|
||||||
"somethingWentWrong": "Quelque chose a échoué",
|
"somethingWentWrong": "Quelque chose a échoué",
|
||||||
"imageSaved": "Image enregistrée",
|
|
||||||
"unableToLoadStylePreset": "Impossible de charger le préréglage de style",
|
"unableToLoadStylePreset": "Impossible de charger le préréglage de style",
|
||||||
"stylePresetLoaded": "Préréglage de style chargé",
|
"stylePresetLoaded": "Préréglage de style chargé",
|
||||||
"parameterNotSetDescWithMessage": "Impossible de rappeler {{parameter}} : {{message}}",
|
"parameterNotSetDescWithMessage": "Impossible de rappeler {{parameter}} : {{message}}",
|
||||||
"importFailed": "Importation échouée",
|
"importFailed": "Importation échouée",
|
||||||
"imageSavingFailed": "Échec de l'enregistrement de l'image",
|
|
||||||
"importSuccessful": "Importation réussie",
|
"importSuccessful": "Importation réussie",
|
||||||
"outOfMemoryError": "Erreur de mémoire insuffisante",
|
"outOfMemoryError": "Erreur de mémoire insuffisante",
|
||||||
"sessionRef": "Session : {{sessionId}}",
|
"sessionRef": "Session : {{sessionId}}",
|
||||||
@@ -523,16 +494,11 @@
|
|||||||
"parameterSetDesc": "Rappelé {{parameter}}",
|
"parameterSetDesc": "Rappelé {{parameter}}",
|
||||||
"parameterNotSetDesc": "Impossible de rappeler {{parameter}}",
|
"parameterNotSetDesc": "Impossible de rappeler {{parameter}}",
|
||||||
"layerCopiedToClipboard": "Calque copié dans le presse-papiers",
|
"layerCopiedToClipboard": "Calque copié dans le presse-papiers",
|
||||||
"layerSavedToAssets": "Calque enregistré dans les ressources",
|
|
||||||
"problemCopyingLayer": "Impossible de copier la couche",
|
"problemCopyingLayer": "Impossible de copier la couche",
|
||||||
"baseModelChanged": "Modèle de base changé",
|
"baseModelChanged": "Modèle de base changé",
|
||||||
"problemSavingLayer": "Impossible d'enregistrer la couche",
|
"problemSavingLayer": "Impossible d'enregistrer la couche",
|
||||||
"imageNotLoadedDesc": "Image introuvable",
|
|
||||||
"linkCopied": "Lien copié",
|
"linkCopied": "Lien copié",
|
||||||
"imagesWillBeAddedTo": "Les images Importées seront ajoutées au ressources de la Planche {{boardName}}.",
|
"imagesWillBeAddedTo": "Les images Importées seront ajoutées au ressources de la Planche {{boardName}}.",
|
||||||
"uploadFailedInvalidUploadDesc_withCount_one": "Doit être au maximum une image PNG ou JPEG.",
|
|
||||||
"uploadFailedInvalidUploadDesc_withCount_many": "Doit être au maximum {{count}} images PNG ou JPEG.",
|
|
||||||
"uploadFailedInvalidUploadDesc_withCount_other": "Doit être au maximum {{count}} images PNG ou JPEG.",
|
|
||||||
"addedToUncategorized": "Ajouté aux ressources de la planche $t(boards.uncategorized)",
|
"addedToUncategorized": "Ajouté aux ressources de la planche $t(boards.uncategorized)",
|
||||||
"pasteSuccess": "Collé à {{destination}}",
|
"pasteSuccess": "Collé à {{destination}}",
|
||||||
"pasteFailed": "Échec du collage",
|
"pasteFailed": "Échec du collage",
|
||||||
@@ -580,8 +546,6 @@
|
|||||||
"movingImagesToBoard_one": "Déplacer {{count}} image à cette planche :",
|
"movingImagesToBoard_one": "Déplacer {{count}} image à cette planche :",
|
||||||
"movingImagesToBoard_many": "Déplacer {{count}} images à cette planche :",
|
"movingImagesToBoard_many": "Déplacer {{count}} images à cette planche :",
|
||||||
"movingImagesToBoard_other": "Déplacer {{count}} image à cette planche :",
|
"movingImagesToBoard_other": "Déplacer {{count}} image à cette planche :",
|
||||||
"viewBoards": "Voir les Planches",
|
|
||||||
"hideBoards": "Cacher les Planches",
|
|
||||||
"noBoards": "Pas de Planches {{boardType}}",
|
"noBoards": "Pas de Planches {{boardType}}",
|
||||||
"shared": "Planches Partagées",
|
"shared": "Planches Partagées",
|
||||||
"searchBoard": "Chercher les Planches...",
|
"searchBoard": "Chercher les Planches...",
|
||||||
@@ -681,7 +645,6 @@
|
|||||||
"batchQueued": "Lot ajouté à la file d'attente",
|
"batchQueued": "Lot ajouté à la file d'attente",
|
||||||
"gallery": "Galerie",
|
"gallery": "Galerie",
|
||||||
"notReady": "Impossible d'ajouter à la file d'attente",
|
"notReady": "Impossible d'ajouter à la file d'attente",
|
||||||
"batchFieldValues": "Valeurs Champ Lot",
|
|
||||||
"front": "début",
|
"front": "début",
|
||||||
"graphQueued": "Graph ajouté à la file d'attente",
|
"graphQueued": "Graph ajouté à la file d'attente",
|
||||||
"other": "Autre",
|
"other": "Autre",
|
||||||
@@ -712,13 +675,11 @@
|
|||||||
"compatibleEmbeddings": "Embeddings Compatibles"
|
"compatibleEmbeddings": "Embeddings Compatibles"
|
||||||
},
|
},
|
||||||
"hrf": {
|
"hrf": {
|
||||||
"upscaleMethod": "Méthode d'Agrandissement",
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"enabled": "Correction Haute Résolution Activée",
|
"enabled": "Correction Haute Résolution Activée",
|
||||||
"strength": "Force de la Correction Haute Résolution",
|
"strength": "Force de la Correction Haute Résolution",
|
||||||
"method": "Méthode de la Correction Haute Résolution"
|
"method": "Méthode de la Correction Haute Résolution"
|
||||||
},
|
},
|
||||||
"enableHrf": "Activer la Correction Haute Résolution",
|
|
||||||
"hrf": "Correction Haute Résolution"
|
"hrf": "Correction Haute Résolution"
|
||||||
},
|
},
|
||||||
"invocationCache": {
|
"invocationCache": {
|
||||||
@@ -901,10 +862,6 @@
|
|||||||
"desc": "Définit le zoom de la toile à 400 %.",
|
"desc": "Définit le zoom de la toile à 400 %.",
|
||||||
"title": "Zoomer à 400 %"
|
"title": "Zoomer à 400 %"
|
||||||
},
|
},
|
||||||
"setFillToWhite": {
|
|
||||||
"title": "Définir la couleur sur blanc",
|
|
||||||
"desc": "Définir la couleur de l'outil actuel sur blanc."
|
|
||||||
},
|
|
||||||
"transformSelected": {
|
"transformSelected": {
|
||||||
"title": "Transformer",
|
"title": "Transformer",
|
||||||
"desc": "Transforme la couche sélectionnée."
|
"desc": "Transforme la couche sélectionnée."
|
||||||
@@ -1490,8 +1447,7 @@
|
|||||||
"showDynamicPrompts": "Afficher les Prompts dynamiques",
|
"showDynamicPrompts": "Afficher les Prompts dynamiques",
|
||||||
"dynamicPrompts": "Prompts Dynamiques",
|
"dynamicPrompts": "Prompts Dynamiques",
|
||||||
"promptsPreview": "Prévisualisation des Prompts",
|
"promptsPreview": "Prévisualisation des Prompts",
|
||||||
"loading": "Génération des Pompts Dynamiques...",
|
"loading": "Génération des Pompts Dynamiques..."
|
||||||
"promptsToGenerate": "Prompts à générer"
|
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"positivePrompt": "Prompt Positif",
|
"positivePrompt": "Prompt Positif",
|
||||||
@@ -1519,18 +1475,12 @@
|
|||||||
"recallParameters": "Rappeler les paramètres",
|
"recallParameters": "Rappeler les paramètres",
|
||||||
"imageDimensions": "Dimensions de l'image",
|
"imageDimensions": "Dimensions de l'image",
|
||||||
"parameterSet": "Paramètre {{parameter}} défini",
|
"parameterSet": "Paramètre {{parameter}} défini",
|
||||||
"parsingFailed": "L'analyse a échoué",
|
|
||||||
"recallParameter": "Rappeler {{label}}",
|
|
||||||
"canvasV2Metadata": "Toile",
|
"canvasV2Metadata": "Toile",
|
||||||
"guidance": "Guide",
|
"guidance": "Guide",
|
||||||
"seamlessXAxis": "Axe X sans bords",
|
"seamlessXAxis": "Axe X sans bords",
|
||||||
"seamlessYAxis": "Axe Y sans bords"
|
"seamlessYAxis": "Axe Y sans bords"
|
||||||
},
|
},
|
||||||
"sdxl": {
|
"sdxl": {
|
||||||
"freePromptStyle": "Écriture de Prompt manuelle",
|
|
||||||
"concatPromptStyle": "Lier Prompt & Style",
|
|
||||||
"negStylePrompt": "Style Prompt Négatif",
|
|
||||||
"posStylePrompt": "Style Prompt Positif",
|
|
||||||
"refinerStart": "Démarrer le Refiner",
|
"refinerStart": "Démarrer le Refiner",
|
||||||
"denoisingStrength": "Force de débruitage",
|
"denoisingStrength": "Force de débruitage",
|
||||||
"steps": "Étapes",
|
"steps": "Étapes",
|
||||||
@@ -1547,8 +1497,6 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"showMinimapnodes": "Afficher la MiniCarte",
|
"showMinimapnodes": "Afficher la MiniCarte",
|
||||||
"fitViewportNodes": "Ajuster la Vue",
|
"fitViewportNodes": "Ajuster la Vue",
|
||||||
"hideLegendNodes": "Masquer la légende du type de champ",
|
|
||||||
"showLegendNodes": "Afficher la légende du type de champ",
|
|
||||||
"hideMinimapnodes": "Masquer MiniCarte",
|
"hideMinimapnodes": "Masquer MiniCarte",
|
||||||
"zoomOutNodes": "Dézoomer",
|
"zoomOutNodes": "Dézoomer",
|
||||||
"zoomInNodes": "Zoomer",
|
"zoomInNodes": "Zoomer",
|
||||||
@@ -1572,9 +1520,7 @@
|
|||||||
"colorCodeEdges": "Code de couleur des connexions",
|
"colorCodeEdges": "Code de couleur des connexions",
|
||||||
"colorCodeEdgesHelp": "Code couleur des connexions en fonction de leurs champs connectés",
|
"colorCodeEdgesHelp": "Code couleur des connexions en fonction de leurs champs connectés",
|
||||||
"currentImage": "Image actuelle",
|
"currentImage": "Image actuelle",
|
||||||
"noFieldsLinearview": "Aucun champ ajouté à la vue linéaire",
|
|
||||||
"float": "Flottant",
|
"float": "Flottant",
|
||||||
"mismatchedVersion": "Nœud invalide : le nœud {{node}} de type {{type}} a une version incompatible (essayez de mettre à jour ?)",
|
|
||||||
"missingTemplate": "Nœud invalide : le nœud {{node}} de type {{type}} modèle manquant (non installé ?)",
|
"missingTemplate": "Nœud invalide : le nœud {{node}} de type {{type}} modèle manquant (non installé ?)",
|
||||||
"noWorkflow": "Pas de Workflow",
|
"noWorkflow": "Pas de Workflow",
|
||||||
"validateConnectionsHelp": "Prévenir la création de connexions invalides et l'invocation de graphes invalides",
|
"validateConnectionsHelp": "Prévenir la création de connexions invalides et l'invocation de graphes invalides",
|
||||||
@@ -1585,12 +1531,10 @@
|
|||||||
"scheduler": "Planificateur",
|
"scheduler": "Planificateur",
|
||||||
"notes": "Notes",
|
"notes": "Notes",
|
||||||
"notesDescription": "Ajouter des notes sur votre workflow",
|
"notesDescription": "Ajouter des notes sur votre workflow",
|
||||||
"unableToLoadWorkflow": "Impossible de charger le Workflow",
|
|
||||||
"addNode": "Ajouter un nœud",
|
"addNode": "Ajouter un nœud",
|
||||||
"problemSettingTitle": "Problème lors de définition du Titre",
|
"problemSettingTitle": "Problème lors de définition du Titre",
|
||||||
"connectionWouldCreateCycle": "La connexion créerait un cycle",
|
"connectionWouldCreateCycle": "La connexion créerait un cycle",
|
||||||
"currentImageDescription": "Affiche l'image actuelle dans l'éditeur de nœuds",
|
"currentImageDescription": "Affiche l'image actuelle dans l'éditeur de nœuds",
|
||||||
"versionUnknown": " Version inconnue",
|
|
||||||
"cannotConnectInputToInput": "Impossible de connecter l'entrée à l'entrée",
|
"cannotConnectInputToInput": "Impossible de connecter l'entrée à l'entrée",
|
||||||
"addNodeToolTip": "Ajouter un nœud (Shift+A, Espace)",
|
"addNodeToolTip": "Ajouter un nœud (Shift+A, Espace)",
|
||||||
"fullyContainNodesHelp": "Les nœuds doivent être entièrement à l'intérieur de la zone de sélection pour être sélectionnés",
|
"fullyContainNodesHelp": "Les nœuds doivent être entièrement à l'intérieur de la zone de sélection pour être sélectionnés",
|
||||||
@@ -1606,7 +1550,6 @@
|
|||||||
"nodeSearch": "Rechercher des nœuds",
|
"nodeSearch": "Rechercher des nœuds",
|
||||||
"collection": "Collection",
|
"collection": "Collection",
|
||||||
"noOutputRecorded": "Aucun résultat enregistré",
|
"noOutputRecorded": "Aucun résultat enregistré",
|
||||||
"removeLinearView": "Retirer de la vue linéaire",
|
|
||||||
"snapToGrid": "Aligner sur la grille",
|
"snapToGrid": "Aligner sur la grille",
|
||||||
"workflow": "Workflow",
|
"workflow": "Workflow",
|
||||||
"updateApp": "Mettre à jour l'application",
|
"updateApp": "Mettre à jour l'application",
|
||||||
@@ -1615,7 +1558,6 @@
|
|||||||
"noConnectionInProgress": "Aucune connexion en cours",
|
"noConnectionInProgress": "Aucune connexion en cours",
|
||||||
"nodeType": "Type de nœud",
|
"nodeType": "Type de nœud",
|
||||||
"workflowContact": "Contact",
|
"workflowContact": "Contact",
|
||||||
"unknownTemplate": "Modèle inconnu",
|
|
||||||
"unknownNode": "Nœud inconnu",
|
"unknownNode": "Nœud inconnu",
|
||||||
"workflowVersion": "Version",
|
"workflowVersion": "Version",
|
||||||
"string": "Chaîne de caractères",
|
"string": "Chaîne de caractères",
|
||||||
@@ -1629,7 +1571,6 @@
|
|||||||
"cannotDuplicateConnection": "Impossible de créer des connexions en double",
|
"cannotDuplicateConnection": "Impossible de créer des connexions en double",
|
||||||
"resetToDefaultValue": "Réinitialiser à la valeur par défaut",
|
"resetToDefaultValue": "Réinitialiser à la valeur par défaut",
|
||||||
"unknownNodeType": "Type de nœud inconnu",
|
"unknownNodeType": "Type de nœud inconnu",
|
||||||
"unknownInput": "Entrée inconnue : {{name}}",
|
|
||||||
"prototypeDesc": "Cette invocation est un prototype. Elle peut subir des modifications majeures lors des mises à jour de l'application et peut être supprimée à tout moment.",
|
"prototypeDesc": "Cette invocation est un prototype. Elle peut subir des modifications majeures lors des mises à jour de l'application et peut être supprimée à tout moment.",
|
||||||
"nodePack": "Paquet de nœuds",
|
"nodePack": "Paquet de nœuds",
|
||||||
"sourceNodeDoesNotExist": "Connexion invalide : le nœud source/de sortie {{node}} n'existe pas",
|
"sourceNodeDoesNotExist": "Connexion invalide : le nœud source/de sortie {{node}} n'existe pas",
|
||||||
@@ -1644,7 +1585,6 @@
|
|||||||
"clearWorkflow": "Effacer le Workflow",
|
"clearWorkflow": "Effacer le Workflow",
|
||||||
"clearWorkflowDesc": "Effacer ce workflow et en commencer un nouveau ?",
|
"clearWorkflowDesc": "Effacer ce workflow et en commencer un nouveau ?",
|
||||||
"unsupportedArrayItemType": "type d'élément de tableau non pris en charge \"{{type}}\"",
|
"unsupportedArrayItemType": "type d'élément de tableau non pris en charge \"{{type}}\"",
|
||||||
"addLinearView": "Ajouter à la vue linéaire",
|
|
||||||
"collectionOrScalarFieldType": "{{name}} (Unique ou Collection)",
|
"collectionOrScalarFieldType": "{{name}} (Unique ou Collection)",
|
||||||
"unableToExtractEnumOptions": "impossible d'extraire les options d'énumération",
|
"unableToExtractEnumOptions": "impossible d'extraire les options d'énumération",
|
||||||
"unsupportedAnyOfLength": "trop de membres dans l'union ({{count}})",
|
"unsupportedAnyOfLength": "trop de membres dans l'union ({{count}})",
|
||||||
@@ -1652,7 +1592,6 @@
|
|||||||
"viewMode": "Utiliser en vue linéaire",
|
"viewMode": "Utiliser en vue linéaire",
|
||||||
"collectionFieldType": "{{name}} (Collection)",
|
"collectionFieldType": "{{name}} (Collection)",
|
||||||
"newWorkflow": "Nouveau Workflow",
|
"newWorkflow": "Nouveau Workflow",
|
||||||
"reorderLinearView": "Réorganiser la vue linéaire",
|
|
||||||
"outputFieldTypeParseError": "Impossible d'analyser le type du champ de sortie {{node}}.{{field}} ({{message}})",
|
"outputFieldTypeParseError": "Impossible d'analyser le type du champ de sortie {{node}}.{{field}} ({{message}})",
|
||||||
"unsupportedMismatchedUnion": "type CollectionOrScalar non concordant avec les types de base {{firstType}} et {{secondType}}",
|
"unsupportedMismatchedUnion": "type CollectionOrScalar non concordant avec les types de base {{firstType}} et {{secondType}}",
|
||||||
"unableToParseFieldType": "impossible d'analyser le type de champ",
|
"unableToParseFieldType": "impossible d'analyser le type de champ",
|
||||||
@@ -1686,13 +1625,9 @@
|
|||||||
"arithmeticSequence": "Séquence Arithmétique",
|
"arithmeticSequence": "Séquence Arithmétique",
|
||||||
"uniformRandomDistribution": "Distribution Aléatoire Uniforme",
|
"uniformRandomDistribution": "Distribution Aléatoire Uniforme",
|
||||||
"noBatchGroup": "aucun groupe",
|
"noBatchGroup": "aucun groupe",
|
||||||
"generatorLoading": "chargement",
|
|
||||||
"generatorLoadFromFile": "Charger depuis un Fichier",
|
"generatorLoadFromFile": "Charger depuis un Fichier",
|
||||||
"dynamicPromptsRandom": "Prompts Dynamiques (Aléatoire)",
|
"dynamicPromptsRandom": "Prompts Dynamiques (Aléatoire)",
|
||||||
"integerRangeGenerator": "Générateur d'interval d'entiers",
|
|
||||||
"generateValues": "Générer Valeurs",
|
|
||||||
"linearDistribution": "Distribution Linéaire",
|
"linearDistribution": "Distribution Linéaire",
|
||||||
"floatRangeGenerator": "Générateur d'interval de nombres décimaux",
|
|
||||||
"generatorNRandomValues_one": "{{count}} valeur aléatoire",
|
"generatorNRandomValues_one": "{{count}} valeur aléatoire",
|
||||||
"generatorNRandomValues_many": "{{count}} valeurs aléatoires",
|
"generatorNRandomValues_many": "{{count}} valeurs aléatoires",
|
||||||
"generatorNRandomValues_other": "{{count}} valeurs aléatoires",
|
"generatorNRandomValues_other": "{{count}} valeurs aléatoires",
|
||||||
@@ -1712,7 +1647,6 @@
|
|||||||
"generatorImagesCategory": "Catégorie",
|
"generatorImagesCategory": "Catégorie",
|
||||||
"generatorImagesFromBoard": "Images de la Planche",
|
"generatorImagesFromBoard": "Images de la Planche",
|
||||||
"missingSourceOrTargetHandle": "Manque de gestionnaire source ou cible",
|
"missingSourceOrTargetHandle": "Manque de gestionnaire source ou cible",
|
||||||
"loadingTemplates": "Chargement de {{name}}",
|
|
||||||
"loadWorkflowDesc2": "Votre workflow actuel contient des modifications non enregistrées.",
|
"loadWorkflowDesc2": "Votre workflow actuel contient des modifications non enregistrées.",
|
||||||
"generatorImages_one": "{{count}} image",
|
"generatorImages_one": "{{count}} image",
|
||||||
"generatorImages_many": "{{count}} images",
|
"generatorImages_many": "{{count}} images",
|
||||||
@@ -1723,10 +1657,8 @@
|
|||||||
"noModelsAvailable": "Aucun modèle disponible",
|
"noModelsAvailable": "Aucun modèle disponible",
|
||||||
"loading": "chargement",
|
"loading": "chargement",
|
||||||
"selectModel": "Sélectionner un modèle",
|
"selectModel": "Sélectionner un modèle",
|
||||||
"noMatchingLoRAs": "Aucun LoRA correspondant",
|
|
||||||
"lora": "LoRA",
|
"lora": "LoRA",
|
||||||
"noRefinerModelsInstalled": "Aucun modèle SDXL Refiner installé",
|
"noRefinerModelsInstalled": "Aucun modèle SDXL Refiner installé",
|
||||||
"noLoRAsInstalled": "Aucun LoRA installé",
|
|
||||||
"addLora": "Ajouter LoRA",
|
"addLora": "Ajouter LoRA",
|
||||||
"defaultVAE": "VAE par défaut",
|
"defaultVAE": "VAE par défaut",
|
||||||
"concepts": "Concepts"
|
"concepts": "Concepts"
|
||||||
@@ -1734,11 +1666,8 @@
|
|||||||
"workflows": {
|
"workflows": {
|
||||||
"workflowLibrary": "Bibliothèque",
|
"workflowLibrary": "Bibliothèque",
|
||||||
"loading": "Chargement des Workflows",
|
"loading": "Chargement des Workflows",
|
||||||
"searchWorkflows": "Chercher des Workflows",
|
|
||||||
"workflowCleared": "Workflow effacé",
|
"workflowCleared": "Workflow effacé",
|
||||||
"noDescription": "Aucune description",
|
|
||||||
"deleteWorkflow": "Supprimer le Workflow",
|
"deleteWorkflow": "Supprimer le Workflow",
|
||||||
"openWorkflow": "Ouvrir le Workflow",
|
|
||||||
"uploadWorkflow": "Charger à partir d'un fichier",
|
"uploadWorkflow": "Charger à partir d'un fichier",
|
||||||
"workflowName": "Nom du Workflow",
|
"workflowName": "Nom du Workflow",
|
||||||
"unnamedWorkflow": "Workflow sans nom",
|
"unnamedWorkflow": "Workflow sans nom",
|
||||||
@@ -1751,8 +1680,6 @@
|
|||||||
"problemSavingWorkflow": "Problème de sauvegarde du Workflow",
|
"problemSavingWorkflow": "Problème de sauvegarde du Workflow",
|
||||||
"workflowEditorMenu": "Menu de l'Éditeur de Workflow",
|
"workflowEditorMenu": "Menu de l'Éditeur de Workflow",
|
||||||
"newWorkflowCreated": "Nouveau Workflow créé",
|
"newWorkflowCreated": "Nouveau Workflow créé",
|
||||||
"clearWorkflowSearchFilter": "Réinitialiser le filtre de recherche de Workflow",
|
|
||||||
"problemLoading": "Problème de chargement des Workflows",
|
|
||||||
"workflowSaved": "Workflow enregistré",
|
"workflowSaved": "Workflow enregistré",
|
||||||
"noWorkflows": "Pas de Workflows",
|
"noWorkflows": "Pas de Workflows",
|
||||||
"ascending": "Ascendant",
|
"ascending": "Ascendant",
|
||||||
@@ -1765,9 +1692,6 @@
|
|||||||
"opened": "Ouvert",
|
"opened": "Ouvert",
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
"autoLayout": "Mise en page automatique",
|
"autoLayout": "Mise en page automatique",
|
||||||
"defaultWorkflows": "Workflows par défaut",
|
|
||||||
"userWorkflows": "Workflows de l'utilisateur",
|
|
||||||
"projectWorkflows": "Workflows du projet",
|
|
||||||
"copyShareLink": "Copier le lien de partage",
|
"copyShareLink": "Copier le lien de partage",
|
||||||
"chooseWorkflowFromLibrary": "Choisir le Workflow dans la Bibliothèque",
|
"chooseWorkflowFromLibrary": "Choisir le Workflow dans la Bibliothèque",
|
||||||
"edit": "Modifer",
|
"edit": "Modifer",
|
||||||
@@ -1784,7 +1708,6 @@
|
|||||||
"multiLine": "Multi Ligne",
|
"multiLine": "Multi Ligne",
|
||||||
"headingPlaceholder": "En-tête vide",
|
"headingPlaceholder": "En-tête vide",
|
||||||
"emptyRootPlaceholderEditMode": "Faites glisser un élément de formulaire ou un champ de nœud ici pour commencer.",
|
"emptyRootPlaceholderEditMode": "Faites glisser un élément de formulaire ou un champ de nœud ici pour commencer.",
|
||||||
"emptyRootPlaceholderViewMode": "Cliquez sur Modifier pour commencer à créer un formulaire pour ce workflow.",
|
|
||||||
"containerPlaceholder": "Conteneur Vide",
|
"containerPlaceholder": "Conteneur Vide",
|
||||||
"row": "Ligne",
|
"row": "Ligne",
|
||||||
"column": "Colonne",
|
"column": "Colonne",
|
||||||
@@ -1798,10 +1721,8 @@
|
|||||||
"builder": "Constructeur de Formulaire",
|
"builder": "Constructeur de Formulaire",
|
||||||
"resetAllNodeFields": "Réinitialiser tous les champs de nœud",
|
"resetAllNodeFields": "Réinitialiser tous les champs de nœud",
|
||||||
"deleteAllElements": "Supprimer tous les éléments de formulaire",
|
"deleteAllElements": "Supprimer tous les éléments de formulaire",
|
||||||
"workflowBuilderAlphaWarning": "Le constructeur de workflow est actuellement en version alpha. Il peut y avoir des changements majeurs avant la version stable.",
|
|
||||||
"showDescription": "Afficher la description"
|
"showDescription": "Afficher la description"
|
||||||
},
|
}
|
||||||
"openLibrary": "Ouvrir la Bibliothèque"
|
|
||||||
},
|
},
|
||||||
"whatsNew": {
|
"whatsNew": {
|
||||||
"whatsNewInInvoke": "Quoi de neuf dans Invoke",
|
"whatsNewInInvoke": "Quoi de neuf dans Invoke",
|
||||||
@@ -1810,8 +1731,7 @@
|
|||||||
"<StrongComponent>FLUX Guidage Régional (bêta)</StrongComponent> : Notre version bêta de FLUX Guidage Régional est en ligne pour le contrôle des prompt régionaux.",
|
"<StrongComponent>FLUX Guidage Régional (bêta)</StrongComponent> : Notre version bêta de FLUX Guidage Régional est en ligne pour le contrôle des prompt régionaux.",
|
||||||
"Autres améliorations : mise en file d'attente par lots plus rapide, meilleur redimensionnement, sélecteur de couleurs amélioré et nœuds de métadonnées."
|
"Autres améliorations : mise en file d'attente par lots plus rapide, meilleur redimensionnement, sélecteur de couleurs amélioré et nœuds de métadonnées."
|
||||||
],
|
],
|
||||||
"readReleaseNotes": "Notes de version",
|
"readReleaseNotes": "Notes de version"
|
||||||
"watchUiUpdatesOverview": "Aperçu des mises à jour de l'interface utilisateur"
|
|
||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"tabs": {
|
"tabs": {
|
||||||
@@ -1820,7 +1740,6 @@
|
|||||||
"upscaling": "Agrandissement",
|
"upscaling": "Agrandissement",
|
||||||
"gallery": "Galerie",
|
"gallery": "Galerie",
|
||||||
"upscalingTab": "$t(ui.tabs.upscaling) $t(common.tab)",
|
"upscalingTab": "$t(ui.tabs.upscaling) $t(common.tab)",
|
||||||
"generation": "Génération",
|
|
||||||
"workflows": "Workflows",
|
"workflows": "Workflows",
|
||||||
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
||||||
"models": "Modèles",
|
"models": "Modèles",
|
||||||
@@ -1829,7 +1748,6 @@
|
|||||||
},
|
},
|
||||||
"controlLayers": {
|
"controlLayers": {
|
||||||
"newLayerFromImage": "Nouvelle couche à partir de l'image",
|
"newLayerFromImage": "Nouvelle couche à partir de l'image",
|
||||||
"sendToGalleryDesc": "Appuyer sur Invoker génère et enregistre une image unique dans votre galerie.",
|
|
||||||
"sendToCanvas": "Envoyer vers la Toile",
|
"sendToCanvas": "Envoyer vers la Toile",
|
||||||
"globalReferenceImage": "Image de référence globale",
|
"globalReferenceImage": "Image de référence globale",
|
||||||
"newCanvasFromImage": "Nouvelle Toile à partir de l'image",
|
"newCanvasFromImage": "Nouvelle Toile à partir de l'image",
|
||||||
@@ -1985,7 +1903,6 @@
|
|||||||
},
|
},
|
||||||
"bookmark": "Marque-page pour Changement Rapide",
|
"bookmark": "Marque-page pour Changement Rapide",
|
||||||
"saveLayerToAssets": "Enregistrer la couche dans les ressources",
|
"saveLayerToAssets": "Enregistrer la couche dans les ressources",
|
||||||
"stagingOnCanvas": "Mise en attente des images sur",
|
|
||||||
"enableTransparencyEffect": "Activer l'effet de transparence",
|
"enableTransparencyEffect": "Activer l'effet de transparence",
|
||||||
"hidingType": "Masquer {{type}}",
|
"hidingType": "Masquer {{type}}",
|
||||||
"settings": {
|
"settings": {
|
||||||
@@ -2016,11 +1933,6 @@
|
|||||||
"disableAutoNegative": "Désactiver l'Auto Négatif",
|
"disableAutoNegative": "Désactiver l'Auto Négatif",
|
||||||
"addNegativePrompt": "Ajouter $t(controlLayers.negativePrompt)",
|
"addNegativePrompt": "Ajouter $t(controlLayers.negativePrompt)",
|
||||||
"addRegionalGuidance": "Ajouter $t(controlLayers.regionalGuidance)",
|
"addRegionalGuidance": "Ajouter $t(controlLayers.regionalGuidance)",
|
||||||
"controlLayers_withCount_hidden": "Control Layers ({{count}} cachées)",
|
|
||||||
"rasterLayers_withCount_hidden": "Couche de Rastérisation ({{count}} cachées)",
|
|
||||||
"regionalGuidance_withCount_hidden": "Guidage Régional ({{count}} caché)",
|
|
||||||
"rasterLayers_withCount_visible": "Couche de Rastérisation ({{count}})",
|
|
||||||
"inpaintMasks_withCount_visible": "Masques de remplissage ({{count}})",
|
|
||||||
"layer_one": "Couche",
|
"layer_one": "Couche",
|
||||||
"layer_many": "Couches",
|
"layer_many": "Couches",
|
||||||
"layer_other": "Couches",
|
"layer_other": "Couches",
|
||||||
@@ -2070,8 +1982,6 @@
|
|||||||
"next": "Suivant",
|
"next": "Suivant",
|
||||||
"saveToGallery": "Enregistrer dans la galerie"
|
"saveToGallery": "Enregistrer dans la galerie"
|
||||||
},
|
},
|
||||||
"viewProgressOnCanvas": "Voir les progrès et les sorties de la scène sur la <Btn>Toile</Btn>.",
|
|
||||||
"sendToCanvasDesc": "Appuyer sur Invoker met en attente votre travail en cours sur la toile.",
|
|
||||||
"mergeVisibleError": "Erreur lors de la fusion des calques visibles",
|
"mergeVisibleError": "Erreur lors de la fusion des calques visibles",
|
||||||
"mergeVisibleOk": "Couches visibles fusionnées",
|
"mergeVisibleOk": "Couches visibles fusionnées",
|
||||||
"clearHistory": "Effacer l'historique",
|
"clearHistory": "Effacer l'historique",
|
||||||
@@ -2080,8 +1990,6 @@
|
|||||||
"duplicate": "Dupliquer",
|
"duplicate": "Dupliquer",
|
||||||
"enableAutoNegative": "Activer l'Auto Négatif",
|
"enableAutoNegative": "Activer l'Auto Négatif",
|
||||||
"showHUD": "Afficher HUD",
|
"showHUD": "Afficher HUD",
|
||||||
"sendToGallery": "Envoyer à la galerie",
|
|
||||||
"sendingToGallery": "Envoi des générations à la galerie",
|
|
||||||
"disableTransparencyEffect": "Désactiver l'effet de transparence",
|
"disableTransparencyEffect": "Désactiver l'effet de transparence",
|
||||||
"HUD": {
|
"HUD": {
|
||||||
"entityStatus": {
|
"entityStatus": {
|
||||||
@@ -2098,16 +2006,11 @@
|
|||||||
"opacity": "Opacité",
|
"opacity": "Opacité",
|
||||||
"savedToGalleryError": "Erreur lors de l'enregistrement dans la galerie",
|
"savedToGalleryError": "Erreur lors de l'enregistrement dans la galerie",
|
||||||
"addInpaintMask": "Ajouter $t(controlLayers.inpaintMask)",
|
"addInpaintMask": "Ajouter $t(controlLayers.inpaintMask)",
|
||||||
"newCanvasSessionDesc": "Cela effacera la toile et tous les paramètres, sauf votre sélection de modèle. Les générations seront mises en attente sur la toile.",
|
|
||||||
"canvas": "Toile",
|
"canvas": "Toile",
|
||||||
"savedToGalleryOk": "Enregistré dans la galerie",
|
"savedToGalleryOk": "Enregistré dans la galerie",
|
||||||
"addPositivePrompt": "Ajouter $t(controlLayers.prompt)",
|
"addPositivePrompt": "Ajouter $t(controlLayers.prompt)",
|
||||||
"showProgressOnCanvas": "Afficher la progression sur la Toile",
|
"showProgressOnCanvas": "Afficher la progression sur la Toile",
|
||||||
"newGallerySession": "Nouvelle session de galerie",
|
|
||||||
"newCanvasSession": "Nouvelle session de toile",
|
|
||||||
"showingType": "Afficher {{type}}",
|
"showingType": "Afficher {{type}}",
|
||||||
"viewProgressInViewer": "Voir les progrès et les résultats dans le <Btn>Visionneur d'images</Btn>.",
|
|
||||||
"deletePrompt": "Supprimer le prompt",
|
|
||||||
"addControlLayer": "Ajouter $t(controlLayers.controlLayer)",
|
"addControlLayer": "Ajouter $t(controlLayers.controlLayer)",
|
||||||
"global": "Global",
|
"global": "Global",
|
||||||
"newGlobalReferenceImageOk": "Image de référence globale créée",
|
"newGlobalReferenceImageOk": "Image de référence globale créée",
|
||||||
@@ -2121,16 +2024,6 @@
|
|||||||
"newRasterLayerError": "Problème de création de couche de rastérisation",
|
"newRasterLayerError": "Problème de création de couche de rastérisation",
|
||||||
"negativePrompt": "Prompt négatif",
|
"negativePrompt": "Prompt négatif",
|
||||||
"weight": "Poids",
|
"weight": "Poids",
|
||||||
"globalReferenceImages_withCount_hidden": "Images de référence globales ({{count}} cachées)",
|
|
||||||
"inpaintMasks_withCount_hidden": "Masques de remplissage ({{count}} cachés)",
|
|
||||||
"regionalGuidance_withCount_visible": "Guidage Régional ({{count}})",
|
|
||||||
"globalReferenceImage_withCount_one": "$t(controlLayers.globalReferenceImage)",
|
|
||||||
"globalReferenceImage_withCount_many": "Images de référence globales",
|
|
||||||
"globalReferenceImage_withCount_other": "Images de référence globales",
|
|
||||||
"layer_withCount_one": "Couche {{count}}",
|
|
||||||
"layer_withCount_many": "Couches {{count}}",
|
|
||||||
"layer_withCount_other": "Couches {{count}}",
|
|
||||||
"globalReferenceImages_withCount_visible": "Images de référence globales ({{count}})",
|
|
||||||
"controlMode": {
|
"controlMode": {
|
||||||
"controlMode": "Mode de contrôle",
|
"controlMode": "Mode de contrôle",
|
||||||
"balanced": "Équilibré",
|
"balanced": "Équilibré",
|
||||||
@@ -2154,18 +2047,14 @@
|
|||||||
},
|
},
|
||||||
"fitBboxToLayers": "Ajuster la bounding box aux calques",
|
"fitBboxToLayers": "Ajuster la bounding box aux calques",
|
||||||
"regionIsEmpty": "La zone sélectionnée est vide",
|
"regionIsEmpty": "La zone sélectionnée est vide",
|
||||||
"controlLayers_withCount_visible": "Couches de contrôle ({{count}})",
|
|
||||||
"cropLayerToBbox": "Rogner la couche selon la bounding box",
|
"cropLayerToBbox": "Rogner la couche selon la bounding box",
|
||||||
"sendingToCanvas": "Mise en attente des Générations sur la Toile",
|
|
||||||
"copyToClipboard": "Copier dans le presse-papiers",
|
"copyToClipboard": "Copier dans le presse-papiers",
|
||||||
"regionalGuidance_withCount_one": "$t(controlLayers.regionalGuidance)",
|
"regionalGuidance_withCount_one": "$t(controlLayers.regionalGuidance)",
|
||||||
"regionalGuidance_withCount_many": "Guidage Régional",
|
"regionalGuidance_withCount_many": "Guidage Régional",
|
||||||
"regionalGuidance_withCount_other": "Guidage Régional",
|
"regionalGuidance_withCount_other": "Guidage Régional",
|
||||||
"newGallerySessionDesc": "Cela effacera la toile et tous les paramètres, sauf votre sélection de modèle. Les générations seront envoyées à la galerie.",
|
|
||||||
"inpaintMask_withCount_one": "$t(controlLayers.inpaintMask)",
|
"inpaintMask_withCount_one": "$t(controlLayers.inpaintMask)",
|
||||||
"inpaintMask_withCount_many": "Remplir les masques",
|
"inpaintMask_withCount_many": "Remplir les masques",
|
||||||
"inpaintMask_withCount_other": "Remplir les masques",
|
"inpaintMask_withCount_other": "Remplir les masques",
|
||||||
"newImg2ImgCanvasFromImage": "Nouvelle Img2Img à partir de l'image",
|
|
||||||
"bboxOverlay": "Afficher la superposition des Bounding Box",
|
"bboxOverlay": "Afficher la superposition des Bounding Box",
|
||||||
"moveToFront": "Déplacer vers le permier plan",
|
"moveToFront": "Déplacer vers le permier plan",
|
||||||
"moveToBack": "Déplacer vers l'arrière plan",
|
"moveToBack": "Déplacer vers l'arrière plan",
|
||||||
@@ -2180,7 +2069,6 @@
|
|||||||
"inpaintMask": "Masque de remplissage",
|
"inpaintMask": "Masque de remplissage",
|
||||||
"deleteReferenceImage": "Supprimer l'image de référence",
|
"deleteReferenceImage": "Supprimer l'image de référence",
|
||||||
"addReferenceImage": "Ajouter $t(controlLayers.referenceImage)",
|
"addReferenceImage": "Ajouter $t(controlLayers.referenceImage)",
|
||||||
"addGlobalReferenceImage": "Ajouter $t(controlLayers.globalReferenceImage)",
|
|
||||||
"removeBookmark": "Supprimer le marque-page",
|
"removeBookmark": "Supprimer le marque-page",
|
||||||
"regionalGuidance": "Guide régional",
|
"regionalGuidance": "Guide régional",
|
||||||
"regionalReferenceImage": "Image de référence régionale",
|
"regionalReferenceImage": "Image de référence régionale",
|
||||||
@@ -2209,16 +2097,12 @@
|
|||||||
"pointType": "Type de point",
|
"pointType": "Type de point",
|
||||||
"exclude": "Exclure",
|
"exclude": "Exclure",
|
||||||
"process": "Traiter",
|
"process": "Traiter",
|
||||||
"reset": "Réinitialiser",
|
"reset": "Réinitialiser"
|
||||||
"help1": "Sélectionnez un seul objet cible. Ajoutez des points <Bold>Inclure</Bold> et <Bold>Exclure</Bold> pour indiquer quelles parties de la couche font partie de l'objet cible.",
|
|
||||||
"help2": "Commencez par un point <Bold>Inclure</Bold> au sein de l'objet cible. Ajoutez d'autres points pour affiner la sélection. Moins de points produisent généralement de meilleurs résultats.",
|
|
||||||
"help3": "Inversez la sélection pour sélectionner tout sauf l'objet cible."
|
|
||||||
},
|
},
|
||||||
"convertRegionalGuidanceTo": "Convertir $t(controlLayers.regionalGuidance) vers",
|
"convertRegionalGuidanceTo": "Convertir $t(controlLayers.regionalGuidance) vers",
|
||||||
"copyRasterLayerTo": "Copier $t(controlLayers.rasterLayer) vers",
|
"copyRasterLayerTo": "Copier $t(controlLayers.rasterLayer) vers",
|
||||||
"newControlLayer": "Nouveau $t(controlLayers.controlLayer)",
|
"newControlLayer": "Nouveau $t(controlLayers.controlLayer)",
|
||||||
"newRegionalGuidance": "Nouveau $t(controlLayers.regionalGuidance)",
|
"newRegionalGuidance": "Nouveau $t(controlLayers.regionalGuidance)",
|
||||||
"replaceCurrent": "Remplacer Actuel",
|
|
||||||
"convertControlLayerTo": "Convertir $t(controlLayers.controlLayer) vers",
|
"convertControlLayerTo": "Convertir $t(controlLayers.controlLayer) vers",
|
||||||
"convertInpaintMaskTo": "Convertir $t(controlLayers.inpaintMask) vers",
|
"convertInpaintMaskTo": "Convertir $t(controlLayers.inpaintMask) vers",
|
||||||
"copyControlLayerTo": "Copier $t(controlLayers.controlLayer) vers",
|
"copyControlLayerTo": "Copier $t(controlLayers.controlLayer) vers",
|
||||||
@@ -2264,9 +2148,7 @@
|
|||||||
"pasteToBboxDesc": "Nouvelle couche (dans Bbox)",
|
"pasteToBboxDesc": "Nouvelle couche (dans Bbox)",
|
||||||
"pasteToCanvasDesc": "Nouvelle couche (dans la Toile)",
|
"pasteToCanvasDesc": "Nouvelle couche (dans la Toile)",
|
||||||
"useImage": "Utiliser l'image",
|
"useImage": "Utiliser l'image",
|
||||||
"pastedTo": "Collé à {{destination}}",
|
"referenceImageEmptyState": "<UploadButton>Séléctionner une image</UploadButton> ou faites glisser une image depuis la <GalleryButton>galerie</GalleryButton> sur cette couche pour commencer."
|
||||||
"referenceImageEmptyState": "<UploadButton>Séléctionner une image</UploadButton> ou faites glisser une image depuis la <GalleryButton>galerie</GalleryButton> sur cette couche pour commencer.",
|
|
||||||
"referenceImageGlobal": "Image de référence (Globale)"
|
|
||||||
},
|
},
|
||||||
"upscaling": {
|
"upscaling": {
|
||||||
"exceedsMaxSizeDetails": "La limite maximale d'agrandissement est de {{maxUpscaleDimension}}x{{maxUpscaleDimension}} pixels. Veuillez essayer une image plus petite ou réduire votre sélection d'échelle.",
|
"exceedsMaxSizeDetails": "La limite maximale d'agrandissement est de {{maxUpscaleDimension}}x{{maxUpscaleDimension}} pixels. Veuillez essayer une image plus petite ou réduire votre sélection d'échelle.",
|
||||||
|
|||||||
@@ -50,8 +50,7 @@
|
|||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "גודל תמונה",
|
"galleryImageSize": "גודל תמונה",
|
||||||
"gallerySettings": "הגדרות גלריה",
|
"gallerySettings": "הגדרות גלריה",
|
||||||
"autoSwitchNewImages": "החלף אוטומטית לתמונות חדשות",
|
"autoSwitchNewImages": "החלף אוטומטית לתמונות חדשות"
|
||||||
"noImagesInGallery": "אין תמונות בגלריה"
|
|
||||||
},
|
},
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"images": "תמונות",
|
"images": "תמונות",
|
||||||
@@ -70,12 +69,10 @@
|
|||||||
"tileSize": "גודל אריח",
|
"tileSize": "גודל אריח",
|
||||||
"symmetry": "סימטריה",
|
"symmetry": "סימטריה",
|
||||||
"copyImage": "העתקת תמונה",
|
"copyImage": "העתקת תמונה",
|
||||||
"downloadImage": "הורדת תמונה",
|
|
||||||
"usePrompt": "שימוש בבקשה",
|
"usePrompt": "שימוש בבקשה",
|
||||||
"useSeed": "שימוש בזרע",
|
"useSeed": "שימוש בזרע",
|
||||||
"useAll": "שימוש בהכל",
|
"useAll": "שימוש בהכל",
|
||||||
"info": "פרטים",
|
"info": "פרטים",
|
||||||
"showOptionsPanel": "הצג חלונית אפשרויות",
|
|
||||||
"shuffle": "ערבוב",
|
"shuffle": "ערבוב",
|
||||||
"noiseThreshold": "סף רעש",
|
"noiseThreshold": "סף רעש",
|
||||||
"perlinNoise": "רעש פרלין",
|
"perlinNoise": "רעש פרלין",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,6 @@
|
|||||||
"openInNewTab": "新しいタブで開く",
|
"openInNewTab": "新しいタブで開く",
|
||||||
"controlNet": "コントロールネット",
|
"controlNet": "コントロールネット",
|
||||||
"linear": "リニア",
|
"linear": "リニア",
|
||||||
"imageFailedToLoad": "画像が読み込めません",
|
|
||||||
"modelManager": "モデルマネージャー",
|
"modelManager": "モデルマネージャー",
|
||||||
"learnMore": "もっと学ぶ",
|
"learnMore": "もっと学ぶ",
|
||||||
"random": "ランダム",
|
"random": "ランダム",
|
||||||
@@ -56,7 +55,6 @@
|
|||||||
"details": "詳細",
|
"details": "詳細",
|
||||||
"inpaint": "inpaint",
|
"inpaint": "inpaint",
|
||||||
"delete": "削除",
|
"delete": "削除",
|
||||||
"nextPage": "次のページ",
|
|
||||||
"copy": "コピー",
|
"copy": "コピー",
|
||||||
"error": "エラー",
|
"error": "エラー",
|
||||||
"file": "ファイル",
|
"file": "ファイル",
|
||||||
@@ -64,13 +62,10 @@
|
|||||||
"input": "インプット",
|
"input": "インプット",
|
||||||
"format": "形式",
|
"format": "形式",
|
||||||
"installed": "インストール済み",
|
"installed": "インストール済み",
|
||||||
"localSystem": "ローカルシステム",
|
|
||||||
"outputs": "アウトプット",
|
"outputs": "アウトプット",
|
||||||
"prevPage": "前のページ",
|
|
||||||
"unknownError": "未知のエラー",
|
"unknownError": "未知のエラー",
|
||||||
"orderBy": "並び順:",
|
"orderBy": "並び順:",
|
||||||
"enabled": "有効",
|
"enabled": "有効",
|
||||||
"notInstalled": "未 $t(common.installed)",
|
|
||||||
"positivePrompt": "ポジティブプロンプト",
|
"positivePrompt": "ポジティブプロンプト",
|
||||||
"negativePrompt": "ネガティブプロンプト",
|
"negativePrompt": "ネガティブプロンプト",
|
||||||
"selected": "選択済み",
|
"selected": "選択済み",
|
||||||
@@ -96,7 +91,6 @@
|
|||||||
"close": "閉じる",
|
"close": "閉じる",
|
||||||
"warnings": "警告",
|
"warnings": "警告",
|
||||||
"dontShowMeThese": "次回から表示しない",
|
"dontShowMeThese": "次回から表示しない",
|
||||||
"goTo": "移動",
|
|
||||||
"generating": "生成中",
|
"generating": "生成中",
|
||||||
"loadingModel": "モデルをロード中",
|
"loadingModel": "モデルをロード中",
|
||||||
"layout": "レイアウト",
|
"layout": "レイアウト",
|
||||||
@@ -107,7 +101,6 @@
|
|||||||
"min": "最小",
|
"min": "最小",
|
||||||
"max": "最大",
|
"max": "最大",
|
||||||
"values": "値",
|
"values": "値",
|
||||||
"resetToDefaults": "デフォルトに戻す",
|
|
||||||
"row": "行",
|
"row": "行",
|
||||||
"column": "列",
|
"column": "列",
|
||||||
"board": "ボード",
|
"board": "ボード",
|
||||||
@@ -131,7 +124,6 @@
|
|||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "画像のサイズ",
|
"galleryImageSize": "画像のサイズ",
|
||||||
"gallerySettings": "ギャラリーの設定",
|
"gallerySettings": "ギャラリーの設定",
|
||||||
"noImagesInGallery": "表示する画像がありません",
|
|
||||||
"autoSwitchNewImages": "新しい画像に自動切替",
|
"autoSwitchNewImages": "新しい画像に自動切替",
|
||||||
"copy": "コピー",
|
"copy": "コピー",
|
||||||
"image": "画像",
|
"image": "画像",
|
||||||
@@ -145,7 +137,6 @@
|
|||||||
"deleteImage_other": "画像 {{count}} 枚を削除",
|
"deleteImage_other": "画像 {{count}} 枚を削除",
|
||||||
"deleteImagePermanent": "削除された画像は復元できません。",
|
"deleteImagePermanent": "削除された画像は復元できません。",
|
||||||
"download": "ダウンロード",
|
"download": "ダウンロード",
|
||||||
"unableToLoad": "ギャラリーをロードできません",
|
|
||||||
"bulkDownloadRequested": "ダウンロード準備中",
|
"bulkDownloadRequested": "ダウンロード準備中",
|
||||||
"bulkDownloadRequestedDesc": "ダウンロードの準備中です。しばらくお待ちください。",
|
"bulkDownloadRequestedDesc": "ダウンロードの準備中です。しばらくお待ちください。",
|
||||||
"bulkDownloadRequestFailed": "ダウンロード準備中に問題が発生",
|
"bulkDownloadRequestFailed": "ダウンロード準備中に問題が発生",
|
||||||
@@ -160,7 +151,6 @@
|
|||||||
"compareImage": "比較画像",
|
"compareImage": "比較画像",
|
||||||
"openInViewer": "ビューアで開く",
|
"openInViewer": "ビューアで開く",
|
||||||
"selectForCompare": "比較対象として選択",
|
"selectForCompare": "比較対象として選択",
|
||||||
"selectAnImageToCompare": "比較する画像を選択",
|
|
||||||
"slider": "スライダー",
|
"slider": "スライダー",
|
||||||
"sideBySide": "横並び",
|
"sideBySide": "横並び",
|
||||||
"hover": "ホバー",
|
"hover": "ホバー",
|
||||||
@@ -172,8 +162,6 @@
|
|||||||
"compareHelp4": "<Kbd>[Z</Kbd>]または<Kbd>[Esc</Kbd>]を押して終了します。",
|
"compareHelp4": "<Kbd>[Z</Kbd>]または<Kbd>[Esc</Kbd>]を押して終了します。",
|
||||||
"compareHelp2": "<Kbd>M</Kbd> キーを押して比較モードを切り替えます。",
|
"compareHelp2": "<Kbd>M</Kbd> キーを押して比較モードを切り替えます。",
|
||||||
"move": "移動",
|
"move": "移動",
|
||||||
"openViewer": "ビューアを開く",
|
|
||||||
"closeViewer": "ビューアを閉じる",
|
|
||||||
"exitSearch": "画像検索を終了",
|
"exitSearch": "画像検索を終了",
|
||||||
"oldestFirst": "最古から",
|
"oldestFirst": "最古から",
|
||||||
"showStarredImagesFirst": "スター付き画像を最初に",
|
"showStarredImagesFirst": "スター付き画像を最初に",
|
||||||
@@ -182,7 +170,6 @@
|
|||||||
"searchImages": "メタデータで検索",
|
"searchImages": "メタデータで検索",
|
||||||
"gallery": "ギャラリー",
|
"gallery": "ギャラリー",
|
||||||
"newestFirst": "最新から",
|
"newestFirst": "最新から",
|
||||||
"jump": "ジャンプ",
|
|
||||||
"go": "進む",
|
"go": "進む",
|
||||||
"sortDirection": "並び替え順",
|
"sortDirection": "並び替え順",
|
||||||
"displayBoardSearch": "ボード検索",
|
"displayBoardSearch": "ボード検索",
|
||||||
@@ -325,10 +312,6 @@
|
|||||||
"desc": "リスト内の前のレイヤーを選択します。",
|
"desc": "リスト内の前のレイヤーを選択します。",
|
||||||
"title": "前のレイヤー"
|
"title": "前のレイヤー"
|
||||||
},
|
},
|
||||||
"setFillToWhite": {
|
|
||||||
"title": "ツール色を白に設定",
|
|
||||||
"desc": "現在のツールの色を白色に設定します。"
|
|
||||||
},
|
|
||||||
"selectViewTool": {
|
"selectViewTool": {
|
||||||
"title": "表示ツール",
|
"title": "表示ツール",
|
||||||
"desc": "表示ツールを選択します。"
|
"desc": "表示ツールを選択します。"
|
||||||
@@ -609,7 +592,6 @@
|
|||||||
"scanResults": "結果をスキャン",
|
"scanResults": "結果をスキャン",
|
||||||
"scanPlaceholder": "ローカルフォルダへのパス",
|
"scanPlaceholder": "ローカルフォルダへのパス",
|
||||||
"typePhraseHere": "ここにフレーズを入力",
|
"typePhraseHere": "ここにフレーズを入力",
|
||||||
"ipAdapters": "IPアダプター",
|
|
||||||
"modelImageUpdated": "モデル画像アップデート",
|
"modelImageUpdated": "モデル画像アップデート",
|
||||||
"installAll": "全てインストール",
|
"installAll": "全てインストール",
|
||||||
"installRepo": "リポジトリをインストール",
|
"installRepo": "リポジトリをインストール",
|
||||||
@@ -651,7 +633,6 @@
|
|||||||
"spandrelImageToImage": "Image to Image(スパンドレル)",
|
"spandrelImageToImage": "Image to Image(スパンドレル)",
|
||||||
"starterBundles": "スターターバンドル",
|
"starterBundles": "スターターバンドル",
|
||||||
"starterModels": "スターターモデル",
|
"starterModels": "スターターモデル",
|
||||||
"starterModelsInModelManager": "スターターモデルがモデルマネージャーで見つかりました",
|
|
||||||
"modelImageDeleteFailed": "モデル画像の削除失敗",
|
"modelImageDeleteFailed": "モデル画像の削除失敗",
|
||||||
"urlForbidden": "このモデルにアクセスできません",
|
"urlForbidden": "このモデルにアクセスできません",
|
||||||
"urlForbiddenErrorMessage": "このモデルを配布しているサイトからリクエスト権限が必要かもしれません.",
|
"urlForbiddenErrorMessage": "このモデルを配布しているサイトからリクエスト権限が必要かもしれません.",
|
||||||
@@ -660,12 +641,10 @@
|
|||||||
"inplaceInstall": "定位置にインストール",
|
"inplaceInstall": "定位置にインストール",
|
||||||
"fileSize": "ファイルサイズ",
|
"fileSize": "ファイルサイズ",
|
||||||
"modelPickerFallbackNoModelsInstalled2": "<LinkComponent>モデルマネージャー</LinkComponent> にアクセスしてモデルをインストールしてください.",
|
"modelPickerFallbackNoModelsInstalled2": "<LinkComponent>モデルマネージャー</LinkComponent> にアクセスしてモデルをインストールしてください.",
|
||||||
"filterModels": "フィルターモデル",
|
|
||||||
"modelPickerFallbackNoModelsInstalled": "モデルがインストールされていません.",
|
"modelPickerFallbackNoModelsInstalled": "モデルがインストールされていません.",
|
||||||
"manageModels": "モデル管理",
|
"manageModels": "モデル管理",
|
||||||
"hfTokenReset": "ハギングフェイストークンリセット",
|
"hfTokenReset": "ハギングフェイストークンリセット",
|
||||||
"relatedModels": "関連のあるモデル",
|
"relatedModels": "関連のあるモデル",
|
||||||
"showOnlyRelatedModels": "関連している",
|
|
||||||
"installedModelsCount": "{{total}} モデルのうち {{installed}} 個がインストールされています。",
|
"installedModelsCount": "{{total}} モデルのうち {{installed}} 個がインストールされています。",
|
||||||
"allNModelsInstalled": "{{count}} 個のモデルがすべてインストールされています",
|
"allNModelsInstalled": "{{count}} 個のモデルがすべてインストールされています",
|
||||||
"nToInstall": "{{count}}個をインストールする",
|
"nToInstall": "{{count}}個をインストールする",
|
||||||
@@ -682,12 +661,8 @@
|
|||||||
"scanFolderDescription": "ローカルフォルダをスキャンしてモデルを自動的に検出し、インストールします。",
|
"scanFolderDescription": "ローカルフォルダをスキャンしてモデルを自動的に検出し、インストールします。",
|
||||||
"recommendedModels": "推奨モデル",
|
"recommendedModels": "推奨モデル",
|
||||||
"exploreStarter": "または、利用可能なすべてのスターターモデルを参照してください",
|
"exploreStarter": "または、利用可能なすべてのスターターモデルを参照してください",
|
||||||
"quickStart": "クイックスタートバンドル",
|
|
||||||
"bundleDescription": "各バンドルには各モデルファミリーの必須モデルと、開始するための厳選されたベースモデルが含まれています。",
|
"bundleDescription": "各バンドルには各モデルファミリーの必須モデルと、開始するための厳選されたベースモデルが含まれています。",
|
||||||
"browseAll": "または、利用可能なすべてのモデルを参照してください。",
|
"sdxl": "SDXL"
|
||||||
"stableDiffusion15": "Stable Diffusion1.5",
|
|
||||||
"sdxl": "SDXL",
|
|
||||||
"fluxDev": "FLUX.1 dev"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"parameters": {
|
"parameters": {
|
||||||
@@ -703,12 +678,10 @@
|
|||||||
"scaleBeforeProcessing": "処理前のスケール",
|
"scaleBeforeProcessing": "処理前のスケール",
|
||||||
"scaledWidth": "幅のスケール",
|
"scaledWidth": "幅のスケール",
|
||||||
"scaledHeight": "高さのスケール",
|
"scaledHeight": "高さのスケール",
|
||||||
"downloadImage": "画像をダウンロード",
|
|
||||||
"usePrompt": "プロンプトを使用",
|
"usePrompt": "プロンプトを使用",
|
||||||
"useSeed": "シード値を使用",
|
"useSeed": "シード値を使用",
|
||||||
"useAll": "すべてを使用",
|
"useAll": "すべてを使用",
|
||||||
"info": "情報",
|
"info": "情報",
|
||||||
"showOptionsPanel": "サイドパネルを表示 (O or T)",
|
|
||||||
"iterations": "生成回数",
|
"iterations": "生成回数",
|
||||||
"general": "基本設定",
|
"general": "基本設定",
|
||||||
"setToOptimalSize": "サイズをモデルに最適化",
|
"setToOptimalSize": "サイズをモデルに最適化",
|
||||||
@@ -722,7 +695,6 @@
|
|||||||
"collectionNumberLTExclusiveMin": "{{value}} <= {{exclusiveMinimum}} (最小値を除く)",
|
"collectionNumberLTExclusiveMin": "{{value}} <= {{exclusiveMinimum}} (最小値を除く)",
|
||||||
"missingInputForField": "入力の欠落",
|
"missingInputForField": "入力の欠落",
|
||||||
"noModelSelected": "モデルが選択されていません",
|
"noModelSelected": "モデルが選択されていません",
|
||||||
"emptyBatches": "空のバッチ",
|
|
||||||
"collectionStringTooLong": "長すぎます,最大{{maxLength}}",
|
"collectionStringTooLong": "長すぎます,最大{{maxLength}}",
|
||||||
"batchNodeCollectionSizeMismatchNoGroupId": "バッチグループのコレクションサイズが合いません",
|
"batchNodeCollectionSizeMismatchNoGroupId": "バッチグループのコレクションサイズが合いません",
|
||||||
"invoke": "呼び出す",
|
"invoke": "呼び出す",
|
||||||
@@ -734,7 +706,6 @@
|
|||||||
"missingNodeTemplate": "ノードテンプレートの欠落",
|
"missingNodeTemplate": "ノードテンプレートの欠落",
|
||||||
"batchNodeNotConnected": "バッチノードが: {{label}}につながっていない",
|
"batchNodeNotConnected": "バッチノードが: {{label}}につながっていない",
|
||||||
"collectionNumberLTMin": "{{value}} < {{minimum}} (最小増加)",
|
"collectionNumberLTMin": "{{value}} < {{minimum}} (最小増加)",
|
||||||
"fluxModelIncompatibleScaledBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), スケーリングされたbboxの高さは{{height}}です",
|
|
||||||
"fluxModelMultipleControlLoRAs": "コントロールLoRAは1度に1つしか使用できません",
|
"fluxModelMultipleControlLoRAs": "コントロールLoRAは1度に1つしか使用できません",
|
||||||
"noPrompts": "プロンプトが生成されません",
|
"noPrompts": "プロンプトが生成されません",
|
||||||
"noNodesInGraph": "グラフにノードがありません",
|
"noNodesInGraph": "グラフにノードがありません",
|
||||||
@@ -742,7 +713,6 @@
|
|||||||
"canvasIsFiltering": "キャンバスがビジー状態(フィルタリング)",
|
"canvasIsFiltering": "キャンバスがビジー状態(フィルタリング)",
|
||||||
"canvasIsCompositing": "キャンバスがビジー状態(合成)",
|
"canvasIsCompositing": "キャンバスがビジー状態(合成)",
|
||||||
"systemDisconnected": "システムが切断されました",
|
"systemDisconnected": "システムが切断されました",
|
||||||
"fluxModelIncompatibleScaledBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), 拡大縮小されたbboxの幅は{{width}}です",
|
|
||||||
"canvasIsTransforming": "キャンバスがビジー状態(変換)",
|
"canvasIsTransforming": "キャンバスがビジー状態(変換)",
|
||||||
"canvasIsRasterizing": "キャンバスがビジー状態(ラスタライズ)",
|
"canvasIsRasterizing": "キャンバスがビジー状態(ラスタライズ)",
|
||||||
"modelIncompatibleBboxHeight": "Bboxの高さは{{height}}ですが,{{model}}は{{multiple}}の倍数が必要です",
|
"modelIncompatibleBboxHeight": "Bboxの高さは{{height}}ですが,{{model}}は{{multiple}}の倍数が必要です",
|
||||||
@@ -750,12 +720,9 @@
|
|||||||
"modelIncompatibleBboxWidth": "Bboxの幅は{{width}}ですが, {{model}}は{{multiple}}の倍数が必要です",
|
"modelIncompatibleBboxWidth": "Bboxの幅は{{width}}ですが, {{model}}は{{multiple}}の倍数が必要です",
|
||||||
"modelIncompatibleScaledBboxWidth": "bboxの幅は{{width}}ですが,{{model}}は{{multiple}}の倍数が必要です",
|
"modelIncompatibleScaledBboxWidth": "bboxの幅は{{width}}ですが,{{model}}は{{multiple}}の倍数が必要です",
|
||||||
"canvasIsSelectingObject": "キャンバスがビジー状態(オブジェクトの選択)",
|
"canvasIsSelectingObject": "キャンバスがビジー状態(オブジェクトの選択)",
|
||||||
"fluxModelIncompatibleBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), bboxの幅は{{width}}です",
|
|
||||||
"fluxModelIncompatibleBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), bboxの高さは{{height}}です",
|
|
||||||
"noFLUXVAEModelSelected": "FLUX生成にVAEモデルが選択されていません",
|
"noFLUXVAEModelSelected": "FLUX生成にVAEモデルが選択されていません",
|
||||||
"noT5EncoderModelSelected": "FLUX生成にT5エンコーダモデルが選択されていません",
|
"noT5EncoderModelSelected": "FLUX生成にT5エンコーダモデルが選択されていません",
|
||||||
"modelDisabledForTrial": "{{modelName}} を使用した生成はトライアルアカウントではご利用いただけません.アカウント設定にアクセスしてアップグレードしてください。",
|
"modelDisabledForTrial": "{{modelName}} を使用した生成はトライアルアカウントではご利用いただけません.アカウント設定にアクセスしてアップグレードしてください。",
|
||||||
"fluxKontextMultipleReferenceImages": "Flux Kontext では一度に 1 つの参照画像しか使用できません",
|
|
||||||
"promptExpansionPending": "プロンプト拡張が進行中",
|
"promptExpansionPending": "プロンプト拡張が進行中",
|
||||||
"promptExpansionResultPending": "プロンプト拡張結果を受け入れるか破棄してください"
|
"promptExpansionResultPending": "プロンプト拡張結果を受け入れるか破棄してください"
|
||||||
},
|
},
|
||||||
@@ -830,8 +797,6 @@
|
|||||||
"enableHighlightFocusedRegions": "重点領域を強調表示",
|
"enableHighlightFocusedRegions": "重点領域を強調表示",
|
||||||
"clearIntermediatesDesc1": "中間物をクリアすると、キャンバスとコントロールネットの状態がリセットされます.",
|
"clearIntermediatesDesc1": "中間物をクリアすると、キャンバスとコントロールネットの状態がリセットされます.",
|
||||||
"showProgressInViewer": "ビューアで進行状況画像を表示する",
|
"showProgressInViewer": "ビューアで進行状況画像を表示する",
|
||||||
"modelDescriptionsDisabled": "ドロップダウンのモデル説明が無効になっています",
|
|
||||||
"modelDescriptionsDisabledDesc": "ドロップダウンのモデル説明が無効になっています.設定で有効にしてください.",
|
|
||||||
"clearIntermediatesDisabled": "中間物をクリアするにはキューが空でなければなりません",
|
"clearIntermediatesDisabled": "中間物をクリアするにはキューが空でなければなりません",
|
||||||
"clearIntermediatesDesc2": "中間画像は生成時に生成される副産物であり、ギャラリーに表示される結果画像とは異なります.中間画像を削除するとディスク容量が解放されます.",
|
"clearIntermediatesDesc2": "中間画像は生成時に生成される副産物であり、ギャラリーに表示される結果画像とは異なります.中間画像を削除するとディスク容量が解放されます.",
|
||||||
"intermediatesClearedFailed": "中間物をクリアする問題",
|
"intermediatesClearedFailed": "中間物をクリアする問題",
|
||||||
@@ -862,11 +827,9 @@
|
|||||||
"imagesWillBeAddedTo": "アップロードされた画像はボード {{boardName}} のアセットに追加されます.",
|
"imagesWillBeAddedTo": "アップロードされた画像はボード {{boardName}} のアセットに追加されます.",
|
||||||
"layerCopiedToClipboard": "レイヤーがクリップボードにコピーされました",
|
"layerCopiedToClipboard": "レイヤーがクリップボードにコピーされました",
|
||||||
"pasteFailed": "貼り付け失敗",
|
"pasteFailed": "貼り付け失敗",
|
||||||
"imageSavingFailed": "画像保存に失敗しました",
|
|
||||||
"importSuccessful": "インポートが成功しました",
|
"importSuccessful": "インポートが成功しました",
|
||||||
"problemDownloadingImage": "画像をダウンロードできません",
|
"problemDownloadingImage": "画像をダウンロードできません",
|
||||||
"modelAddedSimple": "モデルがキューに追加されました",
|
"modelAddedSimple": "モデルがキューに追加されました",
|
||||||
"uploadFailedInvalidUploadDesc_withCount_other": "PNG、JPEG、または WEBP 画像は最大 1 つにする必要があります.",
|
|
||||||
"outOfMemoryErrorDesc": "現在の生成設定はシステム容量を超えています.設定を調整してもう一度お試しください.",
|
"outOfMemoryErrorDesc": "現在の生成設定はシステム容量を超えています.設定を調整してもう一度お試しください.",
|
||||||
"parametersSet": "パラメーターが呼び出されました",
|
"parametersSet": "パラメーターが呼び出されました",
|
||||||
"modelImportCanceled": "モデルのインポートがキャンセルされました",
|
"modelImportCanceled": "モデルのインポートがキャンセルされました",
|
||||||
@@ -881,14 +844,11 @@
|
|||||||
"linkCopied": "リンクがコピーされました",
|
"linkCopied": "リンクがコピーされました",
|
||||||
"unableToLoadImage": "画像をロードできません",
|
"unableToLoadImage": "画像をロードできません",
|
||||||
"unableToLoadImageMetadata": "画像のメタデータをロードできません",
|
"unableToLoadImageMetadata": "画像のメタデータをロードできません",
|
||||||
"imageSaved": "画像が保存されました",
|
|
||||||
"importFailed": "インポートに失敗しました",
|
"importFailed": "インポートに失敗しました",
|
||||||
"invalidUpload": "無効なアップロードです",
|
|
||||||
"outOfMemoryError": "メモリ不足エラー",
|
"outOfMemoryError": "メモリ不足エラー",
|
||||||
"parameterSetDesc": "{{parameter}}を呼び出し",
|
"parameterSetDesc": "{{parameter}}を呼び出し",
|
||||||
"errorCopied": "エラーがコピーされました",
|
"errorCopied": "エラーがコピーされました",
|
||||||
"sentToCanvas": "キャンバスに送信",
|
"sentToCanvas": "キャンバスに送信",
|
||||||
"setControlImage": "コントロール画像としてセット",
|
|
||||||
"workflowLoaded": "ワークフローがロードされました",
|
"workflowLoaded": "ワークフローがロードされました",
|
||||||
"unableToCopy": "コピーできません",
|
"unableToCopy": "コピーできません",
|
||||||
"unableToCopyDesc": "あなたのブラウザはクリップボードアクセスをサポートしていません.Firefoxユーザーの場合は、以下の手順で修正できる可能性があります. ",
|
"unableToCopyDesc": "あなたのブラウザはクリップボードアクセスをサポートしていません.Firefoxユーザーの場合は、以下の手順で修正できる可能性があります. ",
|
||||||
@@ -902,32 +862,23 @@
|
|||||||
"parameterNotSetDescWithMessage": "{{parameter}}: {{message}}を呼び出せません",
|
"parameterNotSetDescWithMessage": "{{parameter}}: {{message}}を呼び出せません",
|
||||||
"problemCopyingLayer": "レイヤーをコピーできません",
|
"problemCopyingLayer": "レイヤーをコピーできません",
|
||||||
"problemSavingLayer": "レイヤー保存ができません",
|
"problemSavingLayer": "レイヤー保存ができません",
|
||||||
"setNodeField": "ノードフィールドとしてセット",
|
|
||||||
"layerSavedToAssets": "レイヤーがアセットに保存されました",
|
|
||||||
"outOfMemoryErrorDescLocal": "OOM を削減するには、<LinkComponent>低 VRAM ガイド</LinkComponent> に従ってください.",
|
"outOfMemoryErrorDescLocal": "OOM を削減するには、<LinkComponent>低 VRAM ガイド</LinkComponent> に従ってください.",
|
||||||
"parameterNotSet": "パラメーターが呼び出されていません",
|
"parameterNotSet": "パラメーターが呼び出されていません",
|
||||||
"addedToBoard": "{{name}} 個の資産をボードに追加しました",
|
"addedToBoard": "{{name}} 個の資産をボードに追加しました",
|
||||||
"addedToUncategorized": "$t(boards.uncategorized)個のアセットがボードに追加されました",
|
"addedToUncategorized": "$t(boards.uncategorized)個のアセットがボードに追加されました",
|
||||||
"problemDeletingWorkflow": "ワークフローが削除された問題",
|
"problemDeletingWorkflow": "ワークフローが削除された問題",
|
||||||
"imageNotLoadedDesc": "画像を見つけられません",
|
|
||||||
"parameterNotSetDesc": "{{parameter}}を呼び出せません",
|
"parameterNotSetDesc": "{{parameter}}を呼び出せません",
|
||||||
"chatGPT4oIncompatibleGenerationMode": "ChatGPT 4oは,テキストから画像への生成と画像から画像への生成のみをサポートしています.インペインティングおよび,アウトペインティングタスクには他のモデルを使用してください.",
|
"chatGPT4oIncompatibleGenerationMode": "ChatGPT 4oは,テキストから画像への生成と画像から画像への生成のみをサポートしています.インペインティングおよび,アウトペインティングタスクには他のモデルを使用してください.",
|
||||||
"imagenIncompatibleGenerationMode": "Google {{model}} はテキストから画像への変換のみをサポートしています. 画像から画像への変換, インペインティング,アウトペインティングのタスクには他のモデルを使用してください.",
|
"imagenIncompatibleGenerationMode": "Google {{model}} はテキストから画像への変換のみをサポートしています. 画像から画像への変換, インペインティング,アウトペインティングのタスクには他のモデルを使用してください.",
|
||||||
"noRasterLayers": "ラスターレイヤーが見つかりません",
|
|
||||||
"noRasterLayersDesc": "PSDにエクスポートするには、少なくとも1つのラスターレイヤーを作成します",
|
|
||||||
"noActiveRasterLayers": "アクティブなラスターレイヤーがありません",
|
|
||||||
"noActiveRasterLayersDesc": "PSD にエクスポートするには、少なくとも 1 つのラスター レイヤーを有効にします",
|
|
||||||
"noVisibleRasterLayers": "表示されるラスター レイヤーがありません",
|
"noVisibleRasterLayers": "表示されるラスター レイヤーがありません",
|
||||||
"noVisibleRasterLayersDesc": "PSD にエクスポートするには、少なくとも 1 つのラスター レイヤーを有効にします",
|
"noVisibleRasterLayersDesc": "PSD にエクスポートするには、少なくとも 1 つのラスター レイヤーを有効にします",
|
||||||
"invalidCanvasDimensions": "キャンバスのサイズが無効です",
|
"invalidCanvasDimensions": "キャンバスのサイズが無効です",
|
||||||
"canvasTooLarge": "キャンバスが大きすぎます",
|
"canvasTooLarge": "キャンバスが大きすぎます",
|
||||||
"canvasTooLargeDesc": "キャンバスのサイズがPSDエクスポートの最大許容サイズを超えています。キャンバス全体の幅と高さを小さくしてから、もう一度お試しください。",
|
"canvasTooLargeDesc": "キャンバスのサイズがPSDエクスポートの最大許容サイズを超えています。キャンバス全体の幅と高さを小さくしてから、もう一度お試しください。",
|
||||||
"failedToProcessLayers": "レイヤーの処理に失敗しました",
|
|
||||||
"psdExportSuccess": "PSDエクスポート完了",
|
"psdExportSuccess": "PSDエクスポート完了",
|
||||||
"psdExportSuccessDesc": "{{count}} 個のレイヤーを PSD ファイルに正常にエクスポートしました",
|
"psdExportSuccessDesc": "{{count}} 個のレイヤーを PSD ファイルに正常にエクスポートしました",
|
||||||
"problemExportingPSD": "PSD のエクスポート中に問題が発生しました",
|
"problemExportingPSD": "PSD のエクスポート中に問題が発生しました",
|
||||||
"canvasManagerNotAvailable": "キャンバスマネージャーは利用できません",
|
"canvasManagerNotAvailable": "キャンバスマネージャーは利用できません",
|
||||||
"noValidLayerAdapters": "有効なレイヤーアダプタが見つかりません",
|
|
||||||
"fluxKontextIncompatibleGenerationMode": "Flux Kontext はテキストから画像への変換のみをサポートしています。画像から画像への変換、インペインティング、アウトペインティングのタスクには他のモデルを使用してください。",
|
"fluxKontextIncompatibleGenerationMode": "Flux Kontext はテキストから画像への変換のみをサポートしています。画像から画像への変換、インペインティング、アウトペインティングのタスクには他のモデルを使用してください。",
|
||||||
"promptGenerationStarted": "プロンプト生成が開始されました",
|
"promptGenerationStarted": "プロンプト生成が開始されました",
|
||||||
"uploadAndPromptGenerationFailed": "画像のアップロードとプロンプトの生成に失敗しました",
|
"uploadAndPromptGenerationFailed": "画像のアップロードとプロンプトの生成に失敗しました",
|
||||||
@@ -959,7 +910,6 @@
|
|||||||
"positivePrompt": "ポジティブプロンプト",
|
"positivePrompt": "ポジティブプロンプト",
|
||||||
"strength": "Image to Image 強度",
|
"strength": "Image to Image 強度",
|
||||||
"recallParameters": "パラメータを再使用",
|
"recallParameters": "パラメータを再使用",
|
||||||
"recallParameter": "{{label}} を再使用",
|
|
||||||
"imageDimensions": "画像サイズ",
|
"imageDimensions": "画像サイズ",
|
||||||
"imageDetails": "画像の詳細",
|
"imageDetails": "画像の詳細",
|
||||||
"model": "モデル",
|
"model": "モデル",
|
||||||
@@ -974,7 +924,6 @@
|
|||||||
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
||||||
"canvasV2Metadata": "キャンバス",
|
"canvasV2Metadata": "キャンバス",
|
||||||
"guidance": "手引き",
|
"guidance": "手引き",
|
||||||
"parsingFailed": "解析に失敗しました",
|
|
||||||
"seamlessXAxis": "シームレスX軸",
|
"seamlessXAxis": "シームレスX軸",
|
||||||
"seamlessYAxis": "シームレスY軸",
|
"seamlessYAxis": "シームレスY軸",
|
||||||
"parameterSet": "パラメーター {{parameter}} が設定されました",
|
"parameterSet": "パラメーター {{parameter}} が設定されました",
|
||||||
@@ -1032,7 +981,6 @@
|
|||||||
"clearQueueAlertDialog2": "キューをクリアしてもよろしいですか?",
|
"clearQueueAlertDialog2": "キューをクリアしてもよろしいですか?",
|
||||||
"item": "項目",
|
"item": "項目",
|
||||||
"graphFailedToQueue": "グラフをキューに追加できませんでした",
|
"graphFailedToQueue": "グラフをキューに追加できませんでした",
|
||||||
"batchFieldValues": "バッチの詳細",
|
|
||||||
"openQueue": "キューを開く",
|
"openQueue": "キューを開く",
|
||||||
"time": "時間",
|
"time": "時間",
|
||||||
"completedIn": "完了まで",
|
"completedIn": "完了まで",
|
||||||
@@ -1062,14 +1010,12 @@
|
|||||||
"models": {
|
"models": {
|
||||||
"noMatchingModels": "一致するモデルがありません",
|
"noMatchingModels": "一致するモデルがありません",
|
||||||
"loading": "読み込み中",
|
"loading": "読み込み中",
|
||||||
"noMatchingLoRAs": "一致するLoRAがありません",
|
|
||||||
"noModelsAvailable": "使用可能なモデルがありません",
|
"noModelsAvailable": "使用可能なモデルがありません",
|
||||||
"selectModel": "モデルを選択してください",
|
"selectModel": "モデルを選択してください",
|
||||||
"concepts": "コンセプト",
|
"concepts": "コンセプト",
|
||||||
"addLora": "LoRAを追加",
|
"addLora": "LoRAを追加",
|
||||||
"lora": "LoRA",
|
"lora": "LoRA",
|
||||||
"defaultVAE": "デフォルトVAE",
|
"defaultVAE": "デフォルトVAE",
|
||||||
"noLoRAsInstalled": "インストールされているLoRAはありません",
|
|
||||||
"noRefinerModelsInstalled": "インストールされているSDXLリファイナーモデルはありません",
|
"noRefinerModelsInstalled": "インストールされているSDXLリファイナーモデルはありません",
|
||||||
"noCompatibleLoRAs": "互換性のあるLoRAはありません"
|
"noCompatibleLoRAs": "互換性のあるLoRAはありません"
|
||||||
},
|
},
|
||||||
@@ -1079,7 +1025,6 @@
|
|||||||
"addNodeToolTip": "ノードを追加 (Shift+A, Space)",
|
"addNodeToolTip": "ノードを追加 (Shift+A, Space)",
|
||||||
"missingTemplate": "Invalid node: タイプ {{type}} のノード {{node}} にテンプレートがありません(未インストール?)",
|
"missingTemplate": "Invalid node: タイプ {{type}} のノード {{node}} にテンプレートがありません(未インストール?)",
|
||||||
"loadWorkflow": "ワークフローを読み込み",
|
"loadWorkflow": "ワークフローを読み込み",
|
||||||
"hideLegendNodes": "フィールドタイプの凡例を非表示",
|
|
||||||
"float": "浮動小数点",
|
"float": "浮動小数点",
|
||||||
"integer": "整数",
|
"integer": "整数",
|
||||||
"nodeTemplate": "ノードテンプレート",
|
"nodeTemplate": "ノードテンプレート",
|
||||||
@@ -1123,13 +1068,11 @@
|
|||||||
"enum": "Enum",
|
"enum": "Enum",
|
||||||
"arithmeticSequence": "等差数列",
|
"arithmeticSequence": "等差数列",
|
||||||
"linearDistribution": "線形分布",
|
"linearDistribution": "線形分布",
|
||||||
"addLinearView": "ライナービューに追加",
|
|
||||||
"animatedEdges": "アニメーションエッジ",
|
"animatedEdges": "アニメーションエッジ",
|
||||||
"uniformRandomDistribution": "一様ランダム分布",
|
"uniformRandomDistribution": "一様ランダム分布",
|
||||||
"noBatchGroup": "グループなし",
|
"noBatchGroup": "グループなし",
|
||||||
"parseString": "文字列の解析",
|
"parseString": "文字列の解析",
|
||||||
"generatorImagesFromBoard": "ボードからの画像",
|
"generatorImagesFromBoard": "ボードからの画像",
|
||||||
"generatorLoading": "読み込み中",
|
|
||||||
"missingNode": "呼び出しノードがありません",
|
"missingNode": "呼び出しノードがありません",
|
||||||
"missingSourceOrTargetNode": "ソースまたはターゲットノードがありません",
|
"missingSourceOrTargetNode": "ソースまたはターゲットノードがありません",
|
||||||
"missingSourceOrTargetHandle": "ソースまたはターゲットハンドルがありません",
|
"missingSourceOrTargetHandle": "ソースまたはターゲットハンドルがありません",
|
||||||
@@ -1150,7 +1093,6 @@
|
|||||||
"missingInvocationTemplate": "呼び出しテンプレートがありません",
|
"missingInvocationTemplate": "呼び出しテンプレートがありません",
|
||||||
"nodePack": "ノードパック",
|
"nodePack": "ノードパック",
|
||||||
"targetNodeFieldDoesNotExist": "無効なエッジ:ターゲット/インプットフィールド{{node}}.{{field}} が存在しません",
|
"targetNodeFieldDoesNotExist": "無効なエッジ:ターゲット/インプットフィールド{{node}}.{{field}} が存在しません",
|
||||||
"mismatchedVersion": "無効なノード:ノード {{node}} のタイプ {{type}} はバージョンとミスマッチしています (アップデートを試されますか?)",
|
|
||||||
"dynamicPromptsCombinatorial": "ダイナミックプロンプト(組み合わせ)",
|
"dynamicPromptsCombinatorial": "ダイナミックプロンプト(組み合わせ)",
|
||||||
"cannotMixAndMatchCollectionItemTypes": "コレクション・アイテムの種類を組み合わせることはできません",
|
"cannotMixAndMatchCollectionItemTypes": "コレクション・アイテムの種類を組み合わせることはできません",
|
||||||
"missingFieldTemplate": "フィールドテンプレートがありません",
|
"missingFieldTemplate": "フィールドテンプレートがありません",
|
||||||
@@ -1160,7 +1102,6 @@
|
|||||||
"collectionOrScalarFieldType": "{{name}} (単数またはコレクション)",
|
"collectionOrScalarFieldType": "{{name}} (単数またはコレクション)",
|
||||||
"unableToUpdateNode": "ノードアップロード失敗:ノード {{node}} のタイプ {{type}} (削除か再生成が必要かもしれません)",
|
"unableToUpdateNode": "ノードアップロード失敗:ノード {{node}} のタイプ {{type}} (削除か再生成が必要かもしれません)",
|
||||||
"deletedInvalidEdge": "無効なエッジを削除しました{{source}} -> {{target}}",
|
"deletedInvalidEdge": "無効なエッジを削除しました{{source}} -> {{target}}",
|
||||||
"noFieldsLinearview": "線形ビューに追加されたフィールドがありません",
|
|
||||||
"collectionFieldType": "{{name}} (コレクション)",
|
"collectionFieldType": "{{name}} (コレクション)",
|
||||||
"colorCodeEdgesHelp": "接続されたフィールドによるカラーコードエッジ",
|
"colorCodeEdgesHelp": "接続されたフィールドによるカラーコードエッジ",
|
||||||
"showEdgeLabelsHelp": "エッジのラベルを表示,接続されているノードを示す",
|
"showEdgeLabelsHelp": "エッジのラベルを表示,接続されているノードを示す",
|
||||||
@@ -1175,7 +1116,6 @@
|
|||||||
"loadWorkflowDesc2": "現在のワークフローは保存されていない変更があります.",
|
"loadWorkflowDesc2": "現在のワークフローは保存されていない変更があります.",
|
||||||
"clearWorkflowDesc": "このワークフローをクリアして新しいワークフローにしますか?",
|
"clearWorkflowDesc": "このワークフローをクリアして新しいワークフローにしますか?",
|
||||||
"updateNode": "ノードをアップデート",
|
"updateNode": "ノードをアップデート",
|
||||||
"versionUnknown": " バージョン不明",
|
|
||||||
"graph": "グラフ",
|
"graph": "グラフ",
|
||||||
"workflowContact": "お問い合わせ",
|
"workflowContact": "お問い合わせ",
|
||||||
"outputFieldTypeParseError": "出力フィールド {{node}}.{{field}} の型を解析できません({{message}})",
|
"outputFieldTypeParseError": "出力フィールド {{node}}.{{field}} の型を解析できません({{message}})",
|
||||||
@@ -1194,36 +1134,28 @@
|
|||||||
"unableToExtractSchemaNameFromRef": "参照からスキーマ名を抽出できません",
|
"unableToExtractSchemaNameFromRef": "参照からスキーマ名を抽出できません",
|
||||||
"unableToUpdateNodes_other": "{{count}} 個のノードをアップデートできません",
|
"unableToUpdateNodes_other": "{{count}} 個のノードをアップデートできません",
|
||||||
"workflowSettings": "ワークフローエディター設定",
|
"workflowSettings": "ワークフローエディター設定",
|
||||||
"generateValues": "値を生成",
|
|
||||||
"floatRangeGenerator": "浮動小数点レンジ生成器",
|
|
||||||
"integerRangeGenerator": "整数レンジ生成器",
|
|
||||||
"specialDesc": "この呼び出しは,アプリ内で特別な処理を行います.例えば,バッチノードは1つのワークフローから複数のグラフをキューに入れるために使用されます.",
|
"specialDesc": "この呼び出しは,アプリ内で特別な処理を行います.例えば,バッチノードは1つのワークフローから複数のグラフをキューに入れるために使用されます.",
|
||||||
"modelAccessError": "モデル {{key}}が見つからないので,デフォルトにリセットします",
|
"modelAccessError": "モデル {{key}}が見つからないので,デフォルトにリセットします",
|
||||||
"betaDesc": "この呼び出しはベータ版です.安定するまでは,アプリのアップデートの際に変更される可能性があります.この呼び出しは長期的にサポートする予定です.",
|
"betaDesc": "この呼び出しはベータ版です.安定するまでは,アプリのアップデートの際に変更される可能性があります.この呼び出しは長期的にサポートする予定です.",
|
||||||
"internalDesc": "この呼び出しはInvokeによって内部的に使用されます.アプリの更新時に変更される可能性があり,いつでも削除される可能性があります.",
|
"internalDesc": "この呼び出しはInvokeによって内部的に使用されます.アプリの更新時に変更される可能性があり,いつでも削除される可能性があります.",
|
||||||
"noFieldsViewMode": "このワークフローには表示する選択フィールドがありません.値を設定するためにはワークフロー全体を表示します.",
|
"noFieldsViewMode": "このワークフローには表示する選択フィールドがありません.値を設定するためにはワークフロー全体を表示します.",
|
||||||
"clearWorkflow": "ワークフローをクリア",
|
"clearWorkflow": "ワークフローをクリア",
|
||||||
"removeLinearView": "線形ビューから削除",
|
|
||||||
"snapToGrid": "グリッドにスナップ",
|
"snapToGrid": "グリッドにスナップ",
|
||||||
"showMinimapnodes": "ミニマップを表示",
|
"showMinimapnodes": "ミニマップを表示",
|
||||||
"reorderLinearView": "線形ビューの並び替え",
|
|
||||||
"description": "説明",
|
"description": "説明",
|
||||||
"notesDescription": "ワークフローに関するメモを追加する",
|
"notesDescription": "ワークフローに関するメモを追加する",
|
||||||
"newWorkflowDesc2": "現在のワークフローに保存されていない変更があります.",
|
"newWorkflowDesc2": "現在のワークフローに保存されていない変更があります.",
|
||||||
"unknownField": "不明なフィールド",
|
"unknownField": "不明なフィールド",
|
||||||
"unexpectedField_withName": "予期しないフィールド\"{{name}}\"",
|
"unexpectedField_withName": "予期しないフィールド\"{{name}}\"",
|
||||||
"loadingTemplates": "読み込み中 {{name}}",
|
|
||||||
"validateConnectionsHelp": "無効な接続が行われたり,無効なグラフが呼び出されたりしないようにします",
|
"validateConnectionsHelp": "無効な接続が行われたり,無効なグラフが呼び出されたりしないようにします",
|
||||||
"validateConnections": "接続とグラフを確認する",
|
"validateConnections": "接続とグラフを確認する",
|
||||||
"saveToGallery": "ギャラリーに保存",
|
"saveToGallery": "ギャラリーに保存",
|
||||||
"newWorkflowDesc": "新しいワークフローを作りますか?",
|
"newWorkflowDesc": "新しいワークフローを作りますか?",
|
||||||
"unknownFieldType": "$t(nodes.unknownField)型: {{type}}",
|
"unknownFieldType": "$t(nodes.unknownField)型: {{type}}",
|
||||||
"unsupportedArrayItemType": "サポートされていない配列項目型です \"{{type}}\"",
|
"unsupportedArrayItemType": "サポートされていない配列項目型です \"{{type}}\"",
|
||||||
"unableToLoadWorkflow": "ワークフローが読み込めません",
|
|
||||||
"unableToValidateWorkflow": "ワークフローを確認できません",
|
"unableToValidateWorkflow": "ワークフローを確認できません",
|
||||||
"unknownErrorValidatingWorkflow": "ワークフローの確認で不明なエラーが発生",
|
"unknownErrorValidatingWorkflow": "ワークフローの確認で不明なエラーが発生",
|
||||||
"clearWorkflowDesc2": "現在のワークフローは保存されていない変更があります.",
|
"clearWorkflowDesc2": "現在のワークフローは保存されていない変更があります.",
|
||||||
"showLegendNodes": "フィールドタイプの凡例を表示",
|
|
||||||
"unsupportedMismatchedUnion": "CollectionOrScalar型とベース型{{firstType}}および{{secondType}}が不一致です",
|
"unsupportedMismatchedUnion": "CollectionOrScalar型とベース型{{firstType}}および{{secondType}}が不一致です",
|
||||||
"updateApp": "アプリケーションをアップデート",
|
"updateApp": "アプリケーションをアップデート",
|
||||||
"noGraph": "グラフなし",
|
"noGraph": "グラフなし",
|
||||||
@@ -1241,10 +1173,8 @@
|
|||||||
"workflowDescription": "短い説明",
|
"workflowDescription": "短い説明",
|
||||||
"workflowValidation": "ワークフロー検証エラー",
|
"workflowValidation": "ワークフロー検証エラー",
|
||||||
"noOutputRecorded": "記録されたアウトプットがありません",
|
"noOutputRecorded": "記録されたアウトプットがありません",
|
||||||
"unknownTemplate": "不明なテンプレート",
|
|
||||||
"nodeOpacity": "ノードの不透明度",
|
"nodeOpacity": "ノードの不透明度",
|
||||||
"unableToParseFieldType": "フィールドタイプを解析できません",
|
"unableToParseFieldType": "フィールドタイプを解析できません"
|
||||||
"unknownInput": "不明な入力: {{name}}"
|
|
||||||
},
|
},
|
||||||
"boards": {
|
"boards": {
|
||||||
"autoAddBoard": "自動追加するボード",
|
"autoAddBoard": "自動追加するボード",
|
||||||
@@ -1268,7 +1198,6 @@
|
|||||||
"deleteBoardOnly": "ボードのみ削除",
|
"deleteBoardOnly": "ボードのみ削除",
|
||||||
"deletedBoardsCannotbeRestored": "削除したボードと画像は復元できません。「ボードのみ削除」を選択すると、画像は未分類の状態になります。",
|
"deletedBoardsCannotbeRestored": "削除したボードと画像は復元できません。「ボードのみ削除」を選択すると、画像は未分類の状態になります。",
|
||||||
"movingImagesToBoard_other": "{{count}} の画像をボードに移動:",
|
"movingImagesToBoard_other": "{{count}} の画像をボードに移動:",
|
||||||
"hideBoards": "ボードを隠す",
|
|
||||||
"assetsWithCount_other": "{{count}} のアセット",
|
"assetsWithCount_other": "{{count}} のアセット",
|
||||||
"addPrivateBoard": "プライベートボードを追加",
|
"addPrivateBoard": "プライベートボードを追加",
|
||||||
"addSharedBoard": "共有ボードを追加",
|
"addSharedBoard": "共有ボードを追加",
|
||||||
@@ -1283,10 +1212,8 @@
|
|||||||
"selectedForAutoAdd": "自動追加に選択済み",
|
"selectedForAutoAdd": "自動追加に選択済み",
|
||||||
"deletedPrivateBoardsCannotbeRestored": "削除されたボードと画像は復元できません。「ボードのみ削除」を選択すると、画像は作成者に対して非公開の未分類状態になります。",
|
"deletedPrivateBoardsCannotbeRestored": "削除されたボードと画像は復元できません。「ボードのみ削除」を選択すると、画像は作成者に対して非公開の未分類状態になります。",
|
||||||
"noBoards": "{{boardType}} ボードがありません",
|
"noBoards": "{{boardType}} ボードがありません",
|
||||||
"viewBoards": "ボードを表示",
|
|
||||||
"uncategorizedImages": "分類されていない画像",
|
"uncategorizedImages": "分類されていない画像",
|
||||||
"deleteAllUncategorizedImages": "分類されていないすべての画像を削除",
|
"deleteAllUncategorizedImages": "分類されていないすべての画像を削除"
|
||||||
"deletedImagesCannotBeRestored": "削除した画像は復元できません."
|
|
||||||
},
|
},
|
||||||
"invocationCache": {
|
"invocationCache": {
|
||||||
"invocationCache": "呼び出しキャッシュ",
|
"invocationCache": "呼び出しキャッシュ",
|
||||||
@@ -1758,9 +1685,7 @@
|
|||||||
"strength": "高解像修復の強度",
|
"strength": "高解像修復の強度",
|
||||||
"enabled": "高解像修復が有効"
|
"enabled": "高解像修復が有効"
|
||||||
},
|
},
|
||||||
"enableHrf": "高解像修復を有効",
|
"hrf": "高解像修復"
|
||||||
"hrf": "高解像修復",
|
|
||||||
"upscaleMethod": "アップスケール手法"
|
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"addPromptTrigger": "プロンプトトリガーを追加",
|
"addPromptTrigger": "プロンプトトリガーを追加",
|
||||||
@@ -1770,10 +1695,7 @@
|
|||||||
"expandCurrentPrompt": "現在のプロンプトを展開",
|
"expandCurrentPrompt": "現在のプロンプトを展開",
|
||||||
"uploadImageForPromptGeneration": "プロンプト生成用の画像をアップロードする",
|
"uploadImageForPromptGeneration": "プロンプト生成用の画像をアップロードする",
|
||||||
"expandingPrompt": "プロンプトを展開しています...",
|
"expandingPrompt": "プロンプトを展開しています...",
|
||||||
"resultTitle": "プロンプト拡張完了",
|
|
||||||
"resultSubtitle": "拡張プロンプトの処理方法を選択します:",
|
|
||||||
"replace": "交換する",
|
"replace": "交換する",
|
||||||
"insert": "挿入する",
|
|
||||||
"discard": "破棄する"
|
"discard": "破棄する"
|
||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
@@ -1783,7 +1705,6 @@
|
|||||||
"workflows": "ワークフロー",
|
"workflows": "ワークフロー",
|
||||||
"models": "モデル",
|
"models": "モデル",
|
||||||
"gallery": "ギャラリー",
|
"gallery": "ギャラリー",
|
||||||
"generation": "生成",
|
|
||||||
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
||||||
"modelsTab": "$t(ui.tabs.models) $t(common.tab)",
|
"modelsTab": "$t(ui.tabs.models) $t(common.tab)",
|
||||||
"upscaling": "アップスケーリング",
|
"upscaling": "アップスケーリング",
|
||||||
@@ -1840,11 +1761,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"controlLayers": {
|
"controlLayers": {
|
||||||
"globalReferenceImage_withCount_other": "全域参照画像",
|
|
||||||
"regionalReferenceImage": "領域参照画像",
|
"regionalReferenceImage": "領域参照画像",
|
||||||
"saveLayerToAssets": "レイヤーをアセットに保存",
|
"saveLayerToAssets": "レイヤーをアセットに保存",
|
||||||
"global": "全域",
|
"global": "全域",
|
||||||
"inpaintMasks_withCount_hidden": "インペイントマスク ({{count}} hidden)",
|
|
||||||
"opacity": "透明度",
|
"opacity": "透明度",
|
||||||
"canvasContextMenu": {
|
"canvasContextMenu": {
|
||||||
"newRegionalGuidance": "新規領域ガイダンス",
|
"newRegionalGuidance": "新規領域ガイダンス",
|
||||||
@@ -1896,7 +1815,6 @@
|
|||||||
"duplicate": "複製",
|
"duplicate": "複製",
|
||||||
"addLayer": "レイヤーを追加",
|
"addLayer": "レイヤーを追加",
|
||||||
"rasterLayer": "ラスターレイヤー",
|
"rasterLayer": "ラスターレイヤー",
|
||||||
"inpaintMasks_withCount_visible": "({{count}}) インペイントマスク",
|
|
||||||
"regional": "領域",
|
"regional": "領域",
|
||||||
"rectangle": "矩形",
|
"rectangle": "矩形",
|
||||||
"moveBackward": "背面へ移動",
|
"moveBackward": "背面へ移動",
|
||||||
@@ -2098,7 +2016,6 @@
|
|||||||
"autoNegative": "オートネガティブ",
|
"autoNegative": "オートネガティブ",
|
||||||
"enableAutoNegative": "オートネガティブを有効にする",
|
"enableAutoNegative": "オートネガティブを有効にする",
|
||||||
"disableAutoNegative": "オートネガティブを無効にする",
|
"disableAutoNegative": "オートネガティブを無効にする",
|
||||||
"deletePrompt": "プロンプトを削除",
|
|
||||||
"deleteReferenceImage": "参照画像を削除",
|
"deleteReferenceImage": "参照画像を削除",
|
||||||
"showHUD": "HUDを表示",
|
"showHUD": "HUDを表示",
|
||||||
"maskFill": "マスク塗りつぶし",
|
"maskFill": "マスク塗りつぶし",
|
||||||
@@ -2110,41 +2027,22 @@
|
|||||||
"addControlLayer": "$t(controlLayers.controlLayer)を追加します",
|
"addControlLayer": "$t(controlLayers.controlLayer)を追加します",
|
||||||
"addInpaintMask": "$t(controlLayers.inpaintMask)を追加します",
|
"addInpaintMask": "$t(controlLayers.inpaintMask)を追加します",
|
||||||
"addRegionalGuidance": "$t(controlLayers.regionalGuidance)を追加します",
|
"addRegionalGuidance": "$t(controlLayers.regionalGuidance)を追加します",
|
||||||
"addGlobalReferenceImage": "$t(controlLayers.globalReferenceImage)を追加します",
|
|
||||||
"addDenoiseLimit": "$t(controlLayers.denoiseLimit)を追加します",
|
"addDenoiseLimit": "$t(controlLayers.denoiseLimit)を追加します",
|
||||||
"controlLayer": "コントロールレイヤー",
|
"controlLayer": "コントロールレイヤー",
|
||||||
"inpaintMask": "インペイントマスク",
|
"inpaintMask": "インペイントマスク",
|
||||||
"referenceImageRegional": "参考画像(地域別)",
|
"referenceImageRegional": "参考画像(地域別)",
|
||||||
"referenceImageGlobal": "参考画像(グローバル)",
|
|
||||||
"asRasterLayer": "$t(controlLayers.rasterLayer) として",
|
"asRasterLayer": "$t(controlLayers.rasterLayer) として",
|
||||||
"asRasterLayerResize": "$t(controlLayers.rasterLayer) として (リサイズ)",
|
"asRasterLayerResize": "$t(controlLayers.rasterLayer) として (リサイズ)",
|
||||||
"asControlLayer": "$t(controlLayers.controlLayer) として",
|
"asControlLayer": "$t(controlLayers.controlLayer) として",
|
||||||
"asControlLayerResize": "$t(controlLayers.controlLayer) として (リサイズ)",
|
"asControlLayerResize": "$t(controlLayers.controlLayer) として (リサイズ)",
|
||||||
"referenceImage": "参照画像",
|
"referenceImage": "参照画像",
|
||||||
"sendingToCanvas": "キャンバスに生成をのせる",
|
|
||||||
"sendingToGallery": "生成をギャラリーに送る",
|
|
||||||
"sendToGallery": "ギャラリーに送る",
|
|
||||||
"sendToGalleryDesc": "Invokeを押すとユニークな画像が生成され、ギャラリーに保存されます。",
|
|
||||||
"sendToCanvas": "キャンバスに送る",
|
"sendToCanvas": "キャンバスに送る",
|
||||||
"newLayerFromImage": "画像から新規レイヤー",
|
"newLayerFromImage": "画像から新規レイヤー",
|
||||||
"newCanvasFromImage": "画像から新規キャンバス",
|
"newCanvasFromImage": "画像から新規キャンバス",
|
||||||
"newImg2ImgCanvasFromImage": "画像からの新規 Img2Img",
|
|
||||||
"copyToClipboard": "クリップボードにコピー",
|
"copyToClipboard": "クリップボードにコピー",
|
||||||
"sendToCanvasDesc": "Invokeを押すと、進行中の作品がキャンバス上にステージされます。",
|
|
||||||
"viewProgressInViewer": "<Btn>画像ビューア</Btn>で進行状況と出力を表示します。",
|
|
||||||
"viewProgressOnCanvas": "<Btn>キャンバス</Btn> で進行状況とステージ出力を表示します。",
|
|
||||||
"rasterLayer_withCount_other": "ラスターレイヤー",
|
"rasterLayer_withCount_other": "ラスターレイヤー",
|
||||||
"controlLayer_withCount_other": "コントロールレイヤー",
|
"controlLayer_withCount_other": "コントロールレイヤー",
|
||||||
"regionalGuidance_withCount_hidden": "地域ガイダンス({{count}} 件非表示)",
|
|
||||||
"controlLayers_withCount_hidden": "コントロールレイヤー({{count}} 個非表示)",
|
|
||||||
"rasterLayers_withCount_hidden": "ラスター レイヤー ({{count}} 個非表示)",
|
|
||||||
"globalReferenceImages_withCount_hidden": "グローバル参照画像({{count}} 枚非表示)",
|
|
||||||
"regionalGuidance_withCount_visible": "地域ガイダンス ({{count}})",
|
|
||||||
"controlLayers_withCount_visible": "コントロールレイヤー ({{count}})",
|
|
||||||
"rasterLayers_withCount_visible": "ラスターレイヤー({{count}})",
|
|
||||||
"globalReferenceImages_withCount_visible": "グローバル参照画像 ({{count}})",
|
|
||||||
"layer_other": "レイヤー",
|
"layer_other": "レイヤー",
|
||||||
"layer_withCount_other": "レイヤー ({{count}})",
|
|
||||||
"convertRasterLayerTo": "$t(controlLayers.rasterLayer) を変換する",
|
"convertRasterLayerTo": "$t(controlLayers.rasterLayer) を変換する",
|
||||||
"convertControlLayerTo": "$t(controlLayers.controlLayer) を変換する",
|
"convertControlLayerTo": "$t(controlLayers.controlLayer) を変換する",
|
||||||
"convertRegionalGuidanceTo": "$t(controlLayers.regionalGuidance) を変換する",
|
"convertRegionalGuidanceTo": "$t(controlLayers.regionalGuidance) を変換する",
|
||||||
@@ -2162,7 +2060,6 @@
|
|||||||
"pasteToBboxDesc": "新しいレイヤー(Bbox内)",
|
"pasteToBboxDesc": "新しいレイヤー(Bbox内)",
|
||||||
"pasteToCanvas": "キャンバス",
|
"pasteToCanvas": "キャンバス",
|
||||||
"pasteToCanvasDesc": "新しいレイヤー(キャンバス内)",
|
"pasteToCanvasDesc": "新しいレイヤー(キャンバス内)",
|
||||||
"pastedTo": "{{destination}} に貼り付けました",
|
|
||||||
"transparency": "透明性",
|
"transparency": "透明性",
|
||||||
"enableTransparencyEffect": "透明効果を有効にする",
|
"enableTransparencyEffect": "透明効果を有効にする",
|
||||||
"disableTransparencyEffect": "透明効果を無効にする",
|
"disableTransparencyEffect": "透明効果を無効にする",
|
||||||
@@ -2175,7 +2072,6 @@
|
|||||||
"locked": "ロックされています",
|
"locked": "ロックされています",
|
||||||
"unlocked": "ロック解除",
|
"unlocked": "ロック解除",
|
||||||
"deleteSelected": "選択項目を削除",
|
"deleteSelected": "選択項目を削除",
|
||||||
"stagingOnCanvas": "ステージング画像",
|
|
||||||
"replaceLayer": "レイヤーの置き換え",
|
"replaceLayer": "レイヤーの置き換え",
|
||||||
"pullBboxIntoLayer": "Bboxをレイヤーに引き込む",
|
"pullBboxIntoLayer": "Bboxをレイヤーに引き込む",
|
||||||
"pullBboxIntoReferenceImage": "Bboxを参照画像に取り込む",
|
"pullBboxIntoReferenceImage": "Bboxを参照画像に取り込む",
|
||||||
@@ -2183,17 +2079,11 @@
|
|||||||
"useImage": "画像を使う",
|
"useImage": "画像を使う",
|
||||||
"negativePrompt": "ネガティブプロンプト",
|
"negativePrompt": "ネガティブプロンプト",
|
||||||
"beginEndStepPercentShort": "開始/終了 %",
|
"beginEndStepPercentShort": "開始/終了 %",
|
||||||
"newGallerySession": "新しいギャラリーセッション",
|
|
||||||
"newGallerySessionDesc": "これにより、キャンバスとモデル選択以外のすべての設定がクリアされます。生成した画像はギャラリーに送信されます。",
|
|
||||||
"newCanvasSession": "新規キャンバスセッション",
|
|
||||||
"newCanvasSessionDesc": "これにより、キャンバスとモデル選択以外のすべての設定がクリアされます。生成はキャンバス上でステージングされます。",
|
|
||||||
"resetCanvasLayers": "キャンバスレイヤーをリセット",
|
"resetCanvasLayers": "キャンバスレイヤーをリセット",
|
||||||
"resetGenerationSettings": "生成設定をリセット",
|
"resetGenerationSettings": "生成設定をリセット",
|
||||||
"replaceCurrent": "現在のものを置き換える",
|
|
||||||
"controlLayerEmptyState": "<UploadButton>画像をアップロード</UploadButton>、<GalleryButton>ギャラリー</GalleryButton>からこのレイヤーに画像をドラッグ、<PullBboxButton>境界ボックスをこのレイヤーにプル</PullBboxButton>、またはキャンバスに描画して開始します。",
|
"controlLayerEmptyState": "<UploadButton>画像をアップロード</UploadButton>、<GalleryButton>ギャラリー</GalleryButton>からこのレイヤーに画像をドラッグ、<PullBboxButton>境界ボックスをこのレイヤーにプル</PullBboxButton>、またはキャンバスに描画して開始します。",
|
||||||
"referenceImageEmptyStateWithCanvasOptions": "開始するには、<UploadButton>画像をアップロード</UploadButton>するか、<GalleryButton>ギャラリー</GalleryButton>からこの参照画像に画像をドラッグするか、<PullBboxButton>境界ボックスをこの参照画像にプル</PullBboxButton>します。",
|
"referenceImageEmptyStateWithCanvasOptions": "開始するには、<UploadButton>画像をアップロード</UploadButton>するか、<GalleryButton>ギャラリー</GalleryButton>からこの参照画像に画像をドラッグするか、<PullBboxButton>境界ボックスをこの参照画像にプル</PullBboxButton>します。",
|
||||||
"referenceImageEmptyState": "開始するには、<UploadButton>画像をアップロード</UploadButton>するか、<GalleryButton>ギャラリー</GalleryButton>からこの参照画像に画像をドラッグします。",
|
"referenceImageEmptyState": "開始するには、<UploadButton>画像をアップロード</UploadButton>するか、<GalleryButton>ギャラリー</GalleryButton>からこの参照画像に画像をドラッグします。",
|
||||||
"uploadOrDragAnImage": "ギャラリーから画像をドラッグするか、<UploadButton>画像をアップロード</UploadButton>します。",
|
|
||||||
"imageNoise": "画像ノイズ",
|
"imageNoise": "画像ノイズ",
|
||||||
"denoiseLimit": "ノイズ除去制限",
|
"denoiseLimit": "ノイズ除去制限",
|
||||||
"warnings": {
|
"warnings": {
|
||||||
@@ -2259,9 +2149,6 @@
|
|||||||
"saveAs": "名前を付けて保存",
|
"saveAs": "名前を付けて保存",
|
||||||
"cancel": "キャンセル",
|
"cancel": "キャンセル",
|
||||||
"process": "プロセス",
|
"process": "プロセス",
|
||||||
"help1": "ターゲットオブジェクトを1つ選択します。<Bold>含める</Bold>ポイントと<Bold>除外</Bold>ポイントを追加して、レイヤーのどの部分がターゲットオブジェクトの一部であるかを示します。",
|
|
||||||
"help2": "対象オブジェクト内に<Bold>含める</Bold>ポイントを1つ選択するところから始めます。ポイントを追加して選択範囲を絞り込みます。ポイントが少ないほど、通常はより良い結果が得られます。",
|
|
||||||
"help3": "選択を反転して、ターゲットオブジェクト以外のすべてを選択します。",
|
|
||||||
"clickToAdd": "レイヤーをクリックしてポイントを追加します",
|
"clickToAdd": "レイヤーをクリックしてポイントを追加します",
|
||||||
"dragToMove": "ポイントをドラッグして移動します",
|
"dragToMove": "ポイントをドラッグして移動します",
|
||||||
"clickToRemove": "ポイントをクリックして削除します"
|
"clickToRemove": "ポイントをクリックして削除します"
|
||||||
@@ -2362,12 +2249,8 @@
|
|||||||
"loading": "ロード中...",
|
"loading": "ロード中...",
|
||||||
"steps": "ステップ",
|
"steps": "ステップ",
|
||||||
"refiner": "Refiner",
|
"refiner": "Refiner",
|
||||||
"negStylePrompt": "ネガティブスタイルプロンプト",
|
|
||||||
"noModelsAvailable": "利用できるモデルがありません",
|
"noModelsAvailable": "利用できるモデルがありません",
|
||||||
"posStylePrompt": "ポジティブスタイルプロンプト",
|
|
||||||
"cfgScale": "CFGスケール",
|
"cfgScale": "CFGスケール",
|
||||||
"concatPromptStyle": "リンキングプロンプトとスタイル",
|
|
||||||
"freePromptStyle": "手動スタイルプロンプト",
|
|
||||||
"posAestheticScore": "ポジティブ美的スコア",
|
"posAestheticScore": "ポジティブ美的スコア",
|
||||||
"refinerSteps": "リファイナーステップ",
|
"refinerSteps": "リファイナーステップ",
|
||||||
"refinerStart": "リファイナースタート",
|
"refinerStart": "リファイナースタート",
|
||||||
@@ -2385,8 +2268,6 @@
|
|||||||
"name": "名前",
|
"name": "名前",
|
||||||
"descending": "降順",
|
"descending": "降順",
|
||||||
"searchPlaceholder": "名前、説明、タグで検索",
|
"searchPlaceholder": "名前、説明、タグで検索",
|
||||||
"projectWorkflows": "プロジェクトワークフロー",
|
|
||||||
"searchWorkflows": "ワークフローを検索",
|
|
||||||
"updated": "アップデート",
|
"updated": "アップデート",
|
||||||
"published": "公表",
|
"published": "公表",
|
||||||
"builder": {
|
"builder": {
|
||||||
@@ -2412,10 +2293,8 @@
|
|||||||
"addToForm": "フォームに追加",
|
"addToForm": "フォームに追加",
|
||||||
"headingPlaceholder": "空の見出し",
|
"headingPlaceholder": "空の見出し",
|
||||||
"nodeFieldTooltip": "ノード フィールドを追加するには、ワークフロー エディターのフィールドにある小さなプラス記号ボタンをクリックするか、フィールド名をフォームにドラッグします。",
|
"nodeFieldTooltip": "ノード フィールドを追加するには、ワークフロー エディターのフィールドにある小さなプラス記号ボタンをクリックするか、フィールド名をフォームにドラッグします。",
|
||||||
"workflowBuilderAlphaWarning": "ワークフロービルダーは現在アルファ版です。安定版リリースまでに互換性に影響する変更が発生する可能性があります。",
|
|
||||||
"component": "コンポーネント",
|
"component": "コンポーネント",
|
||||||
"textPlaceholder": "空のテキスト",
|
"textPlaceholder": "空のテキスト",
|
||||||
"emptyRootPlaceholderViewMode": "このワークフローのフォームの作成を開始するには、[編集] をクリックします。",
|
|
||||||
"addOption": "オプションを追加",
|
"addOption": "オプションを追加",
|
||||||
"singleLine": "単線",
|
"singleLine": "単線",
|
||||||
"numberInput": "数値入力",
|
"numberInput": "数値入力",
|
||||||
@@ -2466,20 +2345,15 @@
|
|||||||
"convertGraph": "グラフを変換",
|
"convertGraph": "グラフを変換",
|
||||||
"downloadWorkflow": "ファイルに保存",
|
"downloadWorkflow": "ファイルに保存",
|
||||||
"saveWorkflow": "ワークフローを保存",
|
"saveWorkflow": "ワークフローを保存",
|
||||||
"userWorkflows": "ユーザーワークフロー",
|
|
||||||
"yourWorkflows": "あなたのワークフロー",
|
"yourWorkflows": "あなたのワークフロー",
|
||||||
"edit": "編集",
|
"edit": "編集",
|
||||||
"workflowLibrary": "ワークフローライブラリ",
|
"workflowLibrary": "ワークフローライブラリ",
|
||||||
"workflowSaved": "ワークフローが保存されました",
|
"workflowSaved": "ワークフローが保存されました",
|
||||||
"clearWorkflowSearchFilter": "ワークフロー検索フィルタをクリア",
|
|
||||||
"workflowCleared": "ワークフローが作成されました",
|
"workflowCleared": "ワークフローが作成されました",
|
||||||
"autoLayout": "オートレイアウト",
|
"autoLayout": "オートレイアウト",
|
||||||
"view": "ビュー",
|
"view": "ビュー",
|
||||||
"saveChanges": "変更を保存",
|
"saveChanges": "変更を保存",
|
||||||
"noDescription": "説明なし",
|
|
||||||
"recommended": "あなたへのおすすめ",
|
"recommended": "あなたへのおすすめ",
|
||||||
"noRecentWorkflows": "最近のワークフローがありません",
|
|
||||||
"problemLoading": "ワークフローのローディングに関する問題",
|
|
||||||
"newWorkflowCreated": "新しいワークフローが作成されました",
|
"newWorkflowCreated": "新しいワークフローが作成されました",
|
||||||
"noWorkflows": "ワークフローがありません",
|
"noWorkflows": "ワークフローがありません",
|
||||||
"copyShareLink": "共有リンクをコピー",
|
"copyShareLink": "共有リンクをコピー",
|
||||||
@@ -2487,21 +2361,16 @@
|
|||||||
"workflowThumbnail": "ワークフローサムネイル",
|
"workflowThumbnail": "ワークフローサムネイル",
|
||||||
"loadWorkflow": "$t(common.load) ワークフロー",
|
"loadWorkflow": "$t(common.load) ワークフロー",
|
||||||
"shared": "共有",
|
"shared": "共有",
|
||||||
"openWorkflow": "ワークフローを開く",
|
|
||||||
"emptyStringPlaceholder": "<空の文字列>",
|
"emptyStringPlaceholder": "<空の文字列>",
|
||||||
"browseWorkflows": "ワークフローを閲覧する",
|
"browseWorkflows": "ワークフローを閲覧する",
|
||||||
"saveWorkflowAs": "ワークフローとして保存",
|
"saveWorkflowAs": "ワークフローとして保存",
|
||||||
"private": "プライベート",
|
"private": "プライベート",
|
||||||
"deselectAll": "すべて選択解除",
|
"deselectAll": "すべて選択解除",
|
||||||
"delete": "削除",
|
"delete": "削除",
|
||||||
"openLibrary": "ライブラリを開く",
|
|
||||||
"loadMore": "もっと読み込む",
|
"loadMore": "もっと読み込む",
|
||||||
"saveWorkflowToProject": "ワークフローをプロジェクトに保存",
|
"saveWorkflowToProject": "ワークフローをプロジェクトに保存",
|
||||||
"created": "作成されました",
|
"created": "作成されました",
|
||||||
"workflowEditorMenu": "ワークフローエディターメニュー",
|
"workflowEditorMenu": "ワークフローエディターメニュー",
|
||||||
"defaultWorkflows": "デフォルトワークフロー",
|
|
||||||
"allLoaded": "すべてのワークフローが読み込まれました",
|
|
||||||
"filterByTags": "タグでフィルター",
|
|
||||||
"recentlyOpened": "最近開いた",
|
"recentlyOpened": "最近開いた",
|
||||||
"opened": "オープン",
|
"opened": "オープン",
|
||||||
"deleteWorkflow": "ワークフローを削除",
|
"deleteWorkflow": "ワークフローを削除",
|
||||||
@@ -2547,7 +2416,6 @@
|
|||||||
"perIterationDesc": "それぞれのいてレーションに別のシードを使う"
|
"perIterationDesc": "それぞれのいてレーションに別のシードを使う"
|
||||||
},
|
},
|
||||||
"showDynamicPrompts": "ダイナミックプロンプトを表示する",
|
"showDynamicPrompts": "ダイナミックプロンプトを表示する",
|
||||||
"promptsToGenerate": "生成するプロンプト",
|
|
||||||
"dynamicPrompts": "ダイナミックプロンプト",
|
"dynamicPrompts": "ダイナミックプロンプト",
|
||||||
"loading": "ダイナミックプロンプトを生成...",
|
"loading": "ダイナミックプロンプトを生成...",
|
||||||
"maxPrompts": "最大プロンプト"
|
"maxPrompts": "最大プロンプト"
|
||||||
@@ -2573,8 +2441,7 @@
|
|||||||
"キャンバス: SDXL のアスペクト比がスマートになり、スクロールによるズームが改善されました。"
|
"キャンバス: SDXL のアスペクト比がスマートになり、スクロールによるズームが改善されました。"
|
||||||
],
|
],
|
||||||
"readReleaseNotes": "リリースノートを読む",
|
"readReleaseNotes": "リリースノートを読む",
|
||||||
"watchRecentReleaseVideos": "最近のリリースビデオを見る",
|
"watchRecentReleaseVideos": "最近のリリースビデオを見る"
|
||||||
"watchUiUpdatesOverview": "Watch UI アップデートの概要"
|
|
||||||
},
|
},
|
||||||
"supportVideos": {
|
"supportVideos": {
|
||||||
"supportVideos": "サポートビデオ",
|
"supportVideos": "サポートビデオ",
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
"save": "저장",
|
"save": "저장",
|
||||||
"created": "생성됨",
|
"created": "생성됨",
|
||||||
"error": "에러",
|
"error": "에러",
|
||||||
"prevPage": "이전 페이지",
|
|
||||||
"ipAdapter": "IP 어댑터",
|
"ipAdapter": "IP 어댑터",
|
||||||
"installed": "설치됨",
|
"installed": "설치됨",
|
||||||
"accept": "수락",
|
"accept": "수락",
|
||||||
@@ -42,7 +41,6 @@
|
|||||||
"outputs": "결과물",
|
"outputs": "결과물",
|
||||||
"unknownError": "알려지지 않은 에러",
|
"unknownError": "알려지지 않은 에러",
|
||||||
"linear": "선형",
|
"linear": "선형",
|
||||||
"imageFailedToLoad": "이미지를 로드할 수 없음",
|
|
||||||
"direction": "방향",
|
"direction": "방향",
|
||||||
"data": "데이터",
|
"data": "데이터",
|
||||||
"somethingWentWrong": "뭔가 잘못됐어요",
|
"somethingWentWrong": "뭔가 잘못됐어요",
|
||||||
@@ -52,7 +50,6 @@
|
|||||||
"orderBy": "정렬 기준",
|
"orderBy": "정렬 기준",
|
||||||
"copyError": "$t(gallery.copy) 에러",
|
"copyError": "$t(gallery.copy) 에러",
|
||||||
"learnMore": "더 알아보기",
|
"learnMore": "더 알아보기",
|
||||||
"nextPage": "다음 페이지",
|
|
||||||
"saveAs": "다른 이름으로 저장",
|
"saveAs": "다른 이름으로 저장",
|
||||||
"loading": "불러오는 중",
|
"loading": "불러오는 중",
|
||||||
"random": "랜덤",
|
"random": "랜덤",
|
||||||
@@ -60,18 +57,15 @@
|
|||||||
"postprocessing": "후처리",
|
"postprocessing": "후처리",
|
||||||
"advanced": "고급",
|
"advanced": "고급",
|
||||||
"input": "입력",
|
"input": "입력",
|
||||||
"details": "세부사항",
|
"details": "세부사항"
|
||||||
"notInstalled": "설치되지 않음"
|
|
||||||
},
|
},
|
||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "이미지 크기",
|
"galleryImageSize": "이미지 크기",
|
||||||
"gallerySettings": "갤러리 설정",
|
"gallerySettings": "갤러리 설정",
|
||||||
"deleteSelection": "선택 항목 삭제",
|
"deleteSelection": "선택 항목 삭제",
|
||||||
"featuresWillReset": "이 이미지를 삭제하면 해당 기능이 즉시 재설정됩니다.",
|
"featuresWillReset": "이 이미지를 삭제하면 해당 기능이 즉시 재설정됩니다.",
|
||||||
"noImagesInGallery": "보여줄 이미지가 없음",
|
|
||||||
"autoSwitchNewImages": "새로운 이미지로 자동 전환",
|
"autoSwitchNewImages": "새로운 이미지로 자동 전환",
|
||||||
"loading": "불러오는 중",
|
"loading": "불러오는 중",
|
||||||
"unableToLoad": "갤러리를 로드할 수 없음",
|
|
||||||
"image": "이미지",
|
"image": "이미지",
|
||||||
"drop": "드랍",
|
"drop": "드랍",
|
||||||
"downloadSelection": "선택 항목 다운로드",
|
"downloadSelection": "선택 항목 다운로드",
|
||||||
@@ -151,8 +145,6 @@
|
|||||||
"loadWorkflow": "Workflow 불러오기",
|
"loadWorkflow": "Workflow 불러오기",
|
||||||
"noOutputRecorded": "기록된 출력 없음",
|
"noOutputRecorded": "기록된 출력 없음",
|
||||||
"colorCodeEdgesHelp": "연결된 필드에 따른 색상 코드 선",
|
"colorCodeEdgesHelp": "연결된 필드에 따른 색상 코드 선",
|
||||||
"hideLegendNodes": "필드 유형 범례 숨기기",
|
|
||||||
"addLinearView": "Linear View에 추가",
|
|
||||||
"float": "실수",
|
"float": "실수",
|
||||||
"targetNodeFieldDoesNotExist": "잘못된 모서리: 대상/입력 필드 {{node}}. {{field}}이(가) 없습니다",
|
"targetNodeFieldDoesNotExist": "잘못된 모서리: 대상/입력 필드 {{node}}. {{field}}이(가) 없습니다",
|
||||||
"animatedEdges": "애니메이션 모서리",
|
"animatedEdges": "애니메이션 모서리",
|
||||||
@@ -160,7 +152,6 @@
|
|||||||
"nodeTemplate": "노드 템플릿",
|
"nodeTemplate": "노드 템플릿",
|
||||||
"nodeOpacity": "노드 불투명도",
|
"nodeOpacity": "노드 불투명도",
|
||||||
"sourceNodeDoesNotExist": "잘못된 모서리: 소스/출력 노드 {{node}}이(가) 없습니다",
|
"sourceNodeDoesNotExist": "잘못된 모서리: 소스/출력 노드 {{node}}이(가) 없습니다",
|
||||||
"noFieldsLinearview": "Linear View에 추가된 필드 없음",
|
|
||||||
"nodeSearch": "노드 검색",
|
"nodeSearch": "노드 검색",
|
||||||
"inputMayOnlyHaveOneConnection": "입력에 하나의 연결만 있을 수 있습니다",
|
"inputMayOnlyHaveOneConnection": "입력에 하나의 연결만 있을 수 있습니다",
|
||||||
"notes": "메모",
|
"notes": "메모",
|
||||||
@@ -195,7 +186,6 @@
|
|||||||
"notesDescription": "Workflow에 대한 메모 추가",
|
"notesDescription": "Workflow에 대한 메모 추가",
|
||||||
"colorCodeEdges": "색상-코드 선",
|
"colorCodeEdges": "색상-코드 선",
|
||||||
"targetNodeDoesNotExist": "잘못된 모서리: 대상/입력 노드 {{node}}이(가) 없습니다",
|
"targetNodeDoesNotExist": "잘못된 모서리: 대상/입력 노드 {{node}}이(가) 없습니다",
|
||||||
"mismatchedVersion": "잘못된 노드: {{type}} 유형의 {{node}} 노드에 일치하지 않는 버전이 있습니다(업데이트 해보시겠습니까?)",
|
|
||||||
"addNodeToolTip": "노드 추가(Shift+A, Space)",
|
"addNodeToolTip": "노드 추가(Shift+A, Space)",
|
||||||
"collectionOrScalarFieldType": "{{name}} 컬렉션|Scalar",
|
"collectionOrScalarFieldType": "{{name}} 컬렉션|Scalar",
|
||||||
"nodeVersion": "노드 버전",
|
"nodeVersion": "노드 버전",
|
||||||
@@ -242,7 +232,6 @@
|
|||||||
"next": "다음",
|
"next": "다음",
|
||||||
"cancelBatch": "Batch 취소",
|
"cancelBatch": "Batch 취소",
|
||||||
"back": "back",
|
"back": "back",
|
||||||
"batchFieldValues": "Batch 필드 값들",
|
|
||||||
"cancel": "취소",
|
"cancel": "취소",
|
||||||
"session": "세션",
|
"session": "세션",
|
||||||
"time": "시간",
|
"time": "시간",
|
||||||
@@ -296,8 +285,6 @@
|
|||||||
"cacheSize": "캐시 크기"
|
"cacheSize": "캐시 크기"
|
||||||
},
|
},
|
||||||
"hrf": {
|
"hrf": {
|
||||||
"enableHrf": "이용 가능한 고해상도 고정",
|
|
||||||
"upscaleMethod": "업스케일 방법",
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"strength": "고해상도 고정 강도",
|
"strength": "고해상도 고정 강도",
|
||||||
"enabled": "고해상도 고정 사용",
|
"enabled": "고해상도 고정 사용",
|
||||||
@@ -308,12 +295,10 @@
|
|||||||
"models": {
|
"models": {
|
||||||
"noMatchingModels": "일치하는 모델 없음",
|
"noMatchingModels": "일치하는 모델 없음",
|
||||||
"loading": "로딩중",
|
"loading": "로딩중",
|
||||||
"noMatchingLoRAs": "일치하는 LoRA 없음",
|
|
||||||
"noModelsAvailable": "사용 가능한 모델이 없음",
|
"noModelsAvailable": "사용 가능한 모델이 없음",
|
||||||
"addLora": "LoRA 추가",
|
"addLora": "LoRA 추가",
|
||||||
"selectModel": "모델 선택",
|
"selectModel": "모델 선택",
|
||||||
"noRefinerModelsInstalled": "SDXL Refiner 모델이 설치되지 않음",
|
"noRefinerModelsInstalled": "SDXL Refiner 모델이 설치되지 않음"
|
||||||
"noLoRAsInstalled": "설치된 LoRA 없음"
|
|
||||||
},
|
},
|
||||||
"boards": {
|
"boards": {
|
||||||
"autoAddBoard": "자동 추가 Board",
|
"autoAddBoard": "자동 추가 Board",
|
||||||
|
|||||||
@@ -30,12 +30,10 @@
|
|||||||
"ipAdapter": "IP-adapter",
|
"ipAdapter": "IP-adapter",
|
||||||
"auto": "Autom.",
|
"auto": "Autom.",
|
||||||
"controlNet": "ControlNet",
|
"controlNet": "ControlNet",
|
||||||
"imageFailedToLoad": "Kan afbeelding niet laden",
|
|
||||||
"learnMore": "Meer informatie",
|
"learnMore": "Meer informatie",
|
||||||
"advanced": "Uitgebreid",
|
"advanced": "Uitgebreid",
|
||||||
"file": "Bestand",
|
"file": "Bestand",
|
||||||
"installed": "Geïnstalleerd",
|
"installed": "Geïnstalleerd",
|
||||||
"notInstalled": "Niet $t(common.installed)",
|
|
||||||
"simple": "Eenvoudig",
|
"simple": "Eenvoudig",
|
||||||
"somethingWentWrong": "Er ging iets mis",
|
"somethingWentWrong": "Er ging iets mis",
|
||||||
"add": "Voeg toe",
|
"add": "Voeg toe",
|
||||||
@@ -43,14 +41,12 @@
|
|||||||
"details": "Details",
|
"details": "Details",
|
||||||
"outputs": "Uitvoeren",
|
"outputs": "Uitvoeren",
|
||||||
"save": "Bewaar",
|
"save": "Bewaar",
|
||||||
"nextPage": "Volgende pagina",
|
|
||||||
"blue": "Blauw",
|
"blue": "Blauw",
|
||||||
"alpha": "Alfa",
|
"alpha": "Alfa",
|
||||||
"red": "Rood",
|
"red": "Rood",
|
||||||
"editor": "Editor",
|
"editor": "Editor",
|
||||||
"folder": "Map",
|
"folder": "Map",
|
||||||
"format": "structuur",
|
"format": "structuur",
|
||||||
"goTo": "Ga naar",
|
|
||||||
"template": "Sjabloon",
|
"template": "Sjabloon",
|
||||||
"input": "Invoer",
|
"input": "Invoer",
|
||||||
"safetensors": "Safetensors",
|
"safetensors": "Safetensors",
|
||||||
@@ -62,7 +58,6 @@
|
|||||||
"negativePrompt": "Negatieve prompt",
|
"negativePrompt": "Negatieve prompt",
|
||||||
"selected": "Geselecteerd",
|
"selected": "Geselecteerd",
|
||||||
"orderBy": "Sorteer op",
|
"orderBy": "Sorteer op",
|
||||||
"prevPage": "Vorige pagina",
|
|
||||||
"beta": "Bèta",
|
"beta": "Bèta",
|
||||||
"copyError": "$t(gallery.copy) Fout",
|
"copyError": "$t(gallery.copy) Fout",
|
||||||
"toResolve": "Op te lossen",
|
"toResolve": "Op te lossen",
|
||||||
@@ -79,21 +74,18 @@
|
|||||||
"delete": "Verwijder",
|
"delete": "Verwijder",
|
||||||
"direction": "Richting",
|
"direction": "Richting",
|
||||||
"error": "Fout",
|
"error": "Fout",
|
||||||
"localSystem": "Lokaal systeem",
|
|
||||||
"unknownError": "Onbekende fout"
|
"unknownError": "Onbekende fout"
|
||||||
},
|
},
|
||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "Afbeeldingsgrootte",
|
"galleryImageSize": "Afbeeldingsgrootte",
|
||||||
"gallerySettings": "Instellingen galerij",
|
"gallerySettings": "Instellingen galerij",
|
||||||
"autoSwitchNewImages": "Wissel autom. naar nieuwe afbeeldingen",
|
"autoSwitchNewImages": "Wissel autom. naar nieuwe afbeeldingen",
|
||||||
"noImagesInGallery": "Geen afbeeldingen om te tonen",
|
|
||||||
"deleteImage_one": "Verwijder afbeelding",
|
"deleteImage_one": "Verwijder afbeelding",
|
||||||
"deleteImage_other": "",
|
"deleteImage_other": "",
|
||||||
"deleteImagePermanent": "Verwijderde afbeeldingen kunnen niet worden hersteld.",
|
"deleteImagePermanent": "Verwijderde afbeeldingen kunnen niet worden hersteld.",
|
||||||
"autoAssignBoardOnClick": "Ken automatisch bord toe bij klikken",
|
"autoAssignBoardOnClick": "Ken automatisch bord toe bij klikken",
|
||||||
"featuresWillReset": "Als je deze afbeelding verwijdert, dan worden deze functies onmiddellijk teruggezet.",
|
"featuresWillReset": "Als je deze afbeelding verwijdert, dan worden deze functies onmiddellijk teruggezet.",
|
||||||
"loading": "Bezig met laden",
|
"loading": "Bezig met laden",
|
||||||
"unableToLoad": "Kan galerij niet laden",
|
|
||||||
"downloadSelection": "Download selectie",
|
"downloadSelection": "Download selectie",
|
||||||
"currentlyInUse": "Deze afbeelding is momenteel in gebruik door de volgende functies:",
|
"currentlyInUse": "Deze afbeelding is momenteel in gebruik door de volgende functies:",
|
||||||
"copy": "Kopieer",
|
"copy": "Kopieer",
|
||||||
@@ -199,12 +191,10 @@
|
|||||||
"scaledHeight": "Geschaalde H",
|
"scaledHeight": "Geschaalde H",
|
||||||
"infillMethod": "Infill-methode",
|
"infillMethod": "Infill-methode",
|
||||||
"tileSize": "Grootte tegel",
|
"tileSize": "Grootte tegel",
|
||||||
"downloadImage": "Download afbeelding",
|
|
||||||
"usePrompt": "Hergebruik invoertekst",
|
"usePrompt": "Hergebruik invoertekst",
|
||||||
"useSeed": "Hergebruik seed",
|
"useSeed": "Hergebruik seed",
|
||||||
"useAll": "Hergebruik alles",
|
"useAll": "Hergebruik alles",
|
||||||
"info": "Info",
|
"info": "Info",
|
||||||
"showOptionsPanel": "Toon deelscherm Opties (O of T)",
|
|
||||||
"symmetry": "Symmetrie",
|
"symmetry": "Symmetrie",
|
||||||
"cancel": {
|
"cancel": {
|
||||||
"cancel": "Annuleer"
|
"cancel": "Annuleer"
|
||||||
@@ -293,15 +283,12 @@
|
|||||||
"baseModelChangedCleared_one": "Basismodel is gewijzigd: {{count}} niet-compatibel submodel weggehaald of uitgeschakeld",
|
"baseModelChangedCleared_one": "Basismodel is gewijzigd: {{count}} niet-compatibel submodel weggehaald of uitgeschakeld",
|
||||||
"baseModelChangedCleared_other": "Basismodel is gewijzigd: {{count}} niet-compatibele submodellen weggehaald of uitgeschakeld",
|
"baseModelChangedCleared_other": "Basismodel is gewijzigd: {{count}} niet-compatibele submodellen weggehaald of uitgeschakeld",
|
||||||
"loadedWithWarnings": "Werkstroom geladen met waarschuwingen",
|
"loadedWithWarnings": "Werkstroom geladen met waarschuwingen",
|
||||||
"setControlImage": "Ingesteld als controle-afbeelding",
|
|
||||||
"setNodeField": "Ingesteld als knooppuntveld",
|
|
||||||
"imageUploaded": "Afbeelding geüpload",
|
"imageUploaded": "Afbeelding geüpload",
|
||||||
"addedToBoard": "Toegevoegd aan bord",
|
"addedToBoard": "Toegevoegd aan bord",
|
||||||
"workflowLoaded": "Werkstroom geladen",
|
"workflowLoaded": "Werkstroom geladen",
|
||||||
"modelAddedSimple": "Model toegevoegd aan wachtrij",
|
"modelAddedSimple": "Model toegevoegd aan wachtrij",
|
||||||
"imageUploadFailed": "Fout bij uploaden afbeelding",
|
"imageUploadFailed": "Fout bij uploaden afbeelding",
|
||||||
"workflowDeleted": "Werkstroom verwijderd",
|
"workflowDeleted": "Werkstroom verwijderd",
|
||||||
"invalidUpload": "Ongeldige upload",
|
|
||||||
"problemRetrievingWorkflow": "Fout bij ophalen van werkstroom",
|
"problemRetrievingWorkflow": "Fout bij ophalen van werkstroom",
|
||||||
"parameters": "Parameters",
|
"parameters": "Parameters",
|
||||||
"modelImportCanceled": "Importeren model geannuleerd",
|
"modelImportCanceled": "Importeren model geannuleerd",
|
||||||
@@ -325,17 +312,14 @@
|
|||||||
"zoomOutNodes": "Uitzoomen",
|
"zoomOutNodes": "Uitzoomen",
|
||||||
"fitViewportNodes": "Aanpassen aan beeld",
|
"fitViewportNodes": "Aanpassen aan beeld",
|
||||||
"hideMinimapnodes": "Minimap verbergen",
|
"hideMinimapnodes": "Minimap verbergen",
|
||||||
"showLegendNodes": "Typelegende veld tonen",
|
|
||||||
"zoomInNodes": "Inzoomen",
|
"zoomInNodes": "Inzoomen",
|
||||||
"showMinimapnodes": "Minimap tonen",
|
"showMinimapnodes": "Minimap tonen",
|
||||||
"hideLegendNodes": "Typelegende veld verbergen",
|
|
||||||
"reloadNodeTemplates": "Herlaad knooppuntsjablonen",
|
"reloadNodeTemplates": "Herlaad knooppuntsjablonen",
|
||||||
"loadWorkflow": "Laad werkstroom",
|
"loadWorkflow": "Laad werkstroom",
|
||||||
"downloadWorkflow": "Download JSON van werkstroom",
|
"downloadWorkflow": "Download JSON van werkstroom",
|
||||||
"scheduler": "Planner",
|
"scheduler": "Planner",
|
||||||
"missingTemplate": "Ongeldig knooppunt: knooppunt {{node}} van het soort {{type}} heeft een ontbrekend sjabloon (niet geïnstalleerd?)",
|
"missingTemplate": "Ongeldig knooppunt: knooppunt {{node}} van het soort {{type}} heeft een ontbrekend sjabloon (niet geïnstalleerd?)",
|
||||||
"workflowDescription": "Korte beschrijving",
|
"workflowDescription": "Korte beschrijving",
|
||||||
"versionUnknown": " Versie onbekend",
|
|
||||||
"noNodeSelected": "Geen knooppunt gekozen",
|
"noNodeSelected": "Geen knooppunt gekozen",
|
||||||
"addNode": "Voeg knooppunt toe",
|
"addNode": "Voeg knooppunt toe",
|
||||||
"unableToValidateWorkflow": "Kan werkstroom niet valideren",
|
"unableToValidateWorkflow": "Kan werkstroom niet valideren",
|
||||||
@@ -349,9 +333,7 @@
|
|||||||
"integer": "Geheel getal",
|
"integer": "Geheel getal",
|
||||||
"nodeTemplate": "Sjabloon knooppunt",
|
"nodeTemplate": "Sjabloon knooppunt",
|
||||||
"nodeOpacity": "Dekking knooppunt",
|
"nodeOpacity": "Dekking knooppunt",
|
||||||
"unableToLoadWorkflow": "Fout bij laden werkstroom",
|
|
||||||
"snapToGrid": "Lijn uit op raster",
|
"snapToGrid": "Lijn uit op raster",
|
||||||
"noFieldsLinearview": "Geen velden toegevoegd aan lineaire weergave",
|
|
||||||
"nodeSearch": "Zoek naar knooppunten",
|
"nodeSearch": "Zoek naar knooppunten",
|
||||||
"updateNode": "Werk knooppunt bij",
|
"updateNode": "Werk knooppunt bij",
|
||||||
"version": "Versie",
|
"version": "Versie",
|
||||||
@@ -370,9 +352,7 @@
|
|||||||
"edge": "Rand",
|
"edge": "Rand",
|
||||||
"animatedEdgesHelp": "Animeer gekozen randen en randen verbonden met de gekozen knooppunten",
|
"animatedEdgesHelp": "Animeer gekozen randen en randen verbonden met de gekozen knooppunten",
|
||||||
"cannotDuplicateConnection": "Kan geen dubbele verbindingen maken",
|
"cannotDuplicateConnection": "Kan geen dubbele verbindingen maken",
|
||||||
"unknownTemplate": "Onbekend sjabloon",
|
|
||||||
"noWorkflow": "Geen werkstroom",
|
"noWorkflow": "Geen werkstroom",
|
||||||
"removeLinearView": "Verwijder uit lineaire weergave",
|
|
||||||
"workflowTags": "Labels",
|
"workflowTags": "Labels",
|
||||||
"fullyContainNodesHelp": "Knooppunten moeten zich volledig binnen het keuzevak bevinden om te worden gekozen",
|
"fullyContainNodesHelp": "Knooppunten moeten zich volledig binnen het keuzevak bevinden om te worden gekozen",
|
||||||
"workflowValidation": "Validatiefout werkstroom",
|
"workflowValidation": "Validatiefout werkstroom",
|
||||||
@@ -397,14 +377,11 @@
|
|||||||
"unknownField": "Onbekend veld",
|
"unknownField": "Onbekend veld",
|
||||||
"colorCodeEdges": "Kleurgecodeerde randen",
|
"colorCodeEdges": "Kleurgecodeerde randen",
|
||||||
"unknownNode": "Onbekend knooppunt",
|
"unknownNode": "Onbekend knooppunt",
|
||||||
"mismatchedVersion": "Ongeldig knooppunt: knooppunt {{node}} van het soort {{type}} heeft een niet-overeenkomende versie (probeer het bij te werken?)",
|
|
||||||
"addNodeToolTip": "Voeg knooppunt toe (Shift+A, spatie)",
|
"addNodeToolTip": "Voeg knooppunt toe (Shift+A, spatie)",
|
||||||
"loadingNodes": "Bezig met laden van knooppunten...",
|
"loadingNodes": "Bezig met laden van knooppunten...",
|
||||||
"snapToGridHelp": "Lijn knooppunten uit op raster bij verplaatsing",
|
"snapToGridHelp": "Lijn knooppunten uit op raster bij verplaatsing",
|
||||||
"workflowSettings": "Instellingen werkstroomeditor",
|
"workflowSettings": "Instellingen werkstroomeditor",
|
||||||
"addLinearView": "Voeg toe aan lineaire weergave",
|
|
||||||
"nodePack": "Knooppuntpakket",
|
"nodePack": "Knooppuntpakket",
|
||||||
"unknownInput": "Onbekende invoer: {{name}}",
|
|
||||||
"sourceNodeFieldDoesNotExist": "Ongeldige rand: bron-/uitvoerveld {{node}}.{{field}} bestaat niet",
|
"sourceNodeFieldDoesNotExist": "Ongeldige rand: bron-/uitvoerveld {{node}}.{{field}} bestaat niet",
|
||||||
"collectionFieldType": "Verzameling {{name}}",
|
"collectionFieldType": "Verzameling {{name}}",
|
||||||
"deletedInvalidEdge": "Ongeldige hoek {{source}} -> {{target}} verwijderd",
|
"deletedInvalidEdge": "Ongeldige hoek {{source}} -> {{target}} verwijderd",
|
||||||
@@ -419,7 +396,6 @@
|
|||||||
"sourceNodeDoesNotExist": "Ongeldige rand: bron-/uitvoerknooppunt {{node}} bestaat niet",
|
"sourceNodeDoesNotExist": "Ongeldige rand: bron-/uitvoerknooppunt {{node}} bestaat niet",
|
||||||
"unsupportedArrayItemType": "niet-ondersteunde soort van het array-onderdeel \"{{type}}\"",
|
"unsupportedArrayItemType": "niet-ondersteunde soort van het array-onderdeel \"{{type}}\"",
|
||||||
"targetNodeFieldDoesNotExist": "Ongeldige rand: doel-/invoerveld {{node}}.{{field}} bestaat niet",
|
"targetNodeFieldDoesNotExist": "Ongeldige rand: doel-/invoerveld {{node}}.{{field}} bestaat niet",
|
||||||
"reorderLinearView": "Herorden lineaire weergave",
|
|
||||||
"newWorkflowDesc": "Een nieuwe werkstroom aanmaken?",
|
"newWorkflowDesc": "Een nieuwe werkstroom aanmaken?",
|
||||||
"collectionOrScalarFieldType": "Verzameling|scalair {{name}}",
|
"collectionOrScalarFieldType": "Verzameling|scalair {{name}}",
|
||||||
"newWorkflow": "Nieuwe werkstroom",
|
"newWorkflow": "Nieuwe werkstroom",
|
||||||
@@ -734,27 +710,21 @@
|
|||||||
"refinerStart": "Startwaarde verfijning",
|
"refinerStart": "Startwaarde verfijning",
|
||||||
"scheduler": "Planner",
|
"scheduler": "Planner",
|
||||||
"cfgScale": "CFG-schaal",
|
"cfgScale": "CFG-schaal",
|
||||||
"negStylePrompt": "Negatieve-stijlprompt",
|
|
||||||
"noModelsAvailable": "Geen modellen beschikbaar",
|
"noModelsAvailable": "Geen modellen beschikbaar",
|
||||||
"refiner": "Verfijning",
|
"refiner": "Verfijning",
|
||||||
"negAestheticScore": "Negatieve esthetische score",
|
"negAestheticScore": "Negatieve esthetische score",
|
||||||
"denoisingStrength": "Sterkte ontruising",
|
"denoisingStrength": "Sterkte ontruising",
|
||||||
"refinermodel": "Verfijningsmodel",
|
"refinermodel": "Verfijningsmodel",
|
||||||
"posAestheticScore": "Positieve esthetische score",
|
"posAestheticScore": "Positieve esthetische score",
|
||||||
"concatPromptStyle": "Koppelen van prompt en stijl",
|
|
||||||
"loading": "Bezig met laden...",
|
"loading": "Bezig met laden...",
|
||||||
"steps": "Stappen",
|
"steps": "Stappen",
|
||||||
"posStylePrompt": "Positieve-stijlprompt",
|
|
||||||
"freePromptStyle": "Handmatige stijlprompt",
|
|
||||||
"refinerSteps": "Aantal stappen verfijner"
|
"refinerSteps": "Aantal stappen verfijner"
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
"noMatchingModels": "Geen overeenkomend modellen",
|
"noMatchingModels": "Geen overeenkomend modellen",
|
||||||
"loading": "bezig met laden",
|
"loading": "bezig met laden",
|
||||||
"noMatchingLoRAs": "Geen overeenkomende LoRA's",
|
|
||||||
"noModelsAvailable": "Geen modellen beschikbaar",
|
"noModelsAvailable": "Geen modellen beschikbaar",
|
||||||
"selectModel": "Kies een model",
|
"selectModel": "Kies een model",
|
||||||
"noLoRAsInstalled": "Geen LoRA's geïnstalleerd",
|
|
||||||
"noRefinerModelsInstalled": "Geen SDXL-verfijningsmodellen geïnstalleerd",
|
"noRefinerModelsInstalled": "Geen SDXL-verfijningsmodellen geïnstalleerd",
|
||||||
"defaultVAE": "Standaard-VAE",
|
"defaultVAE": "Standaard-VAE",
|
||||||
"lora": "LoRA",
|
"lora": "LoRA",
|
||||||
@@ -822,14 +792,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hrf": {
|
"hrf": {
|
||||||
"upscaleMethod": "Opschaalmethode",
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"strength": "Sterkte oplossing voor hoge resolutie",
|
"strength": "Sterkte oplossing voor hoge resolutie",
|
||||||
"method": "Methode oplossing voor hoge resolutie",
|
"method": "Methode oplossing voor hoge resolutie",
|
||||||
"enabled": "Oplossing voor hoge resolutie ingeschakeld"
|
"enabled": "Oplossing voor hoge resolutie ingeschakeld"
|
||||||
},
|
},
|
||||||
"hrf": "Oplossing voor hoge resolutie",
|
"hrf": "Oplossing voor hoge resolutie"
|
||||||
"enableHrf": "Schakel oplossing in voor hoge resolutie"
|
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"addPromptTrigger": "Voeg prompttrigger toe",
|
"addPromptTrigger": "Voeg prompttrigger toe",
|
||||||
|
|||||||
@@ -41,11 +41,9 @@
|
|||||||
"somethingWentWrong": "Coś poszło nie tak",
|
"somethingWentWrong": "Coś poszło nie tak",
|
||||||
"green": "Zielony",
|
"green": "Zielony",
|
||||||
"red": "Czerwony",
|
"red": "Czerwony",
|
||||||
"imageFailedToLoad": "Nie można załadować obrazu",
|
|
||||||
"saveAs": "Zapisz jako",
|
"saveAs": "Zapisz jako",
|
||||||
"outputs": "Wyjścia",
|
"outputs": "Wyjścia",
|
||||||
"data": "Dane",
|
"data": "Dane",
|
||||||
"localSystem": "System Lokalny",
|
|
||||||
"t2iAdapter": "Adapter T2I",
|
"t2iAdapter": "Adapter T2I",
|
||||||
"selected": "Zaznaczone",
|
"selected": "Zaznaczone",
|
||||||
"warnings": "Ostrzeżenia",
|
"warnings": "Ostrzeżenia",
|
||||||
@@ -64,12 +62,10 @@
|
|||||||
"openInViewer": "Otwórz podgląd",
|
"openInViewer": "Otwórz podgląd",
|
||||||
"safetensors": "Bezpieczniki",
|
"safetensors": "Bezpieczniki",
|
||||||
"ok": "Ok",
|
"ok": "Ok",
|
||||||
"goTo": "Idź do",
|
|
||||||
"loadingImage": "wczytywanie zdjęcia",
|
"loadingImage": "wczytywanie zdjęcia",
|
||||||
"input": "Wejście",
|
"input": "Wejście",
|
||||||
"view": "Podgląd",
|
"view": "Podgląd",
|
||||||
"learnMore": "Dowiedz się więcej",
|
"learnMore": "Dowiedz się więcej",
|
||||||
"notInstalled": "Nie $t(common.installed)",
|
|
||||||
"loadingModel": "Wczytywanie modelu",
|
"loadingModel": "Wczytywanie modelu",
|
||||||
"postprocessing": "Przetwarzanie końcowe",
|
"postprocessing": "Przetwarzanie końcowe",
|
||||||
"random": "Losowo",
|
"random": "Losowo",
|
||||||
@@ -83,10 +79,8 @@
|
|||||||
"delete": "Usuń",
|
"delete": "Usuń",
|
||||||
"template": "Szablon",
|
"template": "Szablon",
|
||||||
"txt2img": "Tekst na obraz",
|
"txt2img": "Tekst na obraz",
|
||||||
"prevPage": "Poprzednia strona",
|
|
||||||
"file": "Plik",
|
"file": "Plik",
|
||||||
"toResolve": "Do rozwiązania",
|
"toResolve": "Do rozwiązania",
|
||||||
"nextPage": "Następna strona",
|
|
||||||
"unknownError": "Nieznany błąd",
|
"unknownError": "Nieznany błąd",
|
||||||
"placeholderSelectAModel": "Wybierz model",
|
"placeholderSelectAModel": "Wybierz model",
|
||||||
"new": "Nowy",
|
"new": "Nowy",
|
||||||
@@ -99,7 +93,6 @@
|
|||||||
"galleryImageSize": "Rozmiar obrazów",
|
"galleryImageSize": "Rozmiar obrazów",
|
||||||
"gallerySettings": "Ustawienia galerii",
|
"gallerySettings": "Ustawienia galerii",
|
||||||
"autoSwitchNewImages": "Przełączaj na nowe obrazy",
|
"autoSwitchNewImages": "Przełączaj na nowe obrazy",
|
||||||
"noImagesInGallery": "Brak obrazów w galerii",
|
|
||||||
"gallery": "Galeria",
|
"gallery": "Galeria",
|
||||||
"alwaysShowImageSizeBadge": "Zawsze pokazuj odznakę wielkości obrazu",
|
"alwaysShowImageSizeBadge": "Zawsze pokazuj odznakę wielkości obrazu",
|
||||||
"assetsTab": "Pliki, które wrzuciłeś do użytku w twoich projektach.",
|
"assetsTab": "Pliki, które wrzuciłeś do użytku w twoich projektach.",
|
||||||
@@ -128,12 +121,10 @@
|
|||||||
"scaledHeight": "Sk. do wys.",
|
"scaledHeight": "Sk. do wys.",
|
||||||
"infillMethod": "Metoda wypełniania",
|
"infillMethod": "Metoda wypełniania",
|
||||||
"tileSize": "Rozmiar kafelka",
|
"tileSize": "Rozmiar kafelka",
|
||||||
"downloadImage": "Pobierz obraz",
|
|
||||||
"usePrompt": "Skopiuj sugestie",
|
"usePrompt": "Skopiuj sugestie",
|
||||||
"useSeed": "Skopiuj inicjator",
|
"useSeed": "Skopiuj inicjator",
|
||||||
"useAll": "Skopiuj wszystko",
|
"useAll": "Skopiuj wszystko",
|
||||||
"info": "Informacje",
|
"info": "Informacje"
|
||||||
"showOptionsPanel": "Pokaż panel ustawień"
|
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"models": "Modele",
|
"models": "Modele",
|
||||||
@@ -186,8 +177,6 @@
|
|||||||
"selectedForAutoAdd": "Wybrany do automatycznego dodania",
|
"selectedForAutoAdd": "Wybrany do automatycznego dodania",
|
||||||
"deleteBoard": "Usuń tablicę",
|
"deleteBoard": "Usuń tablicę",
|
||||||
"clearSearch": "Usuń historię",
|
"clearSearch": "Usuń historię",
|
||||||
"hideBoards": "Ukryj tablice",
|
|
||||||
"viewBoards": "Zobacz tablice",
|
|
||||||
"addSharedBoard": "Dodaj udostępnioną tablicę",
|
"addSharedBoard": "Dodaj udostępnioną tablicę",
|
||||||
"boards": "Tablice",
|
"boards": "Tablice",
|
||||||
"addPrivateBoard": "Dodaj prywatną tablicę",
|
"addPrivateBoard": "Dodaj prywatną tablicę",
|
||||||
@@ -233,8 +222,7 @@
|
|||||||
"strength": "Moc poprawki wysokiej rozdzielczości",
|
"strength": "Moc poprawki wysokiej rozdzielczości",
|
||||||
"method": "Metoda High Resolution Fix"
|
"method": "Metoda High Resolution Fix"
|
||||||
},
|
},
|
||||||
"hrf": "Poprawka \"Wysoka rozdzielczość\"",
|
"hrf": "Poprawka \"Wysoka rozdzielczość\""
|
||||||
"enableHrf": "Włącz poprawkę wysokiej rozdzielczości"
|
|
||||||
},
|
},
|
||||||
"queue": {
|
"queue": {
|
||||||
"cancelTooltip": "Anuluj aktualną pozycję",
|
"cancelTooltip": "Anuluj aktualną pozycję",
|
||||||
@@ -296,7 +284,6 @@
|
|||||||
"completed": "Zakończono",
|
"completed": "Zakończono",
|
||||||
"item": "Pozycja",
|
"item": "Pozycja",
|
||||||
"failed": "Niepowodzenie",
|
"failed": "Niepowodzenie",
|
||||||
"batchFieldValues": "Masowe Wartości pól",
|
|
||||||
"graphFailedToQueue": "NIe udało się dodać tabeli do kolejki",
|
"graphFailedToQueue": "NIe udało się dodać tabeli do kolejki",
|
||||||
"workflows": "Przepływy pracy",
|
"workflows": "Przepływy pracy",
|
||||||
"next": "Następny",
|
"next": "Następny",
|
||||||
|
|||||||
@@ -17,8 +17,7 @@
|
|||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "Tamanho da Imagem",
|
"galleryImageSize": "Tamanho da Imagem",
|
||||||
"gallerySettings": "Configurações de Galeria",
|
"gallerySettings": "Configurações de Galeria",
|
||||||
"autoSwitchNewImages": "Trocar para Novas Imagens Automaticamente",
|
"autoSwitchNewImages": "Trocar para Novas Imagens Automaticamente"
|
||||||
"noImagesInGallery": "Sem Imagens na Galeria"
|
|
||||||
},
|
},
|
||||||
"modelManager": {
|
"modelManager": {
|
||||||
"modelManager": "Gerente de Modelo",
|
"modelManager": "Gerente de Modelo",
|
||||||
@@ -74,12 +73,10 @@
|
|||||||
"scaledHeight": "A Escalada",
|
"scaledHeight": "A Escalada",
|
||||||
"infillMethod": "Método de Preenchimento",
|
"infillMethod": "Método de Preenchimento",
|
||||||
"tileSize": "Tamanho do Ladrilho",
|
"tileSize": "Tamanho do Ladrilho",
|
||||||
"downloadImage": "Baixar Imagem",
|
|
||||||
"usePrompt": "Usar Prompt",
|
"usePrompt": "Usar Prompt",
|
||||||
"useSeed": "Usar Seed",
|
"useSeed": "Usar Seed",
|
||||||
"useAll": "Usar Todos",
|
"useAll": "Usar Todos",
|
||||||
"info": "Informações",
|
"info": "Informações",
|
||||||
"showOptionsPanel": "Mostrar Painel de Opções",
|
|
||||||
"symmetry": "Simetria",
|
"symmetry": "Simetria",
|
||||||
"copyImage": "Copiar imagem",
|
"copyImage": "Copiar imagem",
|
||||||
"denoisingStrength": "A força de remoção de ruído",
|
"denoisingStrength": "A força de remoção de ruído",
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
"gallery": {
|
"gallery": {
|
||||||
"gallerySettings": "Configurações de Galeria",
|
"gallerySettings": "Configurações de Galeria",
|
||||||
"autoSwitchNewImages": "Trocar para Novas Imagens Automaticamente",
|
"autoSwitchNewImages": "Trocar para Novas Imagens Automaticamente",
|
||||||
"noImagesInGallery": "Sem Imagens na Galeria",
|
|
||||||
"galleryImageSize": "Tamanho da Imagem"
|
"galleryImageSize": "Tamanho da Imagem"
|
||||||
},
|
},
|
||||||
"modelManager": {
|
"modelManager": {
|
||||||
@@ -69,7 +68,6 @@
|
|||||||
"tileSize": "Tamanho do Ladrilho",
|
"tileSize": "Tamanho do Ladrilho",
|
||||||
"symmetry": "Simetria",
|
"symmetry": "Simetria",
|
||||||
"usePrompt": "Usar Prompt",
|
"usePrompt": "Usar Prompt",
|
||||||
"showOptionsPanel": "Mostrar Painel de Opções",
|
|
||||||
"strength": "Força",
|
"strength": "Força",
|
||||||
"upscaling": "Redimensionando",
|
"upscaling": "Redimensionando",
|
||||||
"scaleBeforeProcessing": "Escala Antes do Processamento",
|
"scaleBeforeProcessing": "Escala Antes do Processamento",
|
||||||
@@ -81,7 +79,6 @@
|
|||||||
"scaledHeight": "A Escalada",
|
"scaledHeight": "A Escalada",
|
||||||
"infillMethod": "Método de Preenchimento",
|
"infillMethod": "Método de Preenchimento",
|
||||||
"copyImage": "Copiar imagem",
|
"copyImage": "Copiar imagem",
|
||||||
"downloadImage": "Descarregar Imagem",
|
|
||||||
"useSeed": "Usar Seed",
|
"useSeed": "Usar Seed",
|
||||||
"useAll": "Usar Todos",
|
"useAll": "Usar Todos",
|
||||||
"info": "Informações"
|
"info": "Informações"
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
"save": "Сохранить",
|
"save": "Сохранить",
|
||||||
"created": "Создано",
|
"created": "Создано",
|
||||||
"error": "Ошибка",
|
"error": "Ошибка",
|
||||||
"prevPage": "Предыдущая страница",
|
|
||||||
"simple": "Простой",
|
"simple": "Простой",
|
||||||
"ipAdapter": "IP Adapter",
|
"ipAdapter": "IP Adapter",
|
||||||
"installed": "Установлено",
|
"installed": "Установлено",
|
||||||
@@ -49,7 +48,6 @@
|
|||||||
"template": "Шаблон",
|
"template": "Шаблон",
|
||||||
"outputs": "результаты",
|
"outputs": "результаты",
|
||||||
"unknownError": "Неизвестная ошибка",
|
"unknownError": "Неизвестная ошибка",
|
||||||
"imageFailedToLoad": "Невозможно загрузить изображение",
|
|
||||||
"direction": "Направление",
|
"direction": "Направление",
|
||||||
"data": "Данные",
|
"data": "Данные",
|
||||||
"somethingWentWrong": "Что-то пошло не так",
|
"somethingWentWrong": "Что-то пошло не так",
|
||||||
@@ -58,11 +56,9 @@
|
|||||||
"orderBy": "Сортировать по",
|
"orderBy": "Сортировать по",
|
||||||
"copyError": "Ошибка $t(gallery.copy)",
|
"copyError": "Ошибка $t(gallery.copy)",
|
||||||
"learnMore": "Узнать больше",
|
"learnMore": "Узнать больше",
|
||||||
"nextPage": "Следущая страница",
|
|
||||||
"saveAs": "Сохранить как",
|
"saveAs": "Сохранить как",
|
||||||
"input": "Вход",
|
"input": "Вход",
|
||||||
"details": "Детали",
|
"details": "Детали",
|
||||||
"notInstalled": "Нет $t(common.installed)",
|
|
||||||
"or": "или",
|
"or": "или",
|
||||||
"aboutHeading": "Владей своей творческой силой",
|
"aboutHeading": "Владей своей творческой силой",
|
||||||
"red": "Красный",
|
"red": "Красный",
|
||||||
@@ -71,7 +67,6 @@
|
|||||||
"alpha": "Альфа",
|
"alpha": "Альфа",
|
||||||
"toResolve": "Чтоб решить",
|
"toResolve": "Чтоб решить",
|
||||||
"copy": "Копировать",
|
"copy": "Копировать",
|
||||||
"localSystem": "Локальная система",
|
|
||||||
"aboutDesc": "Используя Invoke для работы? Проверьте это:",
|
"aboutDesc": "Используя Invoke для работы? Проверьте это:",
|
||||||
"add": "Добавить",
|
"add": "Добавить",
|
||||||
"beta": "Бета",
|
"beta": "Бета",
|
||||||
@@ -79,7 +74,6 @@
|
|||||||
"positivePrompt": "Позитивный запрос",
|
"positivePrompt": "Позитивный запрос",
|
||||||
"negativePrompt": "Негативный запрос",
|
"negativePrompt": "Негативный запрос",
|
||||||
"editor": "Редактор",
|
"editor": "Редактор",
|
||||||
"goTo": "Перейти к",
|
|
||||||
"tab": "Вкладка",
|
"tab": "Вкладка",
|
||||||
"enabled": "Включено",
|
"enabled": "Включено",
|
||||||
"disabled": "Отключено",
|
"disabled": "Отключено",
|
||||||
@@ -101,7 +95,6 @@
|
|||||||
"galleryImageSize": "Размер изображений",
|
"galleryImageSize": "Размер изображений",
|
||||||
"gallerySettings": "Настройка галереи",
|
"gallerySettings": "Настройка галереи",
|
||||||
"autoSwitchNewImages": "Автоматически выбирать новые",
|
"autoSwitchNewImages": "Автоматически выбирать новые",
|
||||||
"noImagesInGallery": "Изображений нет",
|
|
||||||
"deleteImagePermanent": "Удаленные изображения невозможно восстановить.",
|
"deleteImagePermanent": "Удаленные изображения невозможно восстановить.",
|
||||||
"deleteImage_one": "Удалить изображение",
|
"deleteImage_one": "Удалить изображение",
|
||||||
"deleteImage_few": "Удалить {{count}} изображения",
|
"deleteImage_few": "Удалить {{count}} изображения",
|
||||||
@@ -110,7 +103,6 @@
|
|||||||
"deleteSelection": "Удалить выделенное",
|
"deleteSelection": "Удалить выделенное",
|
||||||
"featuresWillReset": "Если вы удалите это изображение, эти функции будут немедленно сброшены.",
|
"featuresWillReset": "Если вы удалите это изображение, эти функции будут немедленно сброшены.",
|
||||||
"loading": "Загрузка",
|
"loading": "Загрузка",
|
||||||
"unableToLoad": "Невозможно загрузить галерею",
|
|
||||||
"image": "изображение",
|
"image": "изображение",
|
||||||
"drop": "перебросить",
|
"drop": "перебросить",
|
||||||
"downloadSelection": "Скачать выделенное",
|
"downloadSelection": "Скачать выделенное",
|
||||||
@@ -136,7 +128,6 @@
|
|||||||
"compareHelp4": "Нажмите <Kbd>Z</Kbd> или <Kbd>Esc</Kbd> для выхода.",
|
"compareHelp4": "Нажмите <Kbd>Z</Kbd> или <Kbd>Esc</Kbd> для выхода.",
|
||||||
"compareImage": "Сравнить изображение",
|
"compareImage": "Сравнить изображение",
|
||||||
"viewerImage": "Изображение просмотрщика",
|
"viewerImage": "Изображение просмотрщика",
|
||||||
"selectAnImageToCompare": "Выберите изображение для сравнения",
|
|
||||||
"slider": "Слайдер",
|
"slider": "Слайдер",
|
||||||
"sideBySide": "Бок о бок",
|
"sideBySide": "Бок о бок",
|
||||||
"compareHelp1": "Удерживайте <Kbd>Alt</Kbd> при нажатии на изображение в галерее или при помощи клавиш со стрелками, чтобы изменить сравниваемое изображение.",
|
"compareHelp1": "Удерживайте <Kbd>Alt</Kbd> при нажатии на изображение в галерее или при помощи клавиш со стрелками, чтобы изменить сравниваемое изображение.",
|
||||||
@@ -154,11 +145,8 @@
|
|||||||
"exitBoardSearch": "Выйти из поиска досок",
|
"exitBoardSearch": "Выйти из поиска досок",
|
||||||
"go": "Перейти",
|
"go": "Перейти",
|
||||||
"exitSearch": "Выйти из поиска изображений",
|
"exitSearch": "Выйти из поиска изображений",
|
||||||
"jump": "Пыгнуть",
|
|
||||||
"move": "Двигать",
|
"move": "Двигать",
|
||||||
"gallery": "Галерея",
|
"gallery": "Галерея",
|
||||||
"openViewer": "Открыть просмотрщик",
|
|
||||||
"closeViewer": "Закрыть просмотрщик",
|
|
||||||
"imagesTab": "Изображения, созданные и сохраненные в Invoke.",
|
"imagesTab": "Изображения, созданные и сохраненные в Invoke.",
|
||||||
"assetsTab": "Файлы, которые вы загрузили для использования в своих проектах.",
|
"assetsTab": "Файлы, которые вы загрузили для использования в своих проектах.",
|
||||||
"boardsSettings": "Настройки доски",
|
"boardsSettings": "Настройки доски",
|
||||||
@@ -285,10 +273,6 @@
|
|||||||
"title": "Next Layer",
|
"title": "Next Layer",
|
||||||
"desc": "Select the next layer in the list."
|
"desc": "Select the next layer in the list."
|
||||||
},
|
},
|
||||||
"setFillToWhite": {
|
|
||||||
"title": "Set Color to White",
|
|
||||||
"desc": "Set the current tool color to white."
|
|
||||||
},
|
|
||||||
"applyFilter": {
|
"applyFilter": {
|
||||||
"title": "Apply Filter",
|
"title": "Apply Filter",
|
||||||
"desc": "Apply the pending filter to the selected layer."
|
"desc": "Apply the pending filter to the selected layer."
|
||||||
@@ -578,8 +562,6 @@
|
|||||||
"noModelsInstalled": "Нет установленных моделей",
|
"noModelsInstalled": "Нет установленных моделей",
|
||||||
"noModelsInstalledDesc1": "Установите модели с помощью",
|
"noModelsInstalledDesc1": "Установите модели с помощью",
|
||||||
"noMatchingModels": "Нет подходящих моделей",
|
"noMatchingModels": "Нет подходящих моделей",
|
||||||
"ipAdapters": "IP адаптеры",
|
|
||||||
"starterModelsInModelManager": "Стартовые модели можно найти в Менеджере моделей",
|
|
||||||
"learnMoreAboutSupportedModels": "Подробнее о поддерживаемых моделях",
|
"learnMoreAboutSupportedModels": "Подробнее о поддерживаемых моделях",
|
||||||
"t5Encoder": "T5 энкодер",
|
"t5Encoder": "T5 энкодер",
|
||||||
"spandrelImageToImage": "Image to Image (Spandrel)",
|
"spandrelImageToImage": "Image to Image (Spandrel)",
|
||||||
@@ -616,12 +598,10 @@
|
|||||||
"scaledHeight": "Масштаб В",
|
"scaledHeight": "Масштаб В",
|
||||||
"infillMethod": "Способ заполнения",
|
"infillMethod": "Способ заполнения",
|
||||||
"tileSize": "Размер области",
|
"tileSize": "Размер области",
|
||||||
"downloadImage": "Скачать",
|
|
||||||
"usePrompt": "Использовать запрос",
|
"usePrompt": "Использовать запрос",
|
||||||
"useSeed": "Использовать сид",
|
"useSeed": "Использовать сид",
|
||||||
"useAll": "Использовать все",
|
"useAll": "Использовать все",
|
||||||
"info": "Метаданные",
|
"info": "Метаданные",
|
||||||
"showOptionsPanel": "Показать панель настроек",
|
|
||||||
"cancel": {
|
"cancel": {
|
||||||
"cancel": "Отмена"
|
"cancel": "Отмена"
|
||||||
},
|
},
|
||||||
@@ -647,10 +627,6 @@
|
|||||||
"missingFieldTemplate": "Отсутствует шаблон поля",
|
"missingFieldTemplate": "Отсутствует шаблон поля",
|
||||||
"addingImagesTo": "Добавление изображений в",
|
"addingImagesTo": "Добавление изображений в",
|
||||||
"invoke": "Создать",
|
"invoke": "Создать",
|
||||||
"fluxModelIncompatibleBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), ширина рамки {{width}}",
|
|
||||||
"fluxModelIncompatibleBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), высота рамки {{height}}",
|
|
||||||
"fluxModelIncompatibleScaledBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), масштабированная высота рамки {{height}}",
|
|
||||||
"fluxModelIncompatibleScaledBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16) масштабированная ширина рамки {{width}}",
|
|
||||||
"noFLUXVAEModelSelected": "Для генерации FLUX не выбрана модель VAE",
|
"noFLUXVAEModelSelected": "Для генерации FLUX не выбрана модель VAE",
|
||||||
"noT5EncoderModelSelected": "Для генерации FLUX не выбрана модель T5 энкодера",
|
"noT5EncoderModelSelected": "Для генерации FLUX не выбрана модель T5 энкодера",
|
||||||
"canvasIsFiltering": "Холст фильтруется",
|
"canvasIsFiltering": "Холст фильтруется",
|
||||||
@@ -736,9 +712,6 @@
|
|||||||
"baseModelChangedCleared_few": "Очищено или отключено {{count}} несовместимых подмодели",
|
"baseModelChangedCleared_few": "Очищено или отключено {{count}} несовместимых подмодели",
|
||||||
"baseModelChangedCleared_many": "Очищено или отключено {{count}} несовместимых подмоделей",
|
"baseModelChangedCleared_many": "Очищено или отключено {{count}} несовместимых подмоделей",
|
||||||
"loadedWithWarnings": "Рабочий процесс загружен с предупреждениями",
|
"loadedWithWarnings": "Рабочий процесс загружен с предупреждениями",
|
||||||
"setControlImage": "Установить как контрольное изображение",
|
|
||||||
"setNodeField": "Установить как поле узла",
|
|
||||||
"invalidUpload": "Неверная загрузка",
|
|
||||||
"imageUploaded": "Изображение загружено",
|
"imageUploaded": "Изображение загружено",
|
||||||
"addedToBoard": "Добавлено в активы доски {{name}}",
|
"addedToBoard": "Добавлено в активы доски {{name}}",
|
||||||
"workflowLoaded": "Рабочий процесс загружен",
|
"workflowLoaded": "Рабочий процесс загружен",
|
||||||
@@ -767,21 +740,14 @@
|
|||||||
"sentToCanvas": "Отправить на холст",
|
"sentToCanvas": "Отправить на холст",
|
||||||
"unableToLoadImage": "Невозможно загрузить изображение",
|
"unableToLoadImage": "Невозможно загрузить изображение",
|
||||||
"unableToLoadImageMetadata": "Невозможно загрузить метаданные изображения",
|
"unableToLoadImageMetadata": "Невозможно загрузить метаданные изображения",
|
||||||
"imageSaved": "Изображение сохранено",
|
|
||||||
"stylePresetLoaded": "Предустановка стиля загружена",
|
"stylePresetLoaded": "Предустановка стиля загружена",
|
||||||
"imageNotLoadedDesc": "Не удалось найти изображение",
|
|
||||||
"imageSavingFailed": "Не удалось сохранить изображение",
|
|
||||||
"problemCopyingLayer": "Не удалось скопировать слой",
|
"problemCopyingLayer": "Не удалось скопировать слой",
|
||||||
"unableToLoadStylePreset": "Невозможно загрузить предустановку стиля",
|
"unableToLoadStylePreset": "Невозможно загрузить предустановку стиля",
|
||||||
"layerCopiedToClipboard": "Слой скопирован в буфер обмена",
|
"layerCopiedToClipboard": "Слой скопирован в буфер обмена",
|
||||||
"sentToUpscale": "Отправить на увеличение",
|
"sentToUpscale": "Отправить на увеличение",
|
||||||
"layerSavedToAssets": "Слой сохранен в активах",
|
|
||||||
"linkCopied": "Ссылка скопирована",
|
"linkCopied": "Ссылка скопирована",
|
||||||
"addedToUncategorized": "Добавлено в активы доски $t(boards.uncategorized)",
|
"addedToUncategorized": "Добавлено в активы доски $t(boards.uncategorized)",
|
||||||
"imagesWillBeAddedTo": "Загруженные изображения будут добавлены в активы доски {{boardName}}.",
|
"imagesWillBeAddedTo": "Загруженные изображения будут добавлены в активы доски {{boardName}}."
|
||||||
"uploadFailedInvalidUploadDesc_withCount_one": "Должно быть не более {{count}} изображения в формате PNG или JPEG.",
|
|
||||||
"uploadFailedInvalidUploadDesc_withCount_few": "Должно быть не более {{count}} изображений в формате PNG или JPEG.",
|
|
||||||
"uploadFailedInvalidUploadDesc_withCount_many": "Должно быть не более {{count}} изображений в формате PNG или JPEG."
|
|
||||||
},
|
},
|
||||||
"accessibility": {
|
"accessibility": {
|
||||||
"uploadImage": "Загрузить изображение",
|
"uploadImage": "Загрузить изображение",
|
||||||
@@ -803,15 +769,12 @@
|
|||||||
"zoomInNodes": "Увеличьте масштаб",
|
"zoomInNodes": "Увеличьте масштаб",
|
||||||
"zoomOutNodes": "Уменьшите масштаб",
|
"zoomOutNodes": "Уменьшите масштаб",
|
||||||
"fitViewportNodes": "Уместить вид",
|
"fitViewportNodes": "Уместить вид",
|
||||||
"showLegendNodes": "Показать тип поля",
|
|
||||||
"hideMinimapnodes": "Скрыть миникарту",
|
"hideMinimapnodes": "Скрыть миникарту",
|
||||||
"hideLegendNodes": "Скрыть тип поля",
|
|
||||||
"showMinimapnodes": "Показать миникарту",
|
"showMinimapnodes": "Показать миникарту",
|
||||||
"loadWorkflow": "Загрузить рабочий процесс",
|
"loadWorkflow": "Загрузить рабочий процесс",
|
||||||
"reloadNodeTemplates": "Перезагрузить шаблоны узлов",
|
"reloadNodeTemplates": "Перезагрузить шаблоны узлов",
|
||||||
"downloadWorkflow": "Скачать JSON рабочего процесса",
|
"downloadWorkflow": "Скачать JSON рабочего процесса",
|
||||||
"addNode": "Добавить узел",
|
"addNode": "Добавить узел",
|
||||||
"addLinearView": "Добавить в линейный вид",
|
|
||||||
"animatedEdges": "Анимированные ребра",
|
"animatedEdges": "Анимированные ребра",
|
||||||
"animatedEdgesHelp": "Анимация выбранных ребер и ребер, соединенных с выбранными узлами",
|
"animatedEdgesHelp": "Анимация выбранных ребер и ребер, соединенных с выбранными узлами",
|
||||||
"boolean": "Логические значения",
|
"boolean": "Логические значения",
|
||||||
@@ -823,7 +786,6 @@
|
|||||||
"workflowDescription": "Краткое описание",
|
"workflowDescription": "Краткое описание",
|
||||||
"inputFieldTypeParseError": "Невозможно разобрать тип поля ввода {{node}}.{{field}} ({{message}})",
|
"inputFieldTypeParseError": "Невозможно разобрать тип поля ввода {{node}}.{{field}} ({{message}})",
|
||||||
"unsupportedAnyOfLength": "слишком много элементов объединения ({{count}})",
|
"unsupportedAnyOfLength": "слишком много элементов объединения ({{count}})",
|
||||||
"versionUnknown": " Версия неизвестна",
|
|
||||||
"unsupportedArrayItemType": "неподдерживаемый тип элемента массива \"{{type}}\"",
|
"unsupportedArrayItemType": "неподдерживаемый тип элемента массива \"{{type}}\"",
|
||||||
"noNodeSelected": "Узел не выбран",
|
"noNodeSelected": "Узел не выбран",
|
||||||
"unableToValidateWorkflow": "Невозможно проверить рабочий процесс",
|
"unableToValidateWorkflow": "Невозможно проверить рабочий процесс",
|
||||||
@@ -841,10 +803,8 @@
|
|||||||
"nodeTemplate": "Шаблон узла",
|
"nodeTemplate": "Шаблон узла",
|
||||||
"nodeOpacity": "Непрозрачность узла",
|
"nodeOpacity": "Непрозрачность узла",
|
||||||
"sourceNodeDoesNotExist": "Недопустимое ребро: исходный/выходной узел {{node}} не существует",
|
"sourceNodeDoesNotExist": "Недопустимое ребро: исходный/выходной узел {{node}} не существует",
|
||||||
"unableToLoadWorkflow": "Невозможно загрузить рабочий процесс",
|
|
||||||
"unableToExtractEnumOptions": "невозможно извлечь параметры перечисления",
|
"unableToExtractEnumOptions": "невозможно извлечь параметры перечисления",
|
||||||
"snapToGrid": "Привязка к сетке",
|
"snapToGrid": "Привязка к сетке",
|
||||||
"noFieldsLinearview": "Нет полей, добавленных в линейный вид",
|
|
||||||
"unableToParseFieldType": "невозможно проанализировать тип поля",
|
"unableToParseFieldType": "невозможно проанализировать тип поля",
|
||||||
"nodeSearch": "Поиск узлов",
|
"nodeSearch": "Поиск узлов",
|
||||||
"updateNode": "Обновить узел",
|
"updateNode": "Обновить узел",
|
||||||
@@ -865,9 +825,7 @@
|
|||||||
"edge": "Край",
|
"edge": "Край",
|
||||||
"sourceNodeFieldDoesNotExist": "Неверный край: поле источника/вывода {{node}}.{{field}} не существует",
|
"sourceNodeFieldDoesNotExist": "Неверный край: поле источника/вывода {{node}}.{{field}} не существует",
|
||||||
"cannotDuplicateConnection": "Невозможно создать дубликаты соединений",
|
"cannotDuplicateConnection": "Невозможно создать дубликаты соединений",
|
||||||
"unknownTemplate": "Неизвестный шаблон",
|
|
||||||
"noWorkflow": "Нет рабочего процесса",
|
"noWorkflow": "Нет рабочего процесса",
|
||||||
"removeLinearView": "Удалить из линейного вида",
|
|
||||||
"workflowTags": "Теги",
|
"workflowTags": "Теги",
|
||||||
"fullyContainNodesHelp": "Чтобы узлы были выбраны, они должны полностью находиться в поле выбора",
|
"fullyContainNodesHelp": "Чтобы узлы были выбраны, они должны полностью находиться в поле выбора",
|
||||||
"unableToGetWorkflowVersion": "Не удалось получить версию схемы рабочего процесса",
|
"unableToGetWorkflowVersion": "Не удалось получить версию схемы рабочего процесса",
|
||||||
@@ -900,7 +858,6 @@
|
|||||||
"colorCodeEdges": "Ребра с цветовой кодировкой",
|
"colorCodeEdges": "Ребра с цветовой кодировкой",
|
||||||
"unknownNode": "Неизвестный узел",
|
"unknownNode": "Неизвестный узел",
|
||||||
"targetNodeDoesNotExist": "Недопустимое ребро: целевой/входной узел {{node}} не существует",
|
"targetNodeDoesNotExist": "Недопустимое ребро: целевой/входной узел {{node}} не существует",
|
||||||
"mismatchedVersion": "Недопустимый узел: узел {{node}} типа {{type}} имеет несоответствующую версию (попробовать обновить?)",
|
|
||||||
"unknownFieldType": "$t(nodes.unknownField) тип: {{type}}",
|
"unknownFieldType": "$t(nodes.unknownField) тип: {{type}}",
|
||||||
"collectionOrScalarFieldType": "{{name}} (Один или коллекция)",
|
"collectionOrScalarFieldType": "{{name}} (Один или коллекция)",
|
||||||
"betaDesc": "Этот вызов находится в бета-версии. Пока он не станет стабильным, в нем могут происходить изменения при обновлении приложений. Мы планируем поддерживать этот вызов в течение длительного времени.",
|
"betaDesc": "Этот вызов находится в бета-версии. Пока он не станет стабильным, в нем могут происходить изменения при обновлении приложений. Мы планируем поддерживать этот вызов в течение длительного времени.",
|
||||||
@@ -909,14 +866,12 @@
|
|||||||
"snapToGridHelp": "Привязка узлов к сетке при перемещении",
|
"snapToGridHelp": "Привязка узлов к сетке при перемещении",
|
||||||
"workflowSettings": "Настройки редактора рабочих процессов",
|
"workflowSettings": "Настройки редактора рабочих процессов",
|
||||||
"deletedInvalidEdge": "Удалено недопустимое ребро {{source}} -> {{target}}",
|
"deletedInvalidEdge": "Удалено недопустимое ребро {{source}} -> {{target}}",
|
||||||
"unknownInput": "Неизвестный вход: {{name}}",
|
|
||||||
"newWorkflow": "Новый рабочий процесс",
|
"newWorkflow": "Новый рабочий процесс",
|
||||||
"newWorkflowDesc": "Создать новый рабочий процесс?",
|
"newWorkflowDesc": "Создать новый рабочий процесс?",
|
||||||
"clearWorkflow": "Очистить рабочий процесс",
|
"clearWorkflow": "Очистить рабочий процесс",
|
||||||
"newWorkflowDesc2": "Текущий рабочий процесс имеет несохраненные изменения.",
|
"newWorkflowDesc2": "Текущий рабочий процесс имеет несохраненные изменения.",
|
||||||
"clearWorkflowDesc": "Очистить этот рабочий процесс и создать новый?",
|
"clearWorkflowDesc": "Очистить этот рабочий процесс и создать новый?",
|
||||||
"clearWorkflowDesc2": "Текущий рабочий процесс имеет несохраненные измерения.",
|
"clearWorkflowDesc2": "Текущий рабочий процесс имеет несохраненные измерения.",
|
||||||
"reorderLinearView": "Изменить порядок линейного просмотра",
|
|
||||||
"viewMode": "Использовать в линейном представлении",
|
"viewMode": "Использовать в линейном представлении",
|
||||||
"editMode": "Открыть в редакторе узлов",
|
"editMode": "Открыть в редакторе узлов",
|
||||||
"resetToDefaultValue": "Сбросить к стандартному значкнию",
|
"resetToDefaultValue": "Сбросить к стандартному значкнию",
|
||||||
@@ -978,8 +933,6 @@
|
|||||||
"addPrivateBoard": "Добавить личную доску",
|
"addPrivateBoard": "Добавить личную доску",
|
||||||
"private": "Личные доски",
|
"private": "Личные доски",
|
||||||
"shared": "Общие доски",
|
"shared": "Общие доски",
|
||||||
"hideBoards": "Скрыть доски",
|
|
||||||
"viewBoards": "Просмотреть доски",
|
|
||||||
"noBoards": "Нет досок {{boardType}}",
|
"noBoards": "Нет досок {{boardType}}",
|
||||||
"deletedPrivateBoardsCannotbeRestored": "Удаленные доски не могут быть восстановлены. Выбор «Удалить только доску» переведет изображения в приватное состояние без категории для создателя изображения.",
|
"deletedPrivateBoardsCannotbeRestored": "Удаленные доски не могут быть восстановлены. Выбор «Удалить только доску» переведет изображения в приватное состояние без категории для создателя изображения.",
|
||||||
"updateBoardError": "Ошибка обновления доски"
|
"updateBoardError": "Ошибка обновления доски"
|
||||||
@@ -1408,8 +1361,6 @@
|
|||||||
"noRecallParameters": "Параметры для вызова не найдены",
|
"noRecallParameters": "Параметры для вызова не найдены",
|
||||||
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
||||||
"parameterSet": "Параметр {{parameter}} установлен",
|
"parameterSet": "Параметр {{parameter}} установлен",
|
||||||
"parsingFailed": "Не удалось выполнить синтаксический анализ",
|
|
||||||
"recallParameter": "Отозвать {{label}}",
|
|
||||||
"allPrompts": "Все запросы",
|
"allPrompts": "Все запросы",
|
||||||
"imageDimensions": "Размеры изображения",
|
"imageDimensions": "Размеры изображения",
|
||||||
"canvasV2Metadata": "Холст",
|
"canvasV2Metadata": "Холст",
|
||||||
@@ -1460,7 +1411,6 @@
|
|||||||
"next": "Следующий",
|
"next": "Следующий",
|
||||||
"cancelBatch": "Отменить пакет",
|
"cancelBatch": "Отменить пакет",
|
||||||
"back": "задний",
|
"back": "задний",
|
||||||
"batchFieldValues": "Пакетные значения полей",
|
|
||||||
"cancel": "Отмена",
|
"cancel": "Отмена",
|
||||||
"session": "Сессия",
|
"session": "Сессия",
|
||||||
"time": "Время",
|
"time": "Время",
|
||||||
@@ -1495,18 +1445,14 @@
|
|||||||
"refinerStart": "Запуск доработчика",
|
"refinerStart": "Запуск доработчика",
|
||||||
"scheduler": "Планировщик",
|
"scheduler": "Планировщик",
|
||||||
"cfgScale": "Шкала точности (CFG)",
|
"cfgScale": "Шкала точности (CFG)",
|
||||||
"negStylePrompt": "Негативный запрос стиля",
|
|
||||||
"noModelsAvailable": "Нет доступных моделей",
|
"noModelsAvailable": "Нет доступных моделей",
|
||||||
"refiner": "Доработчик",
|
"refiner": "Доработчик",
|
||||||
"negAestheticScore": "Отрицательная эстетическая оценка",
|
"negAestheticScore": "Отрицательная эстетическая оценка",
|
||||||
"denoisingStrength": "Шумоподавление",
|
"denoisingStrength": "Шумоподавление",
|
||||||
"refinermodel": "Дорабатывающая модель",
|
"refinermodel": "Дорабатывающая модель",
|
||||||
"posAestheticScore": "Положительная эстетическая оценка",
|
"posAestheticScore": "Положительная эстетическая оценка",
|
||||||
"concatPromptStyle": "Связывание запроса и стиля",
|
|
||||||
"loading": "Загрузка...",
|
"loading": "Загрузка...",
|
||||||
"steps": "Шаги",
|
"steps": "Шаги",
|
||||||
"posStylePrompt": "Запрос стиля",
|
|
||||||
"freePromptStyle": "Ручной запрос стиля",
|
|
||||||
"refinerSteps": "Шаги доработчика"
|
"refinerSteps": "Шаги доработчика"
|
||||||
},
|
},
|
||||||
"invocationCache": {
|
"invocationCache": {
|
||||||
@@ -1531,20 +1477,15 @@
|
|||||||
"workflowEditorMenu": "Меню редактора рабочего процесса",
|
"workflowEditorMenu": "Меню редактора рабочего процесса",
|
||||||
"workflowName": "Имя рабочего процесса",
|
"workflowName": "Имя рабочего процесса",
|
||||||
"saveWorkflow": "Сохранить рабочий процесс",
|
"saveWorkflow": "Сохранить рабочий процесс",
|
||||||
"openWorkflow": "Открытый рабочий процесс",
|
|
||||||
"clearWorkflowSearchFilter": "Очистить фильтр поиска рабочих процессов",
|
|
||||||
"workflowLibrary": "Библиотека",
|
"workflowLibrary": "Библиотека",
|
||||||
"downloadWorkflow": "Сохранить в файл",
|
"downloadWorkflow": "Сохранить в файл",
|
||||||
"workflowSaved": "Рабочий процесс сохранен",
|
"workflowSaved": "Рабочий процесс сохранен",
|
||||||
"unnamedWorkflow": "Безымянный рабочий процесс",
|
"unnamedWorkflow": "Безымянный рабочий процесс",
|
||||||
"savingWorkflow": "Сохранение рабочего процесса...",
|
"savingWorkflow": "Сохранение рабочего процесса...",
|
||||||
"problemLoading": "Проблема с загрузкой рабочих процессов",
|
|
||||||
"loading": "Загрузка рабочих процессов",
|
"loading": "Загрузка рабочих процессов",
|
||||||
"searchWorkflows": "Поиск рабочих процессов",
|
|
||||||
"problemSavingWorkflow": "Проблема с сохранением рабочего процесса",
|
"problemSavingWorkflow": "Проблема с сохранением рабочего процесса",
|
||||||
"deleteWorkflow": "Удалить рабочий процесс",
|
"deleteWorkflow": "Удалить рабочий процесс",
|
||||||
"workflows": "Рабочие процессы",
|
"workflows": "Рабочие процессы",
|
||||||
"noDescription": "Без описания",
|
|
||||||
"uploadWorkflow": "Загрузить из файла",
|
"uploadWorkflow": "Загрузить из файла",
|
||||||
"newWorkflowCreated": "Создан новый рабочий процесс",
|
"newWorkflowCreated": "Создан новый рабочий процесс",
|
||||||
"saveWorkflowToProject": "Сохранить рабочий процесс в проект",
|
"saveWorkflowToProject": "Сохранить рабочий процесс в проект",
|
||||||
@@ -1560,9 +1501,6 @@
|
|||||||
"convertGraph": "Конвертировать график",
|
"convertGraph": "Конвертировать график",
|
||||||
"loadFromGraph": "Загрузка рабочего процесса из графика",
|
"loadFromGraph": "Загрузка рабочего процесса из графика",
|
||||||
"autoLayout": "Автоматическое расположение",
|
"autoLayout": "Автоматическое расположение",
|
||||||
"userWorkflows": "Пользовательские рабочие процессы",
|
|
||||||
"projectWorkflows": "Рабочие процессы проекта",
|
|
||||||
"defaultWorkflows": "Стандартные рабочие процессы",
|
|
||||||
"deleteWorkflow2": "Вы уверены, что хотите удалить этот рабочий процесс? Это нельзя отменить.",
|
"deleteWorkflow2": "Вы уверены, что хотите удалить этот рабочий процесс? Это нельзя отменить.",
|
||||||
"chooseWorkflowFromLibrary": "Выбрать рабочий процесс из библиотеки",
|
"chooseWorkflowFromLibrary": "Выбрать рабочий процесс из библиотеки",
|
||||||
"edit": "Редактировать",
|
"edit": "Редактировать",
|
||||||
@@ -1572,8 +1510,6 @@
|
|||||||
"delete": "Удалить"
|
"delete": "Удалить"
|
||||||
},
|
},
|
||||||
"hrf": {
|
"hrf": {
|
||||||
"enableHrf": "Включить исправление высокого разрешения",
|
|
||||||
"upscaleMethod": "Метод увеличения",
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"strength": "Сила исправления высокого разрешения",
|
"strength": "Сила исправления высокого разрешения",
|
||||||
"enabled": "Исправление высокого разрешения включено",
|
"enabled": "Исправление высокого разрешения включено",
|
||||||
@@ -1584,12 +1520,10 @@
|
|||||||
"models": {
|
"models": {
|
||||||
"noMatchingModels": "Нет подходящих моделей",
|
"noMatchingModels": "Нет подходящих моделей",
|
||||||
"loading": "загрузка",
|
"loading": "загрузка",
|
||||||
"noMatchingLoRAs": "Нет подходящих LoRA",
|
|
||||||
"noModelsAvailable": "Нет доступных моделей",
|
"noModelsAvailable": "Нет доступных моделей",
|
||||||
"addLora": "Добавить LoRA",
|
"addLora": "Добавить LoRA",
|
||||||
"selectModel": "Выберите модель",
|
"selectModel": "Выберите модель",
|
||||||
"noRefinerModelsInstalled": "Дорабатывающие модели SDXL не установлены",
|
"noRefinerModelsInstalled": "Дорабатывающие модели SDXL не установлены",
|
||||||
"noLoRAsInstalled": "Нет установленных LoRA",
|
|
||||||
"lora": "LoRA",
|
"lora": "LoRA",
|
||||||
"defaultVAE": "Стандартное VAE",
|
"defaultVAE": "Стандартное VAE",
|
||||||
"concepts": "LoRA"
|
"concepts": "LoRA"
|
||||||
@@ -1624,7 +1558,6 @@
|
|||||||
"moveForward": "Переместить вперёд",
|
"moveForward": "Переместить вперёд",
|
||||||
"moveBackward": "Переместить назад",
|
"moveBackward": "Переместить назад",
|
||||||
"autoNegative": "Авто негатив",
|
"autoNegative": "Авто негатив",
|
||||||
"deletePrompt": "Удалить запрос",
|
|
||||||
"rectangle": "Прямоугольник",
|
"rectangle": "Прямоугольник",
|
||||||
"addNegativePrompt": "Добавить $t(controlLayers.negativePrompt)",
|
"addNegativePrompt": "Добавить $t(controlLayers.negativePrompt)",
|
||||||
"regionalGuidance": "Региональная точность",
|
"regionalGuidance": "Региональная точность",
|
||||||
@@ -1794,7 +1727,6 @@
|
|||||||
},
|
},
|
||||||
"addReferenceImage": "Добавить $t(controlLayers.referenceImage)",
|
"addReferenceImage": "Добавить $t(controlLayers.referenceImage)",
|
||||||
"inpaintMask": "Маска перерисовки",
|
"inpaintMask": "Маска перерисовки",
|
||||||
"sendToGalleryDesc": "При нажатии кнопки Invoke создается изображение и сохраняется в вашей галерее.",
|
|
||||||
"sendToCanvas": "Отправить на холст",
|
"sendToCanvas": "Отправить на холст",
|
||||||
"regionalGuidance_withCount_one": "$t(controlLayers.regionalGuidance)",
|
"regionalGuidance_withCount_one": "$t(controlLayers.regionalGuidance)",
|
||||||
"regionalGuidance_withCount_few": "Региональных точности",
|
"regionalGuidance_withCount_few": "Региональных точности",
|
||||||
@@ -1806,7 +1738,6 @@
|
|||||||
"inpaintMask_withCount_one": "$t(controlLayers.inpaintMask)",
|
"inpaintMask_withCount_one": "$t(controlLayers.inpaintMask)",
|
||||||
"inpaintMask_withCount_few": "Маски перерисовки",
|
"inpaintMask_withCount_few": "Маски перерисовки",
|
||||||
"inpaintMask_withCount_many": "Масок перерисовки",
|
"inpaintMask_withCount_many": "Масок перерисовки",
|
||||||
"globalReferenceImages_withCount_visible": "Глобальные эталонные изображения ({{count}})",
|
|
||||||
"controlMode": {
|
"controlMode": {
|
||||||
"prompt": "Запрос",
|
"prompt": "Запрос",
|
||||||
"controlMode": "Режим контроля",
|
"controlMode": "Режим контроля",
|
||||||
@@ -1842,7 +1773,6 @@
|
|||||||
"pullBboxIntoReferenceImage": "Поместить рамку в эталонное изображение",
|
"pullBboxIntoReferenceImage": "Поместить рамку в эталонное изображение",
|
||||||
"enableAutoNegative": "Включить авто негатив",
|
"enableAutoNegative": "Включить авто негатив",
|
||||||
"maskFill": "Заполнение маски",
|
"maskFill": "Заполнение маски",
|
||||||
"viewProgressInViewer": "Просматривайте прогресс и результаты в <Btn>Просмотрщике изображений</Btn>.",
|
|
||||||
"tool": {
|
"tool": {
|
||||||
"move": "Двигать",
|
"move": "Двигать",
|
||||||
"bbox": "Ограничительная рамка",
|
"bbox": "Ограничительная рамка",
|
||||||
@@ -1853,18 +1783,10 @@
|
|||||||
"colorPicker": "Подборщик цветов"
|
"colorPicker": "Подборщик цветов"
|
||||||
},
|
},
|
||||||
"rasterLayer": "Растровый слой",
|
"rasterLayer": "Растровый слой",
|
||||||
"sendingToCanvas": "Постановка генераций на холст",
|
|
||||||
"rasterLayers_withCount_visible": "Растровые слои ({{count}})",
|
|
||||||
"regionalGuidance_withCount_hidden": "Региональная точность ({{count}} скрыто)",
|
|
||||||
"enableTransparencyEffect": "Включить эффект прозрачности",
|
"enableTransparencyEffect": "Включить эффект прозрачности",
|
||||||
"hidingType": "Скрыть {{type}}",
|
"hidingType": "Скрыть {{type}}",
|
||||||
"addRegionalGuidance": "Добавить $t(controlLayers.regionalGuidance)",
|
"addRegionalGuidance": "Добавить $t(controlLayers.regionalGuidance)",
|
||||||
"sendingToGallery": "Отправка генераций в галерею",
|
|
||||||
"viewProgressOnCanvas": "Просматривайте прогресс и результаты этапов на <Btn>Холсте</Btn>.",
|
|
||||||
"controlLayers_withCount_hidden": "Контрольные слои ({{count}} скрыто)",
|
|
||||||
"rasterLayers_withCount_hidden": "Растровые слои ({{count}} скрыто)",
|
|
||||||
"deleteSelected": "Удалить выбранное",
|
"deleteSelected": "Удалить выбранное",
|
||||||
"stagingOnCanvas": "Постановка изображений на",
|
|
||||||
"pullBboxIntoLayer": "Поместить рамку в слой",
|
"pullBboxIntoLayer": "Поместить рамку в слой",
|
||||||
"locked": "Заблокировано",
|
"locked": "Заблокировано",
|
||||||
"replaceLayer": "Заменить слой",
|
"replaceLayer": "Заменить слой",
|
||||||
@@ -1873,16 +1795,10 @@
|
|||||||
"addRasterLayer": "Добавить $t(controlLayers.rasterLayer)",
|
"addRasterLayer": "Добавить $t(controlLayers.rasterLayer)",
|
||||||
"addControlLayer": "Добавить $t(controlLayers.controlLayer)",
|
"addControlLayer": "Добавить $t(controlLayers.controlLayer)",
|
||||||
"addInpaintMask": "Добавить $t(controlLayers.inpaintMask)",
|
"addInpaintMask": "Добавить $t(controlLayers.inpaintMask)",
|
||||||
"inpaintMasks_withCount_hidden": "Маски перерисовки ({{count}} скрыто)",
|
|
||||||
"regionalGuidance_withCount_visible": "Региональная точность ({{count}})",
|
|
||||||
"newGallerySessionDesc": "Это очистит холст и все настройки, кроме выбранной модели. Генерации будут отправлены в галерею.",
|
|
||||||
"newCanvasSession": "Новая сессия холста",
|
|
||||||
"newCanvasSessionDesc": "Это очистит холст и все настройки, кроме выбора модели. Генерации будут размещены на холсте.",
|
|
||||||
"cropLayerToBbox": "Обрезать слой по ограничительной рамке",
|
"cropLayerToBbox": "Обрезать слой по ограничительной рамке",
|
||||||
"clipToBbox": "Обрезка штрихов в рамке",
|
"clipToBbox": "Обрезка штрихов в рамке",
|
||||||
"outputOnlyMaskedRegions": "Вывод только маскированных областей",
|
"outputOnlyMaskedRegions": "Вывод только маскированных областей",
|
||||||
"duplicate": "Дублировать",
|
"duplicate": "Дублировать",
|
||||||
"inpaintMasks_withCount_visible": "Маски перерисовки ({{count}})",
|
|
||||||
"layer_one": "Слой",
|
"layer_one": "Слой",
|
||||||
"layer_few": "Слоя",
|
"layer_few": "Слоя",
|
||||||
"layer_many": "Слоев",
|
"layer_many": "Слоев",
|
||||||
@@ -1901,37 +1817,23 @@
|
|||||||
},
|
},
|
||||||
"disableAutoNegative": "Отключить авто негатив",
|
"disableAutoNegative": "Отключить авто негатив",
|
||||||
"deleteReferenceImage": "Удалить эталонное изображение",
|
"deleteReferenceImage": "Удалить эталонное изображение",
|
||||||
"controlLayers_withCount_visible": "Контрольные слои ({{count}})",
|
|
||||||
"rasterLayer_withCount_one": "$t(controlLayers.rasterLayer)",
|
"rasterLayer_withCount_one": "$t(controlLayers.rasterLayer)",
|
||||||
"rasterLayer_withCount_few": "Растровых слоя",
|
"rasterLayer_withCount_few": "Растровых слоя",
|
||||||
"rasterLayer_withCount_many": "Растровых слоев",
|
"rasterLayer_withCount_many": "Растровых слоев",
|
||||||
"transparency": "Прозрачность",
|
"transparency": "Прозрачность",
|
||||||
"weight": "Вес",
|
"weight": "Вес",
|
||||||
"newGallerySession": "Новая сессия галереи",
|
|
||||||
"sendToCanvasDesc": "Нажатие кнопки Invoke отображает вашу текущую работу на холсте.",
|
|
||||||
"globalReferenceImages_withCount_hidden": "Глобальные эталонные изображения ({{count}} скрыто)",
|
|
||||||
"layer_withCount_one": "Слой ({{count}})",
|
|
||||||
"layer_withCount_few": "Слои ({{count}})",
|
|
||||||
"layer_withCount_many": "Слои ({{count}})",
|
|
||||||
"disableTransparencyEffect": "Отключить эффект прозрачности",
|
"disableTransparencyEffect": "Отключить эффект прозрачности",
|
||||||
"showingType": "Показать {{type}}",
|
"showingType": "Показать {{type}}",
|
||||||
"dynamicGrid": "Динамическая сетка",
|
"dynamicGrid": "Динамическая сетка",
|
||||||
"logDebugInfo": "Писать отладочную информацию",
|
"logDebugInfo": "Писать отладочную информацию",
|
||||||
"unlocked": "Разблокировано",
|
"unlocked": "Разблокировано",
|
||||||
"showProgressOnCanvas": "Показать прогресс на холсте",
|
"showProgressOnCanvas": "Показать прогресс на холсте",
|
||||||
"globalReferenceImage_withCount_one": "$t(controlLayers.globalReferenceImage)",
|
|
||||||
"globalReferenceImage_withCount_few": "Глобальных эталонных изображения",
|
|
||||||
"globalReferenceImage_withCount_many": "Глобальных эталонных изображений",
|
|
||||||
"regionalReferenceImage": "Региональное эталонное изображение",
|
"regionalReferenceImage": "Региональное эталонное изображение",
|
||||||
"globalReferenceImage": "Глобальное эталонное изображение",
|
"globalReferenceImage": "Глобальное эталонное изображение",
|
||||||
"sendToGallery": "Отправить в галерею",
|
"referenceImage": "Эталонное изображение"
|
||||||
"referenceImage": "Эталонное изображение",
|
|
||||||
"addGlobalReferenceImage": "Добавить $t(controlLayers.globalReferenceImage)",
|
|
||||||
"newImg2ImgCanvasFromImage": "Новое img2img из изображения"
|
|
||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"generation": "Генерация",
|
|
||||||
"canvas": "Холст",
|
"canvas": "Холст",
|
||||||
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
||||||
"models": "Модели",
|
"models": "Модели",
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "Bildstorlek",
|
"galleryImageSize": "Bildstorlek",
|
||||||
"gallerySettings": "Galleriinställningar",
|
"gallerySettings": "Galleriinställningar",
|
||||||
"noImagesInGallery": "Inga bilder i galleriet",
|
|
||||||
"autoSwitchNewImages": "Ändra automatiskt till nya bilder"
|
"autoSwitchNewImages": "Ändra automatiskt till nya bilder"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,12 +36,10 @@
|
|||||||
"communityLabel": "Topluluk",
|
"communityLabel": "Topluluk",
|
||||||
"back": "Geri",
|
"back": "Geri",
|
||||||
"areYouSure": "Emin misiniz?",
|
"areYouSure": "Emin misiniz?",
|
||||||
"notInstalled": "$t(common.installed) Değil",
|
|
||||||
"openInNewTab": "Yeni Sekmede Aç",
|
"openInNewTab": "Yeni Sekmede Aç",
|
||||||
"aboutHeading": "Yaratıcı Gücünüzün Sahibi Olun",
|
"aboutHeading": "Yaratıcı Gücünüzün Sahibi Olun",
|
||||||
"load": "Yükle",
|
"load": "Yükle",
|
||||||
"loading": "Yükleniyor",
|
"loading": "Yükleniyor",
|
||||||
"localSystem": "Yerel Sistem",
|
|
||||||
"inpaint": "içboyama",
|
"inpaint": "içboyama",
|
||||||
"modelManager": "Model Yöneticisi",
|
"modelManager": "Model Yöneticisi",
|
||||||
"orderBy": "Sırala",
|
"orderBy": "Sırala",
|
||||||
@@ -65,11 +63,8 @@
|
|||||||
"format": "biçim",
|
"format": "biçim",
|
||||||
"details": "Ayrıntılar",
|
"details": "Ayrıntılar",
|
||||||
"error": "Hata",
|
"error": "Hata",
|
||||||
"imageFailedToLoad": "Görsel Yüklenemedi",
|
|
||||||
"safetensors": "Safetensors",
|
"safetensors": "Safetensors",
|
||||||
"upload": "Yükle",
|
"upload": "Yükle",
|
||||||
"nextPage": "Sonraki Sayfa",
|
|
||||||
"prevPage": "Önceki Sayfa",
|
|
||||||
"dontAskMeAgain": "Bir daha sorma",
|
"dontAskMeAgain": "Bir daha sorma",
|
||||||
"delete": "Kaldır",
|
"delete": "Kaldır",
|
||||||
"direction": "Yön",
|
"direction": "Yön",
|
||||||
@@ -181,7 +176,6 @@
|
|||||||
"session": "Oturum",
|
"session": "Oturum",
|
||||||
"batchQueued": "Toplu İş Sıraya Alındı",
|
"batchQueued": "Toplu İş Sıraya Alındı",
|
||||||
"notReady": "Sıraya Alınamadı",
|
"notReady": "Sıraya Alınamadı",
|
||||||
"batchFieldValues": "Toplu İş Değişkenleri",
|
|
||||||
"graphFailedToQueue": "Çizge sıraya alınamadı",
|
"graphFailedToQueue": "Çizge sıraya alınamadı",
|
||||||
"graphQueued": "Çizge sıraya alındı"
|
"graphQueued": "Çizge sıraya alındı"
|
||||||
},
|
},
|
||||||
@@ -207,12 +201,10 @@
|
|||||||
"image": "görsel",
|
"image": "görsel",
|
||||||
"galleryImageSize": "Görsel Boyutu",
|
"galleryImageSize": "Görsel Boyutu",
|
||||||
"copy": "Kopyala",
|
"copy": "Kopyala",
|
||||||
"noImagesInGallery": "Gösterilecek Görsel Yok",
|
|
||||||
"autoSwitchNewImages": "Yeni Görseli Biter Bitmez Gör",
|
"autoSwitchNewImages": "Yeni Görseli Biter Bitmez Gör",
|
||||||
"currentlyInUse": "Bu görsel şurada kullanımda:",
|
"currentlyInUse": "Bu görsel şurada kullanımda:",
|
||||||
"deleteImage_one": "Görseli Sil",
|
"deleteImage_one": "Görseli Sil",
|
||||||
"deleteImage_other": "",
|
"deleteImage_other": "",
|
||||||
"unableToLoad": "Galeri Yüklenemedi",
|
|
||||||
"downloadSelection": "Seçileni İndir",
|
"downloadSelection": "Seçileni İndir",
|
||||||
"dropOrUpload": "$t(gallery.drop) ya da Yükle",
|
"dropOrUpload": "$t(gallery.drop) ya da Yükle",
|
||||||
"dropToUpload": "Yüklemek için $t(gallery.drop)",
|
"dropToUpload": "Yüklemek için $t(gallery.drop)",
|
||||||
@@ -220,13 +212,11 @@
|
|||||||
},
|
},
|
||||||
"hrf": {
|
"hrf": {
|
||||||
"hrf": "Yüksek Çözünürlük Kürü",
|
"hrf": "Yüksek Çözünürlük Kürü",
|
||||||
"enableHrf": "Yüksek Çözünürlük Kürünü Aç",
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"enabled": "Yüksek Çözünürlük Kürü Açık",
|
"enabled": "Yüksek Çözünürlük Kürü Açık",
|
||||||
"strength": "Yüksek Çözünürlük Kürü Etkisi",
|
"strength": "Yüksek Çözünürlük Kürü Etkisi",
|
||||||
"method": "Yüksek Çözünürlük Kürü Yöntemi"
|
"method": "Yüksek Çözünürlük Kürü Yöntemi"
|
||||||
},
|
}
|
||||||
"upscaleMethod": "Büyütme Yöntemi"
|
|
||||||
},
|
},
|
||||||
"hotkeys": {
|
"hotkeys": {
|
||||||
"noHotkeysFound": "Kısayol Tuşu Bulanamadı",
|
"noHotkeysFound": "Kısayol Tuşu Bulanamadı",
|
||||||
@@ -256,7 +246,6 @@
|
|||||||
"unknownErrorValidatingWorkflow": "İş akışını doğrulamada bilinmeyen bir sorun",
|
"unknownErrorValidatingWorkflow": "İş akışını doğrulamada bilinmeyen bir sorun",
|
||||||
"unableToGetWorkflowVersion": "İş akışı sürümüne ulaşılamadı",
|
"unableToGetWorkflowVersion": "İş akışı sürümüne ulaşılamadı",
|
||||||
"newWorkflowDesc2": "Geçerli iş akışında kaydedilmemiş değişiklikler var.",
|
"newWorkflowDesc2": "Geçerli iş akışında kaydedilmemiş değişiklikler var.",
|
||||||
"unableToLoadWorkflow": "İş Akışı Yüklenemedi",
|
|
||||||
"cannotConnectInputToInput": "Giriş girişe bağlanamaz",
|
"cannotConnectInputToInput": "Giriş girişe bağlanamaz",
|
||||||
"zoomInNodes": "Yakınlaştır",
|
"zoomInNodes": "Yakınlaştır",
|
||||||
"boolean": "Boole Değeri",
|
"boolean": "Boole Değeri",
|
||||||
@@ -267,16 +256,12 @@
|
|||||||
"cannotDuplicateConnection": "Kopya bağlantılar yaratılamaz"
|
"cannotDuplicateConnection": "Kopya bağlantılar yaratılamaz"
|
||||||
},
|
},
|
||||||
"workflows": {
|
"workflows": {
|
||||||
"searchWorkflows": "İş Akışlarında Ara",
|
|
||||||
"workflowName": "İş Akışı Adı",
|
"workflowName": "İş Akışı Adı",
|
||||||
"problemSavingWorkflow": "İş Akışını Kaydetmede Sorun",
|
"problemSavingWorkflow": "İş Akışını Kaydetmede Sorun",
|
||||||
"saveWorkflow": "İş Akışını Kaydet",
|
"saveWorkflow": "İş Akışını Kaydet",
|
||||||
"uploadWorkflow": "Dosyadan Yükle",
|
"uploadWorkflow": "Dosyadan Yükle",
|
||||||
"newWorkflowCreated": "Yeni İş Akışı Yaratıldı",
|
"newWorkflowCreated": "Yeni İş Akışı Yaratıldı",
|
||||||
"problemLoading": "İş Akışlarını Yüklemede Sorun",
|
|
||||||
"loading": "İş Akışları Yükleniyor",
|
"loading": "İş Akışları Yükleniyor",
|
||||||
"noDescription": "Tanımsız",
|
|
||||||
"clearWorkflowSearchFilter": "İş Akışı Aramasını Resetle",
|
|
||||||
"workflowEditorMenu": "İş Akışı Düzenleyici Menüsü",
|
"workflowEditorMenu": "İş Akışı Düzenleyici Menüsü",
|
||||||
"downloadWorkflow": "İndir",
|
"downloadWorkflow": "İndir",
|
||||||
"saveWorkflowAs": "İş Akışını Farklı Kaydet",
|
"saveWorkflowAs": "İş Akışını Farklı Kaydet",
|
||||||
@@ -328,7 +313,6 @@
|
|||||||
"noiseThreshold": "Gürültü Eşiği",
|
"noiseThreshold": "Gürültü Eşiği",
|
||||||
"seed": "Tohum",
|
"seed": "Tohum",
|
||||||
"imageActions": "Görsel İşlemleri",
|
"imageActions": "Görsel İşlemleri",
|
||||||
"showOptionsPanel": "Yan Paneli Göster (O ya da T)",
|
|
||||||
"shuffle": "Kar",
|
"shuffle": "Kar",
|
||||||
"usePrompt": "İstemi Kullan",
|
"usePrompt": "İstemi Kullan",
|
||||||
"setToOptimalSizeTooSmall": "$t(parameters.setToOptimalSize) (çok küçük olabilir)",
|
"setToOptimalSizeTooSmall": "$t(parameters.setToOptimalSize) (çok küçük olabilir)",
|
||||||
@@ -346,7 +330,6 @@
|
|||||||
"perlinNoise": "Perlin Gürültüsü",
|
"perlinNoise": "Perlin Gürültüsü",
|
||||||
"scaledWidth": "Ölçekli En",
|
"scaledWidth": "Ölçekli En",
|
||||||
"seamlessXAxis": "Dikişsiz Döşeme X Ekseni",
|
"seamlessXAxis": "Dikişsiz Döşeme X Ekseni",
|
||||||
"downloadImage": "Görseli İndir",
|
|
||||||
"type": "Tür"
|
"type": "Tür"
|
||||||
},
|
},
|
||||||
"modelManager": {
|
"modelManager": {
|
||||||
@@ -399,11 +382,9 @@
|
|||||||
"defaultVAE": "Varsayılan VAE",
|
"defaultVAE": "Varsayılan VAE",
|
||||||
"lora": "LoRA",
|
"lora": "LoRA",
|
||||||
"noModelsAvailable": "Model yok",
|
"noModelsAvailable": "Model yok",
|
||||||
"noMatchingLoRAs": "Uygun LoRA Yok",
|
|
||||||
"noMatchingModels": "Uygun Model Yok",
|
"noMatchingModels": "Uygun Model Yok",
|
||||||
"loading": "yükleniyor",
|
"loading": "yükleniyor",
|
||||||
"selectModel": "Model Seçin",
|
"selectModel": "Model Seçin"
|
||||||
"noLoRAsInstalled": "LoRA Yok"
|
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generation": "Oluşturma"
|
"generation": "Oluşturma"
|
||||||
@@ -411,7 +392,6 @@
|
|||||||
"sdxl": {
|
"sdxl": {
|
||||||
"cfgScale": "CFG Ölçeği",
|
"cfgScale": "CFG Ölçeği",
|
||||||
"loading": "Yükleniyor...",
|
"loading": "Yükleniyor...",
|
||||||
"denoisingStrength": "Arındırma Ölçüsü",
|
"denoisingStrength": "Arındırma Ölçüsü"
|
||||||
"concatPromptStyle": "İstem ve Stili Bitiştir"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,7 @@
|
|||||||
"gallery": {
|
"gallery": {
|
||||||
"galleryImageSize": "Розмір зображень",
|
"galleryImageSize": "Розмір зображень",
|
||||||
"gallerySettings": "Налаштування галереї",
|
"gallerySettings": "Налаштування галереї",
|
||||||
"autoSwitchNewImages": "Автоматично вибирати нові",
|
"autoSwitchNewImages": "Автоматично вибирати нові"
|
||||||
"noImagesInGallery": "Зображень немає"
|
|
||||||
},
|
},
|
||||||
"modelManager": {
|
"modelManager": {
|
||||||
"modelManager": "Менеджер моделей",
|
"modelManager": "Менеджер моделей",
|
||||||
@@ -80,12 +79,10 @@
|
|||||||
"scaledHeight": "Масштаб В",
|
"scaledHeight": "Масштаб В",
|
||||||
"infillMethod": "Засіб заповнення",
|
"infillMethod": "Засіб заповнення",
|
||||||
"tileSize": "Розмір області",
|
"tileSize": "Розмір області",
|
||||||
"downloadImage": "Завантажити",
|
|
||||||
"usePrompt": "Використати запит",
|
"usePrompt": "Використати запит",
|
||||||
"useSeed": "Використати сід",
|
"useSeed": "Використати сід",
|
||||||
"useAll": "Використати все",
|
"useAll": "Використати все",
|
||||||
"info": "Метадані",
|
"info": "Метадані",
|
||||||
"showOptionsPanel": "Показати панель налаштувань",
|
|
||||||
"general": "Основне",
|
"general": "Основне",
|
||||||
"denoisingStrength": "Сила шумоподавлення",
|
"denoisingStrength": "Сила шумоподавлення",
|
||||||
"copyImage": "Копіювати зображення",
|
"copyImage": "Копіювати зображення",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,6 @@
|
|||||||
"batch": "批次管理器",
|
"batch": "批次管理器",
|
||||||
"communityLabel": "社区",
|
"communityLabel": "社区",
|
||||||
"modelManager": "模型管理器",
|
"modelManager": "模型管理器",
|
||||||
"imageFailedToLoad": "无法加载图像",
|
|
||||||
"learnMore": "了解更多",
|
"learnMore": "了解更多",
|
||||||
"advanced": "高级",
|
"advanced": "高级",
|
||||||
"t2iAdapter": "T2I Adapter",
|
"t2iAdapter": "T2I Adapter",
|
||||||
@@ -51,23 +50,19 @@
|
|||||||
"somethingWentWrong": "出了点问题",
|
"somethingWentWrong": "出了点问题",
|
||||||
"copyError": "$t(gallery.copy) 错误",
|
"copyError": "$t(gallery.copy) 错误",
|
||||||
"input": "输入",
|
"input": "输入",
|
||||||
"notInstalled": "非 $t(common.installed)",
|
|
||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
"updated": "已上传",
|
"updated": "已上传",
|
||||||
"save": "保存",
|
"save": "保存",
|
||||||
"created": "已创建",
|
"created": "已创建",
|
||||||
"prevPage": "上一页",
|
|
||||||
"unknownError": "未知错误",
|
"unknownError": "未知错误",
|
||||||
"direction": "指向",
|
"direction": "指向",
|
||||||
"orderBy": "排序方式:",
|
"orderBy": "排序方式:",
|
||||||
"nextPage": "下一页",
|
|
||||||
"saveAs": "保存为",
|
"saveAs": "保存为",
|
||||||
"ai": "ai",
|
"ai": "ai",
|
||||||
"or": "或",
|
"or": "或",
|
||||||
"aboutDesc": "使用 Invoke 工作?来看看:",
|
"aboutDesc": "使用 Invoke 工作?来看看:",
|
||||||
"add": "添加",
|
"add": "添加",
|
||||||
"copy": "复制",
|
"copy": "复制",
|
||||||
"localSystem": "本地系统",
|
|
||||||
"aboutHeading": "掌握你的创造力",
|
"aboutHeading": "掌握你的创造力",
|
||||||
"enabled": "已启用",
|
"enabled": "已启用",
|
||||||
"disabled": "已禁用",
|
"disabled": "已禁用",
|
||||||
@@ -78,7 +73,6 @@
|
|||||||
"selected": "选中的",
|
"selected": "选中的",
|
||||||
"green": "绿",
|
"green": "绿",
|
||||||
"blue": "蓝",
|
"blue": "蓝",
|
||||||
"goTo": "前往",
|
|
||||||
"dontShowMeThese": "请勿显示这些内容",
|
"dontShowMeThese": "请勿显示这些内容",
|
||||||
"beta": "测试版",
|
"beta": "测试版",
|
||||||
"toResolve": "解决",
|
"toResolve": "解决",
|
||||||
@@ -104,13 +98,11 @@
|
|||||||
"galleryImageSize": "预览大小",
|
"galleryImageSize": "预览大小",
|
||||||
"gallerySettings": "预览设置",
|
"gallerySettings": "预览设置",
|
||||||
"autoSwitchNewImages": "自动切换到新图像",
|
"autoSwitchNewImages": "自动切换到新图像",
|
||||||
"noImagesInGallery": "无图像可用于显示",
|
|
||||||
"deleteImage_other": "删除{{count}}张图片",
|
"deleteImage_other": "删除{{count}}张图片",
|
||||||
"deleteImagePermanent": "删除的图片无法被恢复。",
|
"deleteImagePermanent": "删除的图片无法被恢复。",
|
||||||
"autoAssignBoardOnClick": "点击后自动分配面板",
|
"autoAssignBoardOnClick": "点击后自动分配面板",
|
||||||
"featuresWillReset": "如果您删除该图像,这些功能会立即被重置。",
|
"featuresWillReset": "如果您删除该图像,这些功能会立即被重置。",
|
||||||
"loading": "加载中",
|
"loading": "加载中",
|
||||||
"unableToLoad": "无法加载图库",
|
|
||||||
"currentlyInUse": "该图像目前在以下功能中使用:",
|
"currentlyInUse": "该图像目前在以下功能中使用:",
|
||||||
"copy": "复制",
|
"copy": "复制",
|
||||||
"download": "下载",
|
"download": "下载",
|
||||||
@@ -125,7 +117,6 @@
|
|||||||
"starImage": "收藏图像",
|
"starImage": "收藏图像",
|
||||||
"alwaysShowImageSizeBadge": "始终显示图像尺寸",
|
"alwaysShowImageSizeBadge": "始终显示图像尺寸",
|
||||||
"selectForCompare": "选择以比较",
|
"selectForCompare": "选择以比较",
|
||||||
"selectAnImageToCompare": "选择一个图像进行比较",
|
|
||||||
"slider": "滑块",
|
"slider": "滑块",
|
||||||
"sideBySide": "并排",
|
"sideBySide": "并排",
|
||||||
"bulkDownloadFailed": "下载失败",
|
"bulkDownloadFailed": "下载失败",
|
||||||
@@ -148,7 +139,6 @@
|
|||||||
"newestFirst": "最新在前",
|
"newestFirst": "最新在前",
|
||||||
"compareHelp4": "按 <Kbd>Z</Kbd>或 <Kbd>Esc</Kbd> 键退出。",
|
"compareHelp4": "按 <Kbd>Z</Kbd>或 <Kbd>Esc</Kbd> 键退出。",
|
||||||
"searchImages": "按元数据搜索",
|
"searchImages": "按元数据搜索",
|
||||||
"jump": "跳过",
|
|
||||||
"compareHelp2": "按 <Kbd>M</Kbd> 键切换不同的比较模式。",
|
"compareHelp2": "按 <Kbd>M</Kbd> 键切换不同的比较模式。",
|
||||||
"displayBoardSearch": "板块搜索",
|
"displayBoardSearch": "板块搜索",
|
||||||
"displaySearch": "图像搜索",
|
"displaySearch": "图像搜索",
|
||||||
@@ -161,8 +151,6 @@
|
|||||||
"gallery": "画廊",
|
"gallery": "画廊",
|
||||||
"move": "移动",
|
"move": "移动",
|
||||||
"imagesTab": "您在Invoke中创建和保存的图片。",
|
"imagesTab": "您在Invoke中创建和保存的图片。",
|
||||||
"openViewer": "打开查看器",
|
|
||||||
"closeViewer": "关闭查看器",
|
|
||||||
"assetsTab": "您已上传用于项目的文件。"
|
"assetsTab": "您已上传用于项目的文件。"
|
||||||
},
|
},
|
||||||
"hotkeys": {
|
"hotkeys": {
|
||||||
@@ -310,10 +298,6 @@
|
|||||||
"title": "移动工具",
|
"title": "移动工具",
|
||||||
"desc": "选择移动工具。"
|
"desc": "选择移动工具。"
|
||||||
},
|
},
|
||||||
"setFillToWhite": {
|
|
||||||
"title": "将颜色设置为白色",
|
|
||||||
"desc": "将当前工具的颜色设置为白色。"
|
|
||||||
},
|
|
||||||
"cancelTransform": {
|
"cancelTransform": {
|
||||||
"desc": "取消待处理的变换。",
|
"desc": "取消待处理的变换。",
|
||||||
"title": "取消变换"
|
"title": "取消变换"
|
||||||
@@ -577,9 +561,7 @@
|
|||||||
"huggingFacePlaceholder": "所有者或模型名称",
|
"huggingFacePlaceholder": "所有者或模型名称",
|
||||||
"huggingFaceRepoID": "HuggingFace仓库ID",
|
"huggingFaceRepoID": "HuggingFace仓库ID",
|
||||||
"loraTriggerPhrases": "LoRA 触发词",
|
"loraTriggerPhrases": "LoRA 触发词",
|
||||||
"ipAdapters": "IP适配器",
|
|
||||||
"spandrelImageToImage": "图生图(Spandrel)",
|
"spandrelImageToImage": "图生图(Spandrel)",
|
||||||
"starterModelsInModelManager": "您可以在模型管理器中找到初始模型",
|
|
||||||
"noDefaultSettings": "此模型没有配置默认设置。请访问模型管理器添加默认设置。",
|
"noDefaultSettings": "此模型没有配置默认设置。请访问模型管理器添加默认设置。",
|
||||||
"clipEmbed": "CLIP 嵌入",
|
"clipEmbed": "CLIP 嵌入",
|
||||||
"defaultSettingsOutOfSync": "某些设置与模型的默认值不匹配:",
|
"defaultSettingsOutOfSync": "某些设置与模型的默认值不匹配:",
|
||||||
@@ -630,12 +612,10 @@
|
|||||||
"scaledHeight": "缩放长度",
|
"scaledHeight": "缩放长度",
|
||||||
"infillMethod": "填充方法",
|
"infillMethod": "填充方法",
|
||||||
"tileSize": "方格尺寸",
|
"tileSize": "方格尺寸",
|
||||||
"downloadImage": "下载图像",
|
|
||||||
"usePrompt": "使用提示",
|
"usePrompt": "使用提示",
|
||||||
"useSeed": "使用种子",
|
"useSeed": "使用种子",
|
||||||
"useAll": "使用所有参数",
|
"useAll": "使用所有参数",
|
||||||
"info": "信息",
|
"info": "信息",
|
||||||
"showOptionsPanel": "显示侧栏浮窗 (O 或 T)",
|
|
||||||
"seamlessYAxis": "无缝平铺 Y 轴",
|
"seamlessYAxis": "无缝平铺 Y 轴",
|
||||||
"seamlessXAxis": "无缝平铺 X 轴",
|
"seamlessXAxis": "无缝平铺 X 轴",
|
||||||
"denoisingStrength": "去噪强度",
|
"denoisingStrength": "去噪强度",
|
||||||
@@ -661,15 +641,11 @@
|
|||||||
"addingImagesTo": "添加图像到",
|
"addingImagesTo": "添加图像到",
|
||||||
"noPrompts": "没有已生成的提示词",
|
"noPrompts": "没有已生成的提示词",
|
||||||
"canvasIsFiltering": "画布正在过滤",
|
"canvasIsFiltering": "画布正在过滤",
|
||||||
"fluxModelIncompatibleScaledBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16),缩放后的边界框高度为 {{height}}",
|
|
||||||
"noCLIPEmbedModelSelected": "未为FLUX生成选择CLIP嵌入模型",
|
"noCLIPEmbedModelSelected": "未为FLUX生成选择CLIP嵌入模型",
|
||||||
"noFLUXVAEModelSelected": "未为FLUX生成选择VAE模型",
|
"noFLUXVAEModelSelected": "未为FLUX生成选择VAE模型",
|
||||||
"canvasIsRasterizing": "画布正在栅格化",
|
"canvasIsRasterizing": "画布正在栅格化",
|
||||||
"canvasIsCompositing": "画布正在合成",
|
"canvasIsCompositing": "画布正在合成",
|
||||||
"fluxModelIncompatibleBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16),边界框宽度为 {{width}}",
|
|
||||||
"fluxModelIncompatibleScaledBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16),缩放后的边界框宽度为 {{width}}",
|
|
||||||
"noT5EncoderModelSelected": "未为FLUX生成选择T5编码器模型",
|
"noT5EncoderModelSelected": "未为FLUX生成选择T5编码器模型",
|
||||||
"fluxModelIncompatibleBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16),边界框高度为 {{height}}",
|
|
||||||
"canvasIsTransforming": "画布正在变换"
|
"canvasIsTransforming": "画布正在变换"
|
||||||
},
|
},
|
||||||
"patchmatchDownScaleSize": "缩小",
|
"patchmatchDownScaleSize": "缩小",
|
||||||
@@ -733,8 +709,6 @@
|
|||||||
"informationalPopoversDisabledDesc": "信息提示框已被禁用.请在设置中重新启用.",
|
"informationalPopoversDisabledDesc": "信息提示框已被禁用.请在设置中重新启用.",
|
||||||
"enableModelDescriptions": "在下拉菜单中启用模型描述",
|
"enableModelDescriptions": "在下拉菜单中启用模型描述",
|
||||||
"confirmOnNewSession": "新会话时确认",
|
"confirmOnNewSession": "新会话时确认",
|
||||||
"modelDescriptionsDisabledDesc": "下拉菜单中的模型描述已被禁用。可在设置中启用。",
|
|
||||||
"modelDescriptionsDisabled": "下拉菜单中的模型描述已禁用",
|
|
||||||
"showDetailedInvocationProgress": "显示进度详情"
|
"showDetailedInvocationProgress": "显示进度详情"
|
||||||
},
|
},
|
||||||
"toast": {
|
"toast": {
|
||||||
@@ -750,14 +724,11 @@
|
|||||||
"problemCopyingImage": "无法复制图像",
|
"problemCopyingImage": "无法复制图像",
|
||||||
"modelAddedSimple": "模型已加入队列",
|
"modelAddedSimple": "模型已加入队列",
|
||||||
"loadedWithWarnings": "已加载带有警告的工作流",
|
"loadedWithWarnings": "已加载带有警告的工作流",
|
||||||
"setControlImage": "设为控制图像",
|
|
||||||
"setNodeField": "设为节点字段",
|
|
||||||
"imageUploaded": "图像已上传",
|
"imageUploaded": "图像已上传",
|
||||||
"addedToBoard": "添加到{{name}}的资产中",
|
"addedToBoard": "添加到{{name}}的资产中",
|
||||||
"workflowLoaded": "工作流已加载",
|
"workflowLoaded": "工作流已加载",
|
||||||
"imageUploadFailed": "图像上传失败",
|
"imageUploadFailed": "图像上传失败",
|
||||||
"baseModelChangedCleared_other": "已清除或禁用{{count}}个不兼容的子模型",
|
"baseModelChangedCleared_other": "已清除或禁用{{count}}个不兼容的子模型",
|
||||||
"invalidUpload": "无效的上传",
|
|
||||||
"problemDeletingWorkflow": "删除工作流时出现问题",
|
"problemDeletingWorkflow": "删除工作流时出现问题",
|
||||||
"workflowDeleted": "已删除工作流",
|
"workflowDeleted": "已删除工作流",
|
||||||
"problemRetrievingWorkflow": "检索工作流时发生问题",
|
"problemRetrievingWorkflow": "检索工作流时发生问题",
|
||||||
@@ -777,21 +748,16 @@
|
|||||||
"modelImportCanceled": "模型导入已取消",
|
"modelImportCanceled": "模型导入已取消",
|
||||||
"importFailed": "导入失败",
|
"importFailed": "导入失败",
|
||||||
"importSuccessful": "导入成功",
|
"importSuccessful": "导入成功",
|
||||||
"layerSavedToAssets": "图层已保存到资产",
|
|
||||||
"sentToUpscale": "已发送到放大处理",
|
"sentToUpscale": "已发送到放大处理",
|
||||||
"addedToUncategorized": "已添加到看板 $t(boards.uncategorized) 的资产中",
|
"addedToUncategorized": "已添加到看板 $t(boards.uncategorized) 的资产中",
|
||||||
"linkCopied": "链接已复制",
|
"linkCopied": "链接已复制",
|
||||||
"uploadFailedInvalidUploadDesc_withCount_other": "最多只能上传 {{count}} 张 PNG 或 JPEG 图像。",
|
|
||||||
"problemSavingLayer": "无法保存图层",
|
"problemSavingLayer": "无法保存图层",
|
||||||
"unableToLoadImage": "无法加载图像",
|
"unableToLoadImage": "无法加载图像",
|
||||||
"imageNotLoadedDesc": "无法找到图像",
|
|
||||||
"unableToLoadStylePreset": "无法加载样式预设",
|
"unableToLoadStylePreset": "无法加载样式预设",
|
||||||
"stylePresetLoaded": "样式预设已加载",
|
"stylePresetLoaded": "样式预设已加载",
|
||||||
"problemCopyingLayer": "无法复制图层",
|
"problemCopyingLayer": "无法复制图层",
|
||||||
"sentToCanvas": "已发送到画布",
|
"sentToCanvas": "已发送到画布",
|
||||||
"unableToLoadImageMetadata": "无法加载图像元数据",
|
"unableToLoadImageMetadata": "无法加载图像元数据",
|
||||||
"imageSaved": "图像已保存",
|
|
||||||
"imageSavingFailed": "图像保存失败",
|
|
||||||
"layerCopiedToClipboard": "图层已复制到剪贴板",
|
"layerCopiedToClipboard": "图层已复制到剪贴板",
|
||||||
"imagesWillBeAddedTo": "上传的图像将添加到看板 {{boardName}} 的资产中。"
|
"imagesWillBeAddedTo": "上传的图像将添加到看板 {{boardName}} 的资产中。"
|
||||||
},
|
},
|
||||||
@@ -819,11 +785,8 @@
|
|||||||
"fitViewportNodes": "自适应视图",
|
"fitViewportNodes": "自适应视图",
|
||||||
"showMinimapnodes": "显示缩略图",
|
"showMinimapnodes": "显示缩略图",
|
||||||
"hideMinimapnodes": "隐藏缩略图",
|
"hideMinimapnodes": "隐藏缩略图",
|
||||||
"showLegendNodes": "显示字段类型图例",
|
|
||||||
"hideLegendNodes": "隐藏字段类型图例",
|
|
||||||
"downloadWorkflow": "下载工作流 JSON",
|
"downloadWorkflow": "下载工作流 JSON",
|
||||||
"workflowDescription": "简述",
|
"workflowDescription": "简述",
|
||||||
"versionUnknown": " 未知版本",
|
|
||||||
"noNodeSelected": "无选中的节点",
|
"noNodeSelected": "无选中的节点",
|
||||||
"addNode": "添加节点",
|
"addNode": "添加节点",
|
||||||
"unableToValidateWorkflow": "无法验证工作流",
|
"unableToValidateWorkflow": "无法验证工作流",
|
||||||
@@ -833,9 +796,7 @@
|
|||||||
"workflowContact": "联系",
|
"workflowContact": "联系",
|
||||||
"animatedEdges": "边缘动效",
|
"animatedEdges": "边缘动效",
|
||||||
"nodeTemplate": "节点模板",
|
"nodeTemplate": "节点模板",
|
||||||
"unableToLoadWorkflow": "无法加载工作流",
|
|
||||||
"snapToGrid": "对齐网格",
|
"snapToGrid": "对齐网格",
|
||||||
"noFieldsLinearview": "线性视图中未添加任何字段",
|
|
||||||
"nodeSearch": "检索节点",
|
"nodeSearch": "检索节点",
|
||||||
"version": "版本",
|
"version": "版本",
|
||||||
"validateConnections": "验证连接和节点图",
|
"validateConnections": "验证连接和节点图",
|
||||||
@@ -850,8 +811,6 @@
|
|||||||
"fieldTypesMustMatch": "类型必须匹配",
|
"fieldTypesMustMatch": "类型必须匹配",
|
||||||
"workflow": "工作流",
|
"workflow": "工作流",
|
||||||
"animatedEdgesHelp": "为选中边缘和其连接的选中节点的边缘添加动画",
|
"animatedEdgesHelp": "为选中边缘和其连接的选中节点的边缘添加动画",
|
||||||
"unknownTemplate": "未知模板",
|
|
||||||
"removeLinearView": "从线性视图中移除",
|
|
||||||
"workflowTags": "标签",
|
"workflowTags": "标签",
|
||||||
"fullyContainNodesHelp": "节点必须完全位于选择框中才能被选中",
|
"fullyContainNodesHelp": "节点必须完全位于选择框中才能被选中",
|
||||||
"workflowValidation": "工作流验证错误",
|
"workflowValidation": "工作流验证错误",
|
||||||
@@ -885,7 +844,6 @@
|
|||||||
"node": "节点",
|
"node": "节点",
|
||||||
"collection": "合集",
|
"collection": "合集",
|
||||||
"string": "字符串",
|
"string": "字符串",
|
||||||
"mismatchedVersion": "无效的节点:类型为 {{type}} 的节点 {{node}} 版本不匹配(是否尝试更新?)",
|
|
||||||
"cannotDuplicateConnection": "无法创建重复的连接",
|
"cannotDuplicateConnection": "无法创建重复的连接",
|
||||||
"enum": "Enum (枚举)",
|
"enum": "Enum (枚举)",
|
||||||
"float": "浮点",
|
"float": "浮点",
|
||||||
@@ -896,7 +854,6 @@
|
|||||||
"unableToUpdateNodes_other": "{{count}} 个节点无法完成更新",
|
"unableToUpdateNodes_other": "{{count}} 个节点无法完成更新",
|
||||||
"inputFieldTypeParseError": "无法解析 {{node}} 的输入类型 {{field}}。({{message}})",
|
"inputFieldTypeParseError": "无法解析 {{node}} 的输入类型 {{field}}。({{message}})",
|
||||||
"unsupportedArrayItemType": "不支持的数组类型 \"{{type}}\"",
|
"unsupportedArrayItemType": "不支持的数组类型 \"{{type}}\"",
|
||||||
"addLinearView": "添加到线性视图",
|
|
||||||
"targetNodeFieldDoesNotExist": "无效的边缘:{{node}} 的目标/输入区域 {{field}} 不存在",
|
"targetNodeFieldDoesNotExist": "无效的边缘:{{node}} 的目标/输入区域 {{field}} 不存在",
|
||||||
"unsupportedMismatchedUnion": "合集或标量类型与基类 {{firstType}} 和 {{secondType}} 不匹配",
|
"unsupportedMismatchedUnion": "合集或标量类型与基类 {{firstType}} 和 {{secondType}} 不匹配",
|
||||||
"allNodesUpdated": "已更新所有节点",
|
"allNodesUpdated": "已更新所有节点",
|
||||||
@@ -916,7 +873,6 @@
|
|||||||
"collectionOrScalarFieldType": "{{name}} (单一项目或项目集合)",
|
"collectionOrScalarFieldType": "{{name}} (单一项目或项目集合)",
|
||||||
"nodeVersion": "节点版本",
|
"nodeVersion": "节点版本",
|
||||||
"deletedInvalidEdge": "已删除无效的边缘 {{source}} -> {{target}}",
|
"deletedInvalidEdge": "已删除无效的边缘 {{source}} -> {{target}}",
|
||||||
"unknownInput": "未知输入:{{name}}",
|
|
||||||
"prototypeDesc": "此调用是一个原型 (prototype)。它可能会在本项目更新期间发生破坏性更改,并且随时可能被删除。",
|
"prototypeDesc": "此调用是一个原型 (prototype)。它可能会在本项目更新期间发生破坏性更改,并且随时可能被删除。",
|
||||||
"betaDesc": "此调用尚处于测试阶段。在稳定之前,它可能会在项目更新期间发生破坏性更改。本项目计划长期支持这种调用。",
|
"betaDesc": "此调用尚处于测试阶段。在稳定之前,它可能会在项目更新期间发生破坏性更改。本项目计划长期支持这种调用。",
|
||||||
"newWorkflow": "新建工作流",
|
"newWorkflow": "新建工作流",
|
||||||
@@ -928,7 +884,6 @@
|
|||||||
"missingNode": "缺少调用节点",
|
"missingNode": "缺少调用节点",
|
||||||
"missingInvocationTemplate": "缺少调用模版",
|
"missingInvocationTemplate": "缺少调用模版",
|
||||||
"noFieldsViewMode": "此工作流程未选择任何要显示的字段.请查看完整工作流程以进行配置.",
|
"noFieldsViewMode": "此工作流程未选择任何要显示的字段.请查看完整工作流程以进行配置.",
|
||||||
"reorderLinearView": "调整线性视图顺序",
|
|
||||||
"viewMode": "在线性视图中使用",
|
"viewMode": "在线性视图中使用",
|
||||||
"showEdgeLabelsHelp": "在边缘上显示标签,指示连接的节点",
|
"showEdgeLabelsHelp": "在边缘上显示标签,指示连接的节点",
|
||||||
"cannotMixAndMatchCollectionItemTypes": "集合项目类型不能混用",
|
"cannotMixAndMatchCollectionItemTypes": "集合项目类型不能混用",
|
||||||
@@ -1002,7 +957,6 @@
|
|||||||
"session": "会话",
|
"session": "会话",
|
||||||
"enqueueing": "队列中的批次",
|
"enqueueing": "队列中的批次",
|
||||||
"graphFailedToQueue": "节点图加入队列失败",
|
"graphFailedToQueue": "节点图加入队列失败",
|
||||||
"batchFieldValues": "批处理值",
|
|
||||||
"time": "时间",
|
"time": "时间",
|
||||||
"openQueue": "打开队列",
|
"openQueue": "打开队列",
|
||||||
"prompts_other": "提示词",
|
"prompts_other": "提示词",
|
||||||
@@ -1021,18 +975,14 @@
|
|||||||
"refinerStart": "Refiner 开始作用时机",
|
"refinerStart": "Refiner 开始作用时机",
|
||||||
"scheduler": "调度器",
|
"scheduler": "调度器",
|
||||||
"cfgScale": "CFG 等级",
|
"cfgScale": "CFG 等级",
|
||||||
"negStylePrompt": "负向样式提示词",
|
|
||||||
"noModelsAvailable": "无可用模型",
|
"noModelsAvailable": "无可用模型",
|
||||||
"negAestheticScore": "负向美学评分",
|
"negAestheticScore": "负向美学评分",
|
||||||
"denoisingStrength": "去噪强度",
|
"denoisingStrength": "去噪强度",
|
||||||
"refinermodel": "Refiner 模型",
|
"refinermodel": "Refiner 模型",
|
||||||
"posAestheticScore": "正向美学评分",
|
"posAestheticScore": "正向美学评分",
|
||||||
"concatPromptStyle": "链接提示词 & 样式",
|
|
||||||
"loading": "加载中...",
|
"loading": "加载中...",
|
||||||
"steps": "步数",
|
"steps": "步数",
|
||||||
"posStylePrompt": "正向样式提示词",
|
|
||||||
"refiner": "Refiner",
|
"refiner": "Refiner",
|
||||||
"freePromptStyle": "手动输入样式提示词",
|
|
||||||
"refinerSteps": "精炼步数"
|
"refinerSteps": "精炼步数"
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
@@ -1059,8 +1009,6 @@
|
|||||||
"vae": "VAE",
|
"vae": "VAE",
|
||||||
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
||||||
"allPrompts": "所有提示",
|
"allPrompts": "所有提示",
|
||||||
"parsingFailed": "解析失败",
|
|
||||||
"recallParameter": "调用{{label}}",
|
|
||||||
"imageDimensions": "图像尺寸",
|
"imageDimensions": "图像尺寸",
|
||||||
"parameterSet": "已设置参数{{parameter}}",
|
"parameterSet": "已设置参数{{parameter}}",
|
||||||
"guidance": "指导",
|
"guidance": "指导",
|
||||||
@@ -1071,11 +1019,9 @@
|
|||||||
"models": {
|
"models": {
|
||||||
"noMatchingModels": "无相匹配的模型",
|
"noMatchingModels": "无相匹配的模型",
|
||||||
"loading": "加载中",
|
"loading": "加载中",
|
||||||
"noMatchingLoRAs": "无相匹配的 LoRA",
|
|
||||||
"noModelsAvailable": "无可用模型",
|
"noModelsAvailable": "无可用模型",
|
||||||
"selectModel": "选择一个模型",
|
"selectModel": "选择一个模型",
|
||||||
"noRefinerModelsInstalled": "无已安装的 SDXL Refiner 模型",
|
"noRefinerModelsInstalled": "无已安装的 SDXL Refiner 模型",
|
||||||
"noLoRAsInstalled": "无已安装的 LoRA",
|
|
||||||
"addLora": "添加 LoRA",
|
"addLora": "添加 LoRA",
|
||||||
"lora": "LoRA",
|
"lora": "LoRA",
|
||||||
"defaultVAE": "默认 VAE",
|
"defaultVAE": "默认 VAE",
|
||||||
@@ -1104,10 +1050,8 @@
|
|||||||
"deletedBoardsCannotbeRestored": "删除的面板无法恢复。选择“仅删除面板”选项后,相关图片将会被移至未分类区域。",
|
"deletedBoardsCannotbeRestored": "删除的面板无法恢复。选择“仅删除面板”选项后,相关图片将会被移至未分类区域。",
|
||||||
"movingImagesToBoard_other": "移动 {{count}} 张图像到面板:",
|
"movingImagesToBoard_other": "移动 {{count}} 张图像到面板:",
|
||||||
"selectedForAutoAdd": "已选中自动添加",
|
"selectedForAutoAdd": "已选中自动添加",
|
||||||
"hideBoards": "隐藏面板",
|
|
||||||
"noBoards": "没有{{boardType}}类型的面板",
|
"noBoards": "没有{{boardType}}类型的面板",
|
||||||
"unarchiveBoard": "恢复面板",
|
"unarchiveBoard": "恢复面板",
|
||||||
"viewBoards": "查看面板",
|
|
||||||
"addPrivateBoard": "创建私密面板",
|
"addPrivateBoard": "创建私密面板",
|
||||||
"addSharedBoard": "创建共享面板",
|
"addSharedBoard": "创建共享面板",
|
||||||
"boards": "面板",
|
"boards": "面板",
|
||||||
@@ -1576,8 +1520,6 @@
|
|||||||
"useCache": "使用缓存"
|
"useCache": "使用缓存"
|
||||||
},
|
},
|
||||||
"hrf": {
|
"hrf": {
|
||||||
"enableHrf": "启用高分辨率修复",
|
|
||||||
"upscaleMethod": "放大方法",
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"strength": "高分辨率修复强度",
|
"strength": "高分辨率修复强度",
|
||||||
"enabled": "高分辨率修复已启用",
|
"enabled": "高分辨率修复已启用",
|
||||||
@@ -1590,20 +1532,15 @@
|
|||||||
"workflowEditorMenu": "工作流编辑器菜单",
|
"workflowEditorMenu": "工作流编辑器菜单",
|
||||||
"workflowName": "工作流名称",
|
"workflowName": "工作流名称",
|
||||||
"saveWorkflow": "保存工作流",
|
"saveWorkflow": "保存工作流",
|
||||||
"openWorkflow": "打开工作流",
|
|
||||||
"clearWorkflowSearchFilter": "清除工作流检索过滤器",
|
|
||||||
"workflowLibrary": "工作流库",
|
"workflowLibrary": "工作流库",
|
||||||
"downloadWorkflow": "保存到文件",
|
"downloadWorkflow": "保存到文件",
|
||||||
"workflowSaved": "已保存工作流",
|
"workflowSaved": "已保存工作流",
|
||||||
"unnamedWorkflow": "未命名的工作流",
|
"unnamedWorkflow": "未命名的工作流",
|
||||||
"savingWorkflow": "保存工作流中...",
|
"savingWorkflow": "保存工作流中...",
|
||||||
"problemLoading": "加载工作流时出现问题",
|
|
||||||
"loading": "加载工作流中",
|
"loading": "加载工作流中",
|
||||||
"searchWorkflows": "检索工作流",
|
|
||||||
"problemSavingWorkflow": "保存工作流时出现问题",
|
"problemSavingWorkflow": "保存工作流时出现问题",
|
||||||
"deleteWorkflow": "删除工作流",
|
"deleteWorkflow": "删除工作流",
|
||||||
"workflows": "工作流",
|
"workflows": "工作流",
|
||||||
"noDescription": "无描述",
|
|
||||||
"uploadWorkflow": "从文件中加载",
|
"uploadWorkflow": "从文件中加载",
|
||||||
"newWorkflowCreated": "已创建新的工作流",
|
"newWorkflowCreated": "已创建新的工作流",
|
||||||
"name": "名称",
|
"name": "名称",
|
||||||
@@ -1623,9 +1560,6 @@
|
|||||||
"copyShareLinkForWorkflow": "复制工作流程的分享链接",
|
"copyShareLinkForWorkflow": "复制工作流程的分享链接",
|
||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
"download": "下载",
|
"download": "下载",
|
||||||
"defaultWorkflows": "默认工作流程",
|
|
||||||
"userWorkflows": "用户工作流程",
|
|
||||||
"projectWorkflows": "项目工作流程",
|
|
||||||
"copyShareLink": "复制分享链接",
|
"copyShareLink": "复制分享链接",
|
||||||
"chooseWorkflowFromLibrary": "从库中选择工作流程",
|
"chooseWorkflowFromLibrary": "从库中选择工作流程",
|
||||||
"deleteWorkflow2": "您确定要删除此工作流程吗?此操作无法撤销。"
|
"deleteWorkflow2": "您确定要删除此工作流程吗?此操作无法撤销。"
|
||||||
@@ -1663,7 +1597,6 @@
|
|||||||
"moveToBack": "移动到后面",
|
"moveToBack": "移动到后面",
|
||||||
"moveToFront": "移动到前面",
|
"moveToFront": "移动到前面",
|
||||||
"addLayer": "添加层",
|
"addLayer": "添加层",
|
||||||
"deletePrompt": "删除提示词",
|
|
||||||
"addPositivePrompt": "添加 $t(controlLayers.prompt)",
|
"addPositivePrompt": "添加 $t(controlLayers.prompt)",
|
||||||
"addNegativePrompt": "添加 $t(controlLayers.negativePrompt)",
|
"addNegativePrompt": "添加 $t(controlLayers.negativePrompt)",
|
||||||
"rectangle": "矩形",
|
"rectangle": "矩形",
|
||||||
@@ -1687,7 +1620,6 @@
|
|||||||
"maskFill": "遮罩填充",
|
"maskFill": "遮罩填充",
|
||||||
"newCanvasFromImage": "从图像创建新画布",
|
"newCanvasFromImage": "从图像创建新画布",
|
||||||
"pullBboxIntoReferenceImageOk": "边界框已导入到参考图像",
|
"pullBboxIntoReferenceImageOk": "边界框已导入到参考图像",
|
||||||
"globalReferenceImage_withCount_other": "全局参考图像",
|
|
||||||
"addInpaintMask": "添加 $t(controlLayers.inpaintMask)",
|
"addInpaintMask": "添加 $t(controlLayers.inpaintMask)",
|
||||||
"referenceImage": "参考图像",
|
"referenceImage": "参考图像",
|
||||||
"globalReferenceImage": "全局参考图像",
|
"globalReferenceImage": "全局参考图像",
|
||||||
@@ -1696,14 +1628,10 @@
|
|||||||
"copyRasterLayerTo": "复制 $t(controlLayers.rasterLayer) 到",
|
"copyRasterLayerTo": "复制 $t(controlLayers.rasterLayer) 到",
|
||||||
"clearHistory": "清除历史记录",
|
"clearHistory": "清除历史记录",
|
||||||
"inpaintMask": "修复遮罩",
|
"inpaintMask": "修复遮罩",
|
||||||
"regionalGuidance_withCount_visible": "区域引导({{count}} 个)",
|
|
||||||
"inpaintMasks_withCount_hidden": "修复遮罩({{count}} 个已隐藏)",
|
|
||||||
"enableAutoNegative": "启用自动负面提示",
|
"enableAutoNegative": "启用自动负面提示",
|
||||||
"disableAutoNegative": "禁用自动负面提示",
|
"disableAutoNegative": "禁用自动负面提示",
|
||||||
"deleteReferenceImage": "删除参考图像",
|
"deleteReferenceImage": "删除参考图像",
|
||||||
"sendToCanvas": "发送到画布",
|
"sendToCanvas": "发送到画布",
|
||||||
"controlLayers_withCount_visible": "控制图层({{count}} 个)",
|
|
||||||
"rasterLayers_withCount_visible": "栅格图层({{count}} 个)",
|
|
||||||
"convertRegionalGuidanceTo": "将 $t(controlLayers.regionalGuidance) 转换为",
|
"convertRegionalGuidanceTo": "将 $t(controlLayers.regionalGuidance) 转换为",
|
||||||
"newInpaintMask": "新建 $t(controlLayers.inpaintMask)",
|
"newInpaintMask": "新建 $t(controlLayers.inpaintMask)",
|
||||||
"regionIsEmpty": "选定区域为空",
|
"regionIsEmpty": "选定区域为空",
|
||||||
@@ -1715,14 +1643,12 @@
|
|||||||
"addRasterLayer": "添加 $t(controlLayers.rasterLayer)",
|
"addRasterLayer": "添加 $t(controlLayers.rasterLayer)",
|
||||||
"newRasterLayerOk": "已创建栅格层",
|
"newRasterLayerOk": "已创建栅格层",
|
||||||
"newRasterLayerError": "创建栅格层时出现问题",
|
"newRasterLayerError": "创建栅格层时出现问题",
|
||||||
"inpaintMasks_withCount_visible": "修复遮罩({{count}} 个)",
|
|
||||||
"convertRasterLayerTo": "将 $t(controlLayers.rasterLayer) 转换为",
|
"convertRasterLayerTo": "将 $t(controlLayers.rasterLayer) 转换为",
|
||||||
"copyControlLayerTo": "复制 $t(controlLayers.controlLayer) 到",
|
"copyControlLayerTo": "复制 $t(controlLayers.controlLayer) 到",
|
||||||
"copyInpaintMaskTo": "复制 $t(controlLayers.inpaintMask) 到",
|
"copyInpaintMaskTo": "复制 $t(controlLayers.inpaintMask) 到",
|
||||||
"copyRegionalGuidanceTo": "复制 $t(controlLayers.regionalGuidance) 到",
|
"copyRegionalGuidanceTo": "复制 $t(controlLayers.regionalGuidance) 到",
|
||||||
"newRasterLayer": "新建 $t(controlLayers.rasterLayer)",
|
"newRasterLayer": "新建 $t(controlLayers.rasterLayer)",
|
||||||
"newControlLayer": "新建 $t(controlLayers.controlLayer)",
|
"newControlLayer": "新建 $t(controlLayers.controlLayer)",
|
||||||
"newImg2ImgCanvasFromImage": "从图像创建新的图生图",
|
|
||||||
"rasterLayer": "栅格层",
|
"rasterLayer": "栅格层",
|
||||||
"controlLayer": "控制层",
|
"controlLayer": "控制层",
|
||||||
"outputOnlyMaskedRegions": "仅输出生成的区域",
|
"outputOnlyMaskedRegions": "仅输出生成的区域",
|
||||||
@@ -1735,36 +1661,22 @@
|
|||||||
"bboxOverlay": "显示边界框覆盖层",
|
"bboxOverlay": "显示边界框覆盖层",
|
||||||
"clipToBbox": "将Clip限制到边界框",
|
"clipToBbox": "将Clip限制到边界框",
|
||||||
"width": "宽度",
|
"width": "宽度",
|
||||||
"addGlobalReferenceImage": "添加 $t(controlLayers.globalReferenceImage)",
|
|
||||||
"inpaintMask_withCount_other": "修复遮罩",
|
"inpaintMask_withCount_other": "修复遮罩",
|
||||||
"regionalGuidance_withCount_other": "区域引导",
|
"regionalGuidance_withCount_other": "区域引导",
|
||||||
"newRegionalReferenceImageError": "创建局部参考图像时出现问题",
|
"newRegionalReferenceImageError": "创建局部参考图像时出现问题",
|
||||||
"pullBboxIntoLayerError": "将边界框导入图层时出现问题",
|
"pullBboxIntoLayerError": "将边界框导入图层时出现问题",
|
||||||
"pullBboxIntoLayerOk": "边界框已导入到图层",
|
"pullBboxIntoLayerOk": "边界框已导入到图层",
|
||||||
"sendToCanvasDesc": "按下“Invoke”按钮会将您的工作进度暂存到画布上。",
|
|
||||||
"sendToGallery": "发送到图库",
|
|
||||||
"sendToGalleryDesc": "按下“Invoke”键会生成并保存一张唯一的图像到您的图库中。",
|
|
||||||
"rasterLayer_withCount_other": "栅格图层",
|
"rasterLayer_withCount_other": "栅格图层",
|
||||||
"mergeDown": "向下合并",
|
"mergeDown": "向下合并",
|
||||||
"clearCaches": "清除缓存",
|
"clearCaches": "清除缓存",
|
||||||
"recalculateRects": "重新计算矩形",
|
"recalculateRects": "重新计算矩形",
|
||||||
"duplicate": "复制",
|
"duplicate": "复制",
|
||||||
"regionalGuidance_withCount_hidden": "区域引导({{count}} 个已隐藏)",
|
|
||||||
"convertControlLayerTo": "将 $t(controlLayers.controlLayer) 转换为",
|
"convertControlLayerTo": "将 $t(controlLayers.controlLayer) 转换为",
|
||||||
"convertInpaintMaskTo": "将 $t(controlLayers.inpaintMask) 转换为",
|
"convertInpaintMaskTo": "将 $t(controlLayers.inpaintMask) 转换为",
|
||||||
"viewProgressInViewer": "在 <Btn>图像查看器</Btn> 中查看进度和输出结果。",
|
|
||||||
"viewProgressOnCanvas": "在 <Btn>画布</Btn> 上查看进度和暂存的输出内容。",
|
|
||||||
"sendingToGallery": "将生成内容发送到图库",
|
|
||||||
"copyToClipboard": "复制到剪贴板",
|
"copyToClipboard": "复制到剪贴板",
|
||||||
"controlLayer_withCount_other": "控制图层",
|
"controlLayer_withCount_other": "控制图层",
|
||||||
"sendingToCanvas": "在画布上准备生成",
|
|
||||||
"addReferenceImage": "添加 $t(controlLayers.referenceImage)",
|
"addReferenceImage": "添加 $t(controlLayers.referenceImage)",
|
||||||
"addRegionalGuidance": "添加 $t(controlLayers.regionalGuidance)",
|
"addRegionalGuidance": "添加 $t(controlLayers.regionalGuidance)",
|
||||||
"controlLayers_withCount_hidden": "控制图层({{count}} 个已隐藏)",
|
|
||||||
"rasterLayers_withCount_hidden": "栅格图层({{count}} 个已隐藏)",
|
|
||||||
"globalReferenceImages_withCount_hidden": "全局参考图像({{count}} 个已隐藏)",
|
|
||||||
"globalReferenceImages_withCount_visible": "全局参考图像({{count}} 个)",
|
|
||||||
"layer_withCount_other": "图层({{count}} 个)",
|
|
||||||
"enableTransparencyEffect": "启用透明效果",
|
"enableTransparencyEffect": "启用透明效果",
|
||||||
"disableTransparencyEffect": "禁用透明效果",
|
"disableTransparencyEffect": "禁用透明效果",
|
||||||
"hidingType": "隐藏 {{type}}",
|
"hidingType": "隐藏 {{type}}",
|
||||||
@@ -1772,7 +1684,6 @@
|
|||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"generation": "生成",
|
|
||||||
"queue": "队列",
|
"queue": "队列",
|
||||||
"canvas": "画布",
|
"canvas": "画布",
|
||||||
"upscaling": "放大中",
|
"upscaling": "放大中",
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user