Compare commits
1212 Commits
auth-v4.3.
...
photos-v1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87fae3e6d9 | ||
|
|
89cd360f93 | ||
|
|
f1274afdd4 | ||
|
|
0a5005d064 | ||
|
|
b54fe20520 | ||
|
|
204a046e0a | ||
|
|
4f21f1e94e | ||
|
|
039866cf3b | ||
|
|
c4b860a8fe | ||
|
|
1d1e01898f | ||
|
|
53f947b5f0 | ||
|
|
1e3a112c35 | ||
|
|
3dc23092a4 | ||
|
|
fd65e81079 | ||
|
|
eec0480618 | ||
|
|
fac5ab5079 | ||
|
|
051ce42ae6 | ||
|
|
297d4bdbf5 | ||
|
|
9f9ad19d4b | ||
|
|
4d26de8ffd | ||
|
|
f16846b82e | ||
|
|
b44ef9f68a | ||
|
|
cf28fddfb3 | ||
|
|
6c3b2ee25e | ||
|
|
2d8310460b | ||
|
|
0d5363c7a1 | ||
|
|
2f277bbffc | ||
|
|
cbf3340bf2 | ||
|
|
de918f42e6 | ||
|
|
6bd1547e09 | ||
|
|
aa70b2a437 | ||
|
|
13b74f387f | ||
|
|
d52e3894d8 | ||
|
|
780c2c2493 | ||
|
|
405c4d1258 | ||
|
|
5f498b01ee | ||
|
|
af5020e62c | ||
|
|
7ddf0f6fe1 | ||
|
|
5fa951ad4b | ||
|
|
e9ceb705f6 | ||
|
|
9dcd9d63b2 | ||
|
|
129e9f8f49 | ||
|
|
6f02df19c6 | ||
|
|
c8efc1a590 | ||
|
|
8b1a659d68 | ||
|
|
9114fbca27 | ||
|
|
e25d71a7d4 | ||
|
|
1018765f7c | ||
|
|
0fb984d031 | ||
|
|
4ad3560387 | ||
|
|
482b175324 | ||
|
|
894d7382e8 | ||
|
|
53cc78d3e3 | ||
|
|
a634500e55 | ||
|
|
ee8ecd456c | ||
|
|
d69a22a73e | ||
|
|
8b1af42cf0 | ||
|
|
41e7d0056b | ||
|
|
d170789446 | ||
|
|
afbbde5f2b | ||
|
|
4e3112a4f6 | ||
|
|
a4950ece53 | ||
|
|
1a01d759b0 | ||
|
|
175b51fdb3 | ||
|
|
a4ba2edc54 | ||
|
|
1a8a26e9e4 | ||
|
|
a2ddcfd34f | ||
|
|
95700f52f6 | ||
|
|
fc16638bfe | ||
|
|
5d375eb837 | ||
|
|
fe86d3bb34 | ||
|
|
77956d0f67 | ||
|
|
53a22a8d58 | ||
|
|
a5b178d283 | ||
|
|
e651c1e328 | ||
|
|
9069975bf0 | ||
|
|
5938e755ae | ||
|
|
6f7b3738b3 | ||
|
|
4ee9f45b3a | ||
|
|
c835a3d009 | ||
|
|
6d3e55a6d9 | ||
|
|
08b7986d70 | ||
|
|
067c8b2a76 | ||
|
|
d355d18acb | ||
|
|
0e2a0388ff | ||
|
|
2baf3a3dd7 | ||
|
|
854610dd48 | ||
|
|
61be57fef5 | ||
|
|
8d59d7e254 | ||
|
|
1bcf728b3a | ||
|
|
5797be3460 | ||
|
|
20f50e4816 | ||
|
|
5064ebf4d3 | ||
|
|
eb783f0fff | ||
|
|
ca8f310868 | ||
|
|
2e0a2802e7 | ||
|
|
7868c2e16e | ||
|
|
ace5dc04e2 | ||
|
|
4249491730 | ||
|
|
a958380a1d | ||
|
|
b0d940e65b | ||
|
|
5b8472b5a9 | ||
|
|
6bb7627d47 | ||
|
|
b00c406b09 | ||
|
|
ff9494d438 | ||
|
|
b24b5893ae | ||
|
|
9716ff80c4 | ||
|
|
2808f72233 | ||
|
|
5dd097ee09 | ||
|
|
be9fddf1d4 | ||
|
|
f9b3f6e9eb | ||
|
|
dcb73abdec | ||
|
|
a14c6f4d26 | ||
|
|
7afdfe6ed9 | ||
|
|
8ff8981b76 | ||
|
|
b89f247f42 | ||
|
|
c3e5a037c0 | ||
|
|
70a1894071 | ||
|
|
42453675b2 | ||
|
|
bdd09e12d8 | ||
|
|
407ad41520 | ||
|
|
185759d234 | ||
|
|
860760784a | ||
|
|
de10292a84 | ||
|
|
95f10e5a45 | ||
|
|
eabacf24ad | ||
|
|
61ffcfdc93 | ||
|
|
0ade0a2807 | ||
|
|
1e2fb13908 | ||
|
|
856e126bc8 | ||
|
|
845d014945 | ||
|
|
d8b54f5211 | ||
|
|
bc059c861f | ||
|
|
b52ee5bbfb | ||
|
|
93c85a57e4 | ||
|
|
e01826217d | ||
|
|
b79b7ff3ef | ||
|
|
7d52e3d852 | ||
|
|
9a647d6f78 | ||
|
|
6e99206523 | ||
|
|
d7af21aa84 | ||
|
|
ced1f6e164 | ||
|
|
4ea3989a33 | ||
|
|
641a99b823 | ||
|
|
7b48dbc1ad | ||
|
|
54c69e7aa5 | ||
|
|
f8bd8c9955 | ||
|
|
60246be861 | ||
|
|
d71016500a | ||
|
|
f44c2d14c7 | ||
|
|
9c26f4040a | ||
|
|
79e048b4b7 | ||
|
|
5c0ce038d1 | ||
|
|
2903388c94 | ||
|
|
331a65d2a0 | ||
|
|
6c6ab8f463 | ||
|
|
441a884314 | ||
|
|
3372d83c5d | ||
|
|
0cf50513cc | ||
|
|
7ccf473190 | ||
|
|
c1f7a01ed2 | ||
|
|
256243e273 | ||
|
|
dc9dc5d8f9 | ||
|
|
6969385089 | ||
|
|
87a1c9417e | ||
|
|
6d13ff5151 | ||
|
|
0b5317867f | ||
|
|
a32c8116a2 | ||
|
|
d8cd81c702 | ||
|
|
18e7bbd1ed | ||
|
|
63850df06a | ||
|
|
886ab6d106 | ||
|
|
d17296216c | ||
|
|
55ee8b90b9 | ||
|
|
634561347f | ||
|
|
575abdb8eb | ||
|
|
e998502b53 | ||
|
|
2ada68e837 | ||
|
|
28822a8dc1 | ||
|
|
deaa9a703d | ||
|
|
4510edf8bd | ||
|
|
7af59a1ecf | ||
|
|
e003c783f5 | ||
|
|
379d2487bd | ||
|
|
8cdbb737dc | ||
|
|
d528d97a0f | ||
|
|
682e4a913f | ||
|
|
a72041b8ba | ||
|
|
ab1a8aa592 | ||
|
|
c37a0339d2 | ||
|
|
3b60f4954b | ||
|
|
b2ea248a5c | ||
|
|
1bda14fb6f | ||
|
|
54e8d6392d | ||
|
|
afa9e03743 | ||
|
|
a4eaf04a33 | ||
|
|
d30f0fba04 | ||
|
|
b2855cfd72 | ||
|
|
06d260f40a | ||
|
|
fb16346b0d | ||
|
|
41b1638838 | ||
|
|
702b3a8868 | ||
|
|
3572c4328d | ||
|
|
1c2b8061dc | ||
|
|
a9edcead06 | ||
|
|
5a574c69d3 | ||
|
|
192905b21e | ||
|
|
52a533a1e1 | ||
|
|
0314e94359 | ||
|
|
cbef1a9145 | ||
|
|
822c33940e | ||
|
|
eb29c48f0e | ||
|
|
c77b4f176c | ||
|
|
afcc7b1e46 | ||
|
|
84dda89e15 | ||
|
|
4bbc0d1f46 | ||
|
|
aa6d6f4e77 | ||
|
|
ff26dd5652 | ||
|
|
b68d95d481 | ||
|
|
ec1b54cbb1 | ||
|
|
459540fe7a | ||
|
|
2255ea1b92 | ||
|
|
ac704f1082 | ||
|
|
4db2e42ee3 | ||
|
|
f5949f5bd4 | ||
|
|
c4feb4b764 | ||
|
|
29bab5705b | ||
|
|
2ebeed3b6f | ||
|
|
a0dbcd3dbe | ||
|
|
81137652d4 | ||
|
|
4e1418b11a | ||
|
|
91268341be | ||
|
|
fb8fc051a9 | ||
|
|
d99914c4e9 | ||
|
|
736b3fc613 | ||
|
|
ef7f45aa3d | ||
|
|
4dc741151b | ||
|
|
e4471af4cb | ||
|
|
057df349b7 | ||
|
|
24c7b49132 | ||
|
|
5df009c7c7 | ||
|
|
1d276c795c | ||
|
|
bc762b972f | ||
|
|
36e4c06dd6 | ||
|
|
ceb3d3fe42 | ||
|
|
1dc806d270 | ||
|
|
8d03df5c36 | ||
|
|
a1ef8d33d3 | ||
|
|
4f347c1afd | ||
|
|
8171d56168 | ||
|
|
7e7751b5be | ||
|
|
d19a0fccda | ||
|
|
5b38ef394b | ||
|
|
ad87470c25 | ||
|
|
67140fe7f2 | ||
|
|
b372ba47ba | ||
|
|
24c66a9b6b | ||
|
|
201ef60f07 | ||
|
|
89294f2a76 | ||
|
|
4772557f7a | ||
|
|
073d2c5684 | ||
|
|
e022e7ae5b | ||
|
|
2cdeb88b4d | ||
|
|
ca319e501e | ||
|
|
05898dfbe2 | ||
|
|
c129cc15b5 | ||
|
|
a683883733 | ||
|
|
69b575cc66 | ||
|
|
63a4972839 | ||
|
|
6188578d18 | ||
|
|
5a4d8950af | ||
|
|
5007204944 | ||
|
|
4a19fc077e | ||
|
|
2b29f55587 | ||
|
|
4cc8ff2fb1 | ||
|
|
de29246304 | ||
|
|
8deb52301a | ||
|
|
16a20e8b0d | ||
|
|
3824bfbdd5 | ||
|
|
c996c794fd | ||
|
|
ef245e5c02 | ||
|
|
4dc6890afc | ||
|
|
87195f3801 | ||
|
|
8ce45a4fa8 | ||
|
|
520e5d4ae7 | ||
|
|
2a8e167e42 | ||
|
|
2f7bde36bd | ||
|
|
ace375b7f6 | ||
|
|
cde6ebfa39 | ||
|
|
a1e56a457f | ||
|
|
a4ebf972e1 | ||
|
|
7d5bed0493 | ||
|
|
d449bd0f90 | ||
|
|
5d14ca8439 | ||
|
|
619f6795e2 | ||
|
|
04cd1d3bb3 | ||
|
|
0960f189ce | ||
|
|
734b836a7a | ||
|
|
91447cdc77 | ||
|
|
961501a6fb | ||
|
|
914893eae6 | ||
|
|
7a10f4c145 | ||
|
|
092f64c3ca | ||
|
|
bdecb04398 | ||
|
|
e25418e5a6 | ||
|
|
a062c1ccc3 | ||
|
|
d1ae4d52dd | ||
|
|
3c532cd4f4 | ||
|
|
013389c696 | ||
|
|
9ca418d915 | ||
|
|
a52a3e5e57 | ||
|
|
2d739ef4de | ||
|
|
300300a8b9 | ||
|
|
be00cbaa51 | ||
|
|
43641b0b9e | ||
|
|
43cdd10e85 | ||
|
|
539145d38d | ||
|
|
08bb2f25fb | ||
|
|
55264445b2 | ||
|
|
bdadf8dc9c | ||
|
|
1c3428d89d | ||
|
|
6e4a856ea4 | ||
|
|
40ff361af1 | ||
|
|
11fae5e87c | ||
|
|
465e69b254 | ||
|
|
63b0cee589 | ||
|
|
574eea58fc | ||
|
|
f848fe0938 | ||
|
|
138310b8f8 | ||
|
|
3d63ded84d | ||
|
|
b7cd55aec3 | ||
|
|
aadab316f6 | ||
|
|
8bad8b87b1 | ||
|
|
2ff69f661e | ||
|
|
10c65f13c8 | ||
|
|
761c976d7e | ||
|
|
423a7eec37 | ||
|
|
1f7e74131b | ||
|
|
c8b23f80e2 | ||
|
|
191db47d79 | ||
|
|
34621dd00f | ||
|
|
d127199ade | ||
|
|
f44e90801f | ||
|
|
ded497d421 | ||
|
|
a3e48706de | ||
|
|
2709f69f2a | ||
|
|
2b32cd4277 | ||
|
|
57934f612e | ||
|
|
eae5e12c71 | ||
|
|
aef50f3f95 | ||
|
|
6772027c27 | ||
|
|
f386a0a72e | ||
|
|
9c94bcffaa | ||
|
|
6b703e9601 | ||
|
|
22bae0292d | ||
|
|
4c7121fd6c | ||
|
|
f53745bbb0 | ||
|
|
1c6e343994 | ||
|
|
949807bc97 | ||
|
|
fea46532f9 | ||
|
|
8824df29d4 | ||
|
|
2da2616ec1 | ||
|
|
2144f57ee0 | ||
|
|
476fe1b624 | ||
|
|
fb7fc53263 | ||
|
|
a842cdfe4e | ||
|
|
d5de1b5ce2 | ||
|
|
a1801435bd | ||
|
|
bc02238fd8 | ||
|
|
49ef8a693b | ||
|
|
6f585c3ad0 | ||
|
|
18f9f0048a | ||
|
|
6a7ba4156f | ||
|
|
30995b3b73 | ||
|
|
ff705280c7 | ||
|
|
6ff6594a81 | ||
|
|
69f12125ec | ||
|
|
862b11c530 | ||
|
|
e40afac212 | ||
|
|
8c66d9dac0 | ||
|
|
a880726f16 | ||
|
|
b2ab0679b4 | ||
|
|
d63ecf518e | ||
|
|
c5cdaf3e0b | ||
|
|
61f1cd6952 | ||
|
|
e6d4a779c5 | ||
|
|
14087ec5e9 | ||
|
|
15daa9e453 | ||
|
|
73728e60e0 | ||
|
|
5c925c4265 | ||
|
|
83bf336101 | ||
|
|
d5b9a0a92b | ||
|
|
40d84f10a8 | ||
|
|
bffd4d83a5 | ||
|
|
59a534225c | ||
|
|
810ee3d9fe | ||
|
|
9605637e50 | ||
|
|
9016394ccc | ||
|
|
a518bbd608 | ||
|
|
1c4ebcccb1 | ||
|
|
793fd5ba39 | ||
|
|
9b1eacf736 | ||
|
|
cae9988c9a | ||
|
|
538a5df32d | ||
|
|
853b916cf1 | ||
|
|
93d6f58660 | ||
|
|
7b145f0898 | ||
|
|
add09a601d | ||
|
|
cab711d88e | ||
|
|
c392bd2fd2 | ||
|
|
5dda596544 | ||
|
|
8101bee2fd | ||
|
|
c234bc7be8 | ||
|
|
27fd372d62 | ||
|
|
66f23283c1 | ||
|
|
8d7bc81c20 | ||
|
|
5e3ebd4a60 | ||
|
|
f4a4f71135 | ||
|
|
41e870f7a0 | ||
|
|
0342e1ef56 | ||
|
|
efed42ce4a | ||
|
|
185c5f5c43 | ||
|
|
6f5b33ea01 | ||
|
|
ef9d925686 | ||
|
|
d6a8373e5d | ||
|
|
e84f46f435 | ||
|
|
c1193be61c | ||
|
|
9b460ca1dc | ||
|
|
bd0ad0d1b4 | ||
|
|
d19322c1ae | ||
|
|
e71f5cecc7 | ||
|
|
622a368b45 | ||
|
|
72aec4bc5a | ||
|
|
c899725ed1 | ||
|
|
e15eb8d7c7 | ||
|
|
b38c49502b | ||
|
|
0fdee342eb | ||
|
|
0641ce389d | ||
|
|
f34ac356e9 | ||
|
|
120f9cef4d | ||
|
|
9b4247680a | ||
|
|
5d69376b54 | ||
|
|
64260896a0 | ||
|
|
2af46f62c8 | ||
|
|
a53701bc41 | ||
|
|
7a408a6242 | ||
|
|
6b9885c5d7 | ||
|
|
caa453d49d | ||
|
|
dd80acd4f4 | ||
|
|
5aa7682812 | ||
|
|
cb9a88e636 | ||
|
|
3a32659dd4 | ||
|
|
d5b5a26d9a | ||
|
|
d2980abb7a | ||
|
|
1a2f606d94 | ||
|
|
a101dba6cd | ||
|
|
491de296ca | ||
|
|
ab2719a79c | ||
|
|
a614636789 | ||
|
|
48e9032ac1 | ||
|
|
1d2e18444c | ||
|
|
7f9e01a841 | ||
|
|
6933c77f36 | ||
|
|
61cacdddc0 | ||
|
|
936d578093 | ||
|
|
167a81f121 | ||
|
|
b550ee6b15 | ||
|
|
54feb7b2f9 | ||
|
|
f9dad575ec | ||
|
|
a39948ccc3 | ||
|
|
dfabd648d5 | ||
|
|
21e5bbb0fd | ||
|
|
10a0165a0f | ||
|
|
07c640cf90 | ||
|
|
9fa13508b8 | ||
|
|
1c099a60e8 | ||
|
|
efbdaef9ce | ||
|
|
65ddea0f7f | ||
|
|
ed15b47f1b | ||
|
|
6496660718 | ||
|
|
691d31d0a9 | ||
|
|
1f40901fd1 | ||
|
|
4982c1209e | ||
|
|
9170c80b26 | ||
|
|
1b4cb2ed99 | ||
|
|
45fe850afc | ||
|
|
6ae8abb492 | ||
|
|
f077213c62 | ||
|
|
92a8db53bd | ||
|
|
c812b80887 | ||
|
|
62c1f0c6ac | ||
|
|
cc486983ab | ||
|
|
a103bd4cca | ||
|
|
c56d9b312d | ||
|
|
6dda5d8762 | ||
|
|
3e9d78c866 | ||
|
|
c3eb55b258 | ||
|
|
0666bf56df | ||
|
|
fcd8298e10 | ||
|
|
62bd2d13d6 | ||
|
|
4263906c61 | ||
|
|
72acefadd4 | ||
|
|
2be8db783c | ||
|
|
f8e90e765f | ||
|
|
9424d26f55 | ||
|
|
bb352f3266 | ||
|
|
85d55c7d26 | ||
|
|
6062c20251 | ||
|
|
8861e0562f | ||
|
|
5e4de0793a | ||
|
|
80d36b5a91 | ||
|
|
f22ad9611f | ||
|
|
8e038dda14 | ||
|
|
9cafa72ae3 | ||
|
|
a5eba40f29 | ||
|
|
0c9d7321eb | ||
|
|
d98d220019 | ||
|
|
5fc5d0ef48 | ||
|
|
ce6b0da630 | ||
|
|
d1d91338af | ||
|
|
790c022730 | ||
|
|
be65f0fba8 | ||
|
|
3677d53ea9 | ||
|
|
84017c7397 | ||
|
|
f92101eaf8 | ||
|
|
1d3ca81308 | ||
|
|
e9f22cff93 | ||
|
|
e250759999 | ||
|
|
d5740c4b66 | ||
|
|
07bd28381d | ||
|
|
8c8c9d7ffa | ||
|
|
d06016dddc | ||
|
|
f4531ef088 | ||
|
|
56772521e0 | ||
|
|
244ec87a9a | ||
|
|
043d0936ef | ||
|
|
9129910981 | ||
|
|
4194c53d08 | ||
|
|
9d5960c6fe | ||
|
|
f088c24abe | ||
|
|
e197423c1d | ||
|
|
b22bc93e57 | ||
|
|
236301dc16 | ||
|
|
b4a60fd2f4 | ||
|
|
079ac37d1f | ||
|
|
3deb138b77 | ||
|
|
5b9b328c99 | ||
|
|
e541f0522d | ||
|
|
93413687c9 | ||
|
|
48ef4df187 | ||
|
|
96d748dc87 | ||
|
|
9d28fa99a3 | ||
|
|
f9cce787f7 | ||
|
|
dcc02db296 | ||
|
|
c0fd71a668 | ||
|
|
116f22a853 | ||
|
|
501b541134 | ||
|
|
1785baf4af | ||
|
|
b08d8de1c8 | ||
|
|
0284287c9c | ||
|
|
be2665f57f | ||
|
|
b721a84889 | ||
|
|
442d6526be | ||
|
|
08346e5bcd | ||
|
|
e35b4eac40 | ||
|
|
7c6da77c21 | ||
|
|
ab59a15769 | ||
|
|
45e07f3be0 | ||
|
|
a2df4fb48a | ||
|
|
5a2ba82fff | ||
|
|
6a907d0f7d | ||
|
|
20dfec2e67 | ||
|
|
96c3880e38 | ||
|
|
2adabc1e24 | ||
|
|
a6ca7a5792 | ||
|
|
6abea7ae6d | ||
|
|
429b6be368 | ||
|
|
ed9af710fe | ||
|
|
f8ef263e6d | ||
|
|
fae47f102e | ||
|
|
240bfdd296 | ||
|
|
672123d746 | ||
|
|
51d55ee92b | ||
|
|
cc3f20831a | ||
|
|
a282f82909 | ||
|
|
2fde22272e | ||
|
|
d63da04392 | ||
|
|
7cd3f8e2ac | ||
|
|
9517514396 | ||
|
|
41a4f3d286 | ||
|
|
91fefa7eb9 | ||
|
|
63b9a09a2d | ||
|
|
d1a2efff0e | ||
|
|
00d723ca7c | ||
|
|
47b2e0d0ab | ||
|
|
ac9dbd4ee1 | ||
|
|
8b6f6346be | ||
|
|
73ad6b45fb | ||
|
|
020f8cea23 | ||
|
|
d52accdcc9 | ||
|
|
975c7ae8d1 | ||
|
|
c4463d6251 | ||
|
|
e96888d2c9 | ||
|
|
03df804868 | ||
|
|
685e0099c8 | ||
|
|
4a924a7296 | ||
|
|
1f4beab764 | ||
|
|
4fd121adf1 | ||
|
|
a942e68d27 | ||
|
|
ece63f7a8d | ||
|
|
dcdc26e4e8 | ||
|
|
ffa8ccd0d3 | ||
|
|
01f612e450 | ||
|
|
70f80c7b57 | ||
|
|
ab875683ed | ||
|
|
638108a819 | ||
|
|
dec193599f | ||
|
|
4913746a31 | ||
|
|
0966ab7d19 | ||
|
|
83ae436008 | ||
|
|
8f2a2caac1 | ||
|
|
7cc6319d5f | ||
|
|
eabe213207 | ||
|
|
5b7f821a26 | ||
|
|
939ab4398c | ||
|
|
c4effd4ef4 | ||
|
|
bcf1a044cc | ||
|
|
2dd9a080c6 | ||
|
|
57a4e6dd15 | ||
|
|
93cd2d30e4 | ||
|
|
f65db123f2 | ||
|
|
d697f22896 | ||
|
|
65faa98621 | ||
|
|
e4a0125f1c | ||
|
|
98d06f975c | ||
|
|
d0ebe65af4 | ||
|
|
08d936be45 | ||
|
|
71596ebd8e | ||
|
|
8ededf54c7 | ||
|
|
0520fcd7ec | ||
|
|
b6173d6c1b | ||
|
|
6fa07e12db | ||
|
|
804dacef91 | ||
|
|
97350005c9 | ||
|
|
5f36a23f4e | ||
|
|
d336541d2c | ||
|
|
780ea55ca8 | ||
|
|
38663088b1 | ||
|
|
eb9987d2c0 | ||
|
|
cf4084380c | ||
|
|
691469ef5e | ||
|
|
8106bc6940 | ||
|
|
deb68d5cfc | ||
|
|
f4e158dab6 | ||
|
|
e8b0d9c25b | ||
|
|
43ce9edb95 | ||
|
|
3b4c7095c4 | ||
|
|
d95bb0785f | ||
|
|
d53281500b | ||
|
|
44199093f0 | ||
|
|
18442e25fc | ||
|
|
0fa7245144 | ||
|
|
4fc7347cb7 | ||
|
|
4840a44c4d | ||
|
|
109ac573c9 | ||
|
|
23559252e6 | ||
|
|
31b31b1a52 | ||
|
|
8333e2ad7b | ||
|
|
cb5c9f3170 | ||
|
|
7b2e6cb1bd | ||
|
|
d18d939489 | ||
|
|
b3376f27aa | ||
|
|
327bda5b30 | ||
|
|
c3b1da2a7e | ||
|
|
f238b55df3 | ||
|
|
d15a034869 | ||
|
|
7b3ae417e8 | ||
|
|
d35f898b70 | ||
|
|
6730c0c682 | ||
|
|
c2c7ac8b23 | ||
|
|
e322958b25 | ||
|
|
0d660f239f | ||
|
|
c4a50fc9fb | ||
|
|
2f670e316b | ||
|
|
f47a6f7b42 | ||
|
|
8856ad1520 | ||
|
|
3513b51477 | ||
|
|
bd8fc08b7c | ||
|
|
ae925a240e | ||
|
|
adf1379b9e | ||
|
|
e8158ef45a | ||
|
|
71d6aed1aa | ||
|
|
6627f77d92 | ||
|
|
4fa0bf76e8 | ||
|
|
92a9b34836 | ||
|
|
10d7162d6e | ||
|
|
2a1b8ae18e | ||
|
|
5abf2cb35e | ||
|
|
367170be95 | ||
|
|
4d7cfee60f | ||
|
|
29152d1f85 | ||
|
|
6b4ffa4822 | ||
|
|
2883f4bed6 | ||
|
|
c96275cdd1 | ||
|
|
9db8324ffd | ||
|
|
0c664b94b9 | ||
|
|
c087e419d5 | ||
|
|
5ba5cae5ef | ||
|
|
4ea211d923 | ||
|
|
8d8202adab | ||
|
|
267f93e41e | ||
|
|
260ec952b4 | ||
|
|
5e311c2813 | ||
|
|
1d3268916f | ||
|
|
73192cd0fd | ||
|
|
9c886b3fa3 | ||
|
|
017832f11e | ||
|
|
67e76bc42f | ||
|
|
9a6579c55c | ||
|
|
17c0cdef14 | ||
|
|
dd0cc71f36 | ||
|
|
21fd6ab463 | ||
|
|
6e2142c605 | ||
|
|
16338682ed | ||
|
|
a7e8d3dfa6 | ||
|
|
6e9014b915 | ||
|
|
b5e7a3f83f | ||
|
|
d8d76f452d | ||
|
|
c2e475c666 | ||
|
|
9a4bc898f0 | ||
|
|
ca92aa8c62 | ||
|
|
56c6d7ed3c | ||
|
|
6ee4bce676 | ||
|
|
ff3f01af56 | ||
|
|
b5ba81e22b | ||
|
|
d5aab7c6df | ||
|
|
2749457611 | ||
|
|
883b14e96a | ||
|
|
59d7e0acac | ||
|
|
68ac3503ed | ||
|
|
58649db181 | ||
|
|
92ca4eeb15 | ||
|
|
d3e06e6cc9 | ||
|
|
3cef3e9bdc | ||
|
|
d318952feb | ||
|
|
6d8051dfa0 | ||
|
|
6acb9cf23f | ||
|
|
87e5457eb0 | ||
|
|
5ee23118ff | ||
|
|
d198f0c273 | ||
|
|
a88249de09 | ||
|
|
89ded523f8 | ||
|
|
f132a1359f | ||
|
|
48d9d03b32 | ||
|
|
11aba9df96 | ||
|
|
2c0fb5e584 | ||
|
|
69c6adcd06 | ||
|
|
e6c72baef7 | ||
|
|
83853e579f | ||
|
|
02652d3cfa | ||
|
|
fe60dbbb08 | ||
|
|
a1842be6e1 | ||
|
|
5f644ae96d | ||
|
|
3f5043a104 | ||
|
|
df55492984 | ||
|
|
b73171a329 | ||
|
|
b0b02e2ffe | ||
|
|
7b79a42cc9 | ||
|
|
54d1363b58 | ||
|
|
8a9afc40a8 | ||
|
|
958f569969 | ||
|
|
a64214ae15 | ||
|
|
69e8ba6743 | ||
|
|
0b73c92ee6 | ||
|
|
196e601929 | ||
|
|
6252b2c267 | ||
|
|
9f462f90ab | ||
|
|
0e19f5d8b3 | ||
|
|
3ff77ee9c0 | ||
|
|
65c2eda941 | ||
|
|
f6a2deb763 | ||
|
|
08ee4c1351 | ||
|
|
c713e1c22b | ||
|
|
c76a7c75ea | ||
|
|
a56a086dc4 | ||
|
|
c1903c7016 | ||
|
|
4dfadc535f | ||
|
|
8e01a5038e | ||
|
|
05a42efb1b | ||
|
|
3d924ab514 | ||
|
|
ae34a4c41a | ||
|
|
6bc9230dc8 | ||
|
|
93186421b1 | ||
|
|
8dce58713f | ||
|
|
7b391ba08f | ||
|
|
199df72cf6 | ||
|
|
59e998f5be | ||
|
|
bf3373697f | ||
|
|
509955f8c1 | ||
|
|
62279ce72f | ||
|
|
0c80c88548 | ||
|
|
ce3b980e27 | ||
|
|
7b25e65da4 | ||
|
|
3510c01e6e | ||
|
|
14b70ce66e | ||
|
|
d9a5fbfe00 | ||
|
|
d20a8495d8 | ||
|
|
b8cf6012bd | ||
|
|
70dc4db1c5 | ||
|
|
1fb30ceafd | ||
|
|
38ec62a23b | ||
|
|
0a3abb20a1 | ||
|
|
9f9288a5c0 | ||
|
|
d047e05bc8 | ||
|
|
e939b06339 | ||
|
|
2eaeb759c5 | ||
|
|
2f2346286d | ||
|
|
8ed1d34301 | ||
|
|
e38152051c | ||
|
|
100c1d3803 | ||
|
|
7cc3ab1004 | ||
|
|
0c86c53a96 | ||
|
|
130e751072 | ||
|
|
408cc05f7c | ||
|
|
9f70aab9b5 | ||
|
|
39f63b6339 | ||
|
|
81e3c41749 | ||
|
|
831563317e | ||
|
|
a3c43cb54e | ||
|
|
83373c4424 | ||
|
|
ad47dda614 | ||
|
|
4466136776 | ||
|
|
bc874a2292 | ||
|
|
e52816feb1 | ||
|
|
3a34fa4257 | ||
|
|
216a3e3e10 | ||
|
|
c5f02a0116 | ||
|
|
7975de0a9a | ||
|
|
bba262e164 | ||
|
|
03a16119b9 | ||
|
|
2e657d88f4 | ||
|
|
ede5e0be90 | ||
|
|
e6981a8c47 | ||
|
|
0883ed39e3 | ||
|
|
223961bf78 | ||
|
|
f50b3743f5 | ||
|
|
10a7c1172b | ||
|
|
da60436e91 | ||
|
|
9405d549c7 | ||
|
|
47ee46b440 | ||
|
|
a9d9173364 | ||
|
|
088ebdb7b5 | ||
|
|
7a85fb2e72 | ||
|
|
c63ae6fc1f | ||
|
|
8bf9607bb8 | ||
|
|
dabae19cf2 | ||
|
|
da930976ef | ||
|
|
0c57ae3b58 | ||
|
|
543f4c43b3 | ||
|
|
5a8f8b8449 | ||
|
|
64363b70e3 | ||
|
|
c84b6f6824 | ||
|
|
fb6751a439 | ||
|
|
802dd21200 | ||
|
|
782008e5d3 | ||
|
|
94de25cb26 | ||
|
|
b1efd289d3 | ||
|
|
1e1b3e9d74 | ||
|
|
ba0bf3dd5b | ||
|
|
a9a2e89e49 | ||
|
|
cc1240b43c | ||
|
|
06830c3881 | ||
|
|
918a7bad68 | ||
|
|
356f98bf52 | ||
|
|
2d3734bf14 | ||
|
|
73a8d4dcda | ||
|
|
f9e25ed14d | ||
|
|
acede69f5b | ||
|
|
0c46aa338e | ||
|
|
de42700914 | ||
|
|
8a2d4a4eee | ||
|
|
5d0ae9edb6 | ||
|
|
dda7b2a28e | ||
|
|
7735d938a5 | ||
|
|
adfe701016 | ||
|
|
76c7d22754 | ||
|
|
54aab6738e | ||
|
|
825dd79795 | ||
|
|
ef5dc18442 | ||
|
|
4521943fb1 | ||
|
|
dc82c24674 | ||
|
|
6c6d524b15 | ||
|
|
5341049bdf | ||
|
|
3f58bbf9bc | ||
|
|
880cba335f | ||
|
|
cb321f49bd | ||
|
|
15b02c59cc | ||
|
|
727a47cf34 | ||
|
|
f816166743 | ||
|
|
3aba4fad47 | ||
|
|
60137585d1 | ||
|
|
718dbae521 | ||
|
|
2ce4e8e955 | ||
|
|
df858338bc | ||
|
|
43931b852f | ||
|
|
0db4332a02 | ||
|
|
c3d121e4ac | ||
|
|
b8476769d6 | ||
|
|
aeb3142d23 | ||
|
|
8bb5b9406d | ||
|
|
da1e7788f9 | ||
|
|
7098e93ae8 | ||
|
|
1a71513723 | ||
|
|
331675091a | ||
|
|
106338508d | ||
|
|
500a9481cb | ||
|
|
e4771320b1 | ||
|
|
39e0f34b2d | ||
|
|
59316c263f | ||
|
|
44682404ff | ||
|
|
83c864df2b | ||
|
|
9ce9fa2dbf | ||
|
|
6b8800f151 | ||
|
|
d95864be1c | ||
|
|
b01f6d9482 | ||
|
|
5bf3f01de6 | ||
|
|
4fcd938575 | ||
|
|
500cb9d0f2 | ||
|
|
34233875bd | ||
|
|
8871902594 | ||
|
|
184882fae2 | ||
|
|
e59e600a35 | ||
|
|
6f5c5a0b06 | ||
|
|
3d4ff93e65 | ||
|
|
912d52ea6b | ||
|
|
27f635dfaa | ||
|
|
d88621ab5a | ||
|
|
95e6a86b10 | ||
|
|
7ff6785860 | ||
|
|
d6665b1dbf | ||
|
|
1cbc783bc6 | ||
|
|
e6b446c95f | ||
|
|
480e8682f9 | ||
|
|
bb997039c8 | ||
|
|
a2debd6746 | ||
|
|
f454221634 | ||
|
|
6614e4468d | ||
|
|
8c0cbc7343 | ||
|
|
22f05f73a9 | ||
|
|
d53d5090e0 | ||
|
|
64afcc0c70 | ||
|
|
d904aab804 | ||
|
|
1d8aaa49e7 | ||
|
|
39509813c6 | ||
|
|
f362943ab6 | ||
|
|
976eee005c | ||
|
|
e5d63fe9e7 | ||
|
|
9b15ab2f2f | ||
|
|
31f6671626 | ||
|
|
c32e4be8be | ||
|
|
6ae9003585 | ||
|
|
851aed6a78 | ||
|
|
7732f9eee9 | ||
|
|
06099f00c6 | ||
|
|
8e0b0da68f | ||
|
|
55dbc3a8db | ||
|
|
f6744d4b47 | ||
|
|
fbf626b578 | ||
|
|
9508695bba | ||
|
|
645014460b | ||
|
|
e32af8e0e5 | ||
|
|
6e2f645905 | ||
|
|
5e091af787 | ||
|
|
f9dbbb8cc9 | ||
|
|
1fc72383a3 | ||
|
|
c040ae9dcc | ||
|
|
f70148d652 | ||
|
|
60f94362d2 | ||
|
|
a9bf825dde | ||
|
|
004525ddeb | ||
|
|
2ff03d7303 | ||
|
|
fcaf46fcd1 | ||
|
|
d8c50ce3fa | ||
|
|
15ed5e9d7b | ||
|
|
ef6e4ebbcd | ||
|
|
60b3e0977e | ||
|
|
1265002d5a | ||
|
|
c7aecc9b30 | ||
|
|
dba837c62c | ||
|
|
f183c56c20 | ||
|
|
e5bdd74fa9 | ||
|
|
0f31278965 | ||
|
|
01e9d79a22 | ||
|
|
ff22c69ca6 | ||
|
|
016b031bf1 | ||
|
|
c7a2001405 | ||
|
|
3871a538ab | ||
|
|
b52ac3ff5d | ||
|
|
be3e434bec | ||
|
|
9d9a7b548d | ||
|
|
be33ee5a1c | ||
|
|
8df7c1b9a4 | ||
|
|
e8997c16a6 | ||
|
|
141d761ecb | ||
|
|
3708819e6b | ||
|
|
389220357e | ||
|
|
fe5feb0394 | ||
|
|
d9925f29d8 | ||
|
|
7ec0c6dbdb | ||
|
|
be84e1856d | ||
|
|
9808ea5d8e | ||
|
|
2577b9c93a | ||
|
|
0981ba5989 | ||
|
|
c2959d06b0 | ||
|
|
eed42c9df5 | ||
|
|
ec30ace822 | ||
|
|
7fa9e2a627 | ||
|
|
ac0c96ae29 | ||
|
|
9900c346b5 | ||
|
|
2108461450 | ||
|
|
270dd02e20 | ||
|
|
e6deea1533 | ||
|
|
d303a40cc7 | ||
|
|
08d435b920 | ||
|
|
efa4c46f6e | ||
|
|
3cd5127488 | ||
|
|
e77a8cdf9b | ||
|
|
77e4506d2a | ||
|
|
c170384607 | ||
|
|
0dab15b703 | ||
|
|
ce7a564cbd | ||
|
|
0d6f71c193 | ||
|
|
2449dbe0cd | ||
|
|
ab04bd66a5 | ||
|
|
9f3c4c8542 | ||
|
|
879f16a2dd | ||
|
|
136f8d17cc | ||
|
|
4539acd239 | ||
|
|
4d37e415e7 | ||
|
|
361283f072 | ||
|
|
3b4f9ecc22 | ||
|
|
d1289bb467 | ||
|
|
b81098f88d | ||
|
|
432883685d | ||
|
|
55094b7f2a | ||
|
|
5c9d6610c1 | ||
|
|
da1ac0696b | ||
|
|
c61667290b | ||
|
|
61e306e1b3 | ||
|
|
da565172fc | ||
|
|
c686c75141 | ||
|
|
d8617cb782 | ||
|
|
7a12f6edde | ||
|
|
f0c489587f | ||
|
|
b9a81c3693 | ||
|
|
f143add013 | ||
|
|
7d71a0c9a4 | ||
|
|
fb5bd0bdec | ||
|
|
adbaba8a44 | ||
|
|
01d0915004 | ||
|
|
332e759e6a | ||
|
|
a1557e8d27 | ||
|
|
8d667333e3 | ||
|
|
2843cc36d9 | ||
|
|
1019047eb2 | ||
|
|
42a085221c | ||
|
|
e08b228d05 | ||
|
|
3eee5a5fdc | ||
|
|
97c03a4985 | ||
|
|
f3974cdb8a | ||
|
|
dc402b7bca | ||
|
|
5082343708 | ||
|
|
4e34ecd580 | ||
|
|
fb897d237d | ||
|
|
b6a1a77bf7 | ||
|
|
168ef20e0f | ||
|
|
d880255fc8 | ||
|
|
1b1c33977d | ||
|
|
07f89bb1d6 | ||
|
|
47b0d51f22 | ||
|
|
5e489843fa | ||
|
|
5dea3fd8b0 | ||
|
|
8dd9dc16ad | ||
|
|
7f96a11e07 | ||
|
|
d7cb5c29cf | ||
|
|
399ecdfd7d | ||
|
|
d31db6d678 | ||
|
|
a928e87747 | ||
|
|
064092a3e6 | ||
|
|
a76561ebe9 | ||
|
|
6321f50e6c | ||
|
|
f4580c8fdf | ||
|
|
13f78ecc19 | ||
|
|
9267c4012b | ||
|
|
a8e80717aa | ||
|
|
8e552c57bb | ||
|
|
93dd0c4943 | ||
|
|
83fdda46a3 | ||
|
|
23943aae89 | ||
|
|
f01d0ff274 | ||
|
|
d158db9499 | ||
|
|
9186b272b6 | ||
|
|
60f1172033 | ||
|
|
5843aee3d6 | ||
|
|
f6b186a167 | ||
|
|
aa9096134d | ||
|
|
1370f0523c | ||
|
|
c1051b8a10 | ||
|
|
b4d532bb41 | ||
|
|
4327fbb9e5 | ||
|
|
636d2a8069 | ||
|
|
21e0edcb85 | ||
|
|
8b11989e0f | ||
|
|
5bc6505cb8 | ||
|
|
a0184013f8 | ||
|
|
d0b5f84854 | ||
|
|
4bb2aea5d2 | ||
|
|
298faf8e0a | ||
|
|
e816504576 | ||
|
|
1506009a55 | ||
|
|
8930a0ddbc | ||
|
|
8611d5644d | ||
|
|
5df815da58 | ||
|
|
59e2906bdc | ||
|
|
79e8fffc7a | ||
|
|
bbd81a6385 | ||
|
|
1ba31e9442 | ||
|
|
7cf8ccdc7e | ||
|
|
ae6e2b1349 | ||
|
|
a65493192f | ||
|
|
cf538a713b | ||
|
|
3440bbd772 | ||
|
|
657a57f46a | ||
|
|
f6db2daaee | ||
|
|
2d8ffae74b | ||
|
|
1efaefbf9c | ||
|
|
29f5693078 | ||
|
|
94bd9f4dd6 | ||
|
|
ce9c08c607 | ||
|
|
a35d16e20d | ||
|
|
77a6508a0b | ||
|
|
347140c14c | ||
|
|
97bc768092 | ||
|
|
cdb81c621d | ||
|
|
bd7fec03d3 | ||
|
|
0c904d37c8 | ||
|
|
dc9f665029 | ||
|
|
4b0536a5b2 | ||
|
|
c2efd198a6 | ||
|
|
a2a74e2166 | ||
|
|
b0f8258a90 | ||
|
|
c75937759f | ||
|
|
466f31bbb9 | ||
|
|
09f6922ccf | ||
|
|
eacc364498 | ||
|
|
3c3ce516f5 | ||
|
|
7fe070b5ae | ||
|
|
b1fb5d548b | ||
|
|
13bcfe61ed | ||
|
|
4d3926c150 | ||
|
|
7d92b5923b | ||
|
|
864f0317fa | ||
|
|
a928676280 | ||
|
|
2073134e7a | ||
|
|
5a411d1d4d | ||
|
|
28f03d3514 | ||
|
|
c7047ab964 | ||
|
|
5f1d767b9c | ||
|
|
1ecff890f0 | ||
|
|
38aae47445 | ||
|
|
e4cd1434df | ||
|
|
f907beab62 | ||
|
|
daa3fcd354 | ||
|
|
0057e71e02 | ||
|
|
f2e336c35a | ||
|
|
a8b2423d77 | ||
|
|
f8f2e6f7c7 | ||
|
|
e103d7490e | ||
|
|
f068d6ef24 | ||
|
|
3ec3f9f2e1 | ||
|
|
25c472e584 | ||
|
|
6c412e5803 | ||
|
|
8113a9aa97 | ||
|
|
51235bf81b | ||
|
|
4bd31aeea8 | ||
|
|
f2736c43c1 | ||
|
|
c6b4cba8b4 | ||
|
|
50fabee1e0 | ||
|
|
227d76db29 | ||
|
|
9207b0c7b8 | ||
|
|
9b8c48ca6e | ||
|
|
dc05e254cb | ||
|
|
33f29cdb41 | ||
|
|
f047757c63 | ||
|
|
f9711e09a1 | ||
|
|
a5644f292e | ||
|
|
f3a88dc3fa | ||
|
|
9ef2a5fc62 | ||
|
|
36ab2f05df | ||
|
|
723511540c | ||
|
|
886cb06590 | ||
|
|
cd2094f75e | ||
|
|
2e3ac8b485 | ||
|
|
47f0c88ed8 | ||
|
|
162ce32b8e | ||
|
|
a1dbdfd6ba | ||
|
|
74072b952d | ||
|
|
f27ad4786a | ||
|
|
cf0ef0f9f4 | ||
|
|
00c6de0e53 | ||
|
|
4c7d92530f | ||
|
|
cafbdc70e8 |
14
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -26,6 +26,20 @@ body:
|
||||
label: Version
|
||||
description: The version can be seen at the bottom of settings.
|
||||
placeholder: e.g. v1.2.3
|
||||
- type: input
|
||||
attributes:
|
||||
label: Last working version
|
||||
description: >
|
||||
The version where the feature was last known to be working. It is
|
||||
fine if you don't remember the exact version (mention roughly
|
||||
then), but if there just isn't a last known working version, then
|
||||
it is likely that what is being reported is not an issue but a
|
||||
feature request. The difference between the two categories is not
|
||||
just semantic - feature requests use GitHub discussions and so can
|
||||
be [upvoted by the
|
||||
community](https://github.com/ente-io/ente/discussions/categories/feature-requests)
|
||||
(issues can't be).
|
||||
placeholder: e.g. v1.2.3
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: What product are you using?
|
||||
|
||||
10
.github/workflows/auth-release.yml
vendored
@@ -36,7 +36,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build-linux-latest:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
# disable this step if release tag contains nightly or beta
|
||||
if: startsWith(github.ref, 'refs/tags/auth-v') && !contains(github.ref, 'nightly') && !contains(github.ref, 'beta')
|
||||
run: |
|
||||
flutter build appbundle --release --flavor playstore --dart-define=app.flavor=playstore
|
||||
flutter build appbundle --release --flavor playstore --dart-define=app.flavor=playstore --dart-define=cronetHttpNoPlay=true
|
||||
env:
|
||||
SIGNING_KEY_PATH: "/home/runner/work/_temp/keystore/ente_auth_key.jks"
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||
@@ -93,7 +93,7 @@ jobs:
|
||||
- name: Install dependencies for desktop build
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y libsecret-1-dev libsodium-dev libfuse2 ninja-build libgtk-3-dev dpkg-dev pkg-config rpm patchelf libsqlite3-dev locate libayatana-appindicator3-dev libffi-dev libtiff6 xz-utils libarchive-tools libcurl4-openssl-dev
|
||||
sudo apt-get install -y libsecret-1-dev libsodium-dev libfuse2 ninja-build libgtk-3-dev dpkg-dev pkg-config rpm patchelf libsqlite3-dev locate libayatana-appindicator3-dev libffi-dev libtiff5 xz-utils libarchive-tools libcurl4-openssl-dev
|
||||
sudo updatedb --localpaths='/usr/lib/x86_64-linux-gnu'
|
||||
|
||||
- name: Install appimagetool
|
||||
@@ -117,7 +117,9 @@ jobs:
|
||||
mv dist/**/*-*-linux.deb artifacts/ente-${{ github.ref_name }}-x86_64.deb
|
||||
|
||||
- name: Generate checksums
|
||||
run: sha256sum artifacts/ente-* >> artifacts/sha256sum-rpm-appimage
|
||||
run: |
|
||||
sha256sum artifacts/ente-auth-*.apk >> artifacts/sha256sum-apk
|
||||
sha256sum artifacts/ente-auth-*.deb artifacts/ente-auth-*.rpm artifacts/ente-auth-*.AppImage >> artifacts/sha256sum-linux
|
||||
|
||||
- name: Create a draft GitHub release
|
||||
uses: ncipollo/release-action@v1
|
||||
|
||||
77
.github/workflows/mobile-internal-release-rust.yml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
name: "Internal release (photos)"
|
||||
|
||||
on:
|
||||
workflow_dispatch: # Allow manually running the action
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.24.3"
|
||||
RUST_VERSION: "1.85.1"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: mobile
|
||||
|
||||
steps:
|
||||
- name: Checkout code and submodules
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup JDK 17
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 17
|
||||
|
||||
- name: Install Flutter ${{ env.FLUTTER_VERSION }}
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install Rust ${{ env.RUST_VERSION }}
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{ env.RUST_VERSION }}
|
||||
|
||||
- name: Install Flutter Rust Bridge
|
||||
run: cargo install flutter_rust_bridge_codegen
|
||||
|
||||
- name: Setup keys
|
||||
uses: timheuer/base64-to-file@v1
|
||||
with:
|
||||
fileName: "keystore/ente_photos_key.jks"
|
||||
encodedString: ${{ secrets.SIGNING_KEY_PHOTOS }}
|
||||
|
||||
- name: Build PlayStore AAB
|
||||
run: |
|
||||
flutter build appbundle --dart-define=cronetHttpNoPlay=true --release --flavor playstore
|
||||
env:
|
||||
SIGNING_KEY_PATH: "/home/runner/work/_temp/keystore/ente_photos_key.jks"
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS_PHOTOS }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD_PHOTOS }}
|
||||
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD_PHOTOS }}
|
||||
|
||||
- name: Upload AAB to PlayStore
|
||||
uses: r0adkll/upload-google-play@v1
|
||||
with:
|
||||
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
|
||||
packageName: io.ente.photos
|
||||
releaseFiles: mobile/build/app/outputs/bundle/playstoreRelease/app-playstore-release.aab
|
||||
track: internal
|
||||
|
||||
- name: Notify Discord
|
||||
uses: sarisia/actions-status-discord@v1
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_INTERNAL_RELEASE_WEBHOOK }}
|
||||
nodetail: true
|
||||
title: "🏆 Internal release available for Photos"
|
||||
description: "[Download](https://play.google.com/store/apps/details?id=io.ente.photos)"
|
||||
color: 0x00ff00
|
||||
@@ -63,6 +63,6 @@ jobs:
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_INTERNAL_RELEASE_WEBHOOK }}
|
||||
nodetail: true
|
||||
title: "🏆 Internal release available for Photos"
|
||||
title: "🏆 Internal release Photos (Branch: ${{ github.ref_name }})"
|
||||
description: "[Download](https://play.google.com/store/apps/details?id=io.ente.photos)"
|
||||
color: 0x00ff00
|
||||
|
||||
3
auth/.fvmrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"flutter": "3.24.3"
|
||||
}
|
||||
5
auth/.gitignore
vendored
@@ -41,4 +41,7 @@ lib/generated_plugin_registrant.dart
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
|
||||
android/key.properties
|
||||
dist/
|
||||
dist/
|
||||
|
||||
# FVM Version Cache
|
||||
.fvm/
|
||||
2
auth/android/.gitignore
vendored
@@ -5,6 +5,8 @@ gradle-wrapper.jar
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
/app/.cxx/
|
||||
/.kotlin/
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
@@ -1,6 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<foreground>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_launcher_foreground"
|
||||
android:inset="0%" />
|
||||
</foreground>
|
||||
<monochrome>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_launcher_monochrome"
|
||||
android:inset="0%" />
|
||||
</monochrome>
|
||||
</adaptive-icon>
|
||||
|
||||
@@ -43,7 +43,13 @@
|
||||
"title": "Anycoin Direct",
|
||||
"slug": "anycoindirect"
|
||||
},
|
||||
{
|
||||
{
|
||||
"title": "AR24",
|
||||
"altNames": [
|
||||
"Docaposte AR24"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Aruba",
|
||||
"slug": "aruba",
|
||||
"hex": "ef8a33"
|
||||
@@ -132,6 +138,14 @@
|
||||
"Binance US"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Bitazza",
|
||||
"slug": "bitazza"
|
||||
},
|
||||
{
|
||||
"title": "Bitkub",
|
||||
"slug": "bitkub"
|
||||
},
|
||||
{
|
||||
"title": "Bitfinex"
|
||||
},
|
||||
@@ -183,6 +197,11 @@
|
||||
"title": "Bluesky",
|
||||
"slug": "blue_sky"
|
||||
},
|
||||
{
|
||||
"title": "bonify",
|
||||
"slug": "bonify",
|
||||
"altNames": ["bonify.de"]
|
||||
},
|
||||
{
|
||||
"title": "Booking",
|
||||
"altNames": [
|
||||
@@ -208,6 +227,13 @@
|
||||
{
|
||||
"title": "Bugzilla"
|
||||
},
|
||||
{
|
||||
"title": "Bundesagentur für Arbeit",
|
||||
"slug": "bundesagentur_fur_arbeit",
|
||||
"altNames": [
|
||||
"Agentur für Arbeit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "ButterflyMX",
|
||||
"slug": "butterflymx"
|
||||
@@ -285,6 +311,10 @@
|
||||
"title": "CSGORoll",
|
||||
"slug": "csgoroll"
|
||||
},
|
||||
{
|
||||
"title": "Cryptee",
|
||||
"slug": "cryptee"
|
||||
},
|
||||
{
|
||||
"title": "Cwallet",
|
||||
"altNames": [
|
||||
@@ -385,6 +415,13 @@
|
||||
],
|
||||
"hex": "858585"
|
||||
},
|
||||
{
|
||||
"title": "Fanatical",
|
||||
"slug": "fanatical",
|
||||
"altNames": [
|
||||
"FANATICAL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Fastmail"
|
||||
},
|
||||
@@ -410,10 +447,16 @@
|
||||
"title": "Finanzfluss",
|
||||
"slug": "finanzfluss"
|
||||
},
|
||||
{
|
||||
"title": "Finary"
|
||||
},
|
||||
{
|
||||
"title": "Firefox",
|
||||
"slug": "mozilla"
|
||||
},
|
||||
{
|
||||
"title": "fortrabbit"
|
||||
},
|
||||
{
|
||||
"title": "ForUsAll"
|
||||
},
|
||||
@@ -508,12 +551,19 @@
|
||||
"slug": "id_me"
|
||||
},
|
||||
{
|
||||
"title": "Infomaniak"
|
||||
"title": "ImmoScout24",
|
||||
"slug": "immo_scout_24",
|
||||
"altNames": [
|
||||
"ImmobilienScout24"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Impact.com",
|
||||
"slug": "impact"
|
||||
},
|
||||
{
|
||||
"title": "Infomaniak"
|
||||
},
|
||||
{
|
||||
"title": "ING"
|
||||
},
|
||||
@@ -615,8 +665,7 @@
|
||||
},
|
||||
{
|
||||
"title": "LinkedIn",
|
||||
"slug": "linkedin",
|
||||
"hex": "2596be"
|
||||
"slug": "linkedin"
|
||||
},
|
||||
{
|
||||
"title": "Linux.Do",
|
||||
@@ -703,6 +752,7 @@
|
||||
{
|
||||
"title": "Mistral",
|
||||
"altNames": [
|
||||
"Le Chat",
|
||||
"Mistral AI",
|
||||
"MistralAI"
|
||||
]
|
||||
@@ -847,11 +897,15 @@
|
||||
"欧易"
|
||||
]
|
||||
},
|
||||
{
|
||||
{
|
||||
"title": "OnShape",
|
||||
"slug": "onshape",
|
||||
"hex": "7abb5e"
|
||||
},
|
||||
{
|
||||
"title": "Oracle Cloud",
|
||||
"slug": "oracle_cloud"
|
||||
},
|
||||
{
|
||||
"title": "Parqet",
|
||||
"slug": "parqet"
|
||||
@@ -971,7 +1025,7 @@
|
||||
"title": "RealMe",
|
||||
"slug": "realme"
|
||||
},
|
||||
{
|
||||
{
|
||||
"title": "RealVNC",
|
||||
"slug": "realvnc",
|
||||
"hex": "488aec"
|
||||
@@ -1325,4 +1379,4 @@
|
||||
"title": "CoinSpot"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
6
auth/assets/custom-icons/icons/ar24.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="500" height="500" viewBox="0 0 500 500" fill="#0000FF" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M139.63 306.55H125.64C123.41 306.55 121.53 306.5 119.99 306.39C118.45 306.28 117.13 305.99 116.01 305.51C114.9 305.04 113.92 304.32 113.08 303.36C112.22 302.41 111.38 301.09 110.53 299.39L103.85 286.35H35.47L25.29 306.55H0L58.37 194.11H81.26L139.63 306.55ZM93.2 265.36L69.66 218.6L46.12 265.36H93.2Z"/>
|
||||
<path d="M265.23 306.55H245.67C241.96 306.55 238.93 306.07 236.6 305.12C234.27 304.16 232.31 302.68 230.72 300.67L206.17 270.76H177.48V306.55H153.95V195.23C156.92 195.12 160.16 195.04 163.66 194.99C167.17 194.93 170.77 194.86 174.5 194.75C178.21 194.64 181.92 194.57 185.64 194.51C189.36 194.46 192.86 194.43 196.15 194.43C209.74 194.43 220.97 195.41 229.84 197.37C238.71 199.34 246 202.91 251.74 208.1C258.11 214.04 261.3 222.1 261.3 232.28C261.3 237.37 260.61 241.85 259.23 245.72C257.84 249.59 255.88 252.96 253.33 255.81C250.78 258.68 247.7 261.09 244.09 263.05C240.49 265.02 236.45 266.63 231.99 267.9L265.23 306.55ZM196.25 250.25C199.75 250.25 203.27 250.22 206.82 250.17C210.38 250.12 213.74 249.88 216.93 249.45C220.1 249.03 223.02 248.36 225.67 247.46C228.32 246.55 230.5 245.24 232.19 243.54C233.67 241.94 234.82 240.29 235.61 238.59C236.4 236.89 236.81 234.7 236.81 232.03C236.81 230.23 236.45 228.47 235.77 226.77C235.08 225.06 234.15 223.62 232.99 222.45C231.4 220.85 229.44 219.6 227.11 218.7C224.77 217.79 222.1 217.12 219.07 216.7C216.05 216.27 212.63 216.03 208.81 215.98C205 215.93 200.81 215.9 196.25 215.9H187.18C183.58 215.9 180.34 215.95 177.48 216.06V250.1C180.34 250.2 183.58 250.25 187.18 250.25H196.25Z"/>
|
||||
<path d="M324.59 213.35C318.34 213.35 312.61 215.03 307.41 218.37C302.22 221.7 297.93 225.65 294.54 230.22L276.09 217.97C282.13 210.65 289.36 204.66 297.79 200C306.22 195.33 315.47 193 325.55 193C332.33 193 338.53 193.87 344.15 195.62C349.77 197.37 354.59 199.84 358.63 203.02C362.65 206.2 365.78 210.07 368.01 214.63C370.23 219.19 371.35 224.27 371.35 229.89C371.35 235.2 370.36 239.86 368.4 243.89C366.44 247.92 363.85 251.6 360.61 254.94C357.38 258.28 353.69 261.38 349.56 264.25C345.42 267.11 341.18 269.97 336.84 272.84L317.27 285.72H370.87V306.55H279.42V286.04L318.39 260.27C322.2 257.73 325.86 255.32 329.36 253.03C332.86 250.76 335.93 248.42 338.58 246.04C341.24 243.65 343.35 241.13 344.95 238.48C346.54 235.83 347.33 232.91 347.33 229.74C347.33 227.41 346.72 225.23 345.5 223.22C344.28 221.2 342.64 219.45 340.57 217.97C338.51 216.49 336.09 215.35 333.34 214.55C330.58 213.75 327.66 213.35 324.59 213.35Z"/>
|
||||
<path d="M457.22 306.55V283.49H388.84V259.95L455.47 195.23H480.12V263.77H500V283.49H480.12V306.55L457.22 306.55ZM413.17 263.77H457.22V220.35L413.17 263.77Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -1 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 150 150"><defs><style>.e{fill:#2a54ff;}.f{fill:url(#d);}.g{fill:none;}</style><linearGradient id="d" x1="17.68" y1="116.45" x2="132.14" y2="32.11" gradientTransform="matrix(1, 0, 0, 1, 0, 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2a54ff"/><stop offset=".52" stop-color="#2143cb"/><stop offset="1" stop-color="#2a54ff"/></linearGradient></defs><g id="b"><path id="c" class="g" d="M0,0H150V150H0V0Z"/></g><path class="f" d="M140.2,22.33c-25.18-.09-49.79,10.83-66.63,29.47-6.06,6.27-10.1,13.95-14.96,21.06-11.64,15.93-29.81,25.14-49.5,25.13h0v28.65h0c25.17,.1,49.78-10.86,66.63-29.5,6.03-6.27,10.13-13.94,14.96-21.06,11.64-15.91,29.81-25.12,49.5-25.11V22.33h0Z"/><path class="e" d="M140.2,97.99c-19.68,0-37.86-9.2-49.5-25.11-4.81-7.12-8.92-14.78-14.94-21.06C58.95,33.18,34.3,22.24,9.13,22.35h0v28.65h0c21.8-.11,42.05,11.62,53.01,30.46,3.22,5.62,7.06,10.9,11.45,15.74,16.83,18.63,41.46,29.59,66.63,29.5l-.02-28.7h0Z"/></svg>
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="a" viewBox="0 0 150 150">
|
||||
<defs>
|
||||
<linearGradient id="d" x1="17.68" y1="116.45" x2="132.14" y2="32.11"
|
||||
gradientTransform="matrix(1, 0, 0, 1, 0, 0)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#2a54ff" />
|
||||
<stop offset=".52" stop-color="#2143cb" />
|
||||
<stop offset="1" stop-color="#2a54ff" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="b">
|
||||
<path id="c" d="M0,0H150V150H0V0Z" fill="none" />
|
||||
</g>
|
||||
<path
|
||||
d="M140.2,22.33c-25.18-.09-49.79,10.83-66.63,29.47-6.06,6.27-10.1,13.95-14.96,21.06-11.64,15.93-29.81,25.14-49.5,25.13h0v28.65h0c25.17,.1,49.78-10.86,66.63-29.5,6.03-6.27,10.13-13.94,14.96-21.06,11.64-15.91,29.81-25.12,49.5-25.11V22.33h0Z"
|
||||
fill="url(#d)" />
|
||||
<path
|
||||
d="M140.2,97.99c-19.68,0-37.86-9.2-49.5-25.11-4.81-7.12-8.92-14.78-14.94-21.06C58.95,33.18,34.3,22.24,9.13,22.35h0v28.65h0c21.8-.11,42.05,11.62,53.01,30.46,3.22,5.62,7.06,10.9,11.45,15.74,16.83,18.63,41.46,29.59,66.63,29.5l-.02-28.7h0Z"
|
||||
fill="#2a54ff" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
28
auth/assets/custom-icons/icons/bitazza.svg
Normal file
@@ -0,0 +1,28 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="836.84424" height="914.80933">
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path stroke-linecap="round" d="M-186.41-125.66h372.816v351.267H-186.41Z"/>
|
||||
</clipPath>
|
||||
<clipPath id="b">
|
||||
<path stroke-linecap="round" d="M-186.41-95.22h372.816v351.267H-186.41Z"/>
|
||||
</clipPath>
|
||||
<clipPath id="c">
|
||||
<path stroke-linecap="round" d="M-160.08-140.83h372.816v351.267H-160.08Z"/>
|
||||
</clipPath>
|
||||
<clipPath id="d">
|
||||
<path stroke-linecap="round" d="M-212.74-140.83h372.816v351.267H-212.74Z"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clip-path="url(#a)" transform="translate(418.40805 457.4024)scale(3.64)">
|
||||
<path d="m298.246 129.84-6.486-4.585 6.486-4.586c12.26215-8.68661 19.24883-23.025924 18.53269-38.036075-.71613-15.010151-9.03624-28.619172-22.06969-36.098925l-.568-.349c-12.19994-7.033047-27.02434-7.819595-39.9-2.117l-7.053 3.144-.83-7.687c-1.51376-14.021838-9.62342-26.481265-21.832-33.542l-.2-.087C217.64616 2.0246361 210.0606-.00958995 202.34 0c-8.04957.00100343-15.94637 2.1978633-22.84 6.354l-1.114.677c-11.58345 7.090871-19.28369 19.094034-20.9 32.579l-.917 7.6-6.967-3.1c-12.8836-5.747507-27.74063-4.976398-39.96 2.074l-.7.394c-13.604075 7.890873-21.986349 22.420072-22.008 38.147v.787c.02516 14.283035 6.954274 27.67261 18.6 35.942L112 126.04l-6.463 4.586c-12.260313 8.67436-19.255033 22.99852-18.556462 38.00091.698572 15.00239 8.994121 28.61458 22.007462 36.11209l.633.393c12.22088 7.0137 27.04998 7.79342 39.939 2.1l7.054-3.123.807 7.687c1.51242 13.97659 9.57745 26.40246 21.727 33.475l.284.153c13.92748 8.0385 31.12909 7.84683 44.874-.5l1.092-.655c11.59433-7.07976 19.29833-19.08878 20.9-32.579l.9-7.6 6.987 3.123c12.9143 5.73028 27.78955 4.94317 40.027-2.118l.611-.372c13.60439-7.88085 21.98922-22.40383 22.012-38.126v-.808c-.0274-14.27871-6.94846-27.66532-18.583-35.943M292 166.591c-.0145 6.86067-3.67326 13.19693-9.608 16.639l-.654.394c-5.96032 3.4063-13.27768 3.4063-19.238 0l-17.884-10.351-22.841 13.211v20.133c-.0194 6.70609-3.51599 12.92214-9.237 16.421l-1.114.677c-5.99641 3.62641-13.48927 3.70989-19.565.218l-.24-.153c-5.94051-3.43919-9.60731-9.7748-9.63-16.639v-20.657l-22.841-13.211-17.884 10.351c-5.9447 3.40734-13.2503 3.40734-19.195 0l-.677-.415c-5.92257-3.40301-9.59053-9.69703-9.63171-16.52753-.0412-6.83049 3.5506-13.16829 9.43171-16.64247l18.648-11.027-.153-26.313-18.3-10.569c-5.94649-3.42296-9.61685-9.756715-9.63-16.618v-.787c.0184-6.865358 3.68634-13.20295 9.63-16.639l.655-.415c5.9528-3.406398 13.2642-3.406398 19.217 0l17.884 10.351 22.841-13.189V44.7c.0433-6.705114 3.54343-12.913272 9.258-16.421l1.114-.677c5.98556-3.637575 13.47843-3.721536 19.544-.219l.24.131c5.95616 3.434267 9.62726 9.785677 9.63 16.661v20.658l22.841 13.189L262.5 67.671c5.96032-3.406299 13.27768-3.406299 19.238 0l.654.415c5.91101 3.411809 9.56893 9.702792 9.61008 16.527659.0412 6.824866-3.54064 13.159502-9.41008 16.642341l-18.67 11.027.153 26.313 18.321 10.569c5.93573 3.43032 9.59519 9.76235 9.604 16.618z" style="opacity:1;fill:#10f48b;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" transform="translate(-201.88 -125.66)" vector-effect="non-scaling-stroke"/>
|
||||
</g>
|
||||
<g clip-path="url(#b)" transform="translate(418.40805 346.6008)scale(3.64)">
|
||||
<path d="m255.89 111.218-37.166 21.432-37.165-21.432 37.165-21.463Z" style="opacity:1;fill:#10f48b;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" transform="translate(-218.72 -111.2)" vector-effect="non-scaling-stroke"/>
|
||||
</g>
|
||||
<g clip-path="url(#c)" transform="translate(322.56685 512.6212)scale(3.64)">
|
||||
<path d="M209.3 153.613v42.927l-37.166-21.463v-42.9z" style="opacity:1;fill:#10f48b;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" transform="translate(-190.72 -164.36)" vector-effect="non-scaling-stroke"/>
|
||||
</g>
|
||||
<g clip-path="url(#d)" transform="translate(514.24925 512.6212)scale(3.64)">
|
||||
<path d="M273.357 132.181v42.9l-37.166 21.459v-42.927z" style="opacity:1;fill:#10f48b;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" transform="translate(-254.77 -164.36)" vector-effect="non-scaling-stroke"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
1
auth/assets/custom-icons/icons/bitkub.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 245.73 156" xmlns="http://www.w3.org/2000/svg"><g fill="#4cba64"><path d="m167.87 0a23.32 23.32 0 0 0 0 33l44.89 44.9-45 45-22.89-22.9a23.34 23.34 0 0 0 -33 0l55.86 55.87 78-78z"/><circle cx="167.87" cy="78" r="16"/><path d="m77.87 156a23.34 23.34 0 0 0 0-33l-44.87-44.9 45-45 22.87 22.9a23.34 23.34 0 0 0 33 0l-55.87-55.87-78 78z"/><circle cx="77.87" cy="78" r="16"/></g></svg>
|
||||
|
After Width: | Height: | Size: 396 B |
14
auth/assets/custom-icons/icons/bonify.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
|
||||
<defs>
|
||||
<linearGradient id="a" x1="186.97" x2="45.7" y1="96.04" y2="96.04"
|
||||
gradientTransform="matrix(1 0 0 -1 0 150.11)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#165cc3" />
|
||||
<stop offset="1" stop-color="#3ddabb" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
d="M111.63 75.01c.06.86.08 1.72.08 2.59 0 20.52-16.62 37.16-37.14 37.16S37.41 98.14 37.41 77.62s16.62-37.16 37.14-37.16h.02c1.61 0 3.22.1 4.82.32l12.7-17.11C62.3 14 30.31 30.3 20.63 60.09s6.62 61.78 36.41 71.47c29.79 9.68 61.78-6.62 71.47-36.41 4.29-13.2 3.59-27.52-1.97-40.24l-14.9 20.11Z"
|
||||
style="fill:#EFEFEF; mix-blend-mode: difference" />
|
||||
<path d="M120.26 4.82 74.49 66.53 62.93 53.99l-17.26 15.9 30.73 33.43 73.1-98.5z"
|
||||
style="fill:url(#a)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 876 B |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) by Marsupilami -->
|
||||
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="768" height="768" viewBox="-4.3240767 -4.3240767 152.8084434 152.7840434" id="svg7076">
|
||||
<defs id="defs7078"/>
|
||||
<path d="M 0,72.07202 C 0,32.27318 32.2935,0 72.08013,0 c 39.78662,0 72.08017,32.27318 72.08017,72.07202 0,39.80291 -32.29355,72.06387 -72.08017,72.06387 -17.63317,0 -33.75958,-6.32434 -46.30232,-16.82687 11.769,-19.46163 46.13944,-77.28864 46.13944,-77.28864 l 17.0223,28.5022 c 0,0 -8.95912,0.0448 -17.06303,0 -8.14464,-0.0448 -10.46588,1.7063 -14.00878,7.11027 -2.9321,4.4877 -9.85505,16.21193 -10.01793,16.42776 -0.81448,1.29093 -0.3258,2.54114 1.58818,2.54114 l 55.18001,0 28.01759,0 c 1.66968,0 2.64704,-1.16875 1.58822,-2.6226 L 73.34255,2.43932 c -0.81447,-1.37236 -2.11759,-1.25021 -2.85061,0 L 8.4704,105.97411 C 3.09495,95.87068 0,84.32969 0,72.07202" id="path8406" style="fill:#ec1c23;fill-rule:nonzero;stroke:none"/>
|
||||
</svg>
|
||||
<!-- version: 20110311, original size: 144.16029 144.13589, border: 3% -->
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -1,130 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#C5C8CA;}
|
||||
.st1{fill:#9DA4A8;}
|
||||
.st2{fill:#B7BBBD;}
|
||||
.st3{fill:#CBCFD1;}
|
||||
.st4{fill:#BBBFC2;}
|
||||
.st5{fill:#CACDCE;}
|
||||
.st6{fill:#BFC3C5;}
|
||||
.st7{fill:#BCC0C2;}
|
||||
.st8{fill:#BDC1C4;}
|
||||
.st9{fill:#C7CACC;}
|
||||
.st10{fill:url(#SVGID_1_);}
|
||||
.st11{fill:#FFFFFF;}
|
||||
.st12{fill:#B8BCBF;}
|
||||
.st13{fill:#C4C7C9;}
|
||||
.st14{fill:#C1C5C7;}
|
||||
.st15{fill:url(#SVGID_00000003093454306001190100000011813141018663887528_);}
|
||||
.st16{fill:url(#SVGID_00000017503418065689336600000007511615486600436881_);}
|
||||
.st17{fill:url(#SVGID_00000057845154053127761930000017803385842445649033_);}
|
||||
.st18{fill:url(#SVGID_00000156571711195124538550000006687723982713171592_);}
|
||||
.st19{fill:#DF3030;}
|
||||
.st20{fill:url(#SVGID_00000001636660173574603980000008731795684331757470_);}
|
||||
.st21{fill:#17181C;}
|
||||
.st22{fill:url(#SVGID_00000180343933242210086490000003762167186865041053_);}
|
||||
.st23{fill:url(#SVGID_00000015338415700440354440000005681408021599925436_);}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M14.4,29.5c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.2,0H14.4z"/>
|
||||
<path class="st1" d="M15.3,29.5h0.1c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0L15.3,29.5
|
||||
C15.2,29.5,15.3,29.5,15.3,29.5z"/>
|
||||
<path class="st2" d="M15.3,29.5L15.3,29.5l-0.2,0C15.2,29.5,15.2,29.5,15.3,29.5z"/>
|
||||
<path class="st3" d="M15.5,29.5L15.5,29.5L15.5,29.5L15.5,29.5L15.5,29.5z"/>
|
||||
<path class="st0" d="M14.1,29.5c0.1,0,0.1,0,0.2,0H14.1z"/>
|
||||
<path class="st4" d="M13.9,29.5C13.9,29.5,14,29.5,13.9,29.5c0.1,0,0.1,0,0.2,0H13.9z"/>
|
||||
<path class="st5" d="M13.6,29.5C13.6,29.5,13.6,29.5,13.6,29.5c0.1,0,0.1,0,0.1,0H13.6z"/>
|
||||
<path class="st6" d="M13.7,29.5C13.8,29.5,13.8,29.5,13.7,29.5c0.1,0,0.1,0,0.1,0H13.7z"/>
|
||||
<path class="st7" d="M13.3,29.4C13.3,29.4,13.3,29.4,13.3,29.4C13.4,29.4,13.4,29.4,13.3,29.4L13.3,29.4z"/>
|
||||
<path class="st8" d="M13.4,29.5C13.4,29.4,13.5,29.4,13.4,29.5C13.5,29.4,13.5,29.4,13.4,29.5L13.4,29.5z"/>
|
||||
<path class="st8" d="M13.1,29.4C13.1,29.4,13.1,29.4,13.1,29.4C13.1,29.4,13.1,29.4,13.1,29.4L13.1,29.4z"/>
|
||||
<path class="st9" d="M13.2,29.4C13.2,29.4,13.2,29.4,13.2,29.4C13.2,29.4,13.2,29.4,13.2,29.4C13.2,29.4,13.2,29.4,13.2,29.4
|
||||
C13.3,29.4,13.3,29.4,13.2,29.4L13.2,29.4z"/>
|
||||
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="21.8812" y1="-88.078" x2="8.2545" y2="-104.6955" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
|
||||
<stop offset="0" style="stop-color:#020037"/>
|
||||
<stop offset="1" style="stop-color:#050F62"/>
|
||||
</linearGradient>
|
||||
<path class="st10" d="M15,0.4C11.1,0.4,7.5,2,4.7,4.7C2,7.4,0.5,11.1,0.5,15c0,1.7,0.3,3.4,0.9,5.1c0.3,0,0.5,0,0.8,0
|
||||
c2.9,0,5.8,0.9,8.2,2.6c2.4,1.7,4.2,4.1,5.1,6.9c3.8-0.1,7.4-1.7,10-4.4c2.6-2.7,4.1-6.4,4.1-10.1c0-3.9-1.5-7.6-4.3-10.3
|
||||
C22.6,2,18.9,0.4,15,0.4"/>
|
||||
<path class="st11" d="M20.7,22.5C20.7,22.5,20.7,22.5,20.7,22.5L20.7,22.5c0,0.4,0.1,0.8,0.3,1c0.2,0.2,0.6,0.3,1,0.3c0,0,0,0,0,0
|
||||
c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0l0,0c-0.4,0-0.7,0.1-1,0.3c-0.2,0.2-0.3,0.6-0.3,1c0,0,0,0,0,0c0,0,0,0,0,0
|
||||
c0,0,0,0,0,0c0,0,0,0,0,0h0l0,0c0-0.4-0.1-0.7-0.3-1c-0.2-0.2-0.6-0.3-1-0.3c0,0,0,0,0,0l0,0c0,0,0,0,0,0s0,0,0,0c0,0,0,0,0,0
|
||||
c0,0,0,0,0,0c0.4,0,0.7-0.1,1-0.3S20.7,22.9,20.7,22.5C20.7,22.5,20.7,22.5,20.7,22.5C20.7,22.5,20.7,22.5,20.7,22.5z"/>
|
||||
<path class="st11" d="M6.9,15.5C6.9,15.5,6.9,15.5,6.9,15.5L6.9,15.5c0,0.4,0.1,0.8,0.3,1c0.2,0.2,0.6,0.3,1,0.3c0,0,0,0,0,0
|
||||
c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0l0,0c-0.4,0-0.7,0.1-1,0.3c-0.2,0.2-0.3,0.6-0.3,1c0,0,0,0,0,0c0,0,0,0,0,0
|
||||
c0,0,0,0,0,0c0,0,0,0,0,0h0l0,0c0-0.4-0.1-0.7-0.3-1c-0.2-0.2-0.6-0.3-1-0.3c0,0,0,0,0,0l0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0
|
||||
c0,0,0,0,0,0c0.4,0,0.7-0.1,1-0.3C6.8,16.2,6.9,15.9,6.9,15.5C6.9,15.5,6.9,15.5,6.9,15.5C6.9,15.5,6.9,15.5,6.9,15.5z"/>
|
||||
<path class="st11" d="M10.6,4.1L10.6,4.1C10.7,4.1,10.7,4.1,10.6,4.1c0,0.3,0.1,0.5,0.3,0.7c0.2,0.2,0.4,0.3,0.7,0.2h0v0l0,0l0,0
|
||||
l0,0l0,0c-0.3,0-0.5,0.1-0.7,0.2c-0.2,0.2-0.3,0.4-0.2,0.7l0,0l0,0l0,0l0,0h0v0c0-0.3-0.1-0.5-0.2-0.7C10.2,5.1,10,5,9.7,5.1h0v0v0
|
||||
h0C10,5,10.2,5,10.4,4.8C10.6,4.6,10.7,4.3,10.6,4.1C10.6,4.1,10.6,4.1,10.6,4.1C10.6,4.1,10.6,4.1,10.6,4.1z"/>
|
||||
<path class="st12" d="M12.8,29.4C12.8,29.4,12.8,29.4,12.8,29.4C12.8,29.4,12.8,29.4,12.8,29.4C12.8,29.4,12.8,29.4,12.8,29.4
|
||||
C12.8,29.4,12.8,29.4,12.8,29.4L12.8,29.4z"/>
|
||||
<path class="st13" d="M13,29.4C13,29.4,13,29.4,13,29.4C13,29.4,13,29.4,13,29.4L13,29.4z"/>
|
||||
<path class="st14" d="M12.9,29.4C12.9,29.4,12.9,29.4,12.9,29.4C12.9,29.4,12.9,29.4,12.9,29.4L12.9,29.4z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000173122186048074043340000017421439166240502921_" gradientUnits="userSpaceOnUse" x1="19.2457" y1="-89.3156" x2="22.9553" y2="-91.7188" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
|
||||
<stop offset="0" style="stop-color:#E5E5E5"/>
|
||||
<stop offset="1" style="stop-color:#B7B8C1"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000173122186048074043340000017421439166240502921_);" d="M21.8,1.2c-1.4,0.7-3,1.9-4.4,4.2
|
||||
c-2.5,3.9-3.2,7.4-3.2,7.4L16,14l0.3,0.2l1.9,1.2c0,0,2.9-2,5.4-5.9c1.5-2.3,2-4.3,2-5.8c-0.8-0.1-1.5-0.4-2.2-0.8
|
||||
C22.8,2.5,22.2,1.9,21.8,1.2z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000127763695479642710240000017533313096818365313_" gradientUnits="userSpaceOnUse" x1="21.2378" y1="-99.9826" x2="19.0472" y2="-97.8815" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
|
||||
<stop offset="0" style="stop-color:#EC4F4F"/>
|
||||
<stop offset="1" style="stop-color:#A91919"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000127763695479642710240000017533313096818365313_);" d="M20.8,16.8c0.9-1.4,0.3-3.2,0-3.8
|
||||
c-0.7,0.8-1.5,1.5-2.3,2.1c0.1,0.4,0.3,0.8,0.3,1.2c0,0.1,0,0.2-0.1,0.3c-0.4,0.6-0.8,1.3-1.1,2c-0.1,0.1-0.1,0.2-0.1,0.3
|
||||
c-0.1,0.2-0.1,0.3,0,0.5c0,0.3,0.2,0.5,0.3,0.8c0,0,0.1,0.1,0.1,0.1c0.1,0,0.1,0.1,0.2,0.1s0.1,0,0.2-0.1c0.1-0.1,0.3-0.2,0.4-0.4
|
||||
C19.5,19,19.8,18.5,20.8,16.8z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000060717637781723915790000002744012061535479481_" gradientUnits="userSpaceOnUse" x1="11.3158" y1="-99.2586" x2="14.8122" y2="-101.5237" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
|
||||
<stop offset="0" style="stop-color:#F2A518"/>
|
||||
<stop offset="1" style="stop-color:#F4E23E"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000060717637781723915790000002744012061535479481_);" d="M15.1,15.7l-1.7-1.1c-2,3.1-3.3,7-2.4,7.5
|
||||
c0.9,0.6,3.9-2.2,5.9-5.3L15.1,15.7z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000070084874335106853820000008402293642909580433_" gradientUnits="userSpaceOnUse" x1="-4386.2534" y1="747.6443" x2="-4497.9517" y2="769.0099" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
|
||||
<stop offset="0" style="stop-color:#EC4F4F"/>
|
||||
<stop offset="1" style="stop-color:#A91919"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000070084874335106853820000008402293642909580433_);" d="M15.2,9.5c-0.7-0.1-2.5,0.1-3.4,1.5
|
||||
c-1.1,1.6-1.5,2.1-2,3.2c-0.1,0.2-0.1,0.3-0.2,0.5c0,0.1,0,0.1,0,0.2C9.6,15,9.7,15,9.7,15c0,0,0.1,0,0.2,0.1c0.3,0.1,0.6,0,0.8,0
|
||||
c0.2,0,0.3-0.1,0.4-0.2c0.1-0.1,0.2-0.2,0.3-0.3c0.5-0.6,0.9-1.2,1.3-1.8c0.1-0.1,0.2-0.2,0.3-0.2c0.4-0.1,0.8-0.1,1.2-0.2l0,0
|
||||
C14.5,11.4,14.8,10.4,15.2,9.5z"/>
|
||||
<path class="st19" d="M25,0.6c-0.2-0.1-1.5-0.2-3.2,0.7c0.4,0.7,1,1.2,1.6,1.7c0.7,0.4,1.4,0.7,2.2,0.8C25.7,1.9,25.1,0.7,25,0.6z"
|
||||
/>
|
||||
<path class="st19" d="M18.4,15.5L14,12.7c-0.1,0-0.1,0-0.2,0l-0.9,1.4c0,0.1,0,0.1,0,0.2l4.4,2.8c0.1,0,0.1,0,0.2,0l0.9-1.4
|
||||
C18.4,15.6,18.4,15.6,18.4,15.5z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000044894753735506851200000013592864944465274029_" gradientUnits="userSpaceOnUse" x1="14.9436" y1="-95.9217" x2="16.3716" y2="-96.8468" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
|
||||
<stop offset="0" style="stop-color:#B71E1E"/>
|
||||
<stop offset="0.44" style="stop-color:#DF3030"/>
|
||||
<stop offset="1" style="stop-color:#C51D1D"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000044894753735506851200000013592864944465274029_);" d="M17.8,11.6c-0.4-0.2-2.1,1.6-3.2,3.3
|
||||
c-0.8,1.2-1.4,3-1.1,3.2c0.4,0.2,1.7-1,2.5-2.3C17.1,14.2,18.1,11.9,17.8,11.6z"/>
|
||||
<path class="st21" d="M21.2,8.6c1.3,0,2.3-1,2.3-2.3s-1-2.3-2.3-2.3c-1.3,0-2.3,1-2.3,2.3S20,8.6,21.2,8.6z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000090987122570624474440000002432161440392897685_" gradientUnits="userSpaceOnUse" x1="20.068" y1="-87.0655" x2="22.3556" y2="-88.5473" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
|
||||
<stop offset="0" style="stop-color:#CED1EC"/>
|
||||
<stop offset="1" style="stop-color:#FFFFFF"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000090987122570624474440000002432161440392897685_);" d="M21.2,7.7c0.8,0,1.4-0.6,1.4-1.4
|
||||
S22,5,21.2,5c-0.8,0-1.4,0.6-1.4,1.4S20.5,7.7,21.2,7.7z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000044151119195171880090000016489263670362291109_" gradientUnits="userSpaceOnUse" x1="14.4192" y1="-110.4727" x2="2.0973" y2="-101.7197" gradientTransform="matrix(1 0 0 -1 0 -81.48)">
|
||||
<stop offset="0" style="stop-color:#B7B7BD"/>
|
||||
<stop offset="0.68" style="stop-color:#EFEFEF"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000044151119195171880090000016489263670362291109_);" d="M2.1,20c-0.3,0-0.5,0-0.8,0
|
||||
c1,2.8,2.9,5.2,5.3,6.9s5.3,2.6,8.3,2.6c0.1,0,0.3,0,0.4,0c-0.9-2.8-2.7-5.2-5.1-6.9C7.9,20.9,5.1,20,2.1,20z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" x="0" y="0" version="1.1"
|
||||
viewBox="0 0 30 30">
|
||||
<path d="M14.4 29.5h.4z" fill="#c5c8ca" />
|
||||
<path fill="#9da4a8" d="M15.3 29.5h.1zc-.1 0 0 0 0 0" />
|
||||
<path fill="#b7bbbd" d="M15.3 29.5h-.2z" />
|
||||
<path d="M14.1 29.5h.2z" fill="#c5c8ca" />
|
||||
<path fill="#bbbfc2" d="M13.9 29.5s.1 0 0 0h.2z" />
|
||||
<path fill="#cacdce" d="M13.6 29.5h.1z" />
|
||||
<path fill="#bfc3c5" d="M13.7 29.5q.15 0 0 0h.1z" />
|
||||
<path fill="#bcc0c2" d="M13.3 29.4q.15 0 0 0" />
|
||||
<path fill="#bdc1c4" d="M13.4 29.5c0-.1.1-.1 0 0q.15-.15 0 0m-.3-.1" />
|
||||
<path fill="#c7cacc" d="M13.2 29.4q.15 0 0 0" />
|
||||
<linearGradient id="SVGID_1_" x1="21.8812" x2="8.2545" y1="-88.078" y2="-104.6955" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#020037" />
|
||||
<stop offset="1" stop-color="#050f62" />
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_1_)" d="M15 .4C11.1.4 7.5 2 4.7 4.7 2 7.4.5 11.1.5 15q0 2.55.9 5.1h.8c2.9 0 5.8.9 8.2 2.6s4.2 4.1 5.1 6.9c3.8-.1 7.4-1.7 10-4.4s4.1-6.4 4.1-10.1c0-3.9-1.5-7.6-4.3-10.3C22.6 2 18.9.4 15 .4" />
|
||||
<path fill="#fff" d="M20.7 22.5c0 .4.1.8.3 1s.6.3 1 .3c-.4 0-.7.1-1 .3-.2.2-.3.6-.3 1 0-.4-.1-.7-.3-1-.2-.2-.6-.3-1-.3.4 0 .7-.1 1-.3s.3-.6.3-1m-13.8-7c0 .4.1.8.3 1s.6.3 1 .3c-.4 0-.7.1-1 .3-.2.2-.3.6-.3 1 0-.4-.1-.7-.3-1-.2-.2-.6-.3-1-.3.4 0 .7-.1 1-.3.2-.3.3-.6.3-1m3.7-11.4q.15 0 0 0c0 .3.1.5.3.7s.4.3.7.2c-.3 0-.5.1-.7.2-.2.2-.3.4-.2.7 0-.3-.1-.5-.2-.7-.3-.1-.5-.2-.8-.1.3-.1.5-.1.7-.3s.3-.5.2-.7" />
|
||||
<linearGradient id="SVGID_00000173122186048074043340000017421439166240502921_" x1="19.2457" x2="22.9553" y1="-89.3156" y2="-91.7188" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#e5e5e5" />
|
||||
<stop offset="1" stop-color="#b7b8c1" />
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_00000173122186048074043340000017421439166240502921_)" d="M21.8 1.2c-1.4.7-3 1.9-4.4 4.2-2.5 3.9-3.2 7.4-3.2 7.4L16 14l.3.2 1.9 1.2s2.9-2 5.4-5.9c1.5-2.3 2-4.3 2-5.8-.8-.1-1.5-.4-2.2-.8-.6-.4-1.2-1-1.6-1.7" />
|
||||
<linearGradient id="SVGID_00000127763695479642710240000017533313096818365313_" x1="21.2378" x2="19.0472" y1="-99.9826" y2="-97.8815" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ec4f4f" />
|
||||
<stop offset="1" stop-color="#a91919" />
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_00000127763695479642710240000017533313096818365313_)" d="M20.8 16.8c.9-1.4.3-3.2 0-3.8-.7.8-1.5 1.5-2.3 2.1.1.4.3.8.3 1.2 0 .1 0 .2-.1.3-.4.6-.8 1.3-1.1 2-.1.1-.1.2-.1.3-.1.2-.1.3 0 .5 0 .3.2.5.3.8l.1.1c.1 0 .1.1.2.1s.1 0 .2-.1.3-.2.4-.4c.8-.9 1.1-1.4 2.1-3.1" />
|
||||
<linearGradient id="SVGID_00000060717637781723915790000002744012061535479481_" x1="11.3158" x2="14.8122" y1="-99.2586" y2="-101.5237" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f2a518" />
|
||||
<stop offset="1" stop-color="#f4e23e" />
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_00000060717637781723915790000002744012061535479481_)" d="m15.1 15.7-1.7-1.1c-2 3.1-3.3 7-2.4 7.5.9.6 3.9-2.2 5.9-5.3z" />
|
||||
<linearGradient id="SVGID_00000070084874335106853820000008402293642909580433_" x1="-4386.2534" x2="-4497.9517" y1="747.6443" y2="769.0099" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ec4f4f" />
|
||||
<stop offset="1" stop-color="#a91919" />
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_00000070084874335106853820000008402293642909580433_)" d="M15.2 9.5c-.7-.1-2.5.1-3.4 1.5-1.1 1.6-1.5 2.1-2 3.2-.1.2-.1.3-.2.5v.2c0 .1.1.1.1.1s.1 0 .2.1c.3.1.6 0 .8 0s.3-.1.4-.2l.3-.3c.5-.6.9-1.2 1.3-1.8.1-.1.2-.2.3-.2.4-.1.8-.1 1.2-.2.3-1 .6-2 1-2.9" />
|
||||
<path fill="#df3030" d="M25 .6c-.2-.1-1.5-.2-3.2.7.4.7 1 1.2 1.6 1.7.7.4 1.4.7 2.2.8.1-1.9-.5-3.1-.6-3.2m-6.6 14.9L14 12.7h-.2l-.9 1.4v.2l4.4 2.8h.2l.9-1.4z" />
|
||||
<linearGradient id="SVGID_00000044894753735506851200000013592864944465274029_" x1="14.9436" x2="16.3716" y1="-95.9217" y2="-96.8468" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#b71e1e" />
|
||||
<stop offset=".44" stop-color="#df3030" />
|
||||
<stop offset="1" stop-color="#c51d1d" />
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_00000044894753735506851200000013592864944465274029_)" d="M17.8 11.6c-.4-.2-2.1 1.6-3.2 3.3-.8 1.2-1.4 3-1.1 3.2.4.2 1.7-1 2.5-2.3 1.1-1.6 2.1-3.9 1.8-4.2" />
|
||||
<path fill="#17181c" d="M21.2 8.6c1.3 0 2.3-1 2.3-2.3S22.5 4 21.2 4s-2.3 1-2.3 2.3 1.1 2.3 2.3 2.3" />
|
||||
<linearGradient id="SVGID_00000090987122570624474440000002432161440392897685_" x1="20.068" x2="22.3556" y1="-87.0655" y2="-88.5473" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ced1ec" />
|
||||
<stop offset="1" stop-color="#fff" />
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_00000090987122570624474440000002432161440392897685_)" d="M21.2 7.7c.8 0 1.4-.6 1.4-1.4S22 5 21.2 5s-1.4.6-1.4 1.4.7 1.3 1.4 1.3" />
|
||||
<linearGradient id="SVGID_00000044151119195171880090000016489263670362291109_" x1="14.4192" x2="2.0973" y1="-110.4727" y2="-101.7197" gradientTransform="matrix(1 0 0 -1 0 -81.48)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#b7b7bd" />
|
||||
<stop offset=".68" stop-color="#efefef" />
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_00000044151119195171880090000016489263670362291109_)" d="M2.1 20h-.8c1 2.8 2.9 5.2 5.3 6.9s5.3 2.6 8.3 2.6h.4c-.9-2.8-2.7-5.2-5.1-6.9C7.9 20.9 5.1 20 2.1 20" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 5.6 KiB |
1
auth/assets/custom-icons/icons/cryptee.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="1400" height="1400" xmlns="http://www.w3.org/2000/svg"><path d="M699.914 0C1004.659 0 1263.915 194.786 1360 466.662l-399.246-.003C896.674 395.059 803.556 350 699.914 350c-193.276 0-349.957 156.7-349.957 350s156.681 350 349.957 350c103.641 0 196.76-45.059 260.84-116.658L1360 933.34C1263.915 1205.214 1004.659 1400 699.914 1400 313.362 1400 0 1086.6 0 700S313.362 0 699.914 0zm347.087 747.002L1398 747a696.274 696.274 0 0 1-12.453 93H1021a345.75 345.75 0 0 0 26.001-92.998zM1385.547 560A696.301 696.301 0 0 1 1398 653l-351-.002A345.762 345.762 0 0 0 1021 560h364.547z" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 608 B |
44
auth/assets/custom-icons/icons/fanatical.svg
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 399.76401 400"
|
||||
preserveAspectRatio="xMinYMid"
|
||||
aria-labelledby="navbar-fanatical-logo"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
sodipodi:docname="Untitled.svg"
|
||||
width="399.76401"
|
||||
height="400"
|
||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="namedview2"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:zoom="0.69295302"
|
||||
inkscape:cx="205.64165"
|
||||
inkscape:cy="207.08475"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="938"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<g
|
||||
fill="none"
|
||||
id="g2">
|
||||
<path
|
||||
fill="#ff9800"
|
||||
d="m 2.8756,166.0056 h 284.671 a 2.9981,2.9981 0 0 0 2.7221,-1.7424 l 25.8632,-56.0452 c 0.6946,-1.504 0.0391,-3.2867 -1.464,-3.9817 a 2.9968,2.9968 0 0 0 -1.258,-0.2767 L 24.4917,103.9952 C 58.4482,42.0187 124.261,0 199.882,0 c 110.3917,0 199.882,89.543 199.882,200 0,110.457 -89.4903,200 -199.882,200 C 89.4902,400 0,310.457 0,200 0,188.412 0.985,177.054 2.8756,166.0056 Z M 125.9256,328 c 0,2.2091 1.7898,4 3.9977,4 h 5.1722 l 62.8312,-79.0111 h 49.4291 a 2.9981,2.9981 0 0 0 2.722,-1.7422 l 25.835,-55.976 a 3.0015,3.0015 0 0 0 0.2761,-1.2577 c 0,-1.6569 -1.3423,-3 -2.9982,-3 H 125.9257 V 328 Z"
|
||||
id="path1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
3
auth/assets/custom-icons/icons/finary.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="500" height="500" viewBox="0 0 500 500" fill="#F1C086" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M166.67 62C74.62 62 0 136.62 0 228.67H333.33C425.38 228.67 500 154.05 500 62H166.67ZM166.67 270.33C74.62 270.33 0 344.95 0 437H154.76C246.81 437 321.43 362.38 321.43 270.33H166.67Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 302 B |
1
auth/assets/custom-icons/icons/fortrabbit.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"><path d="M115 144c0 6-2 12-7 16s-9 7-16 7-11-3-16-7-6-10-6-16 2-12 6-16 10-7 16-7 12 3 16 7c5 5 7 10 7 16zm71-23-8 38-7 34a63 63 0 0 1-36 42c-5 2-11 3-17 3s-10 0-14-2l-7-4c-2-1-4-3-4-5l-1-6c0-4 1-7 3-9s6-4 10-4l9 2c3 1 4 4 6 6l4 8 3 7c3-3 5-7 7-13l7-22 16-75h-18l2-9h18l1-7c1-6 4-11 7-17s7-10 12-14c4-4 10-8 16-10s11-4 17-4l13 1 8 4 4 6 1 6a15 15 0 0 1-3 8l-4 4-7 1-8-2-6-6-4-8-3-7c-3 3-5 7-7 12l-6 23-2 10h22l-2 9h-22z"/></svg>
|
||||
|
After Width: | Height: | Size: 491 B |
6
auth/assets/custom-icons/icons/immo_scout_24.svg
Normal file
|
After Width: | Height: | Size: 12 KiB |
@@ -1,4 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 724 264">
|
||||
<path
|
||||
d="M38.53 260.65H.43V27.86h38.1zm86.46 2.77c-42.25 0-66.48-22.96-66.48-63V89.33h38.1v108.28c0 23.61 8.7 32.39 32.12 32.39 30.35 0 42.73-14.54 42.73-50.17v-90.5h38.1v171.33h-36.54v-29.91c-4.99 22.98-27.12 32.67-48.03 32.67zm347.2-2.77H434.4V149.87c0-22.5-7.01-30.87-25.88-30.87-24.28 0-37.11 14.45-37.11 41.79v99.86h-37.79V149.87c0-21.93-7.23-30.87-24.94-30.87-31.59 0-38.05 32.96-38.05 41.79v99.86h-38.1V89.33h36.54v29.96c6.49-21.02 27.02-33.71 47.72-33.71 20.69 0 38.09 7.9 45.64 33.71 10.13-26.76 28.35-33.71 50.15-33.71 37.88 0 59.61 18.88 59.61 51.81v123.26h0zm76.65 2.77c-52.62 0-61.55-33.45-61.55-50.52 0-20.1 8.83-38.21 27.93-45.55 8.41-3.11 16.52-5.43 24.84-7.1 7.33-1.47 18.64-3.03 26.91-4.17l2.73-.38c14.38-2 29.67-9.21 29.67-18.62 0-16-20.51-18.39-32.74-18.39-13.87 0-23.64 3.57-27.53 10.05-3.49 6.46-3.73 7.97-4.62 13.6l-.62 4.43h-38.1l.68-5.61c1.35-11.14 3.41-19.03 6.48-24.83 10.54-20.39 31.77-30.75 63.08-30.75 26.11 0 44.63 8.23 53.26 15.94 5.31 4.6 9.1 9.84 11.89 16.46 5.84 12.36 6.32 20.63 6.32 29.4v86.43c0 8.07.78 14.97 2.31 20.5l1.76 6.35h-38.91l-.7-4.19c-.5-2.96-.67-19.75-.88-26.23-8.99 23.61-28.27 33.18-52.21 33.18zm50.53-93.72c-7.97 6.11-20.47 9.6-38.62 13.23-31.27 5.78-36.54 13.06-36.54 27.22 0 12.5 10.63 20.26 27.75 20.26 33.23 0 47.41-15.48 47.41-51.77v-8.94zm124.2-105.51C688.46 64.19 660 35.73 660 .62c0 35.11-28.46 63.57-63.57 63.57h0c35.11 0 63.57 28.46 63.57 63.57h0c0-35.11 28.46-63.57 63.57-63.57z" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 724 264">
|
||||
<path
|
||||
d="M38.53 260.65H.43V27.86h38.1zm86.46 2.77c-42.25 0-66.48-22.96-66.48-63V89.33h38.1v108.28c0 23.61 8.7 32.39 32.12 32.39 30.35 0 42.73-14.54 42.73-50.17v-90.5h38.1v171.33h-36.54v-29.91c-4.99 22.98-27.12 32.67-48.03 32.67zm347.2-2.77H434.4V149.87c0-22.5-7.01-30.87-25.88-30.87-24.28 0-37.11 14.45-37.11 41.79v99.86h-37.79V149.87c0-21.93-7.23-30.87-24.94-30.87-31.59 0-38.05 32.96-38.05 41.79v99.86h-38.1V89.33h36.54v29.96c6.49-21.02 27.02-33.71 47.72-33.71 20.69 0 38.09 7.9 45.64 33.71 10.13-26.76 28.35-33.71 50.15-33.71 37.88 0 59.61 18.88 59.61 51.81v123.26h0zm76.65 2.77c-52.62 0-61.55-33.45-61.55-50.52 0-20.1 8.83-38.21 27.93-45.55 8.41-3.11 16.52-5.43 24.84-7.1 7.33-1.47 18.64-3.03 26.91-4.17l2.73-.38c14.38-2 29.67-9.21 29.67-18.62 0-16-20.51-18.39-32.74-18.39-13.87 0-23.64 3.57-27.53 10.05-3.49 6.46-3.73 7.97-4.62 13.6l-.62 4.43h-38.1l.68-5.61c1.35-11.14 3.41-19.03 6.48-24.83 10.54-20.39 31.77-30.75 63.08-30.75 26.11 0 44.63 8.23 53.26 15.94 5.31 4.6 9.1 9.84 11.89 16.46 5.84 12.36 6.32 20.63 6.32 29.4v86.43c0 8.07.78 14.97 2.31 20.5l1.76 6.35h-38.91l-.7-4.19c-.5-2.96-.67-19.75-.88-26.23-8.99 23.61-28.27 33.18-52.21 33.18zm50.53-93.72c-7.97 6.11-20.47 9.6-38.62 13.23-31.27 5.78-36.54 13.06-36.54 27.22 0 12.5 10.63 20.26 27.75 20.26 33.23 0 47.41-15.48 47.41-51.77v-8.94zm124.2-105.51C688.46 64.19 660 35.73 660 .62c0 35.11-28.46 63.57-63.57 63.57h0c35.11 0 63.57 28.46 63.57 63.57h0c0-35.11 28.46-63.57 63.57-63.57z"
|
||||
fill="#ffffff" style="mix-blend-mode: difference;" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -1,15 +1,7 @@
|
||||
<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g style="mix-blend-mode:difference">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M363.636 23H409.091V477.545H363.636V23ZM0 23H45.4545V477.545H0V23ZM227.273 295.727H181.818V386.636H227.273V295.727ZM272.727 113.909H318.182V204.818H272.727V113.909Z" fill="white"/>
|
||||
</g>
|
||||
<path d="M136.364 386.636H45.4545V477.545H136.364V386.636Z" fill="#EA3326"/>
|
||||
<path d="M500 386.636H409.091V477.545H500V386.636Z" fill="#EA3326"/>
|
||||
<path d="M136.364 295.727H45.4545V386.636H136.364V295.727Z" fill="#EB5829"/>
|
||||
<path d="M318.182 295.727H227.273V386.636H318.182V295.727Z" fill="#EB5829"/>
|
||||
<path d="M500 295.727H409.091V386.636H500V295.727Z" fill="#EB5829"/>
|
||||
<path d="M136.364 23H45.4545V113.909H136.364V23Z" fill="#F7D046"/>
|
||||
<path d="M500 23H409.091V113.909H500V23Z" fill="#F7D046"/>
|
||||
<path d="M227.273 113.909H45.4545V204.818H227.273V113.909Z" fill="#F2A73B"/>
|
||||
<path d="M500 113.909H318.182V204.818H500V113.909Z" fill="#F2A73B"/>
|
||||
<path d="M500 204.818H45.4545V295.727H500V204.818Z" fill="#EE792F"/>
|
||||
</svg>
|
||||
<svg width="500" height="500" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M71.41 73H142.83V143.75H71.41V73ZM357.12 73H428.54V143.75H357.12V73Z" fill="#FFD800"/>
|
||||
<path d="M71.41 143.75H214.25V214.5H71.41V143.75ZM285.7 143.75H428.54V214.5H285.7V143.75Z" fill="#FFAF00"/>
|
||||
<path d="M71.41 214.5H428.54V285.25H71.41V214.5Z" fill="#FF8205"/>
|
||||
<path d="M71.41 285.27H142.83V356.02H71.41V285.27ZM214.27 285.27H285.69V356.02H214.27V285.27ZM357.12 285.27H428.54V356.02H357.12V285.27Z" fill="#FA500F"/>
|
||||
<path d="M0 356.06H214.3V426.82H0V356.06ZM285.7 356.06H500V426.82H285.7V356.06Z" fill="#E10500"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 628 B |
1
auth/assets/custom-icons/icons/oracle_cloud.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg height="2100" viewBox="0 0 32 21" width="3200" xmlns="http://www.w3.org/2000/svg"><path d="m9.9 20.1c-5.5 0-9.9-4.4-9.9-9.9s4.4-9.9 9.9-9.9h11.6c5.5 0 9.9 4.4 9.9 9.9s-4.4 9.9-9.9 9.9zm11.3-3.5c3.6 0 6.4-2.9 6.4-6.4 0-3.6-2.9-6.4-6.4-6.4h-11c-3.6 0-6.4 2.9-6.4 6.4s2.9 6.4 6.4 6.4z" fill="#c74634"/></svg>
|
||||
|
After Width: | Height: | Size: 310 B |
BIN
auth/assets/generation-icons/icon-monochrome.png
Normal file
|
After Width: | Height: | Size: 489 KiB |
@@ -90,11 +90,11 @@ PODS:
|
||||
- SDWebImage (5.21.0):
|
||||
- SDWebImage/Core (= 5.21.0)
|
||||
- SDWebImage/Core (5.21.0)
|
||||
- Sentry/HybridSDK (8.36.0)
|
||||
- sentry_flutter (8.9.0):
|
||||
- Sentry/HybridSDK (8.46.0)
|
||||
- sentry_flutter (8.14.2):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Sentry/HybridSDK (= 8.36.0)
|
||||
- Sentry/HybridSDK (= 8.46.0)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
@@ -232,44 +232,44 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0
|
||||
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
|
||||
cupertino_http: 947a233f40cfea55167a49f2facc18434ea117ba
|
||||
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
|
||||
app_links: 3da4c36b46cac3bf24eb897f1a6ce80bda109874
|
||||
connectivity_plus: 3f6c9057f4cd64198dc826edfb0542892f825343
|
||||
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
|
||||
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
|
||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
||||
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
|
||||
fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
|
||||
file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
|
||||
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
|
||||
fk_user_agent: 137145b086229251761678fe034da53753f4ce59
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
flutter_email_sender: 10a22605f92809a11ef52b2f412db806c6082d40
|
||||
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
|
||||
flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb
|
||||
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
|
||||
flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778
|
||||
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
|
||||
fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c
|
||||
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
|
||||
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
|
||||
flutter_email_sender: 2397f5e84aaacfb61af569637a963e7c687858d8
|
||||
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||
flutter_local_authentication: 989278c681612f1ee0e36019e149137f114b9d7f
|
||||
flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100
|
||||
flutter_native_splash: 35ddbc7228eafcb3969dcc5f1fbbe27c1145a4f0
|
||||
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
|
||||
fluttertoast: 76fea30fcf04176325f6864c87306927bd7d2038
|
||||
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
||||
move_to_background: 155f7bfbd34d43ad847cb630d2d2d87c17199710
|
||||
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
||||
objective_c: 77e887b5ba1827970907e10e832eec1683f3431d
|
||||
objective_c: 89e720c30d716b036faf9c9684022048eee1eee2
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
privacy_screen: 1a131c052ceb3c3659934b003b0d397c2381a24e
|
||||
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
|
||||
package_info_plus: 580e9a5f1b6ca5594e7c9ed5f92d1dfb2a66b5e1
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
privacy_screen: 3159a541f5d3a31bea916cfd4e58f9dc722b3fd4
|
||||
qr_code_scanner: d77f94ecc9abf96d9b9b8fc04ef13f611e5a147a
|
||||
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
|
||||
Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57
|
||||
sentry_flutter: 0eb93e5279eb41e2392212afe1ccd2fecb4f8cbe
|
||||
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
sodium_libs: 1faae17af662384acbd13e41867a0008cd2e2318
|
||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
|
||||
sentry_flutter: 27892878729f42701297c628eb90e7c6529f3684
|
||||
share_plus: 011d6fb4f9d2576b83179a3a5c5e323202cdabcf
|
||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||
sodium_libs: 6c6d0e83f4ee427c6464caa1f1bdc2abf3ca0b7f
|
||||
sqflite: c35dad70033b8862124f8337cc994a809fcd9fa3
|
||||
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
|
||||
sqlite3_flutter_libs: c00457ebd31e59fa6bb830380ddba24d44fbcd3b
|
||||
sqlite3_flutter_libs: 9379996d65aa23dcda7585a5b58766cebe0aa042
|
||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
|
||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||
|
||||
PODFILE CHECKSUM: 78f002751f1a8f65042b8da97902ba4124271c5a
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
"saveAction": "حفظ",
|
||||
"nextTotpTitle": "التالي",
|
||||
"deleteCodeTitle": "حذف الرمز؟",
|
||||
"deleteCodeMessage": "هل أنت متأكد من أنك تريد حذف هذه الشيفرة؟ هذا الإجراء لا رجعة فيه.",
|
||||
"deleteCodeMessage": "هل أنت متيقِّن من أنك تريد حذف هذه الشيفرة؟ هذا الإجراء لا رجعة فيه.",
|
||||
"trashCode": "حذف الكود؟",
|
||||
"trashCodeMessage": "هل أنت متيقِّن أنك تريد حذف الكود الخاص بـ {account}؟",
|
||||
"trash": "سلة المهملات",
|
||||
@@ -513,5 +513,10 @@
|
||||
"free5GB": "5GB مجانًا على <bold-green>ente</bold-green> صور",
|
||||
"loginWithAuthAccount": "سجّل الدخول باستخدام حساب المُصادقة",
|
||||
"freeStorageOffer": "خَصْم 10٪ على صور <bold-green>ente</bold-green>",
|
||||
"freeStorageOfferDescription": "استخدم الكود \"AUTH\" وأحصل على 10٪ خَصْم في السنة الأولى"
|
||||
"freeStorageOfferDescription": "استخدم الكود \"AUTH\" وأحصل على 10٪ خَصْم في السنة الأولى",
|
||||
"advanced": "متقدم",
|
||||
"algorithm": "الخوارزمية",
|
||||
"type": "النوع",
|
||||
"period": "المدّة",
|
||||
"digits": "الأرقام"
|
||||
}
|
||||
@@ -88,6 +88,8 @@
|
||||
"useRecoveryKey": "Použít obnovovací klíč",
|
||||
"incorrectPasswordTitle": "Nesprávné heslo",
|
||||
"welcomeBack": "Vítejte zpět!",
|
||||
"emailAlreadyRegistered": "E-mail je již registrován.",
|
||||
"emailNotRegistered": "E-mail není registrován.",
|
||||
"madeWithLoveAtPrefix": "vyrobeno s ❤️ v ",
|
||||
"supportDevs": "Předplaťte si <bold-green>ente</bold-green>, abyste nás podpořili",
|
||||
"supportDiscount": "Použijte kód \"AUTH\" pro získání 10% slevy na první rok",
|
||||
@@ -495,9 +497,18 @@
|
||||
"appLockOfflineModeWarning": "Zvolili jste si pokračování bez zálohování. Pokud zapomenete heslo do aplikace, přístup k datům bude uzamčen.",
|
||||
"duplicateCodes": "Duplikovat kódy",
|
||||
"noDuplicates": "✨ Žádné duplikáty",
|
||||
"youveNoDuplicateCodesThatCanBeCleared": "Nemáte žádné duplicitní kódy k odstranění",
|
||||
"deduplicateCodes": "Deduplikovat kódy",
|
||||
"deselectAll": "Zrušit výběr všech položek",
|
||||
"selectAll": "Vybrat vše",
|
||||
"deleteDuplicates": "Odstranit duplikáty",
|
||||
"plainHTML": "Prosté HTML"
|
||||
"plainHTML": "Prosté HTML",
|
||||
"tellUsWhatYouThink": "Sdělte nám svůj názor",
|
||||
"dropReviewiOS": "Zanechat recenzi na App Store",
|
||||
"dropReviewAndroid": "Zanechat recenzi na Play Store",
|
||||
"supportEnte": "Podpořte <bold-green>ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "Dejte nám hvězdu na Githubu",
|
||||
"free5GB": "5GB zdarma na <bold-green>ente</bold-green> Fotky",
|
||||
"freeStorageOffer": "10% sleva na <bold-green>ente</bold-green> fotky",
|
||||
"freeStorageOfferDescription": "Použijte kód \"AUTH\" pro získání 10% slevy na první rok"
|
||||
}
|
||||
@@ -91,39 +91,39 @@
|
||||
"emailAlreadyRegistered": "E-Mail ist bereits registriert.",
|
||||
"emailNotRegistered": "E-Mail-Adresse nicht registriert.",
|
||||
"madeWithLoveAtPrefix": "gemacht mit ❤️ bei ",
|
||||
"supportDevs": "Bei <bold-green>ente</bold-green> registrieren, um das Projekt zu unterstützen",
|
||||
"supportDevs": "Abonnieren Sie <bold-green>ente</bold-green>, um das Projekt zu unterstützen",
|
||||
"supportDiscount": "Benutzen Sie den Rabattcode \"AUTH\" für 10 % Rabatt im ersten Jahr",
|
||||
"changeEmail": "E-Mail ändern",
|
||||
"changePassword": "Passwort ändern",
|
||||
"data": "Datei",
|
||||
"data": "Daten",
|
||||
"importCodes": "Codes importieren",
|
||||
"importTypePlainText": "Klartext",
|
||||
"importTypeEnteEncrypted": "Verschlüsselter Ente-Export",
|
||||
"passwordForDecryptingExport": "Passwort um den Export zu entschlüsseln",
|
||||
"passwordEmptyError": "Passwort kann nicht leer sein",
|
||||
"importFromApp": "Importiere Codes von {appName}",
|
||||
"importGoogleAuthGuide": "Exportiere deine Accounts von Google Authenticator zu einem QR-Code, durch die \"Konten übertragen\" Option. Scanne den QR-Code danach mit einem anderen Gerät.\n\nTipp: Du kannst die Kamera eines Laptops verwenden, um ein Foto den dem QR-Code zu erstellen.",
|
||||
"importSelectJsonFile": "Wähle eine JSON-Datei",
|
||||
"importFromApp": "Importieren Sie Codes von {appName}",
|
||||
"importGoogleAuthGuide": "Exportieren Sie Ihre Accounts von Google Authenticator zu einem QR-Code, mithilfe der \"Konten übertragen\" Option. Scanne den QR-Code danach mit einem anderen Gerät.\n\nTipp: Sie können die Kamera eines Laptops verwenden, um ein Foto vom QR-Code zu erstellen.",
|
||||
"importSelectJsonFile": "Wählen Sie eine JSON-Datei",
|
||||
"importSelectAppExport": "{appName} Exportdatei auswählen",
|
||||
"importEnteEncGuide": "Wähle die von Ente exportierte, verschlüsselte JSON-Datei",
|
||||
"importRaivoGuide": "Verwenden Sie die Option \"Export OTPs to Zip archive\" in den Raivo-Einstellungen.\n\nEntpacken Sie die Zip-Datei und importieren Sie die JSON-Datei.",
|
||||
"importEnteEncGuide": "Wählen Sie die von Ente exportierte, verschlüsselte JSON-Datei",
|
||||
"importRaivoGuide": "Verwenden Sie die Option \"Export OTPs to Zip archive\" in den Einstellungen von Raivo.\n\nEntpacken Sie die Zip-Datei und importieren Sie die JSON-Datei.",
|
||||
"importBitwardenGuide": "Verwenden Sie die Option \"Tresor exportieren\" innerhalb der Bitwarden Tools und importieren Sie die unverschlüsselte JSON-Datei.",
|
||||
"importAegisGuide": "Verwenden Sie die Option \"Tresor exportieren\" in den Aegis-Einstellungen.\n\nFalls Ihr Tresor verschlüsselt ist, müssen Sie das Passwort für den Tresor eingeben, um ihn zu entschlüsseln.",
|
||||
"importAegisGuide": "Verwenden Sie die Option \"Tresor exportieren\" in den Einstellungen von Aegis.\n\nFalls Ihr Tresor verschlüsselt ist, müssen Sie das Passwort für den Tresor eingeben, um ihn zu entschlüsseln.",
|
||||
"import2FasGuide": "Verwenden Sie unter \"Einstellungen → Backup\" die Option \"Exportieren\" in 2FAS.\n\nFalls Ihr Backup verschlüsselt ist, müssen Sie das Passwort eingeben, um das Backup zu entschlüsseln.",
|
||||
"importLastpassGuide": "Verwenden Sie die Option \"Konten übertragen → Konten in Datei exportieren\" in den Lastpass Authenticator Einstellungen. \nImportieren Sie anschließend die heruntergeladene JSON-Datei.",
|
||||
"exportCodes": "Codes exportieren",
|
||||
"importLabel": "Importieren",
|
||||
"importInstruction": "Bitte wählen sie eine Datei die Codes in folgendem Format beinhaltet",
|
||||
"importCodeDelimiterInfo": "Codes können in einer neuen Zeile stehen oder durch Kommata getrennt sein",
|
||||
"importInstruction": "Bitte wählen Sie eine Datei die Codes in folgendem Format beinhaltet",
|
||||
"importCodeDelimiterInfo": "Codes können in einer neuen Zeile stehen oder durch ein Komma getrennt sein",
|
||||
"selectFile": "Datei auswählen",
|
||||
"emailVerificationToggle": "E-Mail-Verifizierung",
|
||||
"emailVerificationEnableWarning": "Stellen Sie sicher, eine Kopie Ihrer Zwei-Faktor-Authentifizierung an anderer Stelle zu speichern, um zu vermeiden, dass Sie sich versehentlich aus Ihrem Account aussperren.",
|
||||
"authToChangeEmailVerificationSetting": "Bitte Authentifizieren um die E-Mail Bestätigung zu ändern",
|
||||
"emailVerificationEnableWarning": "Um zu vermeiden, versehentlich aus Ihrem Konto ausgesperrt zu werden, stellen Sie sicher, dass Sie den Zwei-Faktor-Authentifizierungscode für Ihr E-Mail-Konto außerhalb von Ente Auth speichern, bevor Sie die E-Mail-Verifizierung aktivieren.",
|
||||
"authToChangeEmailVerificationSetting": "Bitte authentifizieren, um die E-Mail Bestätigung zu ändern",
|
||||
"authenticateGeneric": "Bitte authentifizieren",
|
||||
"authToViewYourRecoveryKey": "Bitte authentifizieren um ihren Wiederherstellungscode anzuzeigen",
|
||||
"authToChangeYourEmail": "Bitte authentifizieren um ihre Emailadresse zu ändern",
|
||||
"authToChangeYourPassword": "Bitte authentifizieren um ihr Passwort zu ändern",
|
||||
"authToViewSecrets": "Bitte authentifizieren Sie sich, um ihren Wiederherstellungscode anzuzeigen",
|
||||
"authToViewYourRecoveryKey": "Bitte authentifizieren, um Ihren Wiederherstellungscode anzuzeigen",
|
||||
"authToChangeYourEmail": "Bitte authentifizieren, um Ihre E-Mail-Adresse zu ändern",
|
||||
"authToChangeYourPassword": "Bitte authentifizieren, um Ihr Passwort zu ändern",
|
||||
"authToViewSecrets": "Bitte authentifizieren, um Ihren Wiederherstellungscode anzuzeigen",
|
||||
"authToInitiateSignIn": "Bitte authentifizieren, um die Anmeldung zum Backup zu starten.",
|
||||
"ok": "Ok",
|
||||
"cancel": "Abbrechen",
|
||||
@@ -140,18 +140,18 @@
|
||||
"delete": "Löschen",
|
||||
"enterYourPasswordHint": "Geben Sie Ihr Passwort ein",
|
||||
"forgotPassword": "Passwort vergessen",
|
||||
"oops": "Hopla",
|
||||
"oops": "Hoppla",
|
||||
"suggestFeatures": "Features vorschlagen",
|
||||
"faq": "FAQ",
|
||||
"somethingWentWrongMessage": "Ein Fehler ist aufgetreten, bitte versuchen Sie es erneut",
|
||||
"leaveFamily": "Familie verlassen",
|
||||
"leaveFamilyMessage": "Sind Sie sicher, dass Sie den Familien-Plan verlassen wollen?",
|
||||
"inFamilyPlanMessage": "Sie haben einen Familien-Plan!",
|
||||
"hintForMobile": "Lange drücken, um den Code zu bearbeiten oder zu entfernen.",
|
||||
"hintForMobile": "Lange auf einen Code drücken, um ihn zu bearbeiten oder zu entfernen.",
|
||||
"hintForDesktop": "Klicken Sie mit der rechten Maustaste auf einen Code zum Bearbeiten oder Entfernen.",
|
||||
"scan": "Scannen",
|
||||
"scanACode": "Scan einen Code",
|
||||
"verify": "Überprüfen Sie",
|
||||
"verify": "Verifizieren",
|
||||
"verifyEmail": "E-Mail-Adresse verifizieren",
|
||||
"enterCodeHint": "Geben Sie den 6-stelligen Code \naus Ihrer Authentifikator-App ein.",
|
||||
"lostDeviceTitle": "Gerät verloren?",
|
||||
@@ -172,9 +172,10 @@
|
||||
},
|
||||
"invalidQRCode": "Ungültiger QR-Code",
|
||||
"noRecoveryKeyTitle": "Kein Wiederherstellungsschlüssel?",
|
||||
"enterEmailHint": "Geben Sie Ihre E-Mail Adresse ein",
|
||||
"invalidEmailTitle": "Ungültige E-Mail Adresse",
|
||||
"invalidEmailMessage": "Bitte geben Sie eine gültige E-Mail Adresse ein.",
|
||||
"enterEmailHint": "Geben Sie Ihre E-Mail-Adresse ein",
|
||||
"enterNewEmailHint": "Gib deine neue E-Mail-Adresse ein",
|
||||
"invalidEmailTitle": "Ungültige E-Mail-Adresse",
|
||||
"invalidEmailMessage": "Bitte geben Sie eine gültige E-Mail-Adresse ein.",
|
||||
"deleteAccount": "Konto löschen",
|
||||
"deleteAccountQuery": "Es tut uns leid, dass Sie gehen. Haben Sie ein Problem?",
|
||||
"yesSendFeedbackAction": "Ja, Feedback senden",
|
||||
@@ -187,7 +188,7 @@
|
||||
"moderateStrength": "Mittel",
|
||||
"confirmPassword": "Bestätigen Sie das Passwort",
|
||||
"close": "Schließen",
|
||||
"oopsSomethingWentWrong": "Ups, da ist etwas schief gelaufen.",
|
||||
"oopsSomethingWentWrong": "Hoppla, da ist etwas schiefgelaufen.",
|
||||
"selectLanguage": "Sprache auswählen",
|
||||
"language": "Sprache",
|
||||
"social": "Social",
|
||||
@@ -203,26 +204,26 @@
|
||||
"noResult": "Kein Ergebnis",
|
||||
"addCode": "Code hinzufügen",
|
||||
"scanAQrCode": "QR-Code scannen",
|
||||
"enterDetailsManually": "Details manuell hinzufügen",
|
||||
"enterDetailsManually": "Daten manuell hinzufügen",
|
||||
"edit": "Editieren",
|
||||
"share": "Teilen",
|
||||
"shareCodes": "Codes teilen",
|
||||
"shareCodesDuration": "Wählen Sie die Dauer aus, für die Sie die Codes teilen möchten.",
|
||||
"restore": "Wiederherstellen",
|
||||
"copiedToClipboard": "In die Zwischenablage kopieren",
|
||||
"copiedNextToClipboard": "Nächster Code wurde in die Zwischenablage kopiert",
|
||||
"copiedToClipboard": "In die Zwischenablage kopiert",
|
||||
"copiedNextToClipboard": "Nächster Code in die Zwischenablage kopiert",
|
||||
"error": "Fehler",
|
||||
"recoveryKeyCopiedToClipboard": "Wiederherstellungsschlüssel in die Zwischenablage kopiert",
|
||||
"recoveryKeyOnForgotPassword": "Sollten sie ihr Passwort vergessen, dann ist dieser Schlüssel die einzige Möglichkeit ihre Daten wiederherzustellen.",
|
||||
"recoveryKeySaveDescription": "Wir speichern diesen Schlüssel nicht. Sichern sie dieses diesen Schlüssel bestehend aus 24 Wörtern an einem sicheren Platz.",
|
||||
"recoveryKeySaveDescription": "Wir speichern diesen Schlüssel nicht. Sichern Sie diesen Schlüssel bestehend aus 24 Wörtern an einem sicheren Platz.",
|
||||
"doThisLater": "Auf später verschieben",
|
||||
"saveKey": "Schlüssel speichern",
|
||||
"save": "Speichern",
|
||||
"send": "Senden",
|
||||
"saveOrSendDescription": "Möchtest du dies in deinem Speicher (standardmäßig im Ordner Downloads) oder an andere Apps senden?",
|
||||
"saveOrSendDescription": "Möchtest du dies in deinem Speicher (standardmäßig im Ordner Downloads) speichern oder an andere Apps senden?",
|
||||
"saveOnlyDescription": "Möchtest du dies in deinem Speicher (standardmäßig im Ordner Downloads) speichern?",
|
||||
"back": "Zurück",
|
||||
"createAccount": "Account erstellen",
|
||||
"createAccount": "Konto erstellen",
|
||||
"passwordStrength": "Passwortstärke: {passwordStrengthValue}",
|
||||
"@passwordStrength": {
|
||||
"description": "Text to indicate the password strength",
|
||||
@@ -244,17 +245,17 @@
|
||||
"changePasswordTitle": "Passwort ändern",
|
||||
"resetPasswordTitle": "Passwort zurücksetzen",
|
||||
"encryptionKeys": "Verschlüsselungsschlüssel",
|
||||
"passwordWarning": "Wir speichern dieses Passwort nicht. Wenn du es vergisst, <underline>können wir deine Daten nicht entschlüsseln</underline>",
|
||||
"enterPasswordToEncrypt": "Gib ein Passwort ein, mit dem wir deine Daten verschlüsseln können",
|
||||
"enterNewPasswordToEncrypt": "Gib ein neues Passwort ein, mit dem wir deine Daten verschlüsseln können",
|
||||
"passwordWarning": "Wir speichern dieses Passwort nicht. Wenn Sie es vergessen, <underline>können wir Ihre Daten nicht entschlüsseln</underline>",
|
||||
"enterPasswordToEncrypt": "Geben Sie ein Passwort ein, mit dem wir Ihre Daten verschlüsseln können",
|
||||
"enterNewPasswordToEncrypt": "Geben Sie ein neues Passwort ein, mit dem wir Ihre Daten verschlüsseln können",
|
||||
"passwordChangedSuccessfully": "Passwort erfolgreich geändert",
|
||||
"generatingEncryptionKeys": "Generierung von Verschlüsselungsschlüsseln...",
|
||||
"continueLabel": "Weiter",
|
||||
"insecureDevice": "Unsicheres Gerät",
|
||||
"sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease": "Es tut uns leid, wir konnten keine sicheren Schlüssel auf diesem Gerät generieren.\n\nBitte registrieren Sie sich auf einem anderen Gerät.",
|
||||
"howItWorks": "So funktioniert's",
|
||||
"ackPasswordLostWarning": "Ich verstehe, dass der Verlust meines Passworts zum Verlust meiner Daten führen kann, denn diese ist <underline>Ende-zu-Ende verschlüsselt</underline>.",
|
||||
"loginTerms": "Durch das Klicken auf den Login-Button, stimme ich <u-terms>den Nutzungsbedingungen</u-terms> und den <u-policy>Datenschutzbestimmungen</u-policy> zu",
|
||||
"ackPasswordLostWarning": "Ich verstehe, dass der Verlust meines Passworts zum Verlust meiner Daten führen kann, denn diese sind <underline>Ende-zu-Ende verschlüsselt</underline>.",
|
||||
"loginTerms": "Durch das Klicken auf den Login-Button, stimme ich den <u-terms> Nutzungsbedingungen</u-terms> und den <u-policy>Datenschutzbestimmungen</u-policy> zu",
|
||||
"logInLabel": "Einloggen",
|
||||
"logout": "Ausloggen",
|
||||
"areYouSureYouWantToLogout": "Sind sie sicher, dass sie sich ausloggen möchten?",
|
||||
@@ -266,7 +267,7 @@
|
||||
"systemTheme": "System",
|
||||
"verifyingRecoveryKey": "Verifiziere Wiederherstellungsschlüssel...",
|
||||
"recoveryKeyVerified": "Wiederherstellungsschlüssel verifiziert",
|
||||
"recoveryKeySuccessBody": "Großartig! Ihr Wiederherstellungsschlüssel ist gültig. Vielen Dank für die Verifizierung.\n\nBitte denken sie daran, dass sie ihren Wiederherstellungsschlüssel sicher aufbewahren.",
|
||||
"recoveryKeySuccessBody": "Großartig! Ihr Wiederherstellungsschlüssel ist gültig. Vielen Dank für die Verifizierung.\n\nBitte denken Sie daran, den Wiederherstellungsschlüssel sicher aufzubewahren.",
|
||||
"invalidRecoveryKey": "Der eingegebene Wiederherstellungsschlüssel ist nicht gültig. Bitte stellen sie sicher, dass er aus 24 Wörtern besteht und prüfen sie die Schreibweise eines jeden.\n\nSollten sie einen Wiederherstellungsschlüssel im alten Format eingegeben haben vergewissern sie sich, dass er 64 Zeichen lang ist und prüfen sie jedes dieser Zeichen.",
|
||||
"recreatePasswordTitle": "Neues Passwort erstellen",
|
||||
"recreatePasswordBody": "Das benutzte Gerät ist nicht leistungsfähig genug das Passwort zu prüfen. Wir können es aber neu erstellen damit es auf jedem Gerät funktioniert. \n\nBitte loggen sie sich mit ihrem Wiederherstellungsschlüssel ein und erstellen sie ein neues Passwort (Sie können das selbe Passwort wieder verwenden, wenn sie möchten).",
|
||||
@@ -277,15 +278,15 @@
|
||||
"recoveryKeyVerifyReason": "Ihr Wiederherstellungsschlüssel ist der einzige Weg ihre Fotos wiederherzustellen sollten, sie ihr Passwort vergessen. Sie finden ihren Wiederherstellungsschlüssel unter Einstellungen > Account.\n\nBitte tragen sie ihren Wiederherstellungsschlüssel hier ein um zu prüfen ob sie in korrekt abgespeichert haben.",
|
||||
"confirmYourRecoveryKey": "Wiederherstellungsschlüssel bestätigen",
|
||||
"confirm": "Bestätigen",
|
||||
"emailYourLogs": "Email mit Logs senden",
|
||||
"emailYourLogs": "E-Mail mit Logs senden",
|
||||
"pleaseSendTheLogsTo": "Bitte Logs an {toEmail} senden",
|
||||
"copyEmailAddress": "Emailadresse kopieren",
|
||||
"copyEmailAddress": "E-Mail-Adresse kopieren",
|
||||
"exportLogs": "Logs exportieren",
|
||||
"enterYourRecoveryKey": "Wiederherstellungsschlüssel eingeben",
|
||||
"tempErrorContactSupportIfPersists": "Etwas ist schiefgelaufen. Bitte versuchen sie es später noch einmal. Sollte der Fehler weiter bestehen, kontaktieren sie unser Supportteam.",
|
||||
"tempErrorContactSupportIfPersists": "Etwas ist schiefgelaufen. Bitte versuchen Sie es später noch einmal. Sollte der Fehler weiter bestehen, kontaktieren sie unser Supportteam.",
|
||||
"networkHostLookUpErr": "Ente ist im Moment nicht erreichbar. Bitte überprüfen Sie Ihre Netzwerkeinstellungen. Sollte das Problem bestehen bleiben, wenden Sie sich bitte an den Support.",
|
||||
"networkConnectionRefusedErr": "Ente ist im Moment nicht erreichbar. Bitte versuchen Sie es später erneut. Sollte das Problem bestehen bleiben, wenden Sie sich bitte an den Support.",
|
||||
"itLooksLikeSomethingWentWrongPleaseRetryAfterSome": "Etwas ist schiefgelaufen. Bitte versuchen sie es später noch einmal. Sollte der Fehler weiter bestehen, kontaktieren sie unser Supportteam.",
|
||||
"itLooksLikeSomethingWentWrongPleaseRetryAfterSome": "Etwas ist schiefgelaufen. Bitte versuchen Sie es später noch einmal. Sollte der Fehler weiter bestehen, kontaktieren Sie unser Supportteam.",
|
||||
"about": "Über uns",
|
||||
"weAreOpenSource": "Wir sind Opensource!",
|
||||
"privacy": "Datenschutz",
|
||||
@@ -316,10 +317,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"sorry": "Entschuldigen sie",
|
||||
"importFailureDesc": "Ausgewählte Datei ließ sich nicht verarbeiten.\nBitte wenden sie sich an support@ente.io für Hilfe!",
|
||||
"sorry": "Entschuldigen Sie",
|
||||
"importFailureDesc": "Ausgewählte Datei ließ sich nicht verarbeiten.\nBitte wenden Sie sich an support@ente.io für Hilfe!",
|
||||
"pendingSyncs": "Warnung",
|
||||
"pendingSyncsWarningBody": "Einige Codes wurden nicht gesichert.\n\nBitte gehen sie sicher, dass sie einen Backupcode für diese Codes haben bevor sie sich ausloggen.",
|
||||
"pendingSyncsWarningBody": "Einige Codes wurden nicht gesichert.\n\nBitte gehen Sie sicher, dass Sie einen Backupcode für diese Codes haben bevor Sie sich ausloggen.",
|
||||
"checkInboxAndSpamFolder": "Bitte überprüfe deinen E-Mail-Posteingang (und Spam), um die Verifizierung abzuschließen",
|
||||
"tapToEnterCode": "Antippen, um den Code einzugeben",
|
||||
"resendEmail": "E-Mail erneut senden",
|
||||
@@ -339,10 +340,10 @@
|
||||
"mostFrequentlyUsed": "Häufig verwendet",
|
||||
"mostRecentlyUsed": "Zuletzt verwendet",
|
||||
"activeSessions": "Aktive Sitzungen",
|
||||
"somethingWentWrongPleaseTryAgain": "Ein Fehler ist aufgetreten, bitte versuche es erneut",
|
||||
"thisWillLogYouOutOfThisDevice": "Dadurch wirst du von diesem Gerät abgemeldet!",
|
||||
"thisWillLogYouOutOfTheFollowingDevice": "Dadurch wirst du von folgendem Gerät abgemeldet:",
|
||||
"terminateSession": "Sitzungen beenden?",
|
||||
"somethingWentWrongPleaseTryAgain": "Ein Fehler ist aufgetreten, bitte erneut versuchen",
|
||||
"thisWillLogYouOutOfThisDevice": "Dadurch werden Sie von diesem Gerät abgemeldet!",
|
||||
"thisWillLogYouOutOfTheFollowingDevice": "Dadurch werden Sie vom folgendem Gerät abgemeldet:",
|
||||
"terminateSession": "Sitzung beenden?",
|
||||
"terminate": "Beenden",
|
||||
"thisDevice": "Dieses Gerät",
|
||||
"toResetVerifyEmail": "Um Ihr Passwort zurückzusetzen, verifizieren Sie bitte zuerst Ihre E-Mail-Adresse.",
|
||||
@@ -352,7 +353,7 @@
|
||||
"incorrectCode": "Falscher Code",
|
||||
"sorryTheCodeYouveEnteredIsIncorrect": "Leider ist der eingegebene Code falsch",
|
||||
"emailChangedTo": "E-Mail-Adresse geändert zu {newEmail}",
|
||||
"authenticationFailedPleaseTryAgain": "Authentifizierung fehlgeschlagen, versuchen Sie es bitte erneut",
|
||||
"authenticationFailedPleaseTryAgain": "Authentifizierung fehlgeschlagen, bitte erneut versuchen",
|
||||
"authenticationSuccessful": "Authentifizierung erfolgreich!",
|
||||
"twofactorAuthenticationSuccessfullyReset": "Zwei-Faktor-Authentifizierung (2FA) erfolgreich zurückgesetzt",
|
||||
"incorrectRecoveryKey": "Falscher Wiederherstellungs-Schlüssel",
|
||||
@@ -365,22 +366,22 @@
|
||||
"passwordToEncryptExport": "Passwort zum Verschlüssen des Exports",
|
||||
"export": "Export",
|
||||
"useOffline": "Ohne Backup verwenden",
|
||||
"signInToBackup": "Melde dich an, um deine Codes zu sichern",
|
||||
"signInToBackup": "Melden Sie sich an, um Ihre Codes zu sichern",
|
||||
"singIn": "Anmelden",
|
||||
"sigInBackupReminder": "Bitte exportieren Sie Ihre Codes, um sicherzustellen, dass Sie ein Backup haben, aus dem Sie wiederherstellen können.",
|
||||
"sigInBackupReminder": "Bitte exportieren Sie Ihre Codes, um sicherzustellen, dass Sie ein Backup haben, das Sie wiederherstellen können.",
|
||||
"offlineModeWarning": "Sie haben sich dafür entschieden, ohne Sicherungen fortzufahren. Bitte führen Sie manuelle Sicherungen durch, um sicherzustellen, dass Ihre Codes sicher sind.",
|
||||
"showLargeIcons": "Große Symbole anzeigen",
|
||||
"compactMode": "Kompaktmodus",
|
||||
"shouldHideCode": "Codes ausblenden",
|
||||
"doubleTapToViewHiddenCode": "Sie können auf einen Eintrag doppelt tippen, um den Code anzuzeigen",
|
||||
"focusOnSearchBar": "Suche bei App-Start automatisch öffnen",
|
||||
"confirmUpdatingkey": "Sind Sie sich sicher, dass Sie den Secret Key bearbeiten wollen?",
|
||||
"focusOnSearchBar": "Suche beim App-Start fokussieren",
|
||||
"confirmUpdatingkey": "Sind Sie sich sicher, dass Sie den geheimen Schlüssel bearbeiten wollen?",
|
||||
"minimizeAppOnCopy": "Beim Kopieren App minimieren",
|
||||
"editCodeAuthMessage": "Authentifizieren, um Code zu bearbeiten",
|
||||
"deleteCodeAuthMessage": "Authentifizieren, um Code zu löschen",
|
||||
"showQRAuthMessage": "Authentifizieren, um QR-Code anzuzeigen",
|
||||
"confirmAccountDeleteTitle": "Kontolöschung bestätigen",
|
||||
"confirmAccountDeleteMessage": "Dieses Konto ist mit anderen Ente-Apps verknüpft, falls du welche verwendest.\n\nDeine hochgeladenen Daten werden in allen Ente-Apps zur Löschung vorgemerkt und dein Konto wird endgültig gelöscht.",
|
||||
"confirmAccountDeleteMessage": "Dieses Konto ist mit anderen Ente-Apps verknüpft, falls Sie welche verwenden.\n\nIhre hochgeladenen Daten werden in allen Ente-Apps zur Löschung vorgemerkt und Ihr Konto wird endgültig gelöscht.",
|
||||
"androidBiometricHint": "Identität bestätigen",
|
||||
"@androidBiometricHint": {
|
||||
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
|
||||
@@ -417,7 +418,7 @@
|
||||
"@goToSettings": {
|
||||
"description": "Message showed on a button that the user can click to go to settings pages from the current dialog. It is used on both Android and iOS side. Maximum 30 characters."
|
||||
},
|
||||
"androidGoToSettingsDescription": "Auf Ihrem Gerät ist keine biometrische Authentifizierung eingerichtet. Gehen Sie „Einstellungen“ > „Sicherheit“, um die biometrische Authentifizierung hinzuzufügen.",
|
||||
"androidGoToSettingsDescription": "Auf Ihrem Gerät ist keine biometrische Authentifizierung eingerichtet. Gehen Sie zu 'Einstellungen > Sicherheit', um die biometrische Authentifizierung hinzuzufügen.",
|
||||
"@androidGoToSettingsDescription": {
|
||||
"description": "Message advising the user to go to the settings and configure biometric on their device. It shows in a dialog on Android side."
|
||||
},
|
||||
@@ -434,9 +435,9 @@
|
||||
"description": "Message showed on a button that the user can click to leave the current dialog. It is used on iOS side. Maximum 30 characters."
|
||||
},
|
||||
"noInternetConnection": "Keine Internetverbindung",
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain": "Bitte überprüfe deine Internetverbindung und versuche es erneut.",
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain": "Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie erneut.",
|
||||
"signOutFromOtherDevices": "Von anderen Geräten abmelden",
|
||||
"signOutOtherBody": "Falls du denkst, dass jemand dein Passwort kennen könnte, kannst du alle anderen Geräte von deinem Account abmelden.",
|
||||
"signOutOtherBody": "Falls Sie denken, dass jemand Ihr Passwort kennen könnte, können Sie alle anderen Geräte forcieren, sich von Ihrem Konto abzumelden.",
|
||||
"signOutOtherDevices": "Andere Geräte abmelden",
|
||||
"doNotSignOut": "Nicht abmelden",
|
||||
"hearUsWhereTitle": "Wie hast du von Ente erfahren? (optional)",
|
||||
@@ -458,7 +459,7 @@
|
||||
"pinText": "Anpinnen",
|
||||
"unpinText": "Lösen",
|
||||
"pinnedCodeMessage": "{code} wurde angepinnt",
|
||||
"unpinnedCodeMessage": "{code} wird nicht weiter angepinnt",
|
||||
"unpinnedCodeMessage": "{code} wurde losgelöst",
|
||||
"pinned": "Angeheftet",
|
||||
"tags": "Tags",
|
||||
"createNewTag": "Neuen Tag erstellen",
|
||||
@@ -474,7 +475,7 @@
|
||||
"rawCodeData": "Rohcode Daten",
|
||||
"appLock": "App-Sperre",
|
||||
"noSystemLockFound": "Keine Systemsperre gefunden",
|
||||
"toEnableAppLockPleaseSetupDevicePasscodeOrScreen": "Um die App-Sperre zu aktivieren, konfiguriere bitte den Gerätepasscode oder die Bildschirmsperre in den Systemeinstellungen.",
|
||||
"toEnableAppLockPleaseSetupDevicePasscodeOrScreen": "Um die App-Sperre zu aktivieren, konfigurieren Sie bitte den Gerätepasscode oder die Bildschirmsperre in den Systemeinstellungen.",
|
||||
"autoLock": "Automatisches Sperren",
|
||||
"immediately": "Sofort",
|
||||
"reEnterPassword": "Passwort erneut eingeben",
|
||||
@@ -494,22 +495,29 @@
|
||||
"setNewPin": "Neue PIN festlegen",
|
||||
"importFailureDescNew": "Die ausgewählte Datei konnte nicht verarbeitet werden.",
|
||||
"appLockNotEnabled": "App-Sperre nicht aktiviert",
|
||||
"appLockNotEnabledDescription": "Bitte aktivieren Sie die App-Sperre über Security > App-Sperre",
|
||||
"authToViewPasskey": "Bitte authentifizieren, um deinen Passkey zu sehen",
|
||||
"duplicateCodes": "Doppelte Codes",
|
||||
"appLockNotEnabledDescription": "Bitte aktivieren Sie die App-Sperre über Sicherheit > App-Sperre",
|
||||
"authToViewPasskey": "Bitte authentifizieren, um Ihren Passkey zu sehen",
|
||||
"appLockOfflineModeWarning": "Sie haben sich dazu entschieden, ohne Sicherungen fortzufahren. Wenn Sie Ihre App-Sperre vergessen, können Sie nicht mehr auf Ihre Daten zugreifen.",
|
||||
"duplicateCodes": "Codes duplizieren",
|
||||
"noDuplicates": "✨ Keine Duplikate",
|
||||
"youveNoDuplicateCodesThatCanBeCleared": "Du hast keine doppelten Codes, die bereinigt werden können",
|
||||
"deduplicateCodes": "Codes deduplizieren",
|
||||
"deselectAll": "Alle abwählen",
|
||||
"selectAll": "Alles auswählen",
|
||||
"selectAll": "Alle auswählen",
|
||||
"deleteDuplicates": "Duplikate löschen",
|
||||
"plainHTML": "Reines HTML",
|
||||
"tellUsWhatYouThink": "Sagen Sie uns, was Sie denken",
|
||||
"dropReviewiOS": "Hinterlasse eine Rezension im App Store",
|
||||
"dropReviewAndroid": "Hinterlasse eine Rezension im Google Play Store",
|
||||
"supportEnte": "Support <bold-green>ente</bold-green>",
|
||||
"dropReviewiOS": "Hinterlassen Sie eine Rezension im App Store",
|
||||
"dropReviewAndroid": "Hinterlassen Sie eine Rezension im Google Play Store",
|
||||
"supportEnte": "Unterstütze <bold-green>ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "Gib uns einen Stern auf Github",
|
||||
"free5GB": "5GB kostenlos auf <bold-green>ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Mit Ihrem Auth Account anmelden",
|
||||
"freeStorageOffer": "10% Rabatt für <bold-green>ente</bold-green> Photos",
|
||||
"freeStorageOfferDescription": "Verwende den Code \"AUTH\", um 10% im 1. Jahr zu sparen"
|
||||
"freeStorageOfferDescription": "Verwende den Code \"AUTH\", um 10% im ersten Jahr zu sparen",
|
||||
"advanced": "Erweitert",
|
||||
"algorithm": "Algorithmus",
|
||||
"type": "Typ",
|
||||
"period": "Periode",
|
||||
"digits": "Ziffern"
|
||||
}
|
||||
@@ -173,6 +173,7 @@
|
||||
"invalidQRCode": "Invalid QR code",
|
||||
"noRecoveryKeyTitle": "No recovery key?",
|
||||
"enterEmailHint": "Enter your email address",
|
||||
"enterNewEmailHint": "Enter your new email address",
|
||||
"invalidEmailTitle": "Invalid email address",
|
||||
"invalidEmailMessage": "Please enter a valid email address.",
|
||||
"deleteAccount": "Delete account",
|
||||
@@ -513,5 +514,10 @@
|
||||
"free5GB": "5GB free on <bold-green>ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Login with your Auth account",
|
||||
"freeStorageOffer": "10% off on <bold-green>ente</bold-green> photos",
|
||||
"freeStorageOfferDescription": "Use code \"AUTH\" to get 10% off first year"
|
||||
"freeStorageOfferDescription": "Use code \"AUTH\" to get 10% off first year",
|
||||
"advanced": "Advanced",
|
||||
"algorithm": "Algorithm",
|
||||
"type": "Type",
|
||||
"period": "Period",
|
||||
"digits": "Digits"
|
||||
}
|
||||
@@ -173,6 +173,7 @@
|
||||
"invalidQRCode": "QR code non valide",
|
||||
"noRecoveryKeyTitle": "Pas de clé de récupération ?",
|
||||
"enterEmailHint": "Entrez votre adresse e-mail",
|
||||
"enterNewEmailHint": "Saisissez votre nouvelle adresse email",
|
||||
"invalidEmailTitle": "Adresse e-mail invalide",
|
||||
"invalidEmailMessage": "Veuillez saisir une adresse e-mail valide.",
|
||||
"deleteAccount": "Supprimer le compte",
|
||||
@@ -513,5 +514,10 @@
|
||||
"free5GB": "5 Go gratuits sur <bold-green>Ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Connectez-vous avec votre compte Auth",
|
||||
"freeStorageOffer": "10% de réduction sur <bold-green>Ente</bold-green> Photos",
|
||||
"freeStorageOfferDescription": "Utilisez le code coupon \"AUTH\" pour obtenir 10% de réduction la première année"
|
||||
"freeStorageOfferDescription": "Utilisez le code coupon \"AUTH\" pour obtenir 10% de réduction la première année",
|
||||
"advanced": "Avancé",
|
||||
"algorithm": "Algorithme",
|
||||
"type": "Type",
|
||||
"period": "Période",
|
||||
"digits": "Chiffres"
|
||||
}
|
||||
@@ -79,7 +79,7 @@
|
||||
"contactSupport": "Lépj kapcsolatba az Ügyfélszolgálattal",
|
||||
"rateUsOnStore": "Értékelj minket a következőn: {storeName}",
|
||||
"blog": "Blog",
|
||||
"merchandise": "Áru",
|
||||
"merchandise": "Ajándéktárgyak",
|
||||
"verifyPassword": "Jelszó megerősítése",
|
||||
"pleaseWait": "Kérem várjon...",
|
||||
"generatingEncryptionKeysTitle": "Titkosítási kulcs generálása...",
|
||||
@@ -173,6 +173,7 @@
|
||||
"invalidQRCode": "Érvénytelen QR-kód",
|
||||
"noRecoveryKeyTitle": "Nincs helyreállítási kulcs?",
|
||||
"enterEmailHint": "Adja meg az e-mail címét",
|
||||
"enterNewEmailHint": "Add meg az új e-mail címed",
|
||||
"invalidEmailTitle": "Érvénytelen e-mail cím",
|
||||
"invalidEmailMessage": "Kérjük, adjon meg egy érvényes e-mail címet.",
|
||||
"deleteAccount": "Fiók törlése",
|
||||
@@ -499,16 +500,20 @@
|
||||
"appLockOfflineModeWarning": "Úgy döntött, hogy biztonsági mentés nélkül folytatja. Ha elfelejti az alkalmazászárat, akkor nem férhet hozzá adataihoz.",
|
||||
"duplicateCodes": "Ismétlődő kódok",
|
||||
"noDuplicates": "✨Nincs ismétlődés",
|
||||
"youveNoDuplicateCodesThatCanBeCleared": "Nincsenek törölhető ismétlődő kódok",
|
||||
"deduplicateCodes": "Ismétlődő kódok",
|
||||
"deselectAll": "Összes kijelölés megszüntetése",
|
||||
"selectAll": "Összes kijelölése",
|
||||
"deleteDuplicates": "Ismétlődések törlése",
|
||||
"plainHTML": "Sima HTML kód",
|
||||
"tellUsWhatYouThink": "Mondja el mit gondol",
|
||||
"dropReviewiOS": "Írj véleményt az App Store-ban",
|
||||
"dropReviewAndroid": "Írj véleményt a Play Store-ban",
|
||||
"supportEnte": "Támogassa <bold-green>ente <bold-green>",
|
||||
"giveUsAStarOnGithub": "Adj nekünk egy csillagot a Githubon",
|
||||
"free5GB": "5GB ingyen <bold-green>ente <bold-green> Photos",
|
||||
"loginWithAuthAccount": "Jelentkezzen be Auth fiókjával",
|
||||
"freeStorageOffer": "10% kedvezmény on <bold-green>ente<bold-green> photos",
|
||||
"freeStorageOfferDescription": "Használja az \"AUTH\" kódot, hogy 10% kedvezményt kapjon az első évben"
|
||||
"freeStorageOfferDescription": "Használja az \"AUTH\" kódot, hogy 10% kedvezményt kapjon az első évben",
|
||||
"type": "Típus"
|
||||
}
|
||||
@@ -173,6 +173,7 @@
|
||||
"invalidQRCode": "Codice QR non valido",
|
||||
"noRecoveryKeyTitle": "Nessuna chiave di recupero?",
|
||||
"enterEmailHint": "Inserisci il tuo indirizzo email",
|
||||
"enterNewEmailHint": "Inserisci il tuo nuovo indirizzo email",
|
||||
"invalidEmailTitle": "Indirizzo email non valido",
|
||||
"invalidEmailMessage": "Inserisci un indirizzo email valido.",
|
||||
"deleteAccount": "Elimina account",
|
||||
@@ -513,5 +514,10 @@
|
||||
"free5GB": "5GB gratis su <bold-green>ente</bold-green> Foto",
|
||||
"loginWithAuthAccount": "Accedi con il tuo account Auth",
|
||||
"freeStorageOffer": "10% di sconto su <bold-green>ente</bold-green> Foto",
|
||||
"freeStorageOfferDescription": "Utilizzare il codice \"AUTH\" per ottenere il 10% di sconto al primo anno"
|
||||
"freeStorageOfferDescription": "Utilizzare il codice \"AUTH\" per ottenere il 10% di sconto al primo anno",
|
||||
"advanced": "Avanzate",
|
||||
"algorithm": "Algoritmo",
|
||||
"type": "Tipo",
|
||||
"period": "Periodo",
|
||||
"digits": "Cifre"
|
||||
}
|
||||
@@ -508,9 +508,15 @@
|
||||
"tellUsWhatYouThink": "Pasakykite mums, ką manote",
|
||||
"dropReviewiOS": "Rašyti apžvalgą parduotuvėje „App Store“",
|
||||
"dropReviewAndroid": "Rašyti apžvalgą parduotuvėje „Play“ parduotuvė“",
|
||||
"supportEnte": "Paremti „<bold-green>ente</bold-green>“",
|
||||
"giveUsAStarOnGithub": "Suteikite mums žvaigždutę platformoje „Github“",
|
||||
"free5GB": "5 GB nemokami programai „<bold-green>ente</bold-green>“ nuotraukos",
|
||||
"loginWithAuthAccount": "Prisijungti su jūsų „Auth“ paskyra",
|
||||
"freeStorageOffer": "10 % nuolaida programai „<bold-green>ente</bold-green>“ nuotraukos",
|
||||
"freeStorageOfferDescription": "Naudokite kodą „AUTH“, kad gautumėte 10 % nuolaida pirmiesiems metams. "
|
||||
"freeStorageOfferDescription": "Naudokite kodą „AUTH“, kad gautumėte 10 % nuolaida pirmiesiems metams. ",
|
||||
"advanced": "Išplėstiniai",
|
||||
"algorithm": "Algoritmas",
|
||||
"type": "Tipas",
|
||||
"period": "Laikotarpis",
|
||||
"digits": "Skaitmenys"
|
||||
}
|
||||
@@ -173,6 +173,7 @@
|
||||
"invalidQRCode": "Ongeldige QR-code",
|
||||
"noRecoveryKeyTitle": "Geen herstelsleutel?",
|
||||
"enterEmailHint": "Voer je e-mailadres in",
|
||||
"enterNewEmailHint": "Voer uw nieuwe e-mailadres in",
|
||||
"invalidEmailTitle": "Ongeldig e-mailadres",
|
||||
"invalidEmailMessage": "Voer een geldig e-mailadres in.",
|
||||
"deleteAccount": "Account verwijderen",
|
||||
@@ -513,5 +514,10 @@
|
||||
"free5GB": "5GB gratis op <bold-green>ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Log in met je Auth account",
|
||||
"freeStorageOffer": "10% korting op <bold-green>ente</bold-green> photos",
|
||||
"freeStorageOfferDescription": "Gebruik de code \"AUTH\" voor 10% korting op je eerste jaar"
|
||||
"freeStorageOfferDescription": "Gebruik de code \"AUTH\" voor 10% korting op je eerste jaar",
|
||||
"advanced": "Geavanceerd",
|
||||
"algorithm": "Algoritme",
|
||||
"type": "Type",
|
||||
"period": "Periode",
|
||||
"digits": "Cijfers"
|
||||
}
|
||||
@@ -173,6 +173,7 @@
|
||||
"invalidQRCode": "Nieprawidłowy kod QR",
|
||||
"noRecoveryKeyTitle": "Brak klucza odzyskiwania?",
|
||||
"enterEmailHint": "Wprowadź adres e-mail",
|
||||
"enterNewEmailHint": "Wprowadź nowy adres e-mail",
|
||||
"invalidEmailTitle": "Nieprawidłowy adres e-mail",
|
||||
"invalidEmailMessage": "Prosimy podać prawidłowy adres e-mail.",
|
||||
"deleteAccount": "Usuń konto",
|
||||
@@ -513,5 +514,10 @@
|
||||
"free5GB": "5 GB za darmo na zdjęcia <bold-green>ente</bold-green>",
|
||||
"loginWithAuthAccount": "Zaloguj się przy użyciu konta Auth",
|
||||
"freeStorageOffer": "10% zniżki na zdjęcia <bold-green>ente</bold-green>",
|
||||
"freeStorageOfferDescription": "Użyj kodu „AUTH”, aby uzyskać 10% zniżki na pierwszy rok"
|
||||
"freeStorageOfferDescription": "Użyj kodu „AUTH”, aby uzyskać 10% zniżki na pierwszy rok",
|
||||
"advanced": "Zaawansowane",
|
||||
"algorithm": "Algorytm",
|
||||
"type": "Rodzaj",
|
||||
"period": "Okres",
|
||||
"digits": "Cyfry"
|
||||
}
|
||||
@@ -173,6 +173,7 @@
|
||||
"invalidQRCode": "QR Code inválido",
|
||||
"noRecoveryKeyTitle": "Sem chave de recuperação?",
|
||||
"enterEmailHint": "Insira o endereço de e-mail",
|
||||
"enterNewEmailHint": "Insira seu novo e-mail",
|
||||
"invalidEmailTitle": "Endereço de e-mail inválido",
|
||||
"invalidEmailMessage": "Insira um endereço de e-mail válido.",
|
||||
"deleteAccount": "Excluir conta",
|
||||
@@ -513,5 +514,10 @@
|
||||
"free5GB": "5GB grátis no <bold-green>ente</bold-green> Photos",
|
||||
"loginWithAuthAccount": "Registrar-se com sua conta Auth",
|
||||
"freeStorageOffer": "10% de desconto no <bold-green>ente</bold-green> photos",
|
||||
"freeStorageOfferDescription": "Use o cupom \"AUTH\" para obter 10% de desconto no primeiro ano"
|
||||
"freeStorageOfferDescription": "Use o cupom \"AUTH\" para obter 10% de desconto no primeiro ano",
|
||||
"advanced": "Avançado",
|
||||
"algorithm": "Algoritmo",
|
||||
"type": "Tipo",
|
||||
"period": "Período",
|
||||
"digits": "Dígitos"
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
{}
|
||||
{
|
||||
"importScanQrCode": ""
|
||||
}
|
||||
@@ -6,10 +6,10 @@
|
||||
"@counterAppBarTitle": {
|
||||
"description": "Text shown in the AppBar of the Counter Page"
|
||||
},
|
||||
"onBoardingBody": "2 Faktörlü Kimlik Doğrulama kodlarınızı koruyun",
|
||||
"onBoardingBody": "2FA kodlarınızı güvenli bir şekilde yedekleyin",
|
||||
"onBoardingGetStarted": "Başlayın",
|
||||
"setupFirstAccount": "İlk hesabınızı ekleyin",
|
||||
"importScanQrCode": "Karekod tara",
|
||||
"importScanQrCode": "QR kod tara",
|
||||
"qrCode": "QR Kodu",
|
||||
"importEnterSetupKey": "Kurulum anahtarını giriniz",
|
||||
"importAccountPageTitle": "Hesap bilgilerinizi girin",
|
||||
@@ -51,11 +51,11 @@
|
||||
"trashCode": "Kod çöpe atılsın mı?",
|
||||
"trashCodeMessage": "{account} için kodu çöpe atmak istediğinize emin misiniz?",
|
||||
"trash": "Çöp",
|
||||
"viewLogsAction": "Günlüğü görüntüle",
|
||||
"sendLogsDescription": "Günlüğünüz hatanızı çözmemize yardımcı olacaktır. Hassas bilginin kaydedilmediğine dikkat etsek de bu günlükleri paylaşmadan önce kontrol etmenizi isteriz.",
|
||||
"preparingLogsTitle": "Günlük hazırlanıyor...",
|
||||
"emailLogsTitle": "Günlüğü e-posta olarak gönder",
|
||||
"emailLogsMessage": "Lütfen günlüğünüzü {email} adresine gönderin",
|
||||
"viewLogsAction": "Kayıtları görüntüle",
|
||||
"sendLogsDescription": "Kayıtlarınız hatanızı çözmemize yardımcı olacaktır. Hassas bilginin kaydedilmediğine dikkat etsek de bu günlükleri paylaşmadan önce kontrol etmenizi isteriz.",
|
||||
"preparingLogsTitle": "Kayıtlar hazırlanıyor...",
|
||||
"emailLogsTitle": "Kayıtları e-posta olarak gönder",
|
||||
"emailLogsMessage": "Lütfen kayıtlarınızı {email} adresine gönderin",
|
||||
"@emailLogsMessage": {
|
||||
"placeholders": {
|
||||
"email": {
|
||||
@@ -64,7 +64,7 @@
|
||||
}
|
||||
},
|
||||
"copyEmailAction": "E-postayı Kopyala",
|
||||
"exportLogsAction": "Günlüğü dışa aktar",
|
||||
"exportLogsAction": "Kayıtları dışa aktar",
|
||||
"reportABug": "Hata bildirin",
|
||||
"crashAndErrorReporting": "Çökme ve hata bildirimi",
|
||||
"reportBug": "Hata bildir",
|
||||
@@ -90,7 +90,7 @@
|
||||
"welcomeBack": "Tekrar hoş geldiniz!",
|
||||
"emailAlreadyRegistered": "E-posta zaten kayıtlı.",
|
||||
"emailNotRegistered": "E-posta kayıtlı değil.",
|
||||
"madeWithLoveAtPrefix": "❤️ ile şurada yapılmıştır ",
|
||||
"madeWithLoveAtPrefix": "❤️ ile yapılmıştır ",
|
||||
"supportDevs": "Bu projeyi desteklemek için <bold-green>ente</bold-green> kanalına abone olun",
|
||||
"supportDiscount": "İlk yılda %10 indirim için \"AUTH\" kupon kodunu kullanın",
|
||||
"changeEmail": "E-posta adresini değiştir",
|
||||
@@ -176,7 +176,7 @@
|
||||
"invalidEmailTitle": "Geçersiz e-posta adresi",
|
||||
"invalidEmailMessage": "Lütfen geçerli bir e-posta adresi girin.",
|
||||
"deleteAccount": "Hesabı sil",
|
||||
"deleteAccountQuery": "Sizin gitmenizi görmekten üzüleceğiz. Bazı problemlerle mi karşılaşıyorsunuz?",
|
||||
"deleteAccountQuery": "Sizin gittiğinizi görmekten üzüleceğiz. Bazı problemlerle mi karşılaşıyorsunuz?",
|
||||
"yesSendFeedbackAction": "Evet, geri bildirimi gönder",
|
||||
"noDeleteAccountAction": "Hayır, hesabı sil",
|
||||
"initiateAccountDeleteTitle": "Hesap silme işlemini yapabilmek için lütfen kimliğinizi doğrulayın",
|
||||
@@ -253,8 +253,8 @@
|
||||
"insecureDevice": "Güvenli olmayan cihaz",
|
||||
"sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease": "Üzgünüz, bu cihazda güvenli anahtarlar oluşturamadık.\n\nlütfen farklı bir cihazdan kaydolun.",
|
||||
"howItWorks": "Nasıl çalışır",
|
||||
"ackPasswordLostWarning": "Eğer şifremi kaybedersem, verilerim <underline>uçtan uca şifrelendiğinden</underline> verilerimi kaybedebileceğimi anladım.",
|
||||
"loginTerms": "Giriş yaparak, <u-terms>kullanım şartları</u-terms>nı ve <u-policy>gizlilik politikası</u-policy>nı onaylıyorum",
|
||||
"ackPasswordLostWarning": "Eğer şifremi kaybedersem, verilerim <underline> uçtan uca şifrelendiğinden </underline> verilerimi kaybedebileceğimi anladım.",
|
||||
"loginTerms": "Giriş yaparak, <u-terms> kullanım şartları </u-terms>nı ve <u-policy> gizlilik politikası </u-policy>nı onaylıyorum",
|
||||
"logInLabel": "Giriş yapın",
|
||||
"logout": "Çıkış yap",
|
||||
"areYouSureYouWantToLogout": "Çıkış yapmak istediğinize emin misiniz?",
|
||||
@@ -277,10 +277,10 @@
|
||||
"recoveryKeyVerifyReason": "Kurtarma anahtarınız, şifrenizi unutmanız durumunda fotoğraflarınızı kurtarmanın tek yoludur. Kurtarma anahtarınızı Ayarlar > Hesap bölümünde bulabilirsiniz.\n\nDoğru kaydettiğinizi doğrulamak için lütfen kurtarma anahtarınızı buraya girin.",
|
||||
"confirmYourRecoveryKey": "Kurtarma anahtarınızı doğrulayın",
|
||||
"confirm": "Doğrula",
|
||||
"emailYourLogs": "Günlüklerinizi e-postayla gönderin",
|
||||
"pleaseSendTheLogsTo": "Lütfen günlükleri şu adrese gönderin\n{toEmail}",
|
||||
"emailYourLogs": "Kayıtlarınızı e-postayla gönderin",
|
||||
"pleaseSendTheLogsTo": "Lütfen kayıtları şu adrese gönderin\n{toEmail}",
|
||||
"copyEmailAddress": "E-posta adresini kopyala",
|
||||
"exportLogs": "Günlüğü dışa aktar",
|
||||
"exportLogs": "Kayıtları dışa aktar",
|
||||
"enterYourRecoveryKey": "Kurtarma anahtarınızı girin",
|
||||
"tempErrorContactSupportIfPersists": "Bir şeyler ters gitmiş gibi görünüyor. Lütfen bir süre sonra tekrar deneyin. Hata devam ederse, lütfen destek ekibimizle iletişime geçin.",
|
||||
"networkHostLookUpErr": "Ente'ye bağlanılamıyor, lütfen ağ ayarlarınızı kontrol edin ve hata devam ederse desteğe başvurun.",
|
||||
@@ -499,10 +499,24 @@
|
||||
"appLockOfflineModeWarning": "Yedekleme olmadan devam etmeyi seçtiniz. Eğer uygulama parolanızı unutursanız, verilerinize erişiminiz engellenir.",
|
||||
"duplicateCodes": "Yinelenen kodlar",
|
||||
"noDuplicates": "✨ Yinelenen yok",
|
||||
"youveNoDuplicateCodesThatCanBeCleared": "Temizlenebilecek herhangi bir yinelenen kodunuz yok",
|
||||
"deduplicateCodes": "Kodları tekilleştir",
|
||||
"deselectAll": "Tümünün seçimini kaldır",
|
||||
"selectAll": "Tümünü seç",
|
||||
"deleteDuplicates": "Yinelenenleri sil",
|
||||
"plainHTML": "Sade HTML",
|
||||
"supportEnte": "<bold-Green>Ente</bold-Green>'yi destekle"
|
||||
"tellUsWhatYouThink": "Bize ne düşündüğünü söyle",
|
||||
"dropReviewiOS": "App Store'da bir inceleme bırakın",
|
||||
"dropReviewAndroid": "Play Store'da bir inceleme bırakın",
|
||||
"supportEnte": "<bold-Green>Ente</bold-Green>'yi destekle",
|
||||
"giveUsAStarOnGithub": "Github'da bize bir yıldız verin",
|
||||
"free5GB": "<bold-green>ente</bold-green> Fotoğraflarında 5GB ücretsiz",
|
||||
"loginWithAuthAccount": "Kimlik Doğrulama hesabınızla giriş yapın",
|
||||
"freeStorageOffer": "<bold-green>ente</bold-green> fotoğraflarında %10 indirim",
|
||||
"freeStorageOfferDescription": "İlk yılda %10 indirim almak için \"AUTH\" kodunu kullanın",
|
||||
"advanced": "Gelişmiş",
|
||||
"algorithm": "Algoritma",
|
||||
"type": "Tür",
|
||||
"period": "Zaman Aralığı",
|
||||
"digits": "Uzunluk"
|
||||
}
|
||||
@@ -51,7 +51,7 @@
|
||||
"trashCode": "Xóa mã?",
|
||||
"trashCodeMessage": "Bạn có chắc chắn muốn xóa mã cho {account} không?",
|
||||
"trash": "Xóa",
|
||||
"viewLogsAction": "Xem các bản ghi",
|
||||
"viewLogsAction": "Xem nhật ký",
|
||||
"sendLogsDescription": "Thao tác này sẽ gửi nhật ký để giúp chúng tôi gỡ lỗi sự cố của bạn. Mặc dù chúng tôi thực hiện các biện pháp phòng ngừa để đảm bảo rằng thông tin nhạy cảm không được ghi lại, nhưng chúng tôi khuyến khích bạn xem các nhật ký này trước khi chia sẻ chúng.",
|
||||
"preparingLogsTitle": "Đang chuẩn bị nhật ký...",
|
||||
"emailLogsTitle": "Nhật ký email",
|
||||
@@ -506,6 +506,8 @@
|
||||
"deleteDuplicates": "Xóa trùng lặp",
|
||||
"plainHTML": "HTML thuần",
|
||||
"tellUsWhatYouThink": "Hãy cho chúng tôi biết bạn nghĩ gì",
|
||||
"dropReviewiOS": "Đánh giá ngay trên App Store",
|
||||
"dropReviewAndroid": "Đánh giá ngay trên Play Store",
|
||||
"supportEnte": "Hỗ trợ <bold-green>ente</bold-green>",
|
||||
"giveUsAStarOnGithub": "Cho chúng tôi ngôi sao trên Github",
|
||||
"free5GB": "Miễn phí 5GB cho <bold-green>ente</bold-green> Hình ảnh",
|
||||
|
||||
@@ -173,6 +173,7 @@
|
||||
"invalidQRCode": "二维码无效",
|
||||
"noRecoveryKeyTitle": "没有恢复密钥吗?",
|
||||
"enterEmailHint": "请输入您的电子邮件地址",
|
||||
"enterNewEmailHint": "请输入您的新电子邮件地址",
|
||||
"invalidEmailTitle": "无效的电子邮件地址",
|
||||
"invalidEmailMessage": "请输入一个有效的电子邮件地址。",
|
||||
"deleteAccount": "删除账户",
|
||||
@@ -513,5 +514,10 @@
|
||||
"free5GB": "<bold-green>ente</bold-green> Photos 上 5GB 可用空间",
|
||||
"loginWithAuthAccount": "使用您的认证账户登录",
|
||||
"freeStorageOffer": "购买 <bold-green>ente</bold-green> Photos 可享受 10% 优惠",
|
||||
"freeStorageOfferDescription": "使用优惠码“AUTH”可享受首年 10% 折扣"
|
||||
"freeStorageOfferDescription": "使用优惠码“AUTH”可享受首年 10% 折扣",
|
||||
"advanced": "高级",
|
||||
"algorithm": "算法",
|
||||
"type": "类型",
|
||||
"period": "周期",
|
||||
"digits": "数字"
|
||||
}
|
||||
@@ -504,7 +504,7 @@
|
||||
"deselectAll": "取消全選",
|
||||
"selectAll": "全選",
|
||||
"deleteDuplicates": "刪除重複項",
|
||||
"plainHTML": "Plain HTML",
|
||||
"plainHTML": "純HTML",
|
||||
"tellUsWhatYouThink": "告訴我們您的想法",
|
||||
"dropReviewiOS": "在 App Store 上發表意見",
|
||||
"dropReviewAndroid": "在 Play 商店上發表評測",
|
||||
@@ -513,5 +513,10 @@
|
||||
"free5GB": "<bold-green>ente</bold-green> Photos 上 5GB 可用空間",
|
||||
"loginWithAuthAccount": "使用您的認證帳戶登錄",
|
||||
"freeStorageOffer": "購買 <bold-green>ente</bold-green> Photos 可享受 10% 優惠",
|
||||
"freeStorageOfferDescription": "使用優惠碼“AUTH”可享受首年 10% 折扣"
|
||||
"freeStorageOfferDescription": "使用優惠碼“AUTH”可享受首年 10% 折扣",
|
||||
"advanced": "進階",
|
||||
"algorithm": "演算法",
|
||||
"type": "類型",
|
||||
"period": "期間",
|
||||
"digits": "數位"
|
||||
}
|
||||
@@ -38,28 +38,28 @@ const List<Locale> appSupportedLocales = <Locale>[
|
||||
];
|
||||
|
||||
Locale? autoDetectedLocale;
|
||||
Locale localResolutionCallBack(locales, supportedLocales) {
|
||||
Locale? languageCodeMatch;
|
||||
final Map<String, Locale> languageCodeToLocale = {
|
||||
for (Locale supportedLocale in appSupportedLocales)
|
||||
supportedLocale.languageCode: supportedLocale,
|
||||
};
|
||||
|
||||
for (Locale locale in locales) {
|
||||
// This function takes device locales and supported locales as input
|
||||
// and returns the best matching locale.
|
||||
// The device locales are sorted by priority, so the first one is the most preferred.
|
||||
Locale localResolutionCallBack(onDeviceLocales, supportedLocales) {
|
||||
final Set<String> languageSupport = {};
|
||||
for (Locale supportedLocale in appSupportedLocales) {
|
||||
languageSupport.add(supportedLocale.languageCode);
|
||||
}
|
||||
for (Locale locale in onDeviceLocales) {
|
||||
// check if exact local is supported, if yes, return it
|
||||
if (appSupportedLocales.contains(locale)) {
|
||||
autoDetectedLocale = locale;
|
||||
return locale;
|
||||
}
|
||||
|
||||
if (languageCodeMatch == null &&
|
||||
languageCodeToLocale.containsKey(locale.languageCode)) {
|
||||
languageCodeMatch = languageCodeToLocale[locale.languageCode];
|
||||
autoDetectedLocale = languageCodeMatch;
|
||||
// check if language code is supported, if yes, return it
|
||||
if (languageSupport.contains(locale.languageCode)) {
|
||||
autoDetectedLocale = locale;
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the first language code match or default to 'en'
|
||||
return languageCodeMatch ?? const Locale('en');
|
||||
return autoDetectedLocale ?? const Locale('en');
|
||||
}
|
||||
|
||||
Future<Locale?> getLocale({
|
||||
|
||||
@@ -293,10 +293,6 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
widget.code == null
|
||||
? advanceOptionWidget()
|
||||
: const SizedBox.shrink(),
|
||||
const SizedBox(height: 12),
|
||||
Wrap(
|
||||
spacing: 12,
|
||||
alignment: WrapAlignment.start,
|
||||
@@ -343,6 +339,10 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
widget.code == null
|
||||
? advanceOptionWidget()
|
||||
: const SizedBox.shrink(),
|
||||
const SizedBox(height: 40),
|
||||
SizedBox(
|
||||
width: 400,
|
||||
@@ -525,6 +525,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
}
|
||||
|
||||
Widget advanceOptionWidget() {
|
||||
final l10n = context.l10n;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 16.0),
|
||||
child: Column(
|
||||
@@ -537,9 +538,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
'Advanced',
|
||||
),
|
||||
Text(l10n.advanced),
|
||||
ValueListenableBuilder<bool>(
|
||||
valueListenable: showAdvancedOptions,
|
||||
builder: (context, isExpanded, child) {
|
||||
@@ -583,7 +582,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const FieldLabel("Algorithm", width: 60),
|
||||
FieldLabel(l10n.algorithm, width: 60),
|
||||
AlgorithmSelectorWidget(
|
||||
currentAlgorithm: _algorithm,
|
||||
onSelected: (newAlgorithm) async {
|
||||
@@ -597,7 +596,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const FieldLabel("Type", width: 60),
|
||||
FieldLabel(l10n.type, width: 60),
|
||||
ToptSelectorWidget(
|
||||
currentTopt: _type,
|
||||
onSelected: (newTopt) async {
|
||||
@@ -610,7 +609,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const FieldLabel("Period", width: 60),
|
||||
FieldLabel(l10n.period, width: 60),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
keyboardType: TextInputType.number,
|
||||
@@ -639,7 +638,7 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const FieldLabel("Digits", width: 60),
|
||||
FieldLabel(l10n.digits, width: 60),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
keyboardType: TextInputType.number,
|
||||
|
||||
@@ -18,7 +18,7 @@ class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return AlertDialog(
|
||||
title: Text(l10n.enterEmailHint),
|
||||
title: Text(l10n.enterNewEmailHint),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="4.3.8" date="2025-05-20" />
|
||||
<release version="4.2.4" date="2025-01-11" />
|
||||
<release version="4.0.3" date="2024-10-08" />
|
||||
</releases>
|
||||
@@ -33,4 +34,4 @@
|
||||
<color type="primary" scheme_preference="light">#ffffff</color>
|
||||
<color type="primary" scheme_preference="dark">#000000</color>
|
||||
</branding>
|
||||
</component>
|
||||
</component>
|
||||
|
||||
@@ -34,11 +34,11 @@ PODS:
|
||||
- FlutterMacOS
|
||||
- screen_retriever (0.0.1):
|
||||
- FlutterMacOS
|
||||
- Sentry/HybridSDK (8.36.0)
|
||||
- sentry_flutter (8.9.0):
|
||||
- Sentry/HybridSDK (8.46.0)
|
||||
- sentry_flutter (8.14.2):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Sentry/HybridSDK (= 8.36.0)
|
||||
- Sentry/HybridSDK (= 8.46.0)
|
||||
- share_plus (0.0.1):
|
||||
- FlutterMacOS
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
@@ -157,33 +157,33 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a
|
||||
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
|
||||
cupertino_http: 947a233f40cfea55167a49f2facc18434ea117ba
|
||||
device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
|
||||
file_saver: 44e6fbf666677faf097302460e214e977fdd977b
|
||||
flutter_inappwebview_macos: bdf207b8f4ebd58e86ae06cd96b147de99a67c9b
|
||||
flutter_local_authentication: 85674893931e1c9cfa7c9e4f5973cb8c56b018b0
|
||||
flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4
|
||||
flutter_secure_storage_macos: 59459653abe1adb92abbc8ea747d79f8d19866c9
|
||||
app_links: 9028728e32c83a0831d9db8cf91c526d16cc5468
|
||||
connectivity_plus: 3f6c9057f4cd64198dc826edfb0542892f825343
|
||||
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
|
||||
device_info_plus: b0fafc687fb901e2af612763340f1b0d4352f8e5
|
||||
file_saver: e35bd97de451dde55ff8c38862ed7ad0f3418d0f
|
||||
flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d
|
||||
flutter_local_authentication: 2f9a2682f498abcc12d7e9729b5007a947170fdc
|
||||
flutter_local_notifications: 453432cd6399a07d072885bc7828fb2307868856
|
||||
flutter_secure_storage_macos: b2d62a774c23b060f0b99d0173b0b36abb4a8632
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
|
||||
objective_c: e5f8194456e8fc943e034d1af00510a1bc29c067
|
||||
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
||||
objective_c: ec13431e45ba099cb734eb2829a5c1cd37986cba
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
|
||||
Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57
|
||||
sentry_flutter: 0eb93e5279eb41e2392212afe1ccd2fecb4f8cbe
|
||||
share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
sodium_libs: d39bd76697736cb11ce4a0be73b9b4bc64466d6f
|
||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||
package_info_plus: a8a591e70e87ce97ce5d21b2594f69cea9e0312f
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
screen_retriever: 4f97c103641aab8ce183fa5af3b87029df167936
|
||||
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
|
||||
sentry_flutter: 27892878729f42701297c628eb90e7c6529f3684
|
||||
share_plus: 11c7b7fa7020465584eca3ff6392c5bc1e399d6e
|
||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||
sodium_libs: b9459e5bfc1185349f43472e79fc5d8e526b2bda
|
||||
sqflite: c35dad70033b8862124f8337cc994a809fcd9fa3
|
||||
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
|
||||
sqlite3_flutter_libs: 5ca46c1a04eddfbeeb5b16566164aa7ad1616e7b
|
||||
tray_manager: 9064e219c56d75c476e46b9a21182087930baf90
|
||||
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
|
||||
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
|
||||
sqlite3_flutter_libs: 03311aede9d32fb2d24e32bebb8cd01c3b2e6239
|
||||
tray_manager: a104b5c81b578d83f3c3d0f40a997c8b10810166
|
||||
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673
|
||||
window_manager: 1d01fa7ac65a6e6f83b965471b1a7fdd3f06166c
|
||||
|
||||
PODFILE CHECKSUM: 6ff827273ace187339fc5d3684072a26ad85c298
|
||||
|
||||
|
||||
@@ -675,14 +675,13 @@ packages:
|
||||
source: hosted
|
||||
version: "9.2.2"
|
||||
flutter_secure_storage_linux:
|
||||
dependency: "direct overridden"
|
||||
dependency: transitive
|
||||
description:
|
||||
path: flutter_secure_storage_linux
|
||||
ref: develop
|
||||
resolved-ref: "5a5692b609b3886cdd49b2ed06b9c079ecdff996"
|
||||
url: "https://github.com/mogol/flutter_secure_storage.git"
|
||||
source: git
|
||||
version: "1.2.1"
|
||||
name: flutter_secure_storage_linux
|
||||
sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.3"
|
||||
flutter_secure_storage_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1361,18 +1360,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry
|
||||
sha256: "033287044a6644a93498969449d57c37907e56f5cedb17b88a3ff20a882261dd"
|
||||
sha256: "599701ca0693a74da361bc780b0752e1abc98226cf5095f6b069648116c896bb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.0"
|
||||
version: "8.14.2"
|
||||
sentry_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry_flutter
|
||||
sha256: "3780b5a0bb6afd476857cfbc6c7444d969c29a4d9bd1aa5b6960aa76c65b737a"
|
||||
sha256: "5ba2cf40646a77d113b37a07bd69f61bb3ec8a73cbabe5537b05a7c89d2656f8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.0"
|
||||
version: "8.14.2"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
name: ente_auth
|
||||
description: ente two-factor authenticator
|
||||
version: 4.3.4+435
|
||||
version: 4.3.8+438
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
@@ -84,8 +84,8 @@ dependencies:
|
||||
protobuf: ^3.0.0
|
||||
qr_code_scanner: ^1.0.1
|
||||
qr_flutter: ^4.1.0
|
||||
sentry: ^8.7.0
|
||||
sentry_flutter: ^8.7.0
|
||||
sentry: ^8.14.2
|
||||
sentry_flutter: ^8.14.2
|
||||
share_plus: ^10.0.2
|
||||
shared_preferences: ^2.0.5
|
||||
sqflite:
|
||||
@@ -107,12 +107,6 @@ dependencies:
|
||||
window_manager: ^0.4.2
|
||||
xdg_directories: ^1.0.4
|
||||
|
||||
dependency_overrides:
|
||||
flutter_secure_storage_linux:
|
||||
git:
|
||||
url: https://github.com/mogol/flutter_secure_storage.git
|
||||
ref: develop
|
||||
path: flutter_secure_storage_linux
|
||||
dev_dependencies:
|
||||
build_runner: ^2.1.11
|
||||
flutter_test:
|
||||
@@ -148,12 +142,17 @@ flutter:
|
||||
fonts:
|
||||
- asset: fonts/Montserrat-Bold.ttf
|
||||
|
||||
flutter_icons:
|
||||
# run "dart run flutter_launcher_icons" to generate icons
|
||||
flutter_launcher_icons:
|
||||
image_path: "assets/generation-icons/icon-light.png"
|
||||
|
||||
android: "launcher_icon"
|
||||
adaptive_icon_foreground: "assets/generation-icons/icon-light-adaptive-fg.png"
|
||||
adaptive_icon_background: "assets/generation-icons/icon-light-adaptive-bg.png"
|
||||
adaptive_icon_monochrome: "assets/generation-icons/icon-monochrome.png"
|
||||
adaptive_icon_foreground_inset: 0
|
||||
|
||||
ios: true
|
||||
image_path: "assets/generation-icons/icon-light.png"
|
||||
remove_alpha_ios: true
|
||||
|
||||
flutter_native_splash:
|
||||
|
||||
70
auth/scripts/release_tag.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Function to display usage
|
||||
usage() {
|
||||
echo "Usage: $0 tag"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Ensure a tag was provided
|
||||
[[ $# -eq 0 ]] && usage
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status
|
||||
set -e
|
||||
|
||||
# Go to the project root directory
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
# Get the tag from the command line argument
|
||||
TAG=$1
|
||||
|
||||
# Define the appdata file path - use absolute path to avoid directory navigation issues
|
||||
PROJECT_ROOT=$(pwd)
|
||||
APPDATA_FILE="${PROJECT_ROOT}/linux/packaging/enteauth.appdata.xml"
|
||||
|
||||
# Get the version from the pubspec.yaml file and cut everything after the +
|
||||
VERSION=$(grep "^version:" pubspec.yaml | awk '{ print $2 }' | cut -d '+' -f 1)
|
||||
|
||||
PREFIX="auth-v"
|
||||
|
||||
# Ensure the tag has the correct prefix
|
||||
if [[ $TAG != $PREFIX* ]]; then
|
||||
echo "Invalid tag. tags must start with '$PREFIX'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure the tag version is in the pubspec.yaml file
|
||||
if [[ $TAG != *$VERSION ]]; then
|
||||
echo "Invalid tag."
|
||||
echo "The version $VERSION in pubspec doesn't match the version in tag $TAG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract version number from the tag (remove prefix)
|
||||
TAG_VERSION=${TAG#$PREFIX}
|
||||
|
||||
# Check if this version is already in the releases section of the appdata.xml file
|
||||
if ! grep -q "<release version=\"$TAG_VERSION\"" "$APPDATA_FILE"; then
|
||||
echo "Adding release entry for version $TAG_VERSION to appdata.xml"
|
||||
|
||||
# Get today's date in YYYY-MM-DD format
|
||||
TODAY=$(date +%Y-%m-%d)
|
||||
|
||||
# Use a more reliable approach with awk instead of sed for cross-platform compatibility
|
||||
echo "Creating temporary file with updated content..."
|
||||
awk '/<releases>/{print $0; print " <release version=\"'"$TAG_VERSION"'\" date=\"'"$TODAY"'\" />"; next}1' "$APPDATA_FILE" > "${APPDATA_FILE}.tmp"
|
||||
mv "${APPDATA_FILE}.tmp" "$APPDATA_FILE"
|
||||
|
||||
echo "Added release entry for version $TAG_VERSION with date $TODAY"
|
||||
|
||||
# Stage and commit the updated appdata.xml file
|
||||
git add "$APPDATA_FILE"
|
||||
git commit -m "Add release $TAG_VERSION to appdata.xml"
|
||||
echo "Committed appdata.xml changes for version $TAG_VERSION"
|
||||
fi
|
||||
|
||||
# If all checks pass, create the tag
|
||||
git tag $TAG
|
||||
echo "Tag $TAG created."
|
||||
|
||||
exit 0
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||
#include <local_auth_windows/local_auth_plugin.h>
|
||||
#include <screen_retriever/screen_retriever_plugin.h>
|
||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
||||
#include <sodium_libs/sodium_libs_plugin_c_api.h>
|
||||
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||
@@ -38,6 +39,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("LocalAuthPlugin"));
|
||||
ScreenRetrieverPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
|
||||
SentryFlutterPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
|
||||
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
||||
SodiumLibsPluginCApiRegisterWithRegistrar(
|
||||
|
||||
@@ -11,6 +11,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||
flutter_secure_storage_windows
|
||||
local_auth_windows
|
||||
screen_retriever
|
||||
sentry_flutter
|
||||
share_plus
|
||||
sodium_libs
|
||||
sqlite3_flutter_libs
|
||||
@@ -21,7 +22,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
jni
|
||||
sentry_flutter
|
||||
)
|
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||
|
||||
@@ -83,13 +83,14 @@ func (c *Client) VerifySRPSession(
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (c *Client) SendEmailOTP(
|
||||
func (c *Client) SendLoginOTP(
|
||||
ctx context.Context,
|
||||
email string,
|
||||
) error {
|
||||
var res AuthorizationResponse
|
||||
payload := map[string]interface{}{
|
||||
"email": email,
|
||||
"email": email,
|
||||
"purpose": "login",
|
||||
}
|
||||
r, err := c.restClient.R().
|
||||
SetContext(ctx).
|
||||
|
||||
@@ -167,7 +167,7 @@ func (c *ClICtrl) verifyPassKey(ctx context.Context, authResp *api.Authorization
|
||||
}
|
||||
|
||||
func (c *ClICtrl) validateEmail(ctx context.Context, email string) (*api.AuthorizationResponse, error) {
|
||||
err := c.Client.SendEmailOTP(ctx, email)
|
||||
err := c.Client.SendLoginOTP(ctx, email)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.7.12 (Unreleased)
|
||||
## v1.7.13 (Unreleased)
|
||||
|
||||
- Generate streams for videos (beta)
|
||||
|
||||
> Streamable videos can be enabled in Preferences. For more details, see the
|
||||
> [video streaming FAQ](https://help.ente.io/photos/faq/video-streaming).
|
||||
|
||||
- Support Turkish translations.
|
||||
- .
|
||||
|
||||
## v1.7.12
|
||||
|
||||
- Improved video player with streaming support (for already processed videos).
|
||||
- Support Arabic translations.
|
||||
|
||||
## v1.7.11
|
||||
|
||||
- Improved file viewer.
|
||||
|
||||
@@ -39,6 +39,15 @@ export default ts.config(
|
||||
"error",
|
||||
{ allowTernary: true },
|
||||
],
|
||||
// Allow force unwrapping potentially optional values.
|
||||
//
|
||||
// See: [Note: non-null-assertions have better stack trace]
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
// Allow `while(true)` etc.
|
||||
"@typescript-eslint/no-unnecessary-condition": [
|
||||
"error",
|
||||
{ allowConstantLoopConditions: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ente",
|
||||
"version": "1.7.12-beta",
|
||||
"version": "1.7.13-beta",
|
||||
"private": true,
|
||||
"description": "Desktop client for Ente Photos",
|
||||
"repository": "github:ente-io/photos-desktop",
|
||||
@@ -31,32 +31,33 @@
|
||||
"clip-bpe-js": "^0.0.6",
|
||||
"comlink": "^4.4.2",
|
||||
"compare-versions": "^6.1.1",
|
||||
"electron-log": "^5.3.3",
|
||||
"electron-log": "^5.4.0",
|
||||
"electron-store": "^8.2.0",
|
||||
"electron-updater": "^6.6.2",
|
||||
"electron-updater": "^6.6.3",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"lru-cache": "^11.1.0",
|
||||
"next-electron-server": "^1.0.0",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"onnxruntime-node": "^1.20.1"
|
||||
"onnxruntime-node": "^1.20.1",
|
||||
"zod": "^3.25.23"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.24.0",
|
||||
"@tsconfig/node22": "^22.0.1",
|
||||
"@eslint/js": "^9.27.0",
|
||||
"@tsconfig/node22": "^22.0.2",
|
||||
"@types/auto-launch": "^5.0.5",
|
||||
"@types/ffmpeg-static": "^3.0.3",
|
||||
"ajv": "^8.17.1",
|
||||
"concurrently": "^9.1.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"electron": "^35.1.4",
|
||||
"electron-builder": "^26.0.12",
|
||||
"electron": "^36.3.1",
|
||||
"electron-builder": "^26.0.14",
|
||||
"eslint": "^9",
|
||||
"prettier": "3.5.3",
|
||||
"prettier-plugin-organize-imports": "^4.1.0",
|
||||
"prettier-plugin-packagejson": "^2.5.10",
|
||||
"shx": "^0.3.4",
|
||||
"prettier-plugin-packagejson": "^2.5.14",
|
||||
"shx": "^0.4.0",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.29.1"
|
||||
"typescript-eslint": "^8.32.1"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"productName": "ente"
|
||||
|
||||
@@ -78,6 +78,14 @@ export const allowWindowClose = (): void => {
|
||||
* We call this at the end of this file.
|
||||
*/
|
||||
const main = () => {
|
||||
// Workaround for Electron 36 not launching on some Linux distros. Remove
|
||||
// once fixed or otherwise mitigated upstream.
|
||||
//
|
||||
// https://github.com/electron/electron/issues/46538#issuecomment-2808806722
|
||||
if (process.platform == "linux") {
|
||||
app.commandLine.appendSwitch("gtk-version", "3");
|
||||
}
|
||||
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
if (!gotTheLock) {
|
||||
app.quit();
|
||||
@@ -423,7 +431,14 @@ const createMainWindow = () => {
|
||||
window.on("hide", () => {
|
||||
// On macOS, when hiding the window also hide the app's icon in the dock
|
||||
// unless the user has unchecked the Settings > Hide dock icon checkbox.
|
||||
if (shouldHideDockIcon()) app.dock?.hide();
|
||||
if (shouldHideDockIcon()) {
|
||||
// macOS emits a window "hide" event when going fullscreen, and if
|
||||
// we hide the dock icon there then the window disappears. So ignore
|
||||
// this scenario.
|
||||
if (!window.isFullScreen()) {
|
||||
app.dock?.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.on("show", () => void app.dock?.show());
|
||||
|
||||
@@ -13,8 +13,10 @@ import type { BrowserWindow } from "electron";
|
||||
import { ipcMain } from "electron/main";
|
||||
import type {
|
||||
CollectionMapping,
|
||||
FFmpegCommand,
|
||||
FolderWatch,
|
||||
PendingUploads,
|
||||
UtilityProcessType,
|
||||
ZipItem,
|
||||
} from "../types/ipc";
|
||||
import { logToDisk } from "./log";
|
||||
@@ -30,7 +32,7 @@ import {
|
||||
openLogDirectory,
|
||||
selectDirectory,
|
||||
} from "./services/dir";
|
||||
import { ffmpegExec } from "./services/ffmpeg";
|
||||
import { ffmpegDetermineVideoDuration, ffmpegExec } from "./services/ffmpeg";
|
||||
import {
|
||||
fsExists,
|
||||
fsFindFiles,
|
||||
@@ -40,12 +42,12 @@ import {
|
||||
fsRename,
|
||||
fsRm,
|
||||
fsRmdir,
|
||||
fsStatMtime,
|
||||
fsWriteFile,
|
||||
fsWriteFileViaBackup,
|
||||
} from "./services/fs";
|
||||
import { convertToJPEG, generateImageThumbnail } from "./services/image";
|
||||
import { logout } from "./services/logout";
|
||||
import { createMLWorker } from "./services/ml";
|
||||
import {
|
||||
lastShownChangelogVersion,
|
||||
masterKeyB64,
|
||||
@@ -55,8 +57,8 @@ import {
|
||||
import {
|
||||
clearPendingUploads,
|
||||
listZipItems,
|
||||
markUploadedFiles,
|
||||
markUploadedZipItems,
|
||||
markUploadedFile,
|
||||
markUploadedZipItem,
|
||||
pathOrZipItemSize,
|
||||
pendingUploads,
|
||||
setPendingUploads,
|
||||
@@ -68,6 +70,7 @@ import {
|
||||
watchUpdateIgnoredFiles,
|
||||
watchUpdateSyncedFiles,
|
||||
} from "./services/watch";
|
||||
import { triggerCreateUtilityProcess } from "./services/workers";
|
||||
|
||||
/**
|
||||
* Listen for IPC events sent/invoked by the renderer process, and route them to
|
||||
@@ -163,6 +166,8 @@ export const attachIPCHandlers = () => {
|
||||
|
||||
ipcMain.handle("fsIsDir", (_, dirPath: string) => fsIsDir(dirPath));
|
||||
|
||||
ipcMain.handle("fsStatMtime", (_, path: string) => fsStatMtime(path));
|
||||
|
||||
ipcMain.handle("fsFindFiles", (_, folderPath: string) =>
|
||||
fsFindFiles(folderPath),
|
||||
);
|
||||
@@ -177,20 +182,26 @@ export const attachIPCHandlers = () => {
|
||||
"generateImageThumbnail",
|
||||
(
|
||||
_,
|
||||
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
|
||||
pathOrZipItem: string | ZipItem,
|
||||
maxDimension: number,
|
||||
maxSize: number,
|
||||
) => generateImageThumbnail(dataOrPathOrZipItem, maxDimension, maxSize),
|
||||
) => generateImageThumbnail(pathOrZipItem, maxDimension, maxSize),
|
||||
);
|
||||
|
||||
ipcMain.handle(
|
||||
"ffmpegExec",
|
||||
(
|
||||
_,
|
||||
command: string[],
|
||||
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
|
||||
command: FFmpegCommand,
|
||||
pathOrZipItem: string | ZipItem,
|
||||
outputFileExtension: string,
|
||||
) => ffmpegExec(command, dataOrPathOrZipItem, outputFileExtension),
|
||||
) => ffmpegExec(command, pathOrZipItem, outputFileExtension),
|
||||
);
|
||||
|
||||
ipcMain.handle(
|
||||
"ffmpegDetermineVideoDuration",
|
||||
(_, pathOrZipItem: string | ZipItem) =>
|
||||
ffmpegDetermineVideoDuration(pathOrZipItem),
|
||||
);
|
||||
|
||||
// - Upload
|
||||
@@ -210,13 +221,15 @@ export const attachIPCHandlers = () => {
|
||||
);
|
||||
|
||||
ipcMain.handle(
|
||||
"markUploadedFiles",
|
||||
(_, paths: PendingUploads["filePaths"]) => markUploadedFiles(paths),
|
||||
"markUploadedFile",
|
||||
(_, path: string, associatedPath: string | undefined) =>
|
||||
markUploadedFile(path, associatedPath),
|
||||
);
|
||||
|
||||
ipcMain.handle(
|
||||
"markUploadedZipItems",
|
||||
(_, items: PendingUploads["zipItems"]) => markUploadedZipItems(items),
|
||||
"markUploadedZipItem",
|
||||
(_, item: ZipItem, associatedItem: ZipItem | undefined) =>
|
||||
markUploadedZipItem(item, associatedItem),
|
||||
);
|
||||
|
||||
ipcMain.handle("clearPendingUploads", () => clearPendingUploads());
|
||||
@@ -227,9 +240,11 @@ export const attachIPCHandlers = () => {
|
||||
* the main window to do their thing.
|
||||
*/
|
||||
export const attachMainWindowIPCHandlers = (mainWindow: BrowserWindow) => {
|
||||
// - ML
|
||||
// - Utility processes
|
||||
|
||||
ipcMain.on("createMLWorker", () => createMLWorker(mainWindow));
|
||||
ipcMain.on("triggerCreateUtilityProcess", (_, type: UtilityProcessType) =>
|
||||
triggerCreateUtilityProcess(type, mainWindow),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
59
desktop/src/main/log-worker.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* A object that behaves similar to the default export of "./log", except this
|
||||
* can be used from within a utility process.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* We cannot directly do
|
||||
*
|
||||
* import log from "../log";
|
||||
*
|
||||
* because that requires the Electron APIs that are not available to a utility
|
||||
* process (See: [Note: Using Electron APIs in UtilityProcess]).
|
||||
*
|
||||
* But even if that were to work, logging will still be problematic since we'd
|
||||
* try opening the log file from two different Node.js processes (this one, and
|
||||
* the main one), and I didn't find any indication in the electron-log
|
||||
* repository that the log file's integrity would be maintained in such cases.
|
||||
*
|
||||
* So instead we provide this proxy log object that uses the
|
||||
* `process.parentPort` to transport the logs over to the main process, where
|
||||
* the {@link processUtilityProcessLogMessage} function in the main process is
|
||||
* expected to handle these (sending them to the actual log).
|
||||
*/
|
||||
export default {
|
||||
error: (s: string, e?: unknown) =>
|
||||
mainProcess("log.errorString", messageWithError(s, e)),
|
||||
warn: (s: string, e?: unknown) =>
|
||||
mainProcess("log.warnString", messageWithError(s, e)),
|
||||
info: (...ms: unknown[]) => mainProcess("log.info", ms),
|
||||
/**
|
||||
* Unlike the real {@link log.debug}, this is (a) eagerly evaluated, and (b)
|
||||
* accepts only strings.
|
||||
*/
|
||||
debugString: (s: string) => mainProcess("log.debugString", s),
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a message to the main process using a barebones RPC protocol.
|
||||
*/
|
||||
const mainProcess = (method: string, param: unknown) =>
|
||||
process.parentPort.postMessage({ method, p: param });
|
||||
|
||||
// Duplicated verbatim from ./log.ts
|
||||
const messageWithError = (message: string, e?: unknown) => {
|
||||
if (!e) return message;
|
||||
|
||||
let es: string;
|
||||
if (e instanceof Error) {
|
||||
// In practice, we expect ourselves to be called with Error objects, so
|
||||
// this is the happy path so to say.
|
||||
es = [`${e.name}: ${e.message}`, e.stack].filter((x) => x).join("\n");
|
||||
} else {
|
||||
// For the rest rare cases, use the default string serialization of e.
|
||||
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
||||
es = String(e);
|
||||
}
|
||||
|
||||
return `${message}: ${es}`;
|
||||
};
|
||||
@@ -83,6 +83,56 @@ const logDebug = (param: () => unknown) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle log messages posted from the utility process in the main process.
|
||||
*
|
||||
* See: [Note: Using Electron APIs in UtilityProcess]
|
||||
*
|
||||
* @param message The arbitrary message that was received as an argument to the
|
||||
* "message" event invoked on a {@link UtilityProcess}.
|
||||
*
|
||||
* @returns true if the message was recognized and handled, and false otherwise.
|
||||
*/
|
||||
export const processUtilityProcessLogMessage = (
|
||||
logTag: string,
|
||||
message: unknown,
|
||||
) => {
|
||||
const m = message; /* shorter alias */
|
||||
if (m && typeof m == "object" && "method" in m && "p" in m) {
|
||||
const p = m.p;
|
||||
switch (m.method) {
|
||||
case "log.errorString":
|
||||
if (typeof p == "string") {
|
||||
logError(`${logTag} ${p}`);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case "log.warnString":
|
||||
if (typeof p == "string") {
|
||||
logWarn(`${logTag} ${p}`);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case "log.info":
|
||||
if (Array.isArray(p)) {
|
||||
// Need to cast from any[] to unknown[]
|
||||
logInfo(logTag, ...(p as unknown[]));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case "log.debugString":
|
||||
if (typeof p == "string") {
|
||||
logDebug(() => `${logTag} ${p}`);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ente's logger.
|
||||
*
|
||||
|
||||
1132
desktop/src/main/services/ffmpeg-worker.ts
Normal file
@@ -1,132 +1,77 @@
|
||||
import pathToFfmpeg from "ffmpeg-static";
|
||||
/**
|
||||
* @file A bridge to the ffmpeg utility process. This code runs in the main
|
||||
* process.
|
||||
*/
|
||||
|
||||
import { wrap } from "comlink";
|
||||
import fs from "node:fs/promises";
|
||||
import type { ZipItem } from "../../types/ipc";
|
||||
import { ensure } from "../utils/common";
|
||||
import { execAsync } from "../utils/electron";
|
||||
import type { FFmpegCommand, ZipItem } from "../../types/ipc";
|
||||
import {
|
||||
deleteTempFileIgnoringErrors,
|
||||
makeFileForDataOrPathOrZipItem,
|
||||
makeFileForStreamOrPathOrZipItem,
|
||||
makeTempFilePath,
|
||||
} from "../utils/temp";
|
||||
|
||||
/* Ditto in the web app's code (used by the Wasm FFmpeg invocation). */
|
||||
const ffmpegPathPlaceholder = "FFMPEG";
|
||||
const inputPathPlaceholder = "INPUT";
|
||||
const outputPathPlaceholder = "OUTPUT";
|
||||
import type { FFmpegUtilityProcess } from "./ffmpeg-worker";
|
||||
import { ffmpegUtilityProcessEndpoint } from "./workers";
|
||||
|
||||
/**
|
||||
* Run a FFmpeg command
|
||||
*
|
||||
* [Note: FFmpeg in Electron]
|
||||
*
|
||||
* There is a Wasm build of FFmpeg, but that is currently 10-20 times slower
|
||||
* that the native build. That is slow enough to be unusable for our purposes.
|
||||
* https://ffmpegwasm.netlify.app/docs/performance
|
||||
*
|
||||
* So the alternative is to bundle a FFmpeg executable binary with our app. e.g.
|
||||
*
|
||||
* yarn add fluent-ffmpeg ffmpeg-static ffprobe-static
|
||||
*
|
||||
* (we only use ffmpeg-static, the rest are mentioned for completeness' sake).
|
||||
*
|
||||
* Interestingly, Electron already bundles an binary FFmpeg library (it comes
|
||||
* from the ffmpeg fork maintained by Chromium).
|
||||
* https://chromium.googlesource.com/chromium/third_party/ffmpeg
|
||||
* https://stackoverflow.com/questions/53963672/what-version-of-ffmpeg-is-bundled-inside-electron
|
||||
*
|
||||
* This can be found in (e.g. on macOS) at
|
||||
*
|
||||
* $ file ente.app/Contents/Frameworks/Electron\ Framework.framework/Versions/Current/Libraries/libffmpeg.dylib
|
||||
* .../libffmpeg.dylib: Mach-O 64-bit dynamically linked shared library arm64
|
||||
*
|
||||
* But I'm not sure if our code is supposed to be able to use it, and how.
|
||||
* Return a handle to the ffmpeg utility process, starting it if needed.
|
||||
*/
|
||||
export const ffmpegUtilityProcess = () =>
|
||||
ffmpegUtilityProcessEndpoint().then((port) =>
|
||||
wrap<FFmpegUtilityProcess>(port),
|
||||
);
|
||||
|
||||
/**
|
||||
* Implement the IPC "ffmpegExec" contract, writing the input and output to
|
||||
* temporary files as needed, and then forward to the {@link ffmpegExec} running
|
||||
* in the utility process.
|
||||
*/
|
||||
export const ffmpegExec = async (
|
||||
command: string[],
|
||||
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
|
||||
command: FFmpegCommand,
|
||||
pathOrZipItem: string | ZipItem,
|
||||
outputFileExtension: string,
|
||||
): Promise<Uint8Array> => {
|
||||
): Promise<Uint8Array> =>
|
||||
withInputFile(pathOrZipItem, async (worker, inputFilePath) => {
|
||||
const outputFilePath = await makeTempFilePath(outputFileExtension);
|
||||
try {
|
||||
await worker.ffmpegExec(command, inputFilePath, outputFilePath);
|
||||
return await fs.readFile(outputFilePath);
|
||||
} finally {
|
||||
await deleteTempFileIgnoringErrors(outputFilePath);
|
||||
}
|
||||
});
|
||||
|
||||
export const withInputFile = async <T>(
|
||||
pathOrZipItem: string | ZipItem,
|
||||
f: (worker: FFmpegUtilityProcess, inputFilePath: string) => Promise<T>,
|
||||
): Promise<T> => {
|
||||
const worker = await ffmpegUtilityProcess();
|
||||
|
||||
const {
|
||||
path: inputFilePath,
|
||||
isFileTemporary: isInputFileTemporary,
|
||||
writeToTemporaryFile: writeToTemporaryInputFile,
|
||||
} = await makeFileForDataOrPathOrZipItem(dataOrPathOrZipItem);
|
||||
} = await makeFileForStreamOrPathOrZipItem(pathOrZipItem);
|
||||
|
||||
const outputFilePath = await makeTempFilePath(outputFileExtension);
|
||||
try {
|
||||
await writeToTemporaryInputFile();
|
||||
|
||||
const cmd = substitutePlaceholders(
|
||||
command,
|
||||
inputFilePath,
|
||||
outputFilePath,
|
||||
);
|
||||
|
||||
await execAsync(cmd);
|
||||
|
||||
return await fs.readFile(outputFilePath);
|
||||
return await f(worker, inputFilePath);
|
||||
} finally {
|
||||
if (isInputFileTemporary)
|
||||
await deleteTempFileIgnoringErrors(inputFilePath);
|
||||
await deleteTempFileIgnoringErrors(outputFilePath);
|
||||
}
|
||||
};
|
||||
|
||||
const substitutePlaceholders = (
|
||||
command: string[],
|
||||
inputFilePath: string,
|
||||
outputFilePath: string,
|
||||
) =>
|
||||
command.map((segment) => {
|
||||
if (segment == ffmpegPathPlaceholder) {
|
||||
return ffmpegBinaryPath();
|
||||
} else if (segment == inputPathPlaceholder) {
|
||||
return inputFilePath;
|
||||
} else if (segment == outputPathPlaceholder) {
|
||||
return outputFilePath;
|
||||
} else {
|
||||
return segment;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Return the path to the `ffmpeg` binary.
|
||||
*
|
||||
* At runtime, the FFmpeg binary is present in a path like (macOS example):
|
||||
* `ente.app/Contents/Resources/app.asar.unpacked/node_modules/ffmpeg-static/ffmpeg`
|
||||
* Implement the IPC "ffmpegDetermineVideoDuration" contract, writing the input
|
||||
* to temporary files as needed, and then forward to the
|
||||
* {@link ffmpegDetermineVideoDuration} running in the utility process.
|
||||
*/
|
||||
const ffmpegBinaryPath = () => {
|
||||
// This substitution of app.asar by app.asar.unpacked is suggested by the
|
||||
// ffmpeg-static library author themselves:
|
||||
// https://github.com/eugeneware/ffmpeg-static/issues/16
|
||||
return ensure(pathToFfmpeg).replace("app.asar", "app.asar.unpacked");
|
||||
};
|
||||
|
||||
/**
|
||||
* A variant of {@link ffmpegExec} adapted to work with streams so that it can
|
||||
* handle the MP4 conversion of large video files.
|
||||
*
|
||||
* See: [Note: Convert to MP4]
|
||||
|
||||
* @param inputFilePath The path to a file on the user's local file system. This
|
||||
* is the video we want to convert.
|
||||
* @param inputFilePath The path to a file on the user's local file system where
|
||||
* we should write the converted MP4 video.
|
||||
*/
|
||||
export const ffmpegConvertToMP4 = async (
|
||||
inputFilePath: string,
|
||||
outputFilePath: string,
|
||||
): Promise<void> => {
|
||||
const command = [
|
||||
ffmpegPathPlaceholder,
|
||||
"-i",
|
||||
inputPathPlaceholder,
|
||||
"-preset",
|
||||
"ultrafast",
|
||||
outputPathPlaceholder,
|
||||
];
|
||||
|
||||
const cmd = substitutePlaceholders(command, inputFilePath, outputFilePath);
|
||||
|
||||
await execAsync(cmd);
|
||||
};
|
||||
export const ffmpegDetermineVideoDuration = async (
|
||||
pathOrZipItem: string | ZipItem,
|
||||
): Promise<number> =>
|
||||
withInputFile(pathOrZipItem, async (worker, inputFilePath) =>
|
||||
worker.ffmpegDetermineVideoDuration(inputFilePath),
|
||||
);
|
||||
|
||||
@@ -36,6 +36,17 @@ export const fsIsDir = async (dirPath: string) => {
|
||||
return stat.isDirectory();
|
||||
};
|
||||
|
||||
export const fsStatMtime = (path: string) =>
|
||||
// [Note: Integral last modified time]
|
||||
//
|
||||
// Whenever we need to find the modified time of a file, use the
|
||||
// `mtime.getTime()` instead of `mtimeMs` of the stat; this way, it is
|
||||
// guaranteed that the times are integral (we persist these values to remote
|
||||
// in some cases, and the contract is for them to be integral; mtimeMs is a
|
||||
// float with sub-millisecond precision), and that all places use the same
|
||||
// value so that they're comparable.
|
||||
fs.stat(path).then((st) => st.mtime.getTime());
|
||||
|
||||
export const fsFindFiles = async (dirPath: string) => {
|
||||
const items = await fs.readdir(dirPath, { withFileTypes: true });
|
||||
let paths: string[] = [];
|
||||
|
||||
@@ -6,7 +6,7 @@ import { type ZipItem } from "../../types/ipc";
|
||||
import { execAsync, isDev } from "../utils/electron";
|
||||
import {
|
||||
deleteTempFileIgnoringErrors,
|
||||
makeFileForDataOrPathOrZipItem,
|
||||
makeFileForStreamOrPathOrZipItem,
|
||||
makeTempFilePath,
|
||||
} from "../utils/temp";
|
||||
|
||||
@@ -61,7 +61,7 @@ const vipsPath = () =>
|
||||
);
|
||||
|
||||
export const generateImageThumbnail = async (
|
||||
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
|
||||
pathOrZipItem: string | ZipItem,
|
||||
maxDimension: number,
|
||||
maxSize: number,
|
||||
): Promise<Uint8Array> => {
|
||||
@@ -69,7 +69,7 @@ export const generateImageThumbnail = async (
|
||||
path: inputFilePath,
|
||||
isFileTemporary: isInputFileTemporary,
|
||||
writeToTemporaryFile: writeToTemporaryInputFile,
|
||||
} = await makeFileForDataOrPathOrZipItem(dataOrPathOrZipItem);
|
||||
} = await makeFileForStreamOrPathOrZipItem(pathOrZipItem);
|
||||
|
||||
const outputFilePath = await makeTempFilePath("jpeg");
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { FSWatcher } from "chokidar";
|
||||
import log from "../log";
|
||||
import { clearConvertToMP4Results } from "../stream";
|
||||
import { clearPendingVideoResults } from "../stream";
|
||||
import { clearStores } from "./store";
|
||||
import { watchReset } from "./watch";
|
||||
import { terminateUtilityProcesses } from "./workers";
|
||||
import { clearOpenZipCache } from "./zip";
|
||||
|
||||
/**
|
||||
@@ -22,9 +23,9 @@ export const logout = (watcher: FSWatcher) => {
|
||||
ignoreError("FS watch", e);
|
||||
}
|
||||
try {
|
||||
clearConvertToMP4Results();
|
||||
clearPendingVideoResults();
|
||||
} catch (e) {
|
||||
ignoreError("convert-to-mp4", e);
|
||||
ignoreError("video", e);
|
||||
}
|
||||
try {
|
||||
clearStores();
|
||||
@@ -36,4 +37,9 @@ export const logout = (watcher: FSWatcher) => {
|
||||
} catch (e) {
|
||||
ignoreError("zip cache", e);
|
||||
}
|
||||
try {
|
||||
terminateUtilityProcesses();
|
||||
} catch (e) {
|
||||
ignoreError("utility processes", e);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,46 +15,16 @@ import { existsSync } from "fs";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import * as ort from "onnxruntime-node";
|
||||
import { z } from "zod";
|
||||
import log from "../log-worker";
|
||||
import { messagePortMainEndpoint } from "../utils/comlink";
|
||||
import { ensure, wait } from "../utils/common";
|
||||
import { wait } from "../utils/common";
|
||||
import { writeStream } from "../utils/stream";
|
||||
import { fsStatMtime } from "./fs";
|
||||
|
||||
/**
|
||||
* We cannot do
|
||||
*
|
||||
* import log from "../log";
|
||||
*
|
||||
* because that requires the Electron APIs that are not available to a utility
|
||||
* process (See: [Note: Using Electron APIs in UtilityProcess]). But even if
|
||||
* that were to work, logging will still be problematic since we'd try opening
|
||||
* the log file from two different Node.js processes (this one, and the main
|
||||
* one), and I didn't find any indication in the electron-log repository that
|
||||
* the log file's integrity would be maintained in such cases.
|
||||
*
|
||||
* So instead we create this proxy log object that uses `process.parentPort` to
|
||||
* transport the logs over to the main process.
|
||||
*/
|
||||
const log = {
|
||||
/**
|
||||
* Unlike the real {@link log.error}, this accepts only the first string
|
||||
* argument, not the second optional error one.
|
||||
*/
|
||||
errorString: (s: string) => mainProcess("log.errorString", s),
|
||||
info: (...ms: unknown[]) => mainProcess("log.info", ms),
|
||||
/**
|
||||
* Unlike the real {@link log.debug}, this is (a) eagerly evaluated, and (b)
|
||||
* accepts only strings.
|
||||
*/
|
||||
debugString: (s: string) => mainProcess("log.debugString", s),
|
||||
};
|
||||
log.debugString("Started ML utility process");
|
||||
|
||||
/**
|
||||
* Send a message to the main process using a barebones RPC protocol.
|
||||
*/
|
||||
const mainProcess = (method: string, param: unknown) =>
|
||||
process.parentPort.postMessage({ method, p: param });
|
||||
|
||||
log.debugString(`Started ML worker process`);
|
||||
process.on("uncaughtException", (e, origin) => log.error(origin, e));
|
||||
|
||||
process.parentPort.once("message", (e) => {
|
||||
// Initialize ourselves with the data we got from our parent.
|
||||
@@ -63,12 +33,13 @@ process.parentPort.once("message", (e) => {
|
||||
// parent.
|
||||
expose(
|
||||
{
|
||||
fsStatMtime,
|
||||
computeCLIPImageEmbedding,
|
||||
computeCLIPTextEmbeddingIfAvailable,
|
||||
detectFaces,
|
||||
computeFaceEmbeddings,
|
||||
},
|
||||
messagePortMainEndpoint(ensure(e.ports[0])),
|
||||
messagePortMainEndpoint(e.ports[0]!),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -80,19 +51,12 @@ process.parentPort.once("message", (e) => {
|
||||
let _userDataPath: string | undefined;
|
||||
|
||||
/** Equivalent to app.getPath("userData") */
|
||||
const userDataPath = () => ensure(_userDataPath);
|
||||
const userDataPath = () => _userDataPath!;
|
||||
|
||||
const MLWorkerInitData = z.object({ userDataPath: z.string() });
|
||||
|
||||
const parseInitData = (data: unknown) => {
|
||||
if (
|
||||
data &&
|
||||
typeof data == "object" &&
|
||||
"userDataPath" in data &&
|
||||
typeof data.userDataPath == "string"
|
||||
) {
|
||||
_userDataPath = data.userDataPath;
|
||||
} else {
|
||||
log.errorString("Unparseable initialization data");
|
||||
}
|
||||
_userDataPath = MLWorkerInitData.parse(data).userDataPath;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -159,7 +123,7 @@ const modelPathDownloadingIfNeeded = async (
|
||||
} else {
|
||||
const size = (await fs.stat(modelPath)).size;
|
||||
if (size !== expectedByteSize) {
|
||||
log.errorString(
|
||||
log.error(
|
||||
`The size ${size} of model ${modelName} does not match the expected size, downloading again`,
|
||||
);
|
||||
await downloadModel(modelPath, modelName);
|
||||
@@ -250,7 +214,7 @@ export const computeCLIPImageEmbedding = async (
|
||||
const results = await session.run(feeds);
|
||||
log.debugString(`ONNX/CLIP image embedding took ${Date.now() - t} ms`);
|
||||
/* Need these model specific casts to type the result */
|
||||
return ensure(results.output).data as Float32Array;
|
||||
return results.output!.data as Float32Array;
|
||||
};
|
||||
|
||||
const cachedCLIPTextSession = makeCachedInferenceSession(
|
||||
@@ -290,7 +254,7 @@ export const computeCLIPTextEmbeddingIfAvailable = async (text: string) => {
|
||||
const t = Date.now();
|
||||
const results = await session.run(feeds);
|
||||
log.debugString(`ONNX/CLIP text embedding took ${Date.now() - t} ms`);
|
||||
return ensure(results.output).data as Float32Array;
|
||||
return results.output!.data as Float32Array;
|
||||
};
|
||||
|
||||
const cachedFaceDetectionSession = makeCachedInferenceSession(
|
||||
@@ -311,7 +275,7 @@ export const detectFaces = async (
|
||||
const t = Date.now();
|
||||
const results = await session.run(feeds);
|
||||
log.debugString(`ONNX/YOLO face detection took ${Date.now() - t} ms`);
|
||||
return ensure(results.output).data;
|
||||
return results.output!.data;
|
||||
};
|
||||
|
||||
const cachedFaceEmbeddingSession = makeCachedInferenceSession(
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/**
|
||||
* @file ML related functionality. This code runs in the main process.
|
||||
*/
|
||||
|
||||
import {
|
||||
MessageChannelMain,
|
||||
type BrowserWindow,
|
||||
type UtilityProcess,
|
||||
} from "electron";
|
||||
import { app, utilityProcess } from "electron/main";
|
||||
import path from "node:path";
|
||||
import log from "../log";
|
||||
|
||||
/** The active ML worker (utility) process, if any. */
|
||||
let _child: UtilityProcess | undefined;
|
||||
|
||||
/**
|
||||
* Create a new ML worker process, terminating the older ones (if any).
|
||||
*
|
||||
* [Note: ML IPC]
|
||||
*
|
||||
* The primary reason for doing ML tasks in the Node.js layer is so that we can
|
||||
* use the binary ONNX runtime, which is 10-20x faster than the Wasm one that
|
||||
* can be used directly on the web layer.
|
||||
*
|
||||
* For this to work, the main and renderer process need to communicate with each
|
||||
* other. Further, in the web layer the ML indexing runs in a web worker (so as
|
||||
* to not get in the way of the main thread). So the communication has 2 hops:
|
||||
*
|
||||
* Node.js main <-> Renderer main <-> Renderer web worker
|
||||
*
|
||||
* This naive way works, but has a problem. The Node.js main process is in the
|
||||
* code path for delivering user events to the renderer process. The ML tasks we
|
||||
* do take in the order of 100-300 ms (possibly more) for each individual
|
||||
* inference. Thus, the Node.js main process is busy for those 100-300 ms, and
|
||||
* does not forward events to the renderer, causing the UI to jitter.
|
||||
*
|
||||
* The solution for this is to spawn an Electron UtilityProcess, which we can
|
||||
* think of a regular Node.js child process. This frees up the Node.js main
|
||||
* process, and would remove the jitter.
|
||||
* https://www.electronjs.org/docs/latest/tutorial/process-model
|
||||
*
|
||||
* It would seem that this introduces another hop in our IPC
|
||||
*
|
||||
* Node.js utility process <-> Node.js main <-> ...
|
||||
*
|
||||
* but here we can use the special bit about Electron utility processes that
|
||||
* separates them from regular Node.js child processes: their support for
|
||||
* message ports. https://www.electronjs.org/docs/latest/tutorial/message-ports
|
||||
*
|
||||
* As a brief summary, a MessagePort is a web feature that allows two contexts
|
||||
* to communicate. A pair of message ports is called a message channel. The cool
|
||||
* thing about these is that we can pass these ports themselves over IPC.
|
||||
*
|
||||
* > One caveat here is that the message ports can only be passed using the
|
||||
* > `postMessage` APIs, not the usual send/invoke APIs.
|
||||
*
|
||||
* So we
|
||||
*
|
||||
* 1. In the utility process create a message channel.
|
||||
* 2. Spawn a utility process, and send one port of the pair to it.
|
||||
* 3. Send the other port of the pair to the renderer.
|
||||
*
|
||||
* The renderer will forward that port to the web worker that is coordinating
|
||||
* the ML indexing on the web layer. Thereafter, the utility process and web
|
||||
* worker can directly talk to each other!
|
||||
*
|
||||
* Node.js utility process <-> Renderer web worker
|
||||
*
|
||||
* The RPC protocol is handled using comlink on both ends. The port itself needs
|
||||
* to be relayed using `postMessage`.
|
||||
*/
|
||||
export const createMLWorker = (window: BrowserWindow) => {
|
||||
if (_child) {
|
||||
log.debug(() => "Terminating previous ML worker process");
|
||||
_child.kill();
|
||||
_child = undefined;
|
||||
}
|
||||
|
||||
const { port1, port2 } = new MessageChannelMain();
|
||||
|
||||
const child = utilityProcess.fork(path.join(__dirname, "ml-worker.js"));
|
||||
const userDataPath = app.getPath("userData");
|
||||
child.postMessage({ userDataPath }, [port1]);
|
||||
|
||||
window.webContents.postMessage("createMLWorker/port", undefined, [port2]);
|
||||
|
||||
handleMessagesFromUtilityProcess(child);
|
||||
|
||||
_child = child;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle messages posted from the utility process.
|
||||
*
|
||||
* [Note: Using Electron APIs in UtilityProcess]
|
||||
*
|
||||
* Only a small subset of the Electron APIs are available to a UtilityProcess.
|
||||
* As of writing (Jul 2024, Electron 30), only the following are available:
|
||||
*
|
||||
* - net
|
||||
* - systemPreferences
|
||||
*
|
||||
* In particular, `app` is not available.
|
||||
*
|
||||
* We structure our code so that it doesn't need anything apart from `net`.
|
||||
*
|
||||
* For the other cases,
|
||||
*
|
||||
* - Additional parameters to the utility process are passed alongwith the
|
||||
* initial message where we provide it the message port.
|
||||
*
|
||||
* - When we need to communicate from the utility process to the main process,
|
||||
* we use the `parentPort` in the utility process.
|
||||
*/
|
||||
const handleMessagesFromUtilityProcess = (child: UtilityProcess) => {
|
||||
const logTag = "[ml-worker]";
|
||||
child.on("message", (m: unknown) => {
|
||||
if (m && typeof m == "object" && "method" in m && "p" in m) {
|
||||
const p = m.p;
|
||||
switch (m.method) {
|
||||
case "log.errorString":
|
||||
if (typeof p == "string") {
|
||||
log.error(`${logTag} ${p}`);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "log.info":
|
||||
if (Array.isArray(p)) {
|
||||
// Need to cast from any[] to unknown[]
|
||||
log.info(logTag, ...(p as unknown[]));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "log.debugString":
|
||||
if (typeof p == "string") {
|
||||
log.debug(() => `${logTag} ${p}`);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
log.info("Ignoring unknown message from ML worker", m);
|
||||
});
|
||||
};
|
||||
@@ -135,22 +135,35 @@ export const setPendingUploads = ({
|
||||
});
|
||||
};
|
||||
|
||||
export const markUploadedFiles = (paths: string[]) => {
|
||||
export const markUploadedFile = (
|
||||
path: string,
|
||||
associatedPath: string | undefined,
|
||||
) => {
|
||||
const existing = uploadStatusStore.get("filePaths") ?? [];
|
||||
const updated = existing.filter((p) => !paths.includes(p));
|
||||
const updated = existing.filter((p) => p != path && p != associatedPath);
|
||||
uploadStatusStore.set("filePaths", updated);
|
||||
// See: [Note: Integral last modified time]
|
||||
return fs.stat(path).then((st) => st.mtime.getTime());
|
||||
};
|
||||
|
||||
export const markUploadedZipItems = (
|
||||
items: [zipPath: string, entryName: string][],
|
||||
export const markUploadedZipItem = (
|
||||
item: ZipItem,
|
||||
associatedItem: ZipItem | undefined,
|
||||
) => {
|
||||
const existing = uploadStatusStore.get("zipItems") ?? [];
|
||||
const updated = existing.filter(
|
||||
(z) => !items.some((e) => z[0] == e[0] && z[1] == e[1]),
|
||||
const updated = exceptZipItem(
|
||||
exceptZipItem(existing, item),
|
||||
associatedItem,
|
||||
);
|
||||
uploadStatusStore.set("zipItems", updated);
|
||||
return fs.stat(item[0]).then((st) => st.mtime.getTime());
|
||||
};
|
||||
|
||||
const exceptZipItem = (items: ZipItem[], item: ZipItem | undefined) =>
|
||||
item
|
||||
? items.filter((zi) => !(zi[0] == item[0] && zi[1] == item[1]))
|
||||
: items;
|
||||
|
||||
export const clearPendingUploads = () => {
|
||||
uploadStatusStore.clear();
|
||||
clearOpenZipCache();
|
||||
|
||||
241
desktop/src/main/services/workers.ts
Normal file
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* @file This main process code and interface for dealing with the various
|
||||
* utility processes that we create.
|
||||
*/
|
||||
|
||||
import type { Endpoint } from "comlink";
|
||||
import {
|
||||
MessageChannelMain,
|
||||
type BrowserWindow,
|
||||
type UtilityProcess,
|
||||
} from "electron";
|
||||
import { app, utilityProcess } from "electron/main";
|
||||
import path from "node:path";
|
||||
import type { UtilityProcessType } from "../../types/ipc";
|
||||
import log, { processUtilityProcessLogMessage } from "../log";
|
||||
import { messagePortMainEndpoint } from "../utils/comlink";
|
||||
|
||||
/**
|
||||
* Terminate any existing utility processes if they're running.
|
||||
*
|
||||
* This function is called during the logout sequence.
|
||||
*/
|
||||
export const terminateUtilityProcesses = () => {
|
||||
terminateMLProcessIfRunning();
|
||||
terminateFFmpegProcessIfRunning();
|
||||
};
|
||||
|
||||
/** The active ML utility process, if any. */
|
||||
let _utilityProcessML: UtilityProcess | undefined;
|
||||
|
||||
/** The active FFmpeg utility process, if any. */
|
||||
let _utilityProcessFFmpeg: UtilityProcess | undefined;
|
||||
|
||||
/**
|
||||
* A promise to a comlink {@link Endpoint} that can be used to communicate with
|
||||
* the active ffmpeg utility process (if any).
|
||||
*/
|
||||
let _utilityProcessFFmpegEndpoint: Promise<Endpoint> | undefined;
|
||||
|
||||
/**
|
||||
* Create a new utility process of the given {@link type}, terminating the older
|
||||
* ones (if any).
|
||||
*
|
||||
* Currently the only type is "ml". The following note explains the reasoning
|
||||
* why utility processes were used for the first workload (ML) that was handled
|
||||
* this way. Similar reasoning applies to subsequent workloads (ffmpeg) that
|
||||
* have been offloaded to utility processes in a slightly different manner to
|
||||
* avoid stutter in the UI.
|
||||
*
|
||||
* [Note: ML IPC]
|
||||
*
|
||||
* The primary reason for doing ML tasks in the Node.js layer is so that we can
|
||||
* use the binary ONNX runtime, which is 10-20x faster than the Wasm one that
|
||||
* can be used directly on the web layer.
|
||||
*
|
||||
* For this to work, the main and renderer process need to communicate with each
|
||||
* other. Further, in the web layer the ML indexing runs in a web worker (so as
|
||||
* to not get in the way of the main thread). So the communication has 2 hops:
|
||||
*
|
||||
* Node.js main <-> Renderer main <-> Renderer web worker
|
||||
*
|
||||
* This naive way works, but has a problem. The Node.js main process is in the
|
||||
* code path for delivering user events to the renderer process. The ML tasks we
|
||||
* do take in the order of 100-300 ms (possibly more) for each individual
|
||||
* inference. Thus, the Node.js main process is busy for those 100-300 ms, and
|
||||
* does not forward events to the renderer, causing the UI to jitter.
|
||||
*
|
||||
* The solution for this is to spawn an Electron UtilityProcess, which we can
|
||||
* think of a regular Node.js child process. This frees up the Node.js main
|
||||
* process, and would remove the jitter.
|
||||
* https://www.electronjs.org/docs/latest/tutorial/process-model
|
||||
*
|
||||
* It would seem that this introduces another hop in our IPC
|
||||
*
|
||||
* Node.js utility process <-> Node.js main <-> ...
|
||||
*
|
||||
* but here we can use the special bit about Electron utility processes that
|
||||
* separates them from regular Node.js child processes: their support for
|
||||
* message ports. https://www.electronjs.org/docs/latest/tutorial/message-ports
|
||||
*
|
||||
* As a brief summary, a MessagePort is a web feature that allows two contexts
|
||||
* to communicate. A pair of message ports is called a message channel. The cool
|
||||
* thing about these is that we can pass these ports themselves over IPC.
|
||||
*
|
||||
* > One caveat here is that the message ports can only be passed using the
|
||||
* > `postMessage` APIs, not the usual send/invoke APIs.
|
||||
*
|
||||
* So we
|
||||
*
|
||||
* 1. In the utility process create a message channel.
|
||||
* 2. Spawn a utility process, and send one port of the pair to it.
|
||||
* 3. Send the other port of the pair to the renderer.
|
||||
*
|
||||
* The renderer will forward that port to the web worker that is coordinating
|
||||
* the ML indexing on the web layer. Thereafter, the utility process and web
|
||||
* worker can directly talk to each other!
|
||||
*
|
||||
* Node.js utility process <-> Renderer web worker
|
||||
*
|
||||
* The RPC protocol is handled using comlink on both ends. The port itself needs
|
||||
* to be relayed using `postMessage`.
|
||||
*/
|
||||
export const triggerCreateUtilityProcess = (
|
||||
type: UtilityProcessType,
|
||||
window: BrowserWindow,
|
||||
) => triggerCreateMLUtilityProcess(window);
|
||||
|
||||
const terminateMLProcessIfRunning = () => {
|
||||
if (_utilityProcessML) {
|
||||
log.debug(() => "Terminating running ML utility process");
|
||||
_utilityProcessML.kill();
|
||||
_utilityProcessML = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const triggerCreateMLUtilityProcess = (window: BrowserWindow) => {
|
||||
terminateMLProcessIfRunning();
|
||||
|
||||
const { port1, port2 } = new MessageChannelMain();
|
||||
|
||||
const child = utilityProcess.fork(path.join(__dirname, "ml-worker.js"));
|
||||
const userDataPath = app.getPath("userData");
|
||||
child.postMessage(/* MLWorkerInitData */ { userDataPath }, [port1]);
|
||||
|
||||
window.webContents.postMessage("utilityProcessPort/ml", undefined, [port2]);
|
||||
|
||||
handleMessagesFromMLUtilityProcess(child);
|
||||
|
||||
_utilityProcessML = child;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle messages posted from the utility process.
|
||||
*
|
||||
* [Note: Using Electron APIs in UtilityProcess]
|
||||
*
|
||||
* Only a small subset of the Electron APIs are available to a UtilityProcess.
|
||||
* As of writing (Jul 2024, Electron 30), only the following are available:
|
||||
*
|
||||
* - net
|
||||
* - systemPreferences
|
||||
*
|
||||
* In particular, `app` is not available.
|
||||
*
|
||||
* We structure our code so that it doesn't need anything apart from `net`.
|
||||
*
|
||||
* For the other cases,
|
||||
*
|
||||
* - Additional parameters to the utility process are passed alongwith the
|
||||
* initial message where we provide it the message port.
|
||||
*
|
||||
* - When we need to communicate from the utility process to the main process,
|
||||
* we use the `parentPort` in the utility process.
|
||||
*/
|
||||
const handleMessagesFromMLUtilityProcess = (child: UtilityProcess) => {
|
||||
child.on("message", (m: unknown) => {
|
||||
if (processUtilityProcessLogMessage("[ml-worker]", m)) {
|
||||
return;
|
||||
}
|
||||
log.info("Ignoring unknown message from ML utility process", m);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* A comlink endpoint that can be used to communicate with the ffmpeg utility
|
||||
* process. If there is no ffmpeg utility process, a new one is created on
|
||||
* demand.
|
||||
*
|
||||
* See [Note: ML IPC] for a general outline of why utility processes are needed
|
||||
* (tl;dr; to avoid stutter on the UI).
|
||||
*
|
||||
* In the case of ffmpeg, the IPC flow is a bit different: the utility process
|
||||
* is not exposed to the web layer, and is internal to the node layer. The
|
||||
* reason for this difference is that we need to create temporary files etc, and
|
||||
* doing it a utility process requires access to the `app` module which are not
|
||||
* accessible (See: [Note: Using Electron APIs in UtilityProcess]).
|
||||
*
|
||||
* There could've been possible reasonable workarounds, but the architecture
|
||||
* we've adopted of three layers:
|
||||
*
|
||||
* Renderer (web) <-> Node.js main <-> Node.js ffmpeg utility process
|
||||
*
|
||||
* The temporary file creation etc is handled in the Node.js main process, and
|
||||
* paths to the files are forwarded to the ffmpeg utility process to act on.
|
||||
*
|
||||
* @returns an endpoint that can be used to communicate with the utility
|
||||
* process. The utility process is expected to expose an object that conforms to
|
||||
* the {@link ElectronFFmpegWorkerNode} interface on this endpoint.
|
||||
*/
|
||||
export const ffmpegUtilityProcessEndpoint = () =>
|
||||
(_utilityProcessFFmpegEndpoint ??= createFFmpegUtilityProcessEndpoint());
|
||||
|
||||
const terminateFFmpegProcessIfRunning = () => {
|
||||
if (_utilityProcessFFmpeg) {
|
||||
log.debug(() => "Terminating running FFmpeg utility process");
|
||||
_utilityProcessFFmpeg.kill();
|
||||
_utilityProcessFFmpeg = undefined;
|
||||
_utilityProcessFFmpegEndpoint = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const createFFmpegUtilityProcessEndpoint = () => {
|
||||
if (_utilityProcessFFmpeg) {
|
||||
throw new Error("FFmpeg utility process is already running");
|
||||
}
|
||||
|
||||
// Promise.withResolvers is currently in the node available to us.
|
||||
let resolve: ((endpoint: Endpoint) => void) | undefined;
|
||||
const promise = new Promise<Endpoint>((r) => (resolve = r));
|
||||
|
||||
const { port1, port2 } = new MessageChannelMain();
|
||||
|
||||
const child = utilityProcess.fork(path.join(__dirname, "ffmpeg-worker.js"));
|
||||
// Send a handle to the port (one end of the message channel) to the utility
|
||||
// process (alongwith any other init data). The utility process will reply
|
||||
// with an "ack" when it get it.
|
||||
const appVersion = app.getVersion();
|
||||
child.postMessage(/* FFmpegWorkerInitData */ { appVersion }, [port1]);
|
||||
|
||||
child.on("message", (m: unknown) => {
|
||||
if (m && typeof m == "object" && "method" in m) {
|
||||
switch (m.method) {
|
||||
case "ack":
|
||||
resolve!(messagePortMainEndpoint(port2));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (processUtilityProcessLogMessage("[ffmpeg-worker]", m)) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Ignoring unknown message from ffmpeg utility process", m);
|
||||
});
|
||||
|
||||
_utilityProcessFFmpeg = child;
|
||||
|
||||
// Resolve with the other end of the message channel (once we get an "ack"
|
||||
// from the utility process).
|
||||
return promise;
|
||||
};
|
||||
@@ -7,13 +7,14 @@ import fs from "node:fs/promises";
|
||||
import { Writable } from "node:stream";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import log from "./log";
|
||||
import { ffmpegConvertToMP4 } from "./services/ffmpeg";
|
||||
import { ffmpegUtilityProcess } from "./services/ffmpeg";
|
||||
import { type FFmpegGenerateHLSPlaylistAndSegmentsResult } from "./services/ffmpeg-worker";
|
||||
import { markClosableZip, openZip } from "./services/zip";
|
||||
import { ensure } from "./utils/common";
|
||||
import { writeStream } from "./utils/stream";
|
||||
import {
|
||||
deleteTempFile,
|
||||
deleteTempFileIgnoringErrors,
|
||||
makeFileForStreamOrPathOrZipItem,
|
||||
makeTempFilePath,
|
||||
} from "./utils/temp";
|
||||
|
||||
@@ -57,25 +58,39 @@ const handleStreamRequest = async (request: Request): Promise<Response> => {
|
||||
const { host, searchParams } = new URL(url);
|
||||
switch (host) {
|
||||
case "read":
|
||||
return handleRead(ensure(searchParams.get("path")));
|
||||
return handleRead(searchParams.get("path")!);
|
||||
|
||||
case "read-zip":
|
||||
return handleReadZip(
|
||||
ensure(searchParams.get("zipPath")),
|
||||
ensure(searchParams.get("entryName")),
|
||||
searchParams.get("zipPath")!,
|
||||
searchParams.get("entryName")!,
|
||||
);
|
||||
|
||||
case "write":
|
||||
return handleWrite(ensure(searchParams.get("path")), request);
|
||||
return handleWrite(searchParams.get("path")!, request);
|
||||
|
||||
case "video": {
|
||||
const op = searchParams.get("op");
|
||||
if (op) {
|
||||
switch (op) {
|
||||
case "convert-to-mp4":
|
||||
return handleConvertToMP4Write(request);
|
||||
case "generate-hls":
|
||||
return handleGenerateHLSWrite(request, searchParams);
|
||||
default:
|
||||
return new Response(`Unknown op ${op}`, {
|
||||
status: 404,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
case "convert-to-mp4": {
|
||||
const token = searchParams.get("token");
|
||||
const done = searchParams.get("done") !== null;
|
||||
return token
|
||||
? done
|
||||
? handleConvertToMP4ReadDone(token)
|
||||
: handleConvertToMP4Read(token)
|
||||
: handleConvertToMP4Write(request);
|
||||
if (!token) {
|
||||
return new Response("Missing token", { status: 404 });
|
||||
}
|
||||
|
||||
return done ? handleVideoDone(token) : handleVideoRead(token);
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -105,6 +120,7 @@ const handleRead = async (path: string) => {
|
||||
res.headers.set("Content-Length", `${fileSize}`);
|
||||
|
||||
// Add the file's last modified time (as epoch milliseconds).
|
||||
// See: [Note: Integral last modified time]
|
||||
const mtimeMs = stat.mtime.getTime();
|
||||
res.headers.set("X-Last-Modified-Ms", `${mtimeMs}`);
|
||||
}
|
||||
@@ -166,21 +182,21 @@ const handleReadZip = async (zipPath: string, entryName: string) => {
|
||||
};
|
||||
|
||||
const handleWrite = async (path: string, request: Request) => {
|
||||
await writeStream(path, ensure(request.body));
|
||||
await writeStream(path, request.body!);
|
||||
return new Response("", { status: 200 });
|
||||
};
|
||||
|
||||
/**
|
||||
* A map from token to file paths for convert-to-mp4 requests that we have
|
||||
* received.
|
||||
* A map from token to file paths generated as a result of stream://video
|
||||
* requests we have received.
|
||||
*/
|
||||
const convertToMP4Results = new Map<string, string>();
|
||||
const pendingVideoResults = new Map<string, string>();
|
||||
|
||||
/**
|
||||
* Clear any in-memory state for in-flight convert-to-mp4 requests. Meant to be
|
||||
* called during logout.
|
||||
* Clear any in-memory state for in-flight streamed video processing requests.
|
||||
* Meant to be called during logout.
|
||||
*/
|
||||
export const clearConvertToMP4Results = () => convertToMP4Results.clear();
|
||||
export const clearPendingVideoResults = () => pendingVideoResults.clear();
|
||||
|
||||
/**
|
||||
* [Note: Convert to MP4]
|
||||
@@ -195,30 +211,32 @@ export const clearConvertToMP4Results = () => convertToMP4Results.clear();
|
||||
* mode for the Web fetch API). So we need to simulate that using two different
|
||||
* streaming requests.
|
||||
*
|
||||
* renderer → main stream://convert-to-mp4
|
||||
* renderer → main stream://video?op=convert-to-mp4
|
||||
* → request.body is the original video
|
||||
* ← response is a token
|
||||
* ← response is [token]
|
||||
*
|
||||
* renderer → main stream://convert-to-mp4?token=<token>
|
||||
* renderer → main stream://video?token=<token>
|
||||
* ← response.body is the converted video
|
||||
*
|
||||
* renderer → main stream://convert-to-mp4?token=<token>&done
|
||||
* renderer → main stream://video?token=<token>&done
|
||||
* ← 200 OK
|
||||
*
|
||||
* Note that the conversion itself is not streaming. The conversion still
|
||||
* happens in a single shot, we are just streaming the data across the IPC
|
||||
* boundary to allow us to pass large amounts of data without running out of
|
||||
* memory.
|
||||
* happens in a single invocation of ffmpeg, we are just streaming the data
|
||||
* across the IPC boundary to allow us to pass large amounts of data without
|
||||
* running out of memory.
|
||||
*
|
||||
* See also: [Note: IPC streams]
|
||||
*/
|
||||
const handleConvertToMP4Write = async (request: Request) => {
|
||||
const worker = await ffmpegUtilityProcess();
|
||||
|
||||
const inputTempFilePath = await makeTempFilePath();
|
||||
await writeStream(inputTempFilePath, ensure(request.body));
|
||||
await writeStream(inputTempFilePath, request.body!);
|
||||
|
||||
const outputTempFilePath = await makeTempFilePath("mp4");
|
||||
try {
|
||||
await ffmpegConvertToMP4(inputTempFilePath, outputTempFilePath);
|
||||
await worker.ffmpegConvertToMP4(inputTempFilePath, outputTempFilePath);
|
||||
} catch (e) {
|
||||
log.error("Conversion to MP4 failed", e);
|
||||
await deleteTempFileIgnoringErrors(outputTempFilePath);
|
||||
@@ -228,25 +246,112 @@ const handleConvertToMP4Write = async (request: Request) => {
|
||||
}
|
||||
|
||||
const token = randomUUID();
|
||||
convertToMP4Results.set(token, outputTempFilePath);
|
||||
pendingVideoResults.set(token, outputTempFilePath);
|
||||
return new Response(token, { status: 200 });
|
||||
};
|
||||
|
||||
const handleConvertToMP4Read = async (token: string) => {
|
||||
const filePath = convertToMP4Results.get(token);
|
||||
const handleVideoRead = async (token: string) => {
|
||||
const filePath = pendingVideoResults.get(token);
|
||||
if (!filePath)
|
||||
return new Response(`Unknown token ${token}`, { status: 404 });
|
||||
|
||||
return net.fetch(pathToFileURL(filePath).toString());
|
||||
};
|
||||
|
||||
const handleConvertToMP4ReadDone = async (token: string) => {
|
||||
const filePath = convertToMP4Results.get(token);
|
||||
const handleVideoDone = async (token: string) => {
|
||||
const filePath = pendingVideoResults.get(token);
|
||||
if (!filePath)
|
||||
return new Response(`Unknown token ${token}`, { status: 404 });
|
||||
|
||||
await deleteTempFile(filePath);
|
||||
|
||||
convertToMP4Results.delete(token);
|
||||
pendingVideoResults.delete(token);
|
||||
return new Response("", { status: 200 });
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a HLS playlist for the given video.
|
||||
*
|
||||
* See: [Note: Convert to MP4] for the general architecture of commands that do
|
||||
* renderer <-> main I/O using streams.
|
||||
*
|
||||
* The difference here is that we the conversion generates two streams^ - one
|
||||
* for the HLS playlist itself, and one for the file containing the encrypted
|
||||
* and transcoded video chunks. The video stream we write to the pre-signed
|
||||
* object upload URL(s), and then we return a JSON object containing the token
|
||||
* for the playlist, and other metadata for use by the renderer.
|
||||
*
|
||||
* ^ if the video doesn't require a stream to be generated (e.g. it is very
|
||||
* small and already uses a compatible codec) then a HTT 204 is returned and
|
||||
* no stream is generated.
|
||||
*/
|
||||
const handleGenerateHLSWrite = async (
|
||||
request: Request,
|
||||
params: URLSearchParams,
|
||||
) => {
|
||||
const fileID = parseInt(params.get("fileID") ?? "", 10);
|
||||
const fetchURL = params.get("fetchURL");
|
||||
const authToken = params.get("authToken");
|
||||
if (!fileID || !fetchURL || !authToken) throw new Error("Missing params");
|
||||
|
||||
let inputItem: Parameters<typeof makeFileForStreamOrPathOrZipItem>[0];
|
||||
const path = params.get("path");
|
||||
if (path) {
|
||||
inputItem = path;
|
||||
} else {
|
||||
const zipPath = params.get("zipPath");
|
||||
const entryName = params.get("entryName");
|
||||
if (zipPath && entryName) {
|
||||
inputItem = [zipPath, entryName];
|
||||
} else {
|
||||
const body = request.body;
|
||||
if (!body) throw new Error("Missing body");
|
||||
inputItem = body;
|
||||
}
|
||||
}
|
||||
|
||||
const worker = await ffmpegUtilityProcess();
|
||||
|
||||
const {
|
||||
path: inputFilePath,
|
||||
isFileTemporary: isInputFileTemporary,
|
||||
writeToTemporaryFile: writeToTemporaryInputFile,
|
||||
} = await makeFileForStreamOrPathOrZipItem(inputItem);
|
||||
|
||||
const outputFilePathPrefix = await makeTempFilePath();
|
||||
let result: FFmpegGenerateHLSPlaylistAndSegmentsResult | undefined;
|
||||
try {
|
||||
await writeToTemporaryInputFile();
|
||||
|
||||
result = await worker.ffmpegGenerateHLSPlaylistAndSegments(
|
||||
inputFilePath,
|
||||
outputFilePathPrefix,
|
||||
fileID,
|
||||
fetchURL,
|
||||
authToken,
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
// This video doesn't require stream generation.
|
||||
return new Response(null, { status: 204 });
|
||||
}
|
||||
|
||||
const { playlistPath, dimensions, videoSize, videoObjectID } = result;
|
||||
|
||||
const playlistToken = randomUUID();
|
||||
pendingVideoResults.set(playlistToken, playlistPath);
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
playlistToken,
|
||||
dimensions,
|
||||
videoSize,
|
||||
videoObjectID,
|
||||
}),
|
||||
{ status: 200 },
|
||||
);
|
||||
} finally {
|
||||
if (isInputFileTemporary)
|
||||
await deleteTempFileIgnoringErrors(inputFilePath);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export const messagePortMainEndpoint = (mp: MessagePortMain): Endpoint => {
|
||||
const listeners = new WeakMap<NL, EL>();
|
||||
return {
|
||||
postMessage: (message, transfer) => {
|
||||
mp.postMessage(message, transfer as unknown as MessagePortMain[]);
|
||||
mp.postMessage(message, (transfer ?? []) as MessagePortMain[]);
|
||||
},
|
||||
addEventListener: (_, eh) => {
|
||||
const l: EL = (data) =>
|
||||
|
||||
@@ -5,20 +5,21 @@
|
||||
* currently a common package that both of them share.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Throw an exception if the given value is `null` or `undefined`.
|
||||
*/
|
||||
export const ensure = <T>(v: T | null | undefined): T => {
|
||||
if (v === null) throw new Error("Required value was null");
|
||||
if (v === undefined) throw new Error("Required value was not found");
|
||||
return v;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wait for {@link ms} milliseconds
|
||||
*
|
||||
* This function is a promisified `setTimeout`. It returns a promise that
|
||||
* resolves after {@link ms} milliseconds.
|
||||
*
|
||||
* Duplicated from `web/packages/utils/promise.ts`.
|
||||
*/
|
||||
export const wait = (ms: number) =>
|
||||
new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
/**
|
||||
* Convert `null` to `undefined`, passthrough everything else unchanged.
|
||||
*
|
||||
* Duplicated from `web/packages/utils/transform.ts`.
|
||||
*/
|
||||
export const nullToUndefined = <T>(v: T | null | undefined): T | undefined =>
|
||||
v === null ? undefined : v;
|
||||
|
||||
23
desktop/src/main/utils/exec-worker.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import shellescape from "any-shell-escape";
|
||||
import { exec } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import log from "../log-worker";
|
||||
|
||||
/**
|
||||
* Run a shell command asynchronously (utility process edition).
|
||||
*
|
||||
* This is an almost verbatim copy of {@link execAsync} from `electron.ts`,
|
||||
* except it is meant to be usable from a utility process where only a subset of
|
||||
* imports are available. See [Note: Using Electron APIs in UtilityProcess].
|
||||
*/
|
||||
export const execAsyncWorker = async (command: string | string[]) => {
|
||||
const escapedCommand = Array.isArray(command)
|
||||
? shellescape(command)
|
||||
: command;
|
||||
const startTime = Date.now();
|
||||
const result = await execAsync_(escapedCommand);
|
||||
log.debugString(`${escapedCommand} (${Date.now() - startTime} ms)`);
|
||||
return result;
|
||||
};
|
||||
|
||||
const execAsync_ = promisify(exec);
|
||||
31
desktop/src/main/utils/http.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
export const clientPackageName = "io.ente.photos.desktop";
|
||||
|
||||
/**
|
||||
* Reimplementation of {@link publicRequestHeaders} from the web source.
|
||||
*
|
||||
* @param desktopAppVersion The desktop app's version. This will get passed on
|
||||
* as the "X-Client-Version" header.
|
||||
*
|
||||
* We cannot directly use `app.getVersion()` to obtain this value since the
|
||||
* {@link app} module is not accessible to Electron utility processes which also
|
||||
* calls this function.
|
||||
*/
|
||||
export const publicRequestHeaders = (desktopAppVersion: string) => ({
|
||||
"X-Client-Package": clientPackageName,
|
||||
"X-Client-Version": desktopAppVersion,
|
||||
});
|
||||
|
||||
/**
|
||||
* Reimplementation of {@link authenticatedRequestHeaders} from the web source.
|
||||
*
|
||||
* This builds on top of {@link publicRequestHeaders} and takes the same
|
||||
* parameters, and additionally also requires the {@link authToken} that will be
|
||||
* passed as the "X-Auth-Token" header.
|
||||
*/
|
||||
export const authenticatedRequestHeaders = (
|
||||
desktopAppVersion: string,
|
||||
authToken: string,
|
||||
) => ({
|
||||
...publicRequestHeaders(desktopAppVersion),
|
||||
"X-Auth-Token": authToken,
|
||||
});
|
||||
@@ -5,7 +5,7 @@ import path from "node:path";
|
||||
import type { ZipItem } from "../../types/ipc";
|
||||
import log from "../log";
|
||||
import { markClosableZip, openZip } from "../services/zip";
|
||||
import { ensure } from "./common";
|
||||
import { writeStream } from "./stream";
|
||||
|
||||
/**
|
||||
* Our very own directory within the system temp directory. Go crazy, but
|
||||
@@ -20,17 +20,21 @@ const enteTempDirPath = async () => {
|
||||
/** Generate a random string suitable for being used as a file name prefix */
|
||||
const randomPrefix = () => {
|
||||
const ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
const randomChar = () => ensure(ch[Math.floor(Math.random() * ch.length)]);
|
||||
const randomChar = () => ch[Math.floor(Math.random() * ch.length)]!;
|
||||
|
||||
return Array(10).fill("").map(randomChar).join("");
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the path to a temporary file with the given {@link suffix}.
|
||||
* Return the path to a temporary file with an optional {@link extension}.
|
||||
*
|
||||
* The function returns the path to a file in the system temp directory (in an
|
||||
* Ente specific folder therin) with a random prefix and an (optional)
|
||||
* {@link extension}.
|
||||
* {@link extension}. The parent directory is guaranteed to exist.
|
||||
*
|
||||
* @param extension A string, if provided, is used as the extension for the
|
||||
* generated path. It will be automatically prefixed by a dot, so don't include
|
||||
* the dot in the provided string.
|
||||
*
|
||||
* It ensures that there is no existing item with the same name already.
|
||||
*
|
||||
@@ -76,8 +80,8 @@ export const deleteTempFileIgnoringErrors = async (tempFilePath: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
/** The result of {@link makeFileForDataOrPathOrZipItem}. */
|
||||
interface FileForDataOrPathOrZipItem {
|
||||
/** The result of {@link makeFileForStreamOrPathOrZipItem}. */
|
||||
interface FileForStreamOrPathOrZipItem {
|
||||
/**
|
||||
* The path to the file (possibly temporary).
|
||||
*/
|
||||
@@ -101,33 +105,32 @@ interface FileForDataOrPathOrZipItem {
|
||||
/**
|
||||
* Return the path to a file, a boolean indicating if this is a temporary path
|
||||
* that needs to be deleted after processing, and a function to write the given
|
||||
* {@link dataOrPathOrZipItem} into that temporary file if needed.
|
||||
* {@link item} into that temporary file if needed.
|
||||
*
|
||||
* @param dataOrPathOrZipItem The contents of the file, or the path to an
|
||||
* existing file, or a (path to a zip file, name of an entry within that zip
|
||||
* file) tuple.
|
||||
* @param item A {@link ReadableStream} with the contents of the file, or the
|
||||
* path to an existing file, or a (path to a zip file, name of an entry within
|
||||
* that zip file) tuple.
|
||||
*/
|
||||
export const makeFileForDataOrPathOrZipItem = async (
|
||||
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
|
||||
): Promise<FileForDataOrPathOrZipItem> => {
|
||||
export const makeFileForStreamOrPathOrZipItem = async (
|
||||
item: ReadableStream | string | ZipItem,
|
||||
): Promise<FileForStreamOrPathOrZipItem> => {
|
||||
let path: string;
|
||||
let isFileTemporary: boolean;
|
||||
let writeToTemporaryFile = async () => {
|
||||
/* no-op */
|
||||
};
|
||||
|
||||
if (typeof dataOrPathOrZipItem == "string") {
|
||||
path = dataOrPathOrZipItem;
|
||||
if (typeof item == "string") {
|
||||
path = item;
|
||||
isFileTemporary = false;
|
||||
} else {
|
||||
path = await makeTempFilePath();
|
||||
isFileTemporary = true;
|
||||
if (dataOrPathOrZipItem instanceof Uint8Array) {
|
||||
writeToTemporaryFile = () =>
|
||||
fs.writeFile(path, dataOrPathOrZipItem);
|
||||
if (item instanceof ReadableStream) {
|
||||
writeToTemporaryFile = () => writeStream(path, item);
|
||||
} else {
|
||||
writeToTemporaryFile = async () => {
|
||||
const [zipPath, entryName] = dataOrPathOrZipItem;
|
||||
const [zipPath, entryName] = item;
|
||||
const zip = openZip(zipPath);
|
||||
try {
|
||||
await zip.extract(entryName, path);
|
||||
|
||||
@@ -66,8 +66,10 @@ import type { IpcRendererEvent } from "electron";
|
||||
import type {
|
||||
AppUpdate,
|
||||
CollectionMapping,
|
||||
FFmpegCommand,
|
||||
FolderWatch,
|
||||
PendingUploads,
|
||||
UtilityProcessType,
|
||||
ZipItem,
|
||||
} from "./types/ipc";
|
||||
|
||||
@@ -183,47 +185,53 @@ const fsWriteFileViaBackup = (path: string, contents: string) =>
|
||||
|
||||
const fsIsDir = (dirPath: string) => ipcRenderer.invoke("fsIsDir", dirPath);
|
||||
|
||||
const fsStatMtime = (path: string) => ipcRenderer.invoke("fsStatMtime", path);
|
||||
|
||||
// - Conversion
|
||||
|
||||
const convertToJPEG = (imageData: Uint8Array) =>
|
||||
ipcRenderer.invoke("convertToJPEG", imageData);
|
||||
|
||||
const generateImageThumbnail = (
|
||||
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
|
||||
pathOrZipItem: string | ZipItem,
|
||||
maxDimension: number,
|
||||
maxSize: number,
|
||||
) =>
|
||||
ipcRenderer.invoke(
|
||||
"generateImageThumbnail",
|
||||
dataOrPathOrZipItem,
|
||||
pathOrZipItem,
|
||||
maxDimension,
|
||||
maxSize,
|
||||
);
|
||||
|
||||
const ffmpegExec = (
|
||||
command: string[],
|
||||
dataOrPathOrZipItem: Uint8Array | string | ZipItem,
|
||||
command: FFmpegCommand,
|
||||
pathOrZipItem: string | ZipItem,
|
||||
outputFileExtension: string,
|
||||
) =>
|
||||
ipcRenderer.invoke(
|
||||
"ffmpegExec",
|
||||
command,
|
||||
dataOrPathOrZipItem,
|
||||
pathOrZipItem,
|
||||
outputFileExtension,
|
||||
);
|
||||
|
||||
// - ML
|
||||
const ffmpegDetermineVideoDuration = (pathOrZipItem: string | ZipItem) =>
|
||||
ipcRenderer.invoke("ffmpegDetermineVideoDuration", pathOrZipItem);
|
||||
|
||||
const createMLWorker = () => {
|
||||
// - Utility processes
|
||||
|
||||
const triggerCreateUtilityProcess = (type: UtilityProcessType) => {
|
||||
const portEvent = `utilityProcessPort/${type}`;
|
||||
const l = (event: IpcRendererEvent) => {
|
||||
void windowLoaded.then(() => {
|
||||
// "*"" is the origin to send to.
|
||||
window.postMessage("createMLWorker/port", "*", event.ports);
|
||||
ipcRenderer.off("createMLWorker/port", l);
|
||||
window.postMessage(portEvent, "*", event.ports);
|
||||
ipcRenderer.off(portEvent, l);
|
||||
});
|
||||
};
|
||||
ipcRenderer.on("createMLWorker/port", l);
|
||||
ipcRenderer.send("createMLWorker");
|
||||
ipcRenderer.on(portEvent, l);
|
||||
ipcRenderer.send("triggerCreateUtilityProcess", type);
|
||||
};
|
||||
|
||||
// - Watch
|
||||
@@ -289,11 +297,11 @@ const pendingUploads = () => ipcRenderer.invoke("pendingUploads");
|
||||
const setPendingUploads = (pendingUploads: PendingUploads) =>
|
||||
ipcRenderer.invoke("setPendingUploads", pendingUploads);
|
||||
|
||||
const markUploadedFiles = (paths: PendingUploads["filePaths"]) =>
|
||||
ipcRenderer.invoke("markUploadedFiles", paths);
|
||||
const markUploadedFile = (path: string, associatedPath?: string) =>
|
||||
ipcRenderer.invoke("markUploadedFile", path, associatedPath);
|
||||
|
||||
const markUploadedZipItems = (items: PendingUploads["zipItems"]) =>
|
||||
ipcRenderer.invoke("markUploadedZipItems", items);
|
||||
const markUploadedZipItem = (item: ZipItem, associatedItem?: ZipItem) =>
|
||||
ipcRenderer.invoke("markUploadedZipItem", item, associatedItem);
|
||||
|
||||
const clearPendingUploads = () => ipcRenderer.invoke("clearPendingUploads");
|
||||
|
||||
@@ -378,6 +386,7 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
writeFile: fsWriteFile,
|
||||
writeFileViaBackup: fsWriteFileViaBackup,
|
||||
isDir: fsIsDir,
|
||||
statMtime: fsStatMtime,
|
||||
findFiles: fsFindFiles,
|
||||
},
|
||||
|
||||
@@ -386,10 +395,11 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
convertToJPEG,
|
||||
generateImageThumbnail,
|
||||
ffmpegExec,
|
||||
ffmpegDetermineVideoDuration,
|
||||
|
||||
// - ML
|
||||
|
||||
createMLWorker,
|
||||
triggerCreateUtilityProcess,
|
||||
|
||||
// - Watch
|
||||
|
||||
@@ -410,7 +420,7 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
pathOrZipItemSize,
|
||||
pendingUploads,
|
||||
setPendingUploads,
|
||||
markUploadedFiles,
|
||||
markUploadedZipItems,
|
||||
markUploadedFile,
|
||||
markUploadedZipItem,
|
||||
clearPendingUploads,
|
||||
});
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* See [Note: types.ts <-> preload.ts <-> ipc.ts]
|
||||
*/
|
||||
|
||||
export type UtilityProcessType = "ml";
|
||||
|
||||
export interface AppUpdate {
|
||||
autoUpdatable: boolean;
|
||||
version: string;
|
||||
@@ -32,3 +34,5 @@ export interface PendingUploads {
|
||||
filePaths: string[];
|
||||
zipItems: ZipItem[];
|
||||
}
|
||||
|
||||
export type FFmpegCommand = string[] | { default: string[]; hdr: string[] };
|
||||
|
||||
@@ -25,7 +25,16 @@
|
||||
ajv "^6.12.0"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
"@electron/asar@3.2.18", "@electron/asar@^3.2.7":
|
||||
"@electron/asar@3.4.1":
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.4.1.tgz#4e9196a4b54fba18c56cd8d5cac67c5bdc588065"
|
||||
integrity sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==
|
||||
dependencies:
|
||||
commander "^5.0.0"
|
||||
glob "^7.1.6"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
"@electron/asar@^3.2.7":
|
||||
version "3.2.18"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.18.tgz#fa607f829209bab8b9e0ce6658d3fe81b2cba517"
|
||||
integrity sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==
|
||||
@@ -94,10 +103,10 @@
|
||||
minimist "^1.2.6"
|
||||
plist "^3.0.5"
|
||||
|
||||
"@electron/rebuild@3.7.0":
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@electron/rebuild/-/rebuild-3.7.0.tgz#82e20c467ddedbb295d7f641592c52e68c141e9f"
|
||||
integrity sha512-VW++CNSlZwMYP7MyXEbrKjpzEwhB5kDNbzGtiPEjwYysqyTCF+YbNJ210Dj3AjWsGSV4iEEwNkmJN9yGZmVvmw==
|
||||
"@electron/rebuild@3.7.2":
|
||||
version "3.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@electron/rebuild/-/rebuild-3.7.2.tgz#8d808b29159c50086d27a5dec72b40bf16b4b582"
|
||||
integrity sha512-19/KbIR/DAxbsCkiaGMXIdPnMCJLkcf8AvGnduJtWBs/CBwiAjY1apCqOLVxrXg+rtXFCngbXhBanWjxLUt1Mg==
|
||||
dependencies:
|
||||
"@electron/node-gyp" "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2"
|
||||
"@malept/cross-spawn-promise" "^2.0.0"
|
||||
@@ -127,13 +136,20 @@
|
||||
minimatch "^9.0.3"
|
||||
plist "^3.1.0"
|
||||
|
||||
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
|
||||
"@eslint-community/eslint-utils@^4.2.0":
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
|
||||
integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@eslint-community/eslint-utils@^4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a"
|
||||
integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^3.4.3"
|
||||
|
||||
"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.11.0":
|
||||
version "4.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae"
|
||||
@@ -168,10 +184,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.9.1.tgz#4a97e85e982099d6c7ee8410aacb55adaa576f06"
|
||||
integrity sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==
|
||||
|
||||
"@eslint/js@^9.24.0":
|
||||
version "9.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.24.0.tgz#685277980bb7bf84ecc8e4e133ccdda7545a691e"
|
||||
integrity sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==
|
||||
"@eslint/js@^9.27.0":
|
||||
version "9.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.27.0.tgz#181a23460877c484f6dd03890f4e3fa2fdeb8ff0"
|
||||
integrity sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==
|
||||
|
||||
"@eslint/object-schema@^2.1.4":
|
||||
version "2.1.4"
|
||||
@@ -259,10 +275,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
|
||||
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
|
||||
|
||||
"@pkgr/core@^0.1.0":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31"
|
||||
integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==
|
||||
"@pkgr/core@^0.2.4":
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.4.tgz#d897170a2b0ba51f78a099edccd968f7b103387c"
|
||||
integrity sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==
|
||||
|
||||
"@sindresorhus/is@^4.0.0":
|
||||
version "4.6.0"
|
||||
@@ -281,10 +297,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
|
||||
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
|
||||
|
||||
"@tsconfig/node22@^22.0.1":
|
||||
version "22.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node22/-/node22-22.0.1.tgz#27e3ee9b359e31e5b94690bf2bad5a923c1d57d0"
|
||||
integrity sha512-VkgOa3n6jvs1p+r3DiwBqeEwGAwEvnVCg/hIjiANl5IEcqP3G0u5m8cBJspe1t9qjZRlZ7WFgqq5bJrGdgAKMg==
|
||||
"@tsconfig/node22@^22.0.2":
|
||||
version "22.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node22/-/node22-22.0.2.tgz#1e04e2c5cc946dac787d69bb502462a851ae51b6"
|
||||
integrity sha512-Kmwj4u8sDRDrMYRoN9FDEcXD8UpBSaPQQ24Gz+Gamqfm7xxn+GBR7ge/Z7pK8OXNGyUzbSwJj+TH6B+DS/epyA==
|
||||
|
||||
"@types/auto-launch@^5.0.5":
|
||||
version "5.0.5"
|
||||
@@ -376,85 +392,85 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@8.29.1":
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz#593639d9bb5239b2d877d65757b7e2c9100a2e84"
|
||||
integrity sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==
|
||||
"@typescript-eslint/eslint-plugin@8.32.1":
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz#9185b3eaa3b083d8318910e12d56c68b3c4f45b4"
|
||||
integrity sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==
|
||||
dependencies:
|
||||
"@eslint-community/regexpp" "^4.10.0"
|
||||
"@typescript-eslint/scope-manager" "8.29.1"
|
||||
"@typescript-eslint/type-utils" "8.29.1"
|
||||
"@typescript-eslint/utils" "8.29.1"
|
||||
"@typescript-eslint/visitor-keys" "8.29.1"
|
||||
"@typescript-eslint/scope-manager" "8.32.1"
|
||||
"@typescript-eslint/type-utils" "8.32.1"
|
||||
"@typescript-eslint/utils" "8.32.1"
|
||||
"@typescript-eslint/visitor-keys" "8.32.1"
|
||||
graphemer "^1.4.0"
|
||||
ignore "^5.3.1"
|
||||
ignore "^7.0.0"
|
||||
natural-compare "^1.4.0"
|
||||
ts-api-utils "^2.0.1"
|
||||
ts-api-utils "^2.1.0"
|
||||
|
||||
"@typescript-eslint/parser@8.29.1":
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.29.1.tgz#10bf37411be0a199c27b6515726e22fe8d3df8d0"
|
||||
integrity sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==
|
||||
"@typescript-eslint/parser@8.32.1":
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.32.1.tgz#18b0e53315e0bc22b2619d398ae49a968370935e"
|
||||
integrity sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "8.29.1"
|
||||
"@typescript-eslint/types" "8.29.1"
|
||||
"@typescript-eslint/typescript-estree" "8.29.1"
|
||||
"@typescript-eslint/visitor-keys" "8.29.1"
|
||||
"@typescript-eslint/scope-manager" "8.32.1"
|
||||
"@typescript-eslint/types" "8.32.1"
|
||||
"@typescript-eslint/typescript-estree" "8.32.1"
|
||||
"@typescript-eslint/visitor-keys" "8.32.1"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@8.29.1":
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz#cfdfd4144f20c38b9d3e430efd6480e297ef52f6"
|
||||
integrity sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==
|
||||
"@typescript-eslint/scope-manager@8.32.1":
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz#9a6bf5fb2c5380e14fe9d38ccac6e4bbe17e8afc"
|
||||
integrity sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.29.1"
|
||||
"@typescript-eslint/visitor-keys" "8.29.1"
|
||||
"@typescript-eslint/types" "8.32.1"
|
||||
"@typescript-eslint/visitor-keys" "8.32.1"
|
||||
|
||||
"@typescript-eslint/type-utils@8.29.1":
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.29.1.tgz#653dfff5c1711bc920a6a46a5a2c274899f00179"
|
||||
integrity sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==
|
||||
"@typescript-eslint/type-utils@8.32.1":
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz#b9292a45f69ecdb7db74d1696e57d1a89514d21e"
|
||||
integrity sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree" "8.29.1"
|
||||
"@typescript-eslint/utils" "8.29.1"
|
||||
"@typescript-eslint/typescript-estree" "8.32.1"
|
||||
"@typescript-eslint/utils" "8.32.1"
|
||||
debug "^4.3.4"
|
||||
ts-api-utils "^2.0.1"
|
||||
ts-api-utils "^2.1.0"
|
||||
|
||||
"@typescript-eslint/types@8.29.1":
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.29.1.tgz#984ed1283fedbfb41d3993a9abdcb7b299971500"
|
||||
integrity sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==
|
||||
"@typescript-eslint/types@8.32.1":
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.32.1.tgz#b19fe4ac0dc08317bae0ce9ec1168123576c1d4b"
|
||||
integrity sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@8.29.1":
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz#4ac085665ed5390d11c0e3426427978570e3b747"
|
||||
integrity sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==
|
||||
"@typescript-eslint/typescript-estree@8.32.1":
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz#9023720ca4ecf4f59c275a05b5fed69b1276face"
|
||||
integrity sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.29.1"
|
||||
"@typescript-eslint/visitor-keys" "8.29.1"
|
||||
"@typescript-eslint/types" "8.32.1"
|
||||
"@typescript-eslint/visitor-keys" "8.32.1"
|
||||
debug "^4.3.4"
|
||||
fast-glob "^3.3.2"
|
||||
is-glob "^4.0.3"
|
||||
minimatch "^9.0.4"
|
||||
semver "^7.6.0"
|
||||
ts-api-utils "^2.0.1"
|
||||
ts-api-utils "^2.1.0"
|
||||
|
||||
"@typescript-eslint/utils@8.29.1":
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.29.1.tgz#3d206c8c8def3527a8eb0588e94e3e60f7e167c9"
|
||||
integrity sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==
|
||||
"@typescript-eslint/utils@8.32.1":
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.32.1.tgz#4d6d5d29b9e519e9a85e9a74e9f7bdb58abe9704"
|
||||
integrity sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.4.0"
|
||||
"@typescript-eslint/scope-manager" "8.29.1"
|
||||
"@typescript-eslint/types" "8.29.1"
|
||||
"@typescript-eslint/typescript-estree" "8.29.1"
|
||||
"@eslint-community/eslint-utils" "^4.7.0"
|
||||
"@typescript-eslint/scope-manager" "8.32.1"
|
||||
"@typescript-eslint/types" "8.32.1"
|
||||
"@typescript-eslint/typescript-estree" "8.32.1"
|
||||
|
||||
"@typescript-eslint/visitor-keys@8.29.1":
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz#9b74e5098c71138d42bbf2178fbe4dfad45d6b9a"
|
||||
integrity sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==
|
||||
"@typescript-eslint/visitor-keys@8.32.1":
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz#4321395cc55c2eb46036cbbb03e101994d11ddca"
|
||||
integrity sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.29.1"
|
||||
"@typescript-eslint/types" "8.32.1"
|
||||
eslint-visitor-keys "^4.2.0"
|
||||
|
||||
"@xmldom/xmldom@^0.8.8":
|
||||
@@ -560,30 +576,30 @@ app-builder-bin@5.0.0-alpha.12:
|
||||
resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz#2daf82f8badc698e0adcc95ba36af4ff0650dc80"
|
||||
integrity sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==
|
||||
|
||||
app-builder-lib@26.0.12:
|
||||
version "26.0.12"
|
||||
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.12.tgz#2e33df936e0f78d4266b058ece90308ea981eefb"
|
||||
integrity sha512-+/CEPH1fVKf6HowBUs6LcAIoRcjeqgvAeoSE+cl7Y7LndyQ9ViGPYibNk7wmhMHzNgHIuIbw4nWADPO+4mjgWw==
|
||||
app-builder-lib@26.0.14:
|
||||
version "26.0.14"
|
||||
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.14.tgz#a28fbefb600cf052d1259932f32289e043573f61"
|
||||
integrity sha512-nc/A9MUd95MCc7bR4yVW7Lhs9FZTA/l8QdV8PE1vZZOOiogK4dupBfCCJG0UqLU81JS62f078/bwAeuMjt3hfQ==
|
||||
dependencies:
|
||||
"@develar/schema-utils" "~2.6.5"
|
||||
"@electron/asar" "3.2.18"
|
||||
"@electron/asar" "3.4.1"
|
||||
"@electron/fuses" "^1.8.0"
|
||||
"@electron/notarize" "2.5.0"
|
||||
"@electron/osx-sign" "1.3.1"
|
||||
"@electron/rebuild" "3.7.0"
|
||||
"@electron/rebuild" "3.7.2"
|
||||
"@electron/universal" "2.0.1"
|
||||
"@malept/flatpak-bundler" "^0.4.0"
|
||||
"@types/fs-extra" "9.0.13"
|
||||
async-exit-hook "^2.0.1"
|
||||
builder-util "26.0.11"
|
||||
builder-util-runtime "9.3.1"
|
||||
builder-util "26.0.13"
|
||||
builder-util-runtime "9.3.2"
|
||||
chromium-pickle-js "^0.2.0"
|
||||
config-file-ts "0.2.8-rc1"
|
||||
debug "^4.3.4"
|
||||
dotenv "^16.4.5"
|
||||
dotenv-expand "^11.0.6"
|
||||
ejs "^3.1.8"
|
||||
electron-publish "26.0.11"
|
||||
electron-publish "26.0.13"
|
||||
fs-extra "^10.1.0"
|
||||
hosted-git-info "^4.1.0"
|
||||
is-ci "^3.0.0"
|
||||
@@ -719,23 +735,23 @@ buffer@^5.1.0, buffer@^5.5.0:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.1.13"
|
||||
|
||||
builder-util-runtime@9.3.1:
|
||||
version "9.3.1"
|
||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.3.1.tgz#0daedde0f6d381f2a00a50a407b166fe7dca1a67"
|
||||
integrity sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ==
|
||||
builder-util-runtime@9.3.2:
|
||||
version "9.3.2"
|
||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.3.2.tgz#2a69a239b50e26accf4ed4ea1730406a3117213c"
|
||||
integrity sha512-7QDXJ1FwT6d9ZhG4kuObUUPY8/ENBS/Ky26O4hR5vbeoRGavgekS2Jxv+8sCn/v23aPGU2DXRWEeJuijN2ooYA==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
sax "^1.2.4"
|
||||
|
||||
builder-util@26.0.11:
|
||||
version "26.0.11"
|
||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.11.tgz#ad85b92c93f2b976b973e1d87337e0c6813fcb8f"
|
||||
integrity sha512-xNjXfsldUEe153h1DraD0XvDOpqGR0L5eKFkdReB7eFW5HqysDZFfly4rckda6y9dF39N3pkPlOblcfHKGw+uA==
|
||||
builder-util@26.0.13:
|
||||
version "26.0.13"
|
||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.13.tgz#a2c11f8e89e5392719e540d610d70d8413943d74"
|
||||
integrity sha512-6b64uHzywaL2KAG+rVcqk/Prta1m3I2Jo1d4d2CrApb6EeSk2V384tmSL0EniH+P8jaNbMp6qhg7cIALw32zRA==
|
||||
dependencies:
|
||||
"7zip-bin" "~5.2.0"
|
||||
"@types/debug" "^4.1.6"
|
||||
app-builder-bin "5.0.0-alpha.12"
|
||||
builder-util-runtime "9.3.1"
|
||||
builder-util-runtime "9.3.2"
|
||||
chalk "^4.1.2"
|
||||
cross-spawn "^7.0.6"
|
||||
debug "^4.3.4"
|
||||
@@ -998,6 +1014,17 @@ cross-env@^7.0.3:
|
||||
dependencies:
|
||||
cross-spawn "^7.0.1"
|
||||
|
||||
cross-spawn@^6.0.0:
|
||||
version "6.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57"
|
||||
integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==
|
||||
dependencies:
|
||||
nice-try "^1.0.4"
|
||||
path-key "^2.0.1"
|
||||
semver "^5.5.0"
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.6:
|
||||
version "7.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
|
||||
@@ -1078,7 +1105,7 @@ detect-libc@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
|
||||
integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==
|
||||
|
||||
detect-newline@^4.0.0:
|
||||
detect-newline@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-4.0.1.tgz#fcefdb5713e1fb8cb2839b8b6ee22e6716ab8f23"
|
||||
integrity sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==
|
||||
@@ -1096,14 +1123,14 @@ dir-compare@^4.2.0:
|
||||
minimatch "^3.0.5"
|
||||
p-limit "^3.1.0 "
|
||||
|
||||
dmg-builder@26.0.12:
|
||||
version "26.0.12"
|
||||
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.12.tgz#6996ad0bab80a861c9a7b33ee9734d4f60566b46"
|
||||
integrity sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==
|
||||
dmg-builder@26.0.14:
|
||||
version "26.0.14"
|
||||
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.14.tgz#ce8180da319cf3ee05d42cd460a7509207ad474b"
|
||||
integrity sha512-0l7oEj175hee7NfnaUpb0zf7fsgh1SyHeLjDA0AtOMnBUfTGxPPwrifbUxfd73qzamrGNcyeqza+m/EJx3QUug==
|
||||
dependencies:
|
||||
app-builder-lib "26.0.12"
|
||||
builder-util "26.0.11"
|
||||
builder-util-runtime "9.3.1"
|
||||
app-builder-lib "26.0.14"
|
||||
builder-util "26.0.13"
|
||||
builder-util-runtime "9.3.2"
|
||||
fs-extra "^10.1.0"
|
||||
iconv-lite "^0.6.2"
|
||||
js-yaml "^4.1.0"
|
||||
@@ -1150,35 +1177,35 @@ ejs@^3.1.8:
|
||||
dependencies:
|
||||
jake "^10.8.5"
|
||||
|
||||
electron-builder@^26.0.12:
|
||||
version "26.0.12"
|
||||
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.12.tgz#797af2e70efdd96c9ea5d8a8164b8728c90d65ff"
|
||||
integrity sha512-cD1kz5g2sgPTMFHjLxfMjUK5JABq3//J4jPswi93tOPFz6btzXYtK5NrDt717NRbukCUDOrrvmYVOWERlqoiXA==
|
||||
electron-builder@^26.0.14:
|
||||
version "26.0.14"
|
||||
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.14.tgz#8927c6da42a69425d15e08f351e944ea0e7866da"
|
||||
integrity sha512-YBxpWLMGj0oS7fbS3LVingeZqFunU0F8s+uB9QTd5+wN4qgrf/rSGRkqoImbWg2+F2yHq11wmaA/Xr9xzvgQ0w==
|
||||
dependencies:
|
||||
app-builder-lib "26.0.12"
|
||||
builder-util "26.0.11"
|
||||
builder-util-runtime "9.3.1"
|
||||
app-builder-lib "26.0.14"
|
||||
builder-util "26.0.13"
|
||||
builder-util-runtime "9.3.2"
|
||||
chalk "^4.1.2"
|
||||
dmg-builder "26.0.12"
|
||||
dmg-builder "26.0.14"
|
||||
fs-extra "^10.1.0"
|
||||
is-ci "^3.0.0"
|
||||
lazy-val "^1.0.5"
|
||||
simple-update-notifier "2.0.0"
|
||||
yargs "^17.6.2"
|
||||
|
||||
electron-log@^5.3.3:
|
||||
version "5.3.3"
|
||||
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.3.3.tgz#323f5e70b3658d683a0f51f26867dc077a823aa3"
|
||||
integrity sha512-ZOnlgCVfhKC0Nef68L0wDhwhg8nh5QkpEOA+udjpBxcPfTHGgbZbfoCBS6hmAgVHTAWByHNPkHKpSbEOPGZcxA==
|
||||
electron-log@^5.4.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.4.0.tgz#3180bf5194b2e2efacb62ec1392f8150faf4de6b"
|
||||
integrity sha512-AXI5OVppskrWxEAmCxuv8ovX+s2Br39CpCAgkGMNHQtjYT3IiVbSQTncEjFVGPgoH35ZygRm/mvUMBDWwhRxgg==
|
||||
|
||||
electron-publish@26.0.11:
|
||||
version "26.0.11"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.11.tgz#92c9329a101af2836d9d228c82966eca1eee9a7b"
|
||||
integrity sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==
|
||||
electron-publish@26.0.13:
|
||||
version "26.0.13"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.13.tgz#04340520e6e9de5262fecfa011658cfcc3fc8917"
|
||||
integrity sha512-O5hfHSwli5cegQ4JS3Dp0dZcheex6UCRE/qYyRQvhB6DhSwojiwTnAGEuQCJXc8K8Zxz2lku5Du3VwYHf8d5Lw==
|
||||
dependencies:
|
||||
"@types/fs-extra" "^9.0.11"
|
||||
builder-util "26.0.11"
|
||||
builder-util-runtime "9.3.1"
|
||||
builder-util "26.0.13"
|
||||
builder-util-runtime "9.3.2"
|
||||
chalk "^4.1.2"
|
||||
form-data "^4.0.0"
|
||||
fs-extra "^10.1.0"
|
||||
@@ -1193,12 +1220,12 @@ electron-store@^8.2.0:
|
||||
conf "^10.2.0"
|
||||
type-fest "^2.17.0"
|
||||
|
||||
electron-updater@^6.6.2:
|
||||
version "6.6.2"
|
||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.6.2.tgz#3e65e044f1a99b00d61e200e24de8e709c69ce99"
|
||||
integrity sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==
|
||||
electron-updater@^6.6.3:
|
||||
version "6.6.3"
|
||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.6.3.tgz#a1f53671ffbb08a475d495d48f0c0d971e665d5d"
|
||||
integrity sha512-i448/SwMtqxy5wqAcXScnWjiFxZp+hmWA2jZCmojcdfodEGhi/DWTdRP01mE3lCILb8hmdE28SBaHf1oQW3+kw==
|
||||
dependencies:
|
||||
builder-util-runtime "9.3.1"
|
||||
builder-util-runtime "9.3.2"
|
||||
fs-extra "^10.1.0"
|
||||
js-yaml "^4.1.0"
|
||||
lazy-val "^1.0.5"
|
||||
@@ -1207,10 +1234,10 @@ electron-updater@^6.6.2:
|
||||
semver "^7.6.3"
|
||||
tiny-typed-emitter "^2.1.0"
|
||||
|
||||
electron@^35.1.4:
|
||||
version "35.1.4"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-35.1.4.tgz#53f51c3488e2c49828ce9453e60d60d14fb441d5"
|
||||
integrity sha512-8HjE2wqxY//T09Of8k1eTpK/NeTG2FkTyRD+fyKXmec4wZVscGgZcmWFC0HYN4ktyHAjtplpxdFXjtqRnvzBMg==
|
||||
electron@^36.3.1:
|
||||
version "36.3.1"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-36.3.1.tgz#12a8c1b1cd9163a4bd0cb60f89816243b26ab788"
|
||||
integrity sha512-LeOZ+tVahmctHaAssLCGRRUa2SAO09GXua3pKdG+WzkbSDMh+3iOPONNVPTqGp8HlWnzGj4r6mhsIbM2RgH+eQ==
|
||||
dependencies:
|
||||
"@electron/get" "^2.0.0"
|
||||
"@types/node" "^22.7.7"
|
||||
@@ -1280,7 +1307,7 @@ eslint-scope@^8.0.2:
|
||||
esrecurse "^4.3.0"
|
||||
estraverse "^5.2.0"
|
||||
|
||||
eslint-visitor-keys@^3.3.0:
|
||||
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.3:
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
|
||||
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
|
||||
@@ -1363,6 +1390,19 @@ esutils@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
execa@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
|
||||
integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
|
||||
dependencies:
|
||||
cross-spawn "^6.0.0"
|
||||
get-stream "^4.0.0"
|
||||
is-stream "^1.1.0"
|
||||
npm-run-path "^2.0.0"
|
||||
p-finally "^1.0.0"
|
||||
signal-exit "^3.0.0"
|
||||
strip-eof "^1.0.0"
|
||||
|
||||
exponential-backoff@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6"
|
||||
@@ -1429,10 +1469,10 @@ fd-slicer@~1.1.0:
|
||||
dependencies:
|
||||
pend "~1.2.0"
|
||||
|
||||
fdir@^6.4.2:
|
||||
version "6.4.2"
|
||||
resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.2.tgz#ddaa7ce1831b161bc3657bb99cb36e1622702689"
|
||||
integrity sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==
|
||||
fdir@^6.4.4:
|
||||
version "6.4.4"
|
||||
resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.4.tgz#1cfcf86f875a883e19a8fab53622cfe992e8d2f9"
|
||||
integrity sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==
|
||||
|
||||
ffmpeg-static@^5.2.0:
|
||||
version "5.2.0"
|
||||
@@ -1580,10 +1620,12 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
|
||||
has-symbols "^1.0.3"
|
||||
hasown "^2.0.0"
|
||||
|
||||
get-stdin@^9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575"
|
||||
integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==
|
||||
get-stream@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
|
||||
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
get-stream@^5.1.0:
|
||||
version "5.2.0"
|
||||
@@ -1592,10 +1634,10 @@ get-stream@^5.1.0:
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
git-hooks-list@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-3.1.0.tgz#386dc531dcc17474cf094743ff30987a3d3e70fc"
|
||||
integrity sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==
|
||||
git-hooks-list@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-4.1.1.tgz#ae340b82a9312354c73b48007f33840bbd83d3c0"
|
||||
integrity sha512-cmP497iLq54AZnv4YRAEMnEyQ1eIn4tGKbmswqwmFV4GBnAqE8NLtWxxdXa++AalfgL5EBH4IxTPyquEuGY/jA==
|
||||
|
||||
glob-parent@^5.1.2:
|
||||
version "5.1.2"
|
||||
@@ -1623,7 +1665,7 @@ glob@^10.3.12, glob@^10.3.7:
|
||||
package-json-from-dist "^1.0.0"
|
||||
path-scurry "^1.11.1"
|
||||
|
||||
glob@^7.0.0, glob@^7.1.3, glob@^7.1.6:
|
||||
glob@^7.1.3, glob@^7.1.6:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
|
||||
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
|
||||
@@ -1821,11 +1863,16 @@ ieee754@^1.1.13:
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
ignore@^5.2.0, ignore@^5.3.1:
|
||||
ignore@^5.2.0:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
|
||||
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
|
||||
|
||||
ignore@^7.0.0:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.4.tgz#a12c70d0f2607c5bf508fb65a40c75f037d7a078"
|
||||
integrity sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==
|
||||
|
||||
import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
@@ -1936,6 +1983,11 @@ is-plain-obj@^4.1.0:
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0"
|
||||
integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
|
||||
|
||||
is-unicode-supported@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
|
||||
@@ -2235,7 +2287,7 @@ minimatch@^9.0.3, minimatch@^9.0.4:
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
|
||||
minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
@@ -2354,6 +2406,11 @@ next-electron-server@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/next-electron-server/-/next-electron-server-1.0.0.tgz#03e133ed64a5ef671b6c6409f908c4901b1828cb"
|
||||
integrity sha512-fTUaHwT0Jry2fbdUSIkAiIqgDAInI5BJFF4/j90/okvZCYlyx6yxpXB30KpzmOG6TN/ESwyvsFJVvS2WHT8PAA==
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-abi@^3.45.0:
|
||||
version "3.67.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.67.0.tgz#1d159907f18d18e18809dbbb5df47ed2426a08df"
|
||||
@@ -2390,6 +2447,13 @@ normalize-url@^6.0.1:
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
|
||||
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
||||
|
||||
npm-run-path@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
|
||||
integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==
|
||||
dependencies:
|
||||
path-key "^2.0.0"
|
||||
|
||||
object-keys@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
||||
@@ -2454,6 +2518,11 @@ p-cancelable@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
|
||||
integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
|
||||
|
||||
p-finally@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
|
||||
integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
|
||||
|
||||
p-limit@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||
@@ -2526,6 +2595,11 @@ path-is-absolute@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
|
||||
|
||||
path-key@^2.0.0, path-key@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
||||
integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
|
||||
|
||||
path-key@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
@@ -2590,13 +2664,13 @@ prettier-plugin-organize-imports@^4.1.0:
|
||||
resolved "https://registry.yarnpkg.com/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz#f3d3764046a8e7ba6491431158b9be6ffd83b90f"
|
||||
integrity sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==
|
||||
|
||||
prettier-plugin-packagejson@^2.5.10:
|
||||
version "2.5.10"
|
||||
resolved "https://registry.yarnpkg.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.5.10.tgz#f47068d0aa12efcdddb802189d8adae874ba00e7"
|
||||
integrity sha512-LUxATI5YsImIVSaaLJlJ3aE6wTD+nvots18U3GuQMJpUyClChaZlQrqx3dBnbhF20OnKWZyx8EgyZypQtBDtgQ==
|
||||
prettier-plugin-packagejson@^2.5.14:
|
||||
version "2.5.14"
|
||||
resolved "https://registry.yarnpkg.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.5.14.tgz#8ada09114ff60c7f42c3f8755ffb2f8152f3624f"
|
||||
integrity sha512-h+3tSpr2nVpp+YOK1MDIYtYhHVXr8/0V59UUbJpIJFaqi3w4fvUokJo6eV8W+vELrUXIZzJ+DKm5G7lYzrMcKQ==
|
||||
dependencies:
|
||||
sort-package-json "2.15.1"
|
||||
synckit "0.9.2"
|
||||
sort-package-json "3.2.1"
|
||||
synckit "0.11.6"
|
||||
|
||||
prettier@3.5.3:
|
||||
version "3.5.3"
|
||||
@@ -2820,6 +2894,11 @@ semver@^7.3.2, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.6.0, semve
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
|
||||
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
|
||||
|
||||
semver@^7.7.1:
|
||||
version "7.7.2"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58"
|
||||
integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==
|
||||
|
||||
serialize-error@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
|
||||
@@ -2827,6 +2906,13 @@ serialize-error@^7.0.1:
|
||||
dependencies:
|
||||
type-fest "^0.13.1"
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==
|
||||
dependencies:
|
||||
shebang-regex "^1.0.0"
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
@@ -2834,6 +2920,11 @@ shebang-command@^2.0.0:
|
||||
dependencies:
|
||||
shebang-regex "^3.0.0"
|
||||
|
||||
shebang-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
|
||||
|
||||
shebang-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
@@ -2844,24 +2935,25 @@ shell-quote@^1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680"
|
||||
integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==
|
||||
|
||||
shelljs@^0.8.5:
|
||||
version "0.8.5"
|
||||
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
|
||||
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
|
||||
shelljs@^0.9.2:
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.9.2.tgz#a8ac724434520cd7ae24d52071e37a18ac2bb183"
|
||||
integrity sha512-S3I64fEiKgTZzKCC46zT/Ib9meqofLrQVbpSswtjFfAVDW+AZ54WTnAM/3/yENoxz/V1Cy6u3kiiEbQ4DNphvw==
|
||||
dependencies:
|
||||
glob "^7.0.0"
|
||||
execa "^1.0.0"
|
||||
fast-glob "^3.3.2"
|
||||
interpret "^1.0.0"
|
||||
rechoir "^0.6.2"
|
||||
|
||||
shx@^0.3.4:
|
||||
version "0.3.4"
|
||||
resolved "https://registry.yarnpkg.com/shx/-/shx-0.3.4.tgz#74289230b4b663979167f94e1935901406e40f02"
|
||||
integrity sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==
|
||||
shx@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/shx/-/shx-0.4.0.tgz#c6ea6ace7e778da0ab32d2eab9def59d788e9336"
|
||||
integrity sha512-Z0KixSIlGPpijKgcH6oCMCbltPImvaKy0sGH8AkLRXw1KyzpKtaCTizP2xen+hNDqVF4xxgvA0KXSb9o4Q6hnA==
|
||||
dependencies:
|
||||
minimist "^1.2.3"
|
||||
shelljs "^0.8.5"
|
||||
minimist "^1.2.8"
|
||||
shelljs "^0.9.2"
|
||||
|
||||
signal-exit@^3.0.2:
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
||||
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
||||
@@ -2914,19 +3006,18 @@ sort-object-keys@^1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45"
|
||||
integrity sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==
|
||||
|
||||
sort-package-json@2.15.1:
|
||||
version "2.15.1"
|
||||
resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-2.15.1.tgz#e5a035fad7da277b1947b9eecc93ea09c1c2526e"
|
||||
integrity sha512-9x9+o8krTT2saA9liI4BljNjwAbvUnWf11Wq+i/iZt8nl2UGYnf3TH5uBydE7VALmP7AGwlfszuEeL8BDyb0YA==
|
||||
sort-package-json@3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-3.2.1.tgz#889f3bdf43ceeff5fa4278a7c53ae5b1520d287e"
|
||||
integrity sha512-rTfRdb20vuoAn7LDlEtCqOkYfl2X+Qze6cLbNOzcDpbmKEhJI30tTN44d5shbKJnXsvz24QQhlCm81Bag7EOKg==
|
||||
dependencies:
|
||||
detect-indent "^7.0.1"
|
||||
detect-newline "^4.0.0"
|
||||
get-stdin "^9.0.0"
|
||||
git-hooks-list "^3.0.0"
|
||||
detect-newline "^4.0.1"
|
||||
git-hooks-list "^4.0.0"
|
||||
is-plain-obj "^4.1.0"
|
||||
semver "^7.6.0"
|
||||
semver "^7.7.1"
|
||||
sort-object-keys "^1.1.3"
|
||||
tinyglobby "^0.2.9"
|
||||
tinyglobby "^0.2.12"
|
||||
|
||||
source-map-support@^0.5.19:
|
||||
version "0.5.21"
|
||||
@@ -2981,6 +3072,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-eof@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
||||
integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==
|
||||
|
||||
strip-json-comments@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
@@ -3012,13 +3108,12 @@ supports-preserve-symlinks-flag@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
synckit@0.9.2:
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.2.tgz#a3a935eca7922d48b9e7d6c61822ee6c3ae4ec62"
|
||||
integrity sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==
|
||||
synckit@0.11.6:
|
||||
version "0.11.6"
|
||||
resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.6.tgz#e742a0c27bbc1fbc96f2010770521015cca7ed5c"
|
||||
integrity sha512-2pR2ubZSV64f/vqm9eLPz/KOvR9Dm+Co/5ChLgeHl0yEDRc6h5hXHoxEQH8Y5Ljycozd3p1k5TTSVdzYGkPvLw==
|
||||
dependencies:
|
||||
"@pkgr/core" "^0.1.0"
|
||||
tslib "^2.6.2"
|
||||
"@pkgr/core" "^0.2.4"
|
||||
|
||||
tar@^6.0.5, tar@^6.1.11, tar@^6.1.12, tar@^6.2.1:
|
||||
version "6.2.1"
|
||||
@@ -3069,12 +3164,12 @@ tiny-typed-emitter@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5"
|
||||
integrity sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==
|
||||
|
||||
tinyglobby@^0.2.9:
|
||||
version "0.2.10"
|
||||
resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.10.tgz#e712cf2dc9b95a1f5c5bbd159720e15833977a0f"
|
||||
integrity sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==
|
||||
tinyglobby@^0.2.12:
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.13.tgz#a0e46515ce6cbcd65331537e57484af5a7b2ff7e"
|
||||
integrity sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==
|
||||
dependencies:
|
||||
fdir "^6.4.2"
|
||||
fdir "^6.4.4"
|
||||
picomatch "^4.0.2"
|
||||
|
||||
tmp-promise@^3.0.2:
|
||||
@@ -3108,12 +3203,12 @@ truncate-utf8-bytes@^1.0.0:
|
||||
dependencies:
|
||||
utf8-byte-length "^1.0.1"
|
||||
|
||||
ts-api-utils@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.1.tgz#660729385b625b939aaa58054f45c058f33f10cd"
|
||||
integrity sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==
|
||||
ts-api-utils@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91"
|
||||
integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==
|
||||
|
||||
tslib@^2.1.0, tslib@^2.6.2:
|
||||
tslib@^2.1.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
|
||||
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
|
||||
@@ -3140,14 +3235,14 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
|
||||
|
||||
typescript-eslint@^8.29.1:
|
||||
version "8.29.1"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.29.1.tgz#c0b205e542ade22f9027caaaa9c4ec31a202010f"
|
||||
integrity sha512-f8cDkvndhbQMPcysk6CUSGBWV+g1utqdn71P5YKwMumVMOG/5k7cHq0KyG4O52nB0oKS4aN2Tp5+wB4APJGC+w==
|
||||
typescript-eslint@^8.32.1:
|
||||
version "8.32.1"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.32.1.tgz#1784335c781491be528ff84ab666e2f0f7591fd1"
|
||||
integrity sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==
|
||||
dependencies:
|
||||
"@typescript-eslint/eslint-plugin" "8.29.1"
|
||||
"@typescript-eslint/parser" "8.29.1"
|
||||
"@typescript-eslint/utils" "8.29.1"
|
||||
"@typescript-eslint/eslint-plugin" "8.32.1"
|
||||
"@typescript-eslint/parser" "8.32.1"
|
||||
"@typescript-eslint/utils" "8.32.1"
|
||||
|
||||
typescript@^5.4.3, typescript@^5.8.3:
|
||||
version "5.8.3"
|
||||
@@ -3221,6 +3316,13 @@ wcwidth@^1.0.1:
|
||||
dependencies:
|
||||
defaults "^1.0.3"
|
||||
|
||||
which@^1.2.9:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
||||
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
which@^2.0.1, which@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
@@ -3302,3 +3404,8 @@ yocto-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
zod@^3.25.23:
|
||||
version "3.25.23"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.23.tgz#128fb02f3619a8bca6bbbf6b07b457236cf33391"
|
||||
integrity sha512-Od2bdMosahjSrSgJtakrwjMDb1zM1A3VIHCPGveZt/3/wlrTWBya2lmEh2OYe4OIu8mPTmmr0gnLHIWQXdtWBg==
|
||||
|
||||
@@ -182,6 +182,7 @@ export const sidebar = [
|
||||
text: "Auth",
|
||||
items: [
|
||||
{ text: "Introduction", link: "/auth/" },
|
||||
{ text: "Features", link: "/auth/features/" },
|
||||
{
|
||||
text: "FAQ",
|
||||
collapsed: true,
|
||||
@@ -223,6 +224,7 @@ export const sidebar = [
|
||||
},
|
||||
{
|
||||
text: "Troubleshooting",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Windows login",
|
||||
@@ -238,58 +240,91 @@ export const sidebar = [
|
||||
items: [
|
||||
{ text: "Getting started", link: "/self-hosting/" },
|
||||
{
|
||||
text: "System requirements",
|
||||
link: "/self-hosting/guides/system-requirements",
|
||||
text: "Connecting to custom server",
|
||||
link: "/self-hosting/guides/custom-server/",
|
||||
},
|
||||
{
|
||||
text: "Creating accounts",
|
||||
link: "/self-hosting/creating-accounts",
|
||||
},
|
||||
{
|
||||
text: "Configuring your server",
|
||||
link: "/self-hosting/museum",
|
||||
},
|
||||
{
|
||||
text: "Configuring S3",
|
||||
link: "/self-hosting/guides/configuring-s3",
|
||||
},
|
||||
{
|
||||
text: "Reverse proxy",
|
||||
link: "/self-hosting/reverse-proxy",
|
||||
},
|
||||
{
|
||||
text: "Guides",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Introduction", link: "/self-hosting/guides/" },
|
||||
{
|
||||
text: "Connect to custom server",
|
||||
link: "/self-hosting/guides/custom-server/",
|
||||
},
|
||||
{
|
||||
text: "Hosting the web app",
|
||||
link: "/self-hosting/guides/web-app",
|
||||
},
|
||||
{
|
||||
text: "Configuring S3",
|
||||
link: "/self-hosting/guides/configuring-s3",
|
||||
},
|
||||
{
|
||||
text: "Hosting Ente with external S3 (Community)",
|
||||
link: "/self-hosting/guides/external-s3",
|
||||
},
|
||||
{
|
||||
text: "DB migration",
|
||||
link: "/self-hosting/guides/db-migration",
|
||||
},
|
||||
{
|
||||
text: "Hosting Ente without Docker",
|
||||
link: "/self-hosting/guides/standalone-ente",
|
||||
},
|
||||
{
|
||||
text: "Ente via Tailscale (Community)",
|
||||
link: "/self-hosting/guides/Tailscale.md",
|
||||
},
|
||||
{
|
||||
text: "Configure CLI for Self Hosted Instance",
|
||||
link: "/self-hosting/guides/selfhost-cli",
|
||||
},
|
||||
{
|
||||
text: "Administering your server",
|
||||
link: "/self-hosting/guides/admin",
|
||||
},
|
||||
|
||||
{
|
||||
text: "Mobile build",
|
||||
link: "/self-hosting/guides/mobile-build",
|
||||
text: "Configuring CLI for your instance",
|
||||
link: "/self-hosting/guides/selfhost-cli",
|
||||
},
|
||||
{
|
||||
text: "Running Ente from source",
|
||||
link: "/self-hosting/guides/from-source",
|
||||
},
|
||||
{
|
||||
text: "Running Ente without Docker",
|
||||
link: "/self-hosting/guides/standalone-ente",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Troubleshooting",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "General",
|
||||
link: "/self-hosting/troubleshooting/misc",
|
||||
},
|
||||
{
|
||||
text: "Bucket CORS",
|
||||
link: '/self-hosting/troubleshooting/bucket-cors'
|
||||
},
|
||||
{
|
||||
text: "Uploads",
|
||||
link: "/self-hosting/troubleshooting/uploads",
|
||||
},
|
||||
{
|
||||
text: "Docker / quickstart",
|
||||
link: "/self-hosting/troubleshooting/docker",
|
||||
},
|
||||
{
|
||||
text: "Ente CLI secrets",
|
||||
link: "/self-hosting/troubleshooting/keyring",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Community Guides",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Ente via Tailscale",
|
||||
link: "/self-hosting/guides/Tailscale",
|
||||
},
|
||||
{
|
||||
text: "Ente with External S3",
|
||||
link: "/self-hosting/guides/external-s3",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "FAQ",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "General", link: "/self-hosting/faq/" },
|
||||
{
|
||||
@@ -304,30 +339,9 @@ export const sidebar = [
|
||||
text: "Backups",
|
||||
link: "/self-hosting/faq/backup",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Troubleshooting",
|
||||
items: [
|
||||
{
|
||||
text: "General",
|
||||
link: "/self-hosting/troubleshooting/misc",
|
||||
},
|
||||
{
|
||||
text: "Uploads",
|
||||
link: "/self-hosting/troubleshooting/uploads",
|
||||
},
|
||||
{
|
||||
text: "Docker / quickstart",
|
||||
link: "/self-hosting/troubleshooting/docker",
|
||||
},
|
||||
{
|
||||
text: "Yarn",
|
||||
link: "/self-hosting/troubleshooting/yarn",
|
||||
},
|
||||
{
|
||||
text: "Ente CLI Secrets",
|
||||
link: "/self-hosting/troubleshooting/keyring",
|
||||
text: "Environment variables",
|
||||
link: "/self-hosting/faq/environment",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
139
docs/docs/auth/features/index.md
Normal file
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: Features - Auth
|
||||
description: Features available in Ente Auth
|
||||
---
|
||||
|
||||
# Features
|
||||
|
||||
This page outlines the key features available in Ente Auth.
|
||||
|
||||
### Icons
|
||||
|
||||
Ente Auth supports the icon pack provided by
|
||||
[simple-icons](https://github.com/simple-icons/simple-icons). If an icon you
|
||||
need is missing, please refer to the
|
||||
[docs/adding-icons](https://github.com/ente-io/ente/blob/main/auth/docs/adding-icons.md)
|
||||
guide for instructions on how to contribute.
|
||||
|
||||
### Search
|
||||
|
||||
Quickly find your codes by searching based on issuer or account name. You can
|
||||
also configure the app to focus the search bar automatically on app start by
|
||||
going to **Settings → General → Focus search on app start**.
|
||||
|
||||
### Tags
|
||||
|
||||
Organize and filter your codes with ease using tags.
|
||||
|
||||
- **Creating a Tag:** When adding or editing a code, tap the orange (+) icon to
|
||||
create a new tag.
|
||||
- **Adding an existing Tag:** When adding or editing a code, select the desired
|
||||
tag from the list.
|
||||
|
||||
### Pinning
|
||||
|
||||
Highlight your frequently used services by pinning them to the top of your code
|
||||
list. To pin a code, long-press (mobile) or right-click (desktop) the code and
|
||||
select "Pin".
|
||||
|
||||
### Notes
|
||||
|
||||
Add additional information to your codes using notes. Notes can be added during
|
||||
the process of creating or modifying a code.
|
||||
|
||||
### Sharing
|
||||
|
||||
Securely share codes temporarily with others.
|
||||
|
||||
- Long-press (mobile) or right-click (desktop) on a code and choose "Share".
|
||||
- Select a duration for the shared link: 2 minutes, 5 minutes, or 10 minutes.
|
||||
- This generates a unique, time-limited link. Recipients can view the codes for
|
||||
the specified duration without gaining access to the underlying secret key.
|
||||
After the link expires, the recipients will no longer be able to view new
|
||||
codes.
|
||||
|
||||
### Custom sorting
|
||||
|
||||
Customize the order in which your codes are displayed. Ente Auth provides
|
||||
several sorting options:
|
||||
|
||||
- Issuer name
|
||||
- Account name
|
||||
- Frequently used
|
||||
- Recently used
|
||||
- Manual (custom drag-and-drop order)
|
||||
|
||||
Access the sort menu in the top-right corner (next to the search icon) to change
|
||||
your sorting preference.
|
||||
|
||||
### Offline mode
|
||||
|
||||
Ente Auth can be used entirely offline. Choose "Use without backups" on the
|
||||
login screen. In this mode, your codes are stored locally on your device.
|
||||
|
||||
Unlike when using an account, data is not synced or backed up to the cloud. You
|
||||
are responsible for manually backing up your codes.
|
||||
|
||||
### Display options
|
||||
|
||||
Customize how your codes are displayed for optimal usability.
|
||||
|
||||
- **Show large icons:** Display codes with larger icons for enhanced visibility.
|
||||
- **Compact mode:** Switch to a more compact layout to view more codes on the
|
||||
screen simultaneously.
|
||||
- **Hide codes:** Hide the actual code values for extra privacy. Double-tap a
|
||||
code to reveal it when needed.
|
||||
|
||||
### App lock
|
||||
|
||||
Add an additional layer of protection using the app lock. Choose from the
|
||||
following lock methods:
|
||||
|
||||
- **Device lock:** Use the existing lock configured on your device (e.g., Face
|
||||
ID, Touch ID, system password).
|
||||
- **PIN lock:** Set up a 4-digit PIN code to unlock the app.
|
||||
- **Password lock:** Set up a password to unlock the app.
|
||||
|
||||
Additionally, configure **Auto lock** to automatically lock the app after a
|
||||
specified period of time (options: Immediately, 5s, 15s, 1m, 5m, 30m).
|
||||
|
||||
### Import / Export
|
||||
|
||||
Ente Auth offers various import and export options for your codes.
|
||||
|
||||
- **Export:** Export your codes in plain text, as an encrypted file, or
|
||||
automatically via the CLI.
|
||||
- **Import:** Import codes from various other authentication apps.
|
||||
|
||||
For detailed instructions, refer to the
|
||||
[migration guides](../migration-guides/).
|
||||
|
||||
### Deduplicate codes
|
||||
|
||||
If you import codes and end up with duplicates, you can easily remove them. Go
|
||||
to **Settings → Data → Duplicate codes** to find and remove duplicate codes.
|
||||
|
||||
### Trash
|
||||
|
||||
Manage unwanted codes by moving them to the Trash. The Trash is not cleared
|
||||
automatically, giving you the flexibility to restore or permanently delete codes
|
||||
at any time.
|
||||
|
||||
- **Trashing a code:** Long-press (mobile) or right-click (desktop) on a code
|
||||
and select "Trash" to move it to the Trash.
|
||||
- **Viewing trashed codes:** If you have trashed codes, you can view them by
|
||||
selecting the Trash tag.
|
||||
- **Managing trashed codes:** In the Trash view, you can either permanently
|
||||
delete codes or restore them back to your main list.
|
||||
|
||||
### Scan QR
|
||||
|
||||
Easily add or share entries using QR codes:
|
||||
|
||||
- **Add by scanning (mobile):** On mobile, you can add a new entry by scanning
|
||||
the QR code provided by the service. This quickly adds the entry to Ente Auth.
|
||||
- **Show entry as QR code:** On all apps, you can long-press (mobile) or
|
||||
right-click (desktop) a code and select "QR". This allows you to easily share
|
||||
the complete entry (including the secret) with others by letting them scan the
|
||||
displayed QR code. This can also be used to easily add the same entry to
|
||||
another authenticatior app or service.
|
||||
@@ -21,7 +21,7 @@ always available on your machine.
|
||||
background without you needing to run any other cron jobs. See
|
||||
[migration/export](/photos/migration/export/) for more details.
|
||||
|
||||
## Does the exported data preserve folder structure?
|
||||
## Does the exported data preserve album structure?
|
||||
|
||||
Yes. When you export your data for local backup, it will maintain the exact
|
||||
album structure how you have set up within Ente.
|
||||
|
||||
@@ -26,9 +26,6 @@ unsupported file format and we will do our best to help you out.
|
||||
|
||||
Yes, we currently do not support files larger than 4 GB.
|
||||
|
||||
If this constraint is a concern for you, please write to
|
||||
[support@ente.io](mailto:support@ente.io) with your use case and we will do our
|
||||
best to help you.
|
||||
|
||||
## Does Ente support videos?
|
||||
|
||||
|
||||
@@ -8,22 +8,43 @@ description:
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> Video streaming is available in beta on mobile apps starting v0.9.98.
|
||||
> Video streaming is available in beta on mobile apps starting v0.9.98 and on
|
||||
> desktop starting v1.7.13.
|
||||
|
||||
### How to enable video streaming?
|
||||
|
||||
#### On mobile
|
||||
|
||||
- Open Settings -> General -> Advanced
|
||||
- Switch on the toggle for `Video streaming`
|
||||
|
||||
#### On desktop
|
||||
|
||||
- Open Settings -> Preferences
|
||||
- Enable the toggle for `Streamable videos`
|
||||
|
||||
### What happens when I enable video streaming?
|
||||
|
||||
#### On mobile
|
||||
|
||||
Enabling video streaming will start processing videos captured in the last 30
|
||||
days, generating streams for each. Both local and remote videos will be
|
||||
processed, so this may consume bandwidth for downloading of remote files and
|
||||
uploading of the generated streams.
|
||||
|
||||
#### On desktop
|
||||
|
||||
When enabled, the desktop app will generate streams both for new uploads, and
|
||||
also for all existing videos that were previously uploaded.
|
||||
|
||||
Stream generation is CPU intensive and can take time so the app will continue
|
||||
processing them in the background. Clicking on search bar will show "Processing
|
||||
videos..." when stream generation is happening.
|
||||
|
||||
### How can I view video streams?
|
||||
|
||||
### On mobile
|
||||
|
||||
Settings -> Backup > Backup status will show details regarding the processing
|
||||
status for videos. Processed videos will have a green play button next to them.
|
||||
You can open these videos by tapping on them.
|
||||
@@ -34,6 +55,12 @@ play the stream.
|
||||
Clicking on the `Info` icon within the original video will show details about
|
||||
the generated stream.
|
||||
|
||||
### On desktop and web
|
||||
|
||||
Desktop and web app will automatically play the streaming version of a video if
|
||||
it has been already generated. The quality selector will show "Auto" when
|
||||
playing the stream.
|
||||
|
||||
### What is a stream?
|
||||
|
||||
Stream is an encrypted HLS file with an `.m3u8` playlist that helps play a video
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Deleting items and trash
|
||||
# Trash
|
||||
|
||||
Whenever you delete an item from Ente, it is moved to Trash. These items will be
|
||||
automatically deleted from Trash after 30 days. You can manaully select photos
|
||||
automatically deleted from Trash after 30 days. You can manually select photos
|
||||
to permanently delete or completely empty the trash if you wish.
|
||||
|
||||
Items in trash are included in your used storage calculation.
|
||||
|
||||
@@ -14,9 +14,21 @@ directly stream chunks of Google Takeout zips that are stored on network drives.
|
||||
|
||||
In particular, the folder watch functionality suffers a lot since the app needs
|
||||
access to file system events to detect changes to the users files so that they
|
||||
can be uploaded whenever there are changes.
|
||||
can be uploaded whenever there are changes. Network drives are less reliable in
|
||||
providing these file change events correctly.
|
||||
|
||||
Since are high chances of the user having a subpar experience, we request
|
||||
customers to avoid using the desktop app directly with network attached storage
|
||||
and instead temporarily copy the files to their local storage for uploads, and
|
||||
avoid watching folders that live on a network drive.
|
||||
|
||||
## Exporting to UNC paths
|
||||
|
||||
Generally, exports are likely to work better than imports, since the interaction
|
||||
with the file system is relatively simpler (Note that the app still needs to
|
||||
scan the folder to find existing files, esp. if the continuous export option is
|
||||
enabled).
|
||||
|
||||
A special case is when exporting to a UNC path. In this case, the file
|
||||
separators will not work as expected and the export will not start. As a
|
||||
workaround, you can map your UNC path to a network drive and use that instead.
|
||||
|
||||
BIN
docs/docs/public/cloudflare.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
docs/docs/public/endpoint.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/docs/public/otp.png
Normal file
|
After Width: | Height: | Size: 438 KiB |
BIN
docs/docs/public/quickstart.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
docs/docs/public/web-app.webp
Normal file
|
After Width: | Height: | Size: 75 KiB |
27
docs/docs/self-hosting/creating-accounts.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Creating accounts
|
||||
description: Creating accounts on your deployment
|
||||
---
|
||||
|
||||
# Creating accounts
|
||||
|
||||
Once Ente is up and running, the Ente Photos web app will be accessible on
|
||||
`http://localhost:3000`. Open this URL in your browser and proceed with creating
|
||||
an account.
|
||||
|
||||
The default API endpoint for museum will be `localhost:8080`.
|
||||
|
||||

|
||||
|
||||
To complete your account registration you will need to enter a 6-digit
|
||||
verification code.
|
||||
|
||||
This code can be found in the server logs, which should already be shown in your
|
||||
quickstart terminal. Alternatively, you can open the server logs with the
|
||||
following command from inside the `my-ente` folder:
|
||||
|
||||
```sh
|
||||
sudo docker compose logs
|
||||
```
|
||||
|
||||

|
||||
49
docs/docs/self-hosting/faq/environment.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: "Environment Variables and Ports"
|
||||
description: "Information about all the Environment Variables needed to run Ente"
|
||||
---
|
||||
|
||||
# Environment variables and ports
|
||||
A self-hosted Ente instance requires specific endpoints in both Museum (the server) and web apps. This document outlines the essential environment variables and port mappings of the web apps.
|
||||
|
||||
Here's the list of important variables that a self hoster should know about:
|
||||
|
||||
### Museum
|
||||
|
||||
1. `NEXT_PUBLIC_ENTE_ENDPOINT`
|
||||
|
||||
The above environment variable is used to configure Museums endpoint. Where Museum is
|
||||
running and which port it is listening on. This endpoint should be configured for
|
||||
all the apps to connect to your self hosted endpoint.
|
||||
|
||||
All the apps (regardless of platform) by default connect to api.ente.io - which is
|
||||
our production instance of Museum.
|
||||
|
||||
### Web Apps
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Web apps don't need to be configured with the below endpoints. Web app environment
|
||||
> variables are being documented here just so that the users know everything in detail.
|
||||
> Checkout [Configuring your Server](/self-hosting/museum) to configure endpoints for
|
||||
> particular app.
|
||||
|
||||
In Ente, all the web apps are separate NextJS applications. Therefore, they are all
|
||||
configured via environment variables. The photos app (Ente Photos) has information
|
||||
about and connects to other web apps like albums, cast, etc.
|
||||
|
||||
|
||||
1. `NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT`
|
||||
|
||||
This environment variable is used to configure and declare the endpoint for the Albums
|
||||
web app.
|
||||
|
||||
## Ports
|
||||
|
||||
The below format is according to how ports are mapped in Docker.
|
||||
Typically,`<host>:<container-port>`
|
||||
|
||||
1. `8080:8080`: Museum (Ente's server)
|
||||
2. `3000:3000`: Ente Photos web app
|
||||
3. `3001:3001`: Ente Accounts web app
|
||||
4. `3003:3003`: [Ente Auth web app](https://ente.io/auth/)
|
||||
5. `3004:3004`: [Ente Cast web app](http://ente.io/cast)
|
||||
@@ -12,6 +12,19 @@ verification code by:
|
||||
|
||||
- Reading it from the DB (otts table)
|
||||
|
||||
The easiest option when getting started is to look for it in the server (museum)
|
||||
logs. If you're already running the docker compose cluster using the quickstart
|
||||
script, you should be already seeing the logs in your terminal. Otherwise you
|
||||
can go to the folder (e.g. `my-ente`) where your `compose.yaml` is, then run
|
||||
`docker compose logs museum --follow`. Once you can see the logs, look for a
|
||||
line like:
|
||||
|
||||
```
|
||||
... Skipping sending email to email@example.com: *Verification code: 112089*
|
||||
```
|
||||
|
||||
That is the verification code.
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> You can also configure your instance to send out emails so that you can get
|
||||
|
||||
@@ -3,32 +3,6 @@ title: Server admin
|
||||
description: Administering your custom self-hosted Ente instance using the CLI
|
||||
---
|
||||
|
||||
# Administering your custom server
|
||||
|
||||
You can use
|
||||
[Ente's CLI](https://github.com/ente-io/ente/releases?q=tag%3Acli-v0) to
|
||||
administer your self hosted server.
|
||||
|
||||
First we need to get your CLI to connect to your custom server. Define a
|
||||
config.yaml and put it either in the same directory as CLI or path defined in
|
||||
env variable `ENTE_CLI_CONFIG_PATH`
|
||||
|
||||
```yaml
|
||||
endpoint:
|
||||
api: "http://localhost:8080"
|
||||
```
|
||||
|
||||
Now you should be able to
|
||||
[add an account](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_account_add.md),
|
||||
and subsequently increase the
|
||||
[storage and account validity](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_admin_update-subscription.md)
|
||||
using the CLI.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> The CLI command to add an account does not create Ente accounts. It only adds
|
||||
> existing accounts to the list of (existing) accounts that the CLI can use.
|
||||
|
||||
## Becoming an admin
|
||||
|
||||
By default, the first user (and only the first user) created on the system is
|
||||
@@ -40,7 +14,7 @@ explicit whitelist of admins.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> The first user is only treated as the admin if the list of admins in the
|
||||
> The first user is only treated as the admin if the list of admins in the
|
||||
> configuration is empty.
|
||||
>
|
||||
> Also, if at some point you delete the first user, then you will need to define
|
||||
@@ -78,6 +52,38 @@ You can use
|
||||
[account list](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_account_list.md)
|
||||
command to find the user id of any account.
|
||||
|
||||
# Administering your custom server
|
||||
|
||||
> [!NOTE]
|
||||
> For the first user (admin) to perform administrative actions using the CLI, their
|
||||
> userID must be whitelisted in the `museum.yaml` configuration file under
|
||||
> `internal.admins`. While the first user is automatically granted admin privileges
|
||||
> on the server, this additional step is required for CLI operations.
|
||||
|
||||
You can use
|
||||
[Ente's CLI](https://github.com/ente-io/ente/releases?q=tag%3Acli-v0) to
|
||||
administer your self hosted server.
|
||||
|
||||
First we need to get your CLI to connect to your custom server. Define a
|
||||
config.yaml and put it either in the same directory as CLI or path defined in
|
||||
env variable `ENTE_CLI_CONFIG_PATH`
|
||||
|
||||
```yaml
|
||||
endpoint:
|
||||
api: "http://localhost:8080"
|
||||
```
|
||||
|
||||
Now you should be able to
|
||||
[add an account](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_account_add.md),
|
||||
and subsequently increase the
|
||||
[storage and account validity](https://github.com/ente-io/ente/blob/main/cli/docs/generated/ente_admin_update-subscription.md)
|
||||
using the CLI.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> The CLI command to add an account does not create Ente accounts. It only adds
|
||||
> existing accounts to the list of (existing) accounts that the CLI can use.
|
||||
|
||||
## Backups
|
||||
|
||||
See this [FAQ](/self-hosting/faq/backup).
|
||||
|
||||