Compare commits
3368
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71a4e84d7c | ||
|
|
d6c36146ba | ||
|
|
9013778f58 | ||
|
|
1af03dd145 | ||
|
|
b83e0fd092 | ||
|
|
1f8d786d05 | ||
|
|
5d87a4ada0 | ||
|
|
4d4fb1e398 | ||
|
|
05eea54f06 | ||
|
|
a00d9ef765 | ||
|
|
aa6ddac9c5 | ||
|
|
9a6f17c745 | ||
|
|
980977aaf3 | ||
|
|
3ed0afaf91 | ||
|
|
250adb4b33 | ||
|
|
0baf09cb53 | ||
|
|
d04a914b9b | ||
|
|
59775cb27c | ||
|
|
fb76cd7b1b | ||
|
|
52fb5306b6 | ||
|
|
74f7d95718 | ||
|
|
bcc1b78c7c | ||
|
|
3978abea87 | ||
|
|
556b726349 | ||
|
|
e0f16f31e6 | ||
|
|
b39e24467c | ||
|
|
65613f07ba | ||
|
|
666a7e4d77 | ||
|
|
cf08bfdd9b | ||
|
|
1f47d56c55 | ||
|
|
1a7dde848f | ||
|
|
c8207308a8 | ||
|
|
f23020cc6f | ||
|
|
555e487f1e | ||
|
|
107bb0b15d | ||
|
|
87a2de393e | ||
|
|
a7e4412454 | ||
|
|
7dce4cfa8e | ||
|
|
2b30aca47c | ||
|
|
0073d2862b | ||
|
|
b182c97185 | ||
|
|
a32119bada | ||
|
|
a928cfd066 | ||
|
|
8c7a371336 | ||
|
|
6f61eb4946 | ||
|
|
1096f05344 | ||
|
|
26f96d3e38 | ||
|
|
4a02189a59 | ||
|
|
7a5bab41f6 | ||
|
|
84c32fb28d | ||
|
|
a3cb6d2782 | ||
|
|
45be957df5 | ||
|
|
8e45014e3f | ||
|
|
d84e948352 | ||
|
|
68bd835038 | ||
|
|
c297bebea1 | ||
|
|
6c0a823216 | ||
|
|
067a701bdc | ||
|
|
c3fb008c92 | ||
|
|
bc4321da2e | ||
|
|
8dec040803 | ||
|
|
29e4e77c44 | ||
|
|
11429ef7fe | ||
|
|
f5fcd96a1e | ||
|
|
19120038c5 | ||
|
|
9021f28ead | ||
|
|
62934f72e3 | ||
|
|
6c534e1049 | ||
|
|
f80cd90792 | ||
|
|
3999c0c114 | ||
|
|
59399453c4 | ||
|
|
694bb19e2a | ||
|
|
9928ecd4d9 | ||
|
|
2c5293af6e | ||
|
|
9569ca774d | ||
|
|
3a04460926 | ||
|
|
acb4fb6166 | ||
|
|
7d137bb016 | ||
|
|
8c2ed37b72 | ||
|
|
749b230250 | ||
|
|
23531cb6e0 | ||
|
|
0ac11dbe0b | ||
|
|
9b0e017542 | ||
|
|
f2f5fcacf9 | ||
|
|
52ded265f3 | ||
|
|
e77f905c4a | ||
|
|
2d14d34d53 | ||
|
|
78facda18a | ||
|
|
1fe1b43015 | ||
|
|
63164dc70a | ||
|
|
0d39092a7f | ||
|
|
c50db8a327 | ||
|
|
7e107cc5e2 | ||
|
|
260949e3a7 | ||
|
|
d9ec108721 | ||
|
|
1e97407936 | ||
|
|
73afe05a18 | ||
|
|
23475de932 | ||
|
|
6fb2172c2c | ||
|
|
9226b71119 | ||
|
|
58e38b58bf | ||
|
|
db0d110627 | ||
|
|
08812bf7ff | ||
|
|
daf7f8ffca | ||
|
|
74564fa07f | ||
|
|
fc51d3fc81 | ||
|
|
c5d5b8abd2 | ||
|
|
193badccb8 | ||
|
|
2653d0568a | ||
|
|
adf5a65371 | ||
|
|
5b59dabc66 | ||
|
|
f7259c5b40 | ||
|
|
6f9fceaef8 | ||
|
|
6a64ff51ed | ||
|
|
ea9d9cfba7 | ||
|
|
75c6561896 | ||
|
|
8f8db82e9d | ||
|
|
a114a8ac72 | ||
|
|
2c6216057f | ||
|
|
c5cbcf7418 | ||
|
|
5746e3bb57 | ||
|
|
fd3c87be22 | ||
|
|
866fff3e45 | ||
|
|
06df7befb6 | ||
|
|
8021f86473 | ||
|
|
c9919a8b39 | ||
|
|
386015a9ec | ||
|
|
cbce98b34e | ||
|
|
f69521fc1a | ||
|
|
01b4054368 | ||
|
|
e07aab4434 | ||
|
|
18caa87512 | ||
|
|
5676de24da | ||
|
|
57bbb1fe38 | ||
|
|
dcbfbc2e5f | ||
|
|
e1f473d301 | ||
|
|
a33256d29f | ||
|
|
6a81877b09 | ||
|
|
6cd7b85b94 | ||
|
|
df97a9c4b9 | ||
|
|
5cb91e9b45 | ||
|
|
94794cb0db | ||
|
|
a16c021000 | ||
|
|
49d4ae078f | ||
|
|
eb45068df3 | ||
|
|
1aa750d676 | ||
|
|
af85a68e3d | ||
|
|
a8fc4003a3 | ||
|
|
675df44745 | ||
|
|
7e271d7e8e | ||
|
|
acb2c720af | ||
|
|
5d0c2e3f05 | ||
|
|
3d5e3620dd | ||
|
|
43aefeedae | ||
|
|
c2cbcc009d | ||
|
|
2aa494d9b7 | ||
|
|
8f3a11f374 | ||
|
|
76298f15e4 | ||
|
|
58839e0def | ||
|
|
6fe62db5e4 | ||
|
|
9b9f25d405 | ||
|
|
e47d7378ec | ||
|
|
51b385408d | ||
|
|
8e7cced8d2 | ||
|
|
affeb3e106 | ||
|
|
a2377857e9 | ||
|
|
7714ff8938 | ||
|
|
352853b88c | ||
|
|
23d282e354 | ||
|
|
b93c12de89 | ||
|
|
e0e5a155aa | ||
|
|
e1f34a7b1b | ||
|
|
298e80eb9d | ||
|
|
3ecfd83f1e | ||
|
|
1dcf4e7f46 | ||
|
|
f1a856cb45 | ||
|
|
af32d7eea7 | ||
|
|
47be2754e5 | ||
|
|
39b16b6650 | ||
|
|
0a809a564c | ||
|
|
07e24013c8 | ||
|
|
8e8394985d | ||
|
|
e54b33aaaa | ||
|
|
e6a22d8ef4 | ||
|
|
ae25018574 | ||
|
|
28160608ec | ||
|
|
38651eba1d | ||
|
|
cc53fa5f1c | ||
|
|
70f8181752 | ||
|
|
9e506f6258 | ||
|
|
1304c728cf | ||
|
|
80e11c54e7 | ||
|
|
ff5d58b101 | ||
|
|
bf550d99bc | ||
|
|
7738b7bc29 | ||
|
|
01f51b1000 | ||
|
|
16dfacb285 | ||
|
|
a253ddf7e4 | ||
|
|
ffb488482c | ||
|
|
0e29754ce9 | ||
|
|
ee97720e1f | ||
|
|
29d4e6370c | ||
|
|
9040cb54d4 | ||
|
|
f082766f06 | ||
|
|
e2372891cb | ||
|
|
9dc5b5c539 | ||
|
|
886e025ac8 | ||
|
|
feb13cbd79 | ||
|
|
66baaad86f | ||
|
|
4142f28822 | ||
|
|
c578b16e27 | ||
|
|
32887acecd | ||
|
|
5cf5cc5e34 | ||
|
|
4dc0f7e02e | ||
|
|
6e9c6e6269 | ||
|
|
a22880a9b1 | ||
|
|
7357724392 | ||
|
|
fb1b08e7e8 | ||
|
|
1405b99ab8 | ||
|
|
f7aec69dae | ||
|
|
f15a0fc4bb | ||
|
|
6330fc3bdc | ||
|
|
01e3f3e9b7 | ||
|
|
e0c614cf71 | ||
|
|
b34764d4c2 | ||
|
|
f46f84e533 | ||
|
|
ca0eaf2053 | ||
|
|
25f283ee9c | ||
|
|
8ee23ab520 | ||
|
|
6964baf3f6 | ||
|
|
01aa7af175 | ||
|
|
5982bd2d4b | ||
|
|
d0fbb3539f | ||
|
|
284fb4242b | ||
|
|
beeb4bdbd4 | ||
|
|
76a52903e5 | ||
|
|
a19b8782a8 | ||
|
|
31f66fd05b | ||
|
|
bc3c4e969c | ||
|
|
4231402e54 | ||
|
|
ff4f76dfa5 | ||
|
|
2ff9df4c07 | ||
|
|
7cbc641178 | ||
|
|
08d5621b59 | ||
|
|
d39c2fdfa2 | ||
|
|
27e02ad642 | ||
|
|
11e9faef7c | ||
|
|
cbb8971dd1 | ||
|
|
1077f4d8cf | ||
|
|
594f9412e3 | ||
|
|
7674f6a0f7 | ||
|
|
aea6fbf4ab | ||
|
|
962f9bfff5 | ||
|
|
60532e2622 | ||
|
|
5c7a834342 | ||
|
|
ca940080a9 | ||
|
|
2273dd541a | ||
|
|
422062226d | ||
|
|
6a6da6f059 | ||
|
|
4cbb0eca4f | ||
|
|
ebb3eb1ab3 | ||
|
|
ebf645acaf | ||
|
|
ec787ebde2 | ||
|
|
4f190cb0ef | ||
|
|
2a36868d11 | ||
|
|
176d8be565 | ||
|
|
7b581e45e1 | ||
|
|
4888e29f79 | ||
|
|
e5f6d1b1aa | ||
|
|
d544bbfbeb | ||
|
|
ed20d6022b | ||
|
|
4191e2091c | ||
|
|
1eeb5a51f6 | ||
|
|
dd0776758f | ||
|
|
cf3ccf6155 | ||
|
|
fa6e4acad6 | ||
|
|
db33a72a8e | ||
|
|
0f8a0549b1 | ||
|
|
26ff30af6c | ||
|
|
c2fa32f430 | ||
|
|
2734de0588 | ||
|
|
aa219e4b71 | ||
|
|
645656b4cd | ||
|
|
ef16bdeb75 | ||
|
|
84299b4db7 | ||
|
|
953e216dde | ||
|
|
c57fd0a923 | ||
|
|
f9cb3d769f | ||
|
|
dd62571943 | ||
|
|
9edd33d88d | ||
|
|
b2fded76d5 | ||
|
|
1761493c8e | ||
|
|
6aa6ee2810 | ||
|
|
84728a1490 | ||
|
|
a1568467f0 | ||
|
|
32e2a03c31 | ||
|
|
d4609593e2 | ||
|
|
a2af7437c0 | ||
|
|
ab5af22fc3 | ||
|
|
39a159e5ca | ||
|
|
ec8a54906c | ||
|
|
73c0ce02ea | ||
|
|
7d2e0f7f7e | ||
|
|
7515a049c2 | ||
|
|
a317d5303e | ||
|
|
c4045ded70 | ||
|
|
3cb1b1eee4 | ||
|
|
5423af46c5 | ||
|
|
a2883840e0 | ||
|
|
14810b4c2c | ||
|
|
f5a9a41790 | ||
|
|
500d00d214 | ||
|
|
49810f8fd1 | ||
|
|
6ad3ab228f | ||
|
|
3a29ce291b | ||
|
|
1e28a4c7ab | ||
|
|
645467d20f | ||
|
|
b2a5fe9f52 | ||
|
|
2ea3c03360 | ||
|
|
0c147967d2 | ||
|
|
de1fab2595 | ||
|
|
b86eebf0a7 | ||
|
|
07345f90e6 | ||
|
|
5fe520e575 | ||
|
|
a9dd705ec5 | ||
|
|
e36520faad | ||
|
|
edaf0a4275 | ||
|
|
7735237ea7 | ||
|
|
7bbc4ea618 | ||
|
|
db99392082 | ||
|
|
7bf6a9f545 | ||
|
|
51c0efebc4 | ||
|
|
7ef70aa16e | ||
|
|
c5c0c6c4bd | ||
|
|
b26cba8ea9 | ||
|
|
90b4c16166 | ||
|
|
9b0f6fe433 | ||
|
|
e24735c341 | ||
|
|
9680ada9ee | ||
|
|
028a7c2352 | ||
|
|
80e5f36c4e | ||
|
|
e0b65184e2 | ||
|
|
395a48ddeb | ||
|
|
e22a39f549 | ||
|
|
e17d934ebf | ||
|
|
10746417b6 | ||
|
|
3ef45ba0cc | ||
|
|
a3e7b6ef43 | ||
|
|
c444a3b435 | ||
|
|
5161802465 | ||
|
|
8c27feec7a | ||
|
|
37e895cdca | ||
|
|
e1ad4e3b90 | ||
|
|
5f0be5ae43 | ||
|
|
9a7cabb221 | ||
|
|
6acc552058 | ||
|
|
b4f4d442eb | ||
|
|
21016dda53 | ||
|
|
576e5b1b58 | ||
|
|
17437a6882 | ||
|
|
04f9f087da | ||
|
|
c508947728 | ||
|
|
ce1dc55d3c | ||
|
|
e9f615819f | ||
|
|
8da3546558 | ||
|
|
d8f8dcffbd | ||
|
|
e79113b19e | ||
|
|
2a7f65a1bd | ||
|
|
e322878b95 | ||
|
|
11b09f187c | ||
|
|
926309733c | ||
|
|
c4b2bcab66 | ||
|
|
b88c96894d | ||
|
|
8502671203 | ||
|
|
4a7d6f7489 | ||
|
|
aec34c81aa | ||
|
|
1d4fe30e04 | ||
|
|
a2cfecd922 | ||
|
|
d36aef3214 | ||
|
|
c632231813 | ||
|
|
d8dd68c9b6 | ||
|
|
d6a58d5d34 | ||
|
|
41f8168c28 | ||
|
|
4513ead30a | ||
|
|
f4e23a5738 | ||
|
|
79b167002c | ||
|
|
a9a763ae5f | ||
|
|
a5fc29bc66 | ||
|
|
02c568fd7a | ||
|
|
ce55891bc2 | ||
|
|
87b1160c72 | ||
|
|
ccc6d004de | ||
|
|
20b145bee5 | ||
|
|
a37cc59a56 | ||
|
|
7cbffff12c | ||
|
|
4e5ae53775 | ||
|
|
a53de63695 | ||
|
|
8020c139ec | ||
|
|
3c5375a9a6 | ||
|
|
1d9008a1a6 | ||
|
|
fb577dc026 | ||
|
|
675eb1b7e2 | ||
|
|
6a3d522dfa | ||
|
|
47aa5c64e7 | ||
|
|
5ecf5c41ca | ||
|
|
bc6d12a873 | ||
|
|
4d983830df | ||
|
|
2f1e0d030e | ||
|
|
b7c873a172 | ||
|
|
9d5eb55290 | ||
|
|
78ffb1c4fe | ||
|
|
031d622d5d | ||
|
|
34da120a43 | ||
|
|
5285e1ccf2 | ||
|
|
e28efc1f50 | ||
|
|
1c043a81a6 | ||
|
|
9a769cc7b6 | ||
|
|
045c6abe40 | ||
|
|
4ad5cef412 | ||
|
|
c3ffab3c79 | ||
|
|
c82de0b779 | ||
|
|
4e36cbabc0 | ||
|
|
94f87b14b7 | ||
|
|
6bc80d1afa | ||
|
|
fe4d004083 | ||
|
|
28410befa3 | ||
|
|
515f7deb7e | ||
|
|
800e66261e | ||
|
|
65658c4a02 | ||
|
|
0488c7ebf4 | ||
|
|
c30c1b29ef | ||
|
|
876001ad99 | ||
|
|
60dc59adbc | ||
|
|
c994890f28 | ||
|
|
76223a2cd2 | ||
|
|
6274b39b68 | ||
|
|
cca3a3e350 | ||
|
|
86ef8f2b48 | ||
|
|
5d116d9477 | ||
|
|
6e73fcc8c9 | ||
|
|
3bd12a3047 | ||
|
|
c99d8e8275 | ||
|
|
4a12e71877 | ||
|
|
3043901b5a | ||
|
|
7cc28955d6 | ||
|
|
ef44bb4857 | ||
|
|
37660ef697 | ||
|
|
9821b3aaab | ||
|
|
1f5331af5a | ||
|
|
3ea6c82a6d | ||
|
|
ba53d01fa1 | ||
|
|
df8ae8d11a | ||
|
|
c817726ab3 | ||
|
|
9eb606810f | ||
|
|
fbb030ec8e | ||
|
|
28afebefb1 | ||
|
|
da2610657c | ||
|
|
6e3471ba1b | ||
|
|
5a9ab6c4eb | ||
|
|
1fe553d039 | ||
|
|
42e0b0aeab | ||
|
|
9e0ea32296 | ||
|
|
d3f5274b7e | ||
|
|
faff0733e9 | ||
|
|
7b32cde7dd | ||
|
|
648d1d10b3 | ||
|
|
52727100a0 | ||
|
|
8a2dbb99f0 | ||
|
|
d880b30ea9 | ||
|
|
0e2ca4e150 | ||
|
|
e0eef82ed8 | ||
|
|
09839086a2 | ||
|
|
3ca3ab7273 | ||
|
|
8386bf9c69 | ||
|
|
99b8ee1f78 | ||
|
|
0333a8c679 | ||
|
|
e0bb09e902 | ||
|
|
77677cead3 | ||
|
|
d4b2ff7de9 | ||
|
|
b81bae09d1 | ||
|
|
846e66a56c | ||
|
|
5cec635e52 | ||
|
|
8d0dc88125 | ||
|
|
51b58bb797 | ||
|
|
f79aa2350c | ||
|
|
719dddeab9 | ||
|
|
c1522568fd | ||
|
|
3ad6b9106b | ||
|
|
549387ac91 | ||
|
|
7d2f985ffa | ||
|
|
7e8b0a5800 | ||
|
|
69252ae8a4 | ||
|
|
eeed56b211 | ||
|
|
8aaad071ea | ||
|
|
7ef67e1bf9 | ||
|
|
1c15d9a956 | ||
|
|
70082090a1 | ||
|
|
dbc1a32496 | ||
|
|
e8c9ee5dd0 | ||
|
|
5c3657736b | ||
|
|
5191408d06 | ||
|
|
347ce6854d | ||
|
|
f86dec9b2e | ||
|
|
c74b128b1a | ||
|
|
8ee28a4b4f | ||
|
|
3b07b6997d | ||
|
|
f59023ed03 | ||
|
|
3fc13e61c3 | ||
|
|
ae22f448a8 | ||
|
|
450c15d51e | ||
|
|
d9e5bb4399 | ||
|
|
369904f659 | ||
|
|
96302b2344 | ||
|
|
eeffb12e3b | ||
|
|
57c12f7df0 | ||
|
|
37eb2f1aed | ||
|
|
c70ec5f354 | ||
|
|
7139af4629 | ||
|
|
a2bac029f5 | ||
|
|
6c68074e8b | ||
|
|
991caf73f4 | ||
|
|
0ba11641fa | ||
|
|
b51120e914 | ||
|
|
b02fb2d1d7 | ||
|
|
c6247230da | ||
|
|
d64be78b4e | ||
|
|
e75f633165 | ||
|
|
27c5598133 | ||
|
|
a9449bfbc7 | ||
|
|
4fecbe259b | ||
|
|
81d72edbf0 | ||
|
|
ea7e6e4624 | ||
|
|
6335d5bca4 | ||
|
|
227b430dbb | ||
|
|
0bba56a29f | ||
|
|
c07d9da7b0 | ||
|
|
900c5ed007 | ||
|
|
ba0788f6df | ||
|
|
c517856e89 | ||
|
|
791ee0ddbf | ||
|
|
0746938cb9 | ||
|
|
bbae24aba9 | ||
|
|
677edb0e02 | ||
|
|
a4328c5111 | ||
|
|
27cf341fef | ||
|
|
bc654e98b8 | ||
|
|
588f78e598 | ||
|
|
70f952285a | ||
|
|
a6f5e4f98d | ||
|
|
6fe5c1d666 | ||
|
|
1dba12ec94 | ||
|
|
aeb3f689d1 | ||
|
|
0a2268d4de | ||
|
|
9a32b020cf | ||
|
|
c5b01a7089 | ||
|
|
0634fbb724 | ||
|
|
445e9511a0 | ||
|
|
ac532acb5b | ||
|
|
7a8e21fbef | ||
|
|
58b0f3a41e | ||
|
|
ab373990cd | ||
|
|
272c157fe0 | ||
|
|
e5e047ee10 | ||
|
|
bf0b529018 | ||
|
|
acf2392406 | ||
|
|
cecd6fb359 | ||
|
|
7b67210876 | ||
|
|
e40c4f2c71 | ||
|
|
b0717b38b1 | ||
|
|
18c9b95b9b | ||
|
|
fc63c41ab0 | ||
|
|
d1c7434993 | ||
|
|
da15ba8b9a | ||
|
|
1d2a2a3608 | ||
|
|
145cd7a7c0 | ||
|
|
048415f3e0 | ||
|
|
95ccabc756 | ||
|
|
1f08c0e08c | ||
|
|
b036aeef23 | ||
|
|
d469a8404c | ||
|
|
5b16b6aed9 | ||
|
|
151949aecf | ||
|
|
de2c4ca3f5 | ||
|
|
e5bebcfe80 | ||
|
|
0080a482e4 | ||
|
|
756867416b | ||
|
|
124ff2f190 | ||
|
|
828a3d09b6 | ||
|
|
fc3b9d73ec | ||
|
|
ba943a31d4 | ||
|
|
8ee1ac7617 | ||
|
|
113f2a1794 | ||
|
|
f6028813e2 | ||
|
|
b094a32d12 | ||
|
|
fd3e4bdc60 | ||
|
|
142092d930 | ||
|
|
75e3e78ecb | ||
|
|
053832681f | ||
|
|
29e33d6e69 | ||
|
|
2d878e2f1c | ||
|
|
0fdbfbb1ae | ||
|
|
52f314f6b0 | ||
|
|
ff8d8916aa | ||
|
|
b2368b312f | ||
|
|
3cade906d6 | ||
|
|
e7cb33ef6f | ||
|
|
8c331c9577 | ||
|
|
8560a050ba | ||
|
|
583637b692 | ||
|
|
791359e949 | ||
|
|
e238b6aec0 | ||
|
|
17a143c4de | ||
|
|
dfb0aa823e | ||
|
|
b5cad36967 | ||
|
|
86378630bb | ||
|
|
730035aff7 | ||
|
|
64ac770c56 | ||
|
|
557a5599e2 | ||
|
|
ffd24015ac | ||
|
|
5eb1f12113 | ||
|
|
8425fed5a7 | ||
|
|
1e34aa4d9a | ||
|
|
f383594050 | ||
|
|
086db7572d | ||
|
|
082e05584a | ||
|
|
fb20f899e2 | ||
|
|
c0c07ff2cf | ||
|
|
2f67b741ff | ||
|
|
5a96048051 | ||
|
|
5d8b38ecf9 | ||
|
|
2941ac8285 | ||
|
|
07e316d9a9 | ||
|
|
5bd9fa3a62 | ||
|
|
0b5da2b2dd | ||
|
|
714a8ccf65 | ||
|
|
5c731cc6b2 | ||
|
|
eda8115fe5 | ||
|
|
cf0a408b90 | ||
|
|
f9786377a5 | ||
|
|
93f234b16d | ||
|
|
afb986937b | ||
|
|
61fecaffe1 | ||
|
|
6f87afc1bf | ||
|
|
2e5950a1a8 | ||
|
|
4bf0c4ecec | ||
|
|
3a8dbcdb32 | ||
|
|
1f3546f3cc | ||
|
|
f864d65d98 | ||
|
|
3479498c6c | ||
|
|
ac319330be | ||
|
|
9b3595e45f | ||
|
|
d855858543 | ||
|
|
ada52f1687 | ||
|
|
ef68374f52 | ||
|
|
0bf8049021 | ||
|
|
3cff3f837a | ||
|
|
ca94a63762 | ||
|
|
81b8bc9029 | ||
|
|
9d38520b85 | ||
|
|
800e09adad | ||
|
|
30d6c11220 | ||
|
|
e465356df8 | ||
|
|
ff8e1b7d28 | ||
|
|
175e1d7df9 | ||
|
|
271c1b1390 | ||
|
|
a128356fc4 | ||
|
|
2ed957b5f2 | ||
|
|
85bb9b9f97 | ||
|
|
050b5c0451 | ||
|
|
a14df3fc0c | ||
|
|
939136476e | ||
|
|
7e2af653ee | ||
|
|
d357a55307 | ||
|
|
23509ac2c9 | ||
|
|
118a4f75c0 | ||
|
|
2b8a7fafe6 | ||
|
|
10eda7e5f3 | ||
|
|
c23cadec8a | ||
|
|
0114081a2b | ||
|
|
2611601fb9 | ||
|
|
4194087f0b | ||
|
|
673adc41ba | ||
|
|
b195ae25a8 | ||
|
|
556c49fbfd | ||
|
|
358a5249a4 | ||
|
|
d5b837e6af | ||
|
|
61100d0c83 | ||
|
|
8473ca9fff | ||
|
|
37a2227c5c | ||
|
|
d6a4ab7471 | ||
|
|
6291288c42 | ||
|
|
6c926419e9 | ||
|
|
f292f31ac1 | ||
|
|
86a49f764e | ||
|
|
5dad21f4ea | ||
|
|
a4e9291bf9 | ||
|
|
2a667e62f4 | ||
|
|
6bd8063976 | ||
|
|
0aba5907b0 | ||
|
|
32182a7791 | ||
|
|
198960f93c | ||
|
|
618f14a732 | ||
|
|
fec2c39364 | ||
|
|
dd06d82cd9 | ||
|
|
4c98ee5350 | ||
|
|
2800a7bc15 | ||
|
|
04818e5afb | ||
|
|
122089eb1e | ||
|
|
b991e5d70a | ||
|
|
0d00ae207a | ||
|
|
9e451c18d9 | ||
|
|
71ebd99115 | ||
|
|
116dbead4b | ||
|
|
ef8adb00f4 | ||
|
|
7d74781f96 | ||
|
|
b7627dc576 | ||
|
|
cf42acd65c | ||
|
|
4163c895df | ||
|
|
63ddd5ea89 | ||
|
|
216dfded4b | ||
|
|
08b5eac6bd | ||
|
|
6e541be6ca | ||
|
|
17a9c02f96 | ||
|
|
ed640ab00e | ||
|
|
d69df5f7ab | ||
|
|
6f6461e855 | ||
|
|
682d959688 | ||
|
|
179686de16 | ||
|
|
32e35622bd | ||
|
|
c9c06202bb | ||
|
|
42d17621f9 | ||
|
|
629044c241 | ||
|
|
9be19489a4 | ||
|
|
cde4f9e405 | ||
|
|
16fddcb377 | ||
|
|
35cff4647a | ||
|
|
80ad749fc2 | ||
|
|
1a1d444b20 | ||
|
|
bb2d500067 | ||
|
|
c3c7e88c15 | ||
|
|
8dc3b1f376 | ||
|
|
b49a80bb35 | ||
|
|
21bfd4dd2d | ||
|
|
3551ed7c7a | ||
|
|
5f8ab98e9e | ||
|
|
8c6b2f5366 | ||
|
|
bac60fbec8 | ||
|
|
4eed03ebed | ||
|
|
e33295d0a6 | ||
|
|
07a495c499 | ||
|
|
e69eba6023 | ||
|
|
8be6ad84fc | ||
|
|
59e46aeeea | ||
|
|
4404531171 | ||
|
|
99db84fdd0 | ||
|
|
aa50b69754 | ||
|
|
fa2933df7c | ||
|
|
c51a26b9b7 | ||
|
|
9859a1eaac | ||
|
|
cd3858ace8 | ||
|
|
0c54e8b0b3 | ||
|
|
e32a7b61b6 | ||
|
|
ea2977268b | ||
|
|
6b529bcb18 | ||
|
|
941e7d18f3 | ||
|
|
d0fe9fac8c | ||
|
|
8f37c5ba25 | ||
|
|
b63b36e6d2 | ||
|
|
081357cbb4 | ||
|
|
0f7aa5f9ea | ||
|
|
a565b428e8 | ||
|
|
71f4df6f05 | ||
|
|
5da2f91e6a | ||
|
|
a6e9867596 | ||
|
|
9e1cff014d | ||
|
|
9c06f10d43 | ||
|
|
3f11df1dc6 | ||
|
|
6dd4505cec | ||
|
|
8faabd7759 | ||
|
|
288e56d7e0 | ||
|
|
7bcddb5f51 | ||
|
|
7b0bd309e4 | ||
|
|
237938b1f0 | ||
|
|
07009f8bd6 | ||
|
|
f7ef768c8f | ||
|
|
d1c3c9a37a | ||
|
|
78f15860e0 | ||
|
|
6b11773da9 | ||
|
|
ed26cb8f35 | ||
|
|
337f27dc38 | ||
|
|
97fab45877 | ||
|
|
8e8749ed6e | ||
|
|
a0e999576e | ||
|
|
b29802c260 | ||
|
|
665e5a3d39 | ||
|
|
c2a2dafb47 | ||
|
|
1d12a16e3d | ||
|
|
f3fe5f0a75 | ||
|
|
3bad1d06f4 | ||
|
|
70f2bfb760 | ||
|
|
9e86d42972 | ||
|
|
c8ade4d750 | ||
|
|
11b7bbd7ef | ||
|
|
513bce51ea | ||
|
|
f2c8c5d66d | ||
|
|
4e08f4f962 | ||
|
|
a9bd55dff5 | ||
|
|
5cec825dbe | ||
|
|
14c5b28cdc | ||
|
|
7693b11e0a | ||
|
|
f9cb49e4d3 | ||
|
|
892a614246 | ||
|
|
4a482d996e | ||
|
|
af9baa8ce4 | ||
|
|
39a11525a9 | ||
|
|
2337dda4eb | ||
|
|
c0a610a02b | ||
|
|
85f7b54719 | ||
|
|
e0aea2fedf | ||
|
|
ee83dbb877 | ||
|
|
1de4bc11eb | ||
|
|
04a7656afa | ||
|
|
77ec7e76e9 | ||
|
|
9ca7be081a | ||
|
|
fb36346f0b | ||
|
|
95679f3fb9 | ||
|
|
addd4124c1 | ||
|
|
74b79d9faa | ||
|
|
9daa05ef02 | ||
|
|
5ee884e0a2 | ||
|
|
dba7f4e6c0 | ||
|
|
8221514805 | ||
|
|
2ae3effc0e | ||
|
|
5b450ff18f | ||
|
|
92be6e9340 | ||
|
|
8884aeec11 | ||
|
|
8e15eda4e3 | ||
|
|
0dbf220655 | ||
|
|
fe69d59ef1 | ||
|
|
1e1f8350b5 | ||
|
|
afa2d03b56 | ||
|
|
1293d7fe28 | ||
|
|
62e879f2de | ||
|
|
a771994f6f | ||
|
|
8c2ba051a0 | ||
|
|
ae2f289122 | ||
|
|
703d63d106 | ||
|
|
2d7b024293 | ||
|
|
26906f6709 | ||
|
|
e9ec97403f | ||
|
|
34fb72707b | ||
|
|
fb7eb64c3a | ||
|
|
ef65720999 | ||
|
|
3bc71d6798 | ||
|
|
c4be269fb7 | ||
|
|
1238edfe2b | ||
|
|
747fd23b96 | ||
|
|
022f7a3ef1 | ||
|
|
e0cad8600c | ||
|
|
9510ebbc31 | ||
|
|
b63f2fd393 | ||
|
|
95a0e9f03b | ||
|
|
8265dd7f02 | ||
|
|
67feb19cab | ||
|
|
614e847de0 | ||
|
|
c2ff4b6a0b | ||
|
|
b273f1039c | ||
|
|
bea0c6a1f0 | ||
|
|
dcfaa361ec | ||
|
|
9904e166d2 | ||
|
|
5f02769012 | ||
|
|
19e5636dd2 | ||
|
|
9a220f89d9 | ||
|
|
1c76ec813c | ||
|
|
d36c189430 | ||
|
|
61e2ace5c8 | ||
|
|
d6a3f21754 | ||
|
|
4e54d7f66f | ||
|
|
f2dff038cd | ||
|
|
a7b30640e0 | ||
|
|
45048b1f46 | ||
|
|
498129314a | ||
|
|
3ee4b4a61e | ||
|
|
ee59c0f22e | ||
|
|
c56134cd92 | ||
|
|
b3d1b66a06 | ||
|
|
c9bb81bf63 | ||
|
|
d176810dae | ||
|
|
17bdca71b1 | ||
|
|
22fd3730df | ||
|
|
23d1271949 | ||
|
|
bf6aa3e8ae | ||
|
|
75fcfde892 | ||
|
|
89be27995e | ||
|
|
6738dc6cdc | ||
|
|
9ff0decb98 | ||
|
|
717d3717ba | ||
|
|
fdbca869a8 | ||
|
|
aafa750ca3 | ||
|
|
afe2bac672 | ||
|
|
b6f5d72db5 | ||
|
|
f0021a7601 | ||
|
|
ea5bfbb346 | ||
|
|
38fbcf4457 | ||
|
|
7c43e8f349 | ||
|
|
93df4e3dd9 | ||
|
|
f7d45a52a7 | ||
|
|
328f96d115 | ||
|
|
22338a72d8 | ||
|
|
256dedcb7c | ||
|
|
95d2438b84 | ||
|
|
f8d27e165e | ||
|
|
e2f024ae29 | ||
|
|
9c28fbeaf8 | ||
|
|
6458eb090a | ||
|
|
f1ca2b6958 | ||
|
|
60f031e7e3 | ||
|
|
e6a44ee0e1 | ||
|
|
7a3a641a07 | ||
|
|
1021efb239 | ||
|
|
edbe6509e1 | ||
|
|
44a6253bfc | ||
|
|
3d6e5df71e | ||
|
|
2733d2e58c | ||
|
|
0c78673870 | ||
|
|
d618948429 | ||
|
|
7584704d22 | ||
|
|
4a4658cc54 | ||
|
|
e9875f1a24 | ||
|
|
cc11257d80 | ||
|
|
4fd64601ef | ||
|
|
7eea490adf | ||
|
|
b2b12f7b93 | ||
|
|
66d026cffa | ||
|
|
5a15a20dd6 | ||
|
|
70450a9725 | ||
|
|
470a3c6a09 | ||
|
|
15f8b2f15d | ||
|
|
717cbe7630 | ||
|
|
d34075d29d | ||
|
|
80d4d66fb5 | ||
|
|
6b20b46761 | ||
|
|
cd764a4a3c | ||
|
|
5422b3d8bd | ||
|
|
0273390d79 | ||
|
|
8f7242b939 | ||
|
|
246dee63b4 | ||
|
|
697918a73a | ||
|
|
67e480220e | ||
|
|
5784eb008e | ||
|
|
82d66c4d57 | ||
|
|
ab8671cc3b | ||
|
|
2e52dda208 | ||
|
|
1ab08d0ae1 | ||
|
|
702be0ed43 | ||
|
|
4067543701 | ||
|
|
074689c60e | ||
|
|
2beb715df3 | ||
|
|
7ea2597899 | ||
|
|
34a8f92865 | ||
|
|
6e2a2de13f | ||
|
|
e073232352 | ||
|
|
6f49b4d23e | ||
|
|
97cad20ab1 | ||
|
|
9300a3d9ce | ||
|
|
28b7f80a8f | ||
|
|
a06d23753a | ||
|
|
98d66b3e6c | ||
|
|
6e59583dea | ||
|
|
2f0571e384 | ||
|
|
64a6074e02 | ||
|
|
0b7cb4cf41 | ||
|
|
e620832e33 | ||
|
|
f82e4af0e3 | ||
|
|
02baa793f8 | ||
|
|
9311a9e7f9 | ||
|
|
00a60ad6ab | ||
|
|
e740c25211 | ||
|
|
79c6b63c56 | ||
|
|
bc914566dd | ||
|
|
2c6ccfb23d | ||
|
|
646767e712 | ||
|
|
754b14d349 | ||
|
|
38c18149aa | ||
|
|
35b448a274 | ||
|
|
c1e63b5a5d | ||
|
|
37f984829a | ||
|
|
65942021d0 | ||
|
|
ecef20d52b | ||
|
|
1a092bb200 | ||
|
|
a880f801fb | ||
|
|
f00360e81c | ||
|
|
1737163364 | ||
|
|
f9a3c3d266 | ||
|
|
7db04e4359 | ||
|
|
934629d829 | ||
|
|
cd65bb057d | ||
|
|
f2d94f1ed6 | ||
|
|
e29281ce39 | ||
|
|
1e719a8738 | ||
|
|
92926487b6 | ||
|
|
69f744131a | ||
|
|
83cd9bdd00 | ||
|
|
1130f4f114 | ||
|
|
d99d9008dd | ||
|
|
78f61b2396 | ||
|
|
32829bbf15 | ||
|
|
a2d3046070 | ||
|
|
95641e398a | ||
|
|
97c39d07e8 | ||
|
|
14fa2fab71 | ||
|
|
ef8c31ae52 | ||
|
|
353080867a | ||
|
|
4d09b895d4 | ||
|
|
6c00d66334 | ||
|
|
77de187207 | ||
|
|
79eec13856 | ||
|
|
562c6fa9a4 | ||
|
|
9fa3ddd254 | ||
|
|
d11a0b9b8a | ||
|
|
41cf3fbe89 | ||
|
|
ac12ab93e5 | ||
|
|
8b4e978cf4 | ||
|
|
c15f22400e | ||
|
|
1773116313 | ||
|
|
62424fbad1 | ||
|
|
d07bd1aa29 | ||
|
|
8433df09e3 | ||
|
|
0634898cb6 | ||
|
|
2ebafc3eeb | ||
|
|
8288559e44 | ||
|
|
2caf3f0174 | ||
|
|
e88e48906d | ||
|
|
8fb5153983 | ||
|
|
03725b0ab4 | ||
|
|
b0896ea465 | ||
|
|
654e9a79c5 | ||
|
|
7f541e2623 | ||
|
|
198e905050 | ||
|
|
3744018af8 | ||
|
|
a21ba04e95 | ||
|
|
bf4d39421b | ||
|
|
2e4935715f | ||
|
|
cf8ce9642a | ||
|
|
cac65d9030 | ||
|
|
4a83829dfd | ||
|
|
c0348484fe | ||
|
|
213133ab45 | ||
|
|
8469eac18c | ||
|
|
5aaa1bb5b3 | ||
|
|
9f500b85e6 | ||
|
|
0d6fd8d7ad | ||
|
|
7e4b6dbf31 | ||
|
|
8bf3f0f094 | ||
|
|
198acef666 | ||
|
|
1d0c76b2b2 | ||
|
|
567875cf00 | ||
|
|
58069e8925 | ||
|
|
a90cf3c72b | ||
|
|
2fbf226ccd | ||
|
|
d674672ce2 | ||
|
|
dab7968ce3 | ||
|
|
510719f890 | ||
|
|
96b92239b0 | ||
|
|
363029cbdd | ||
|
|
7783a8de15 | ||
|
|
26a589fc1d | ||
|
|
4c467c304f | ||
|
|
9496b9396a | ||
|
|
669a9ee1e3 | ||
|
|
d08b7c2d94 | ||
|
|
534f6aa22c | ||
|
|
8ea731159f | ||
|
|
7704fa9318 | ||
|
|
d0e3de7121 | ||
|
|
40af1862a0 | ||
|
|
33e24aa46c | ||
|
|
5a97561389 | ||
|
|
26701d84f7 | ||
|
|
d13b09aaf3 | ||
|
|
6a65b61785 | ||
|
|
2b8bfab44b | ||
|
|
b9e1d79be6 | ||
|
|
0f9e1819c1 | ||
|
|
eda97347fc | ||
|
|
2bd24b6a8b | ||
|
|
8306342ab6 | ||
|
|
6b6ba91721 | ||
|
|
68155e6a6b | ||
|
|
bfbceefef2 | ||
|
|
21b39135fe | ||
|
|
6adc7f7221 | ||
|
|
6bfa8d1ea4 | ||
|
|
6f22269d93 | ||
|
|
b68dc98ae0 | ||
|
|
f9ad1f724b | ||
|
|
afd22635bd | ||
|
|
a9f9706be3 | ||
|
|
41f35498fe | ||
|
|
58628b6556 | ||
|
|
875858618e | ||
|
|
70b7bf390a | ||
|
|
de3d6de4cf | ||
|
|
e3b4caa37d | ||
|
|
f8e19f7772 | ||
|
|
ea5dd8b1bf | ||
|
|
bd7db1a016 | ||
|
|
02ac048d74 | ||
|
|
9a3c9b9cbd | ||
|
|
80c77c740e | ||
|
|
0f62662963 | ||
|
|
576d6515db | ||
|
|
30d29bfa80 | ||
|
|
c7c0446f23 | ||
|
|
134777584d | ||
|
|
0b64eadb0c | ||
|
|
ea93960bf4 | ||
|
|
71032e3010 | ||
|
|
d6a3a351f5 | ||
|
|
a574bca48e | ||
|
|
785faf1bf4 | ||
|
|
fbcc32b3ee | ||
|
|
46b19a9de5 | ||
|
|
d2f47d51f9 | ||
|
|
db380507f5 | ||
|
|
84cf67d21a | ||
|
|
8f53591800 | ||
|
|
65ffd78844 | ||
|
|
c00b5e6635 | ||
|
|
8160991086 | ||
|
|
f0c933d97a | ||
|
|
3fb8d3e73b | ||
|
|
d8efff9921 | ||
|
|
32170688b6 | ||
|
|
ca74bfe2e4 | ||
|
|
41767f0fd7 | ||
|
|
c62ca4dd23 | ||
|
|
9c5eddb903 | ||
|
|
4a0df07805 | ||
|
|
37a3edd44b | ||
|
|
f117abd483 | ||
|
|
4593714298 | ||
|
|
a148fd6ec3 | ||
|
|
23a44e2f3b | ||
|
|
01e03ec0f0 | ||
|
|
4594ac592c | ||
|
|
eee0f2dded | ||
|
|
b4080302c3 | ||
|
|
337e210b5b | ||
|
|
a05b9174d4 | ||
|
|
aa8adfb6f7 | ||
|
|
1034fcd7b0 | ||
|
|
69a26aeedb | ||
|
|
dd607b41e9 | ||
|
|
fd45319715 | ||
|
|
c34ba56896 | ||
|
|
6e00a4133c | ||
|
|
9924b6ec0b | ||
|
|
4d09504abc | ||
|
|
f901bd2336 | ||
|
|
187c35fe88 | ||
|
|
cc94bed772 | ||
|
|
8c9cdf46db | ||
|
|
09dd200655 | ||
|
|
38294e8cfc | ||
|
|
87a42cf53d | ||
|
|
2adf2c15fa | ||
|
|
99ac2a287e | ||
|
|
371ccab596 | ||
|
|
590c505f33 | ||
|
|
01c2f3ea69 | ||
|
|
4c4eec118d | ||
|
|
310be050d8 | ||
|
|
181e0301aa | ||
|
|
a86ca2e82c | ||
|
|
85c911cf35 | ||
|
|
db57e2dde6 | ||
|
|
c163ad42a6 | ||
|
|
a2af3a4652 | ||
|
|
59a9448d70 | ||
|
|
22b87de29d | ||
|
|
d98292da1d | ||
|
|
5422c04c53 | ||
|
|
0a5783de89 | ||
|
|
717e2191b0 | ||
|
|
eedc3ba5eb | ||
|
|
30ee1816df | ||
|
|
940047de11 | ||
|
|
c0e2041efe | ||
|
|
8f9d2adcfe | ||
|
|
1bfda83665 | ||
|
|
39b896e1b9 | ||
|
|
cfe7ee7f9c | ||
|
|
2a95d6707a | ||
|
|
f4fe5f1783 | ||
|
|
10040b2923 | ||
|
|
42c56616fb | ||
|
|
f8c926e1cd | ||
|
|
2adf620059 | ||
|
|
4bdc182520 | ||
|
|
bc4c7f62a0 | ||
|
|
b2d0c59913 | ||
|
|
ceb5424772 | ||
|
|
5a5a5da2d9 | ||
|
|
0ff9b03596 | ||
|
|
acbe4eafa9 | ||
|
|
0a5600d949 | ||
|
|
63a83257fe | ||
|
|
d115e28403 | ||
|
|
3d1ae0acfc | ||
|
|
a3a01065c0 | ||
|
|
ae33d692bf | ||
|
|
39f55d7db1 | ||
|
|
a86f8d6096 | ||
|
|
b28fc3ffc4 | ||
|
|
5d4f544b94 | ||
|
|
b0f0686821 | ||
|
|
b7c8afe7d2 | ||
|
|
02855b68e6 | ||
|
|
cf8097babc | ||
|
|
2d5a2022b4 | ||
|
|
2fac22970e | ||
|
|
8c10836e6e | ||
|
|
69bba560f0 | ||
|
|
a9d5c15bd9 | ||
|
|
1d0812ddaf | ||
|
|
02bdc9c1a3 | ||
|
|
6a08460e8e | ||
|
|
091ad5cf0f | ||
|
|
f911e4629c | ||
|
|
0265ddc6e1 | ||
|
|
ead2300d90 | ||
|
|
b3a8547527 | ||
|
|
37a5dbd20d | ||
|
|
c20dc66db3 | ||
|
|
31c32123c9 | ||
|
|
14faa38de3 | ||
|
|
4827b7e077 | ||
|
|
2d9a17bd25 | ||
|
|
ce3ad45c09 | ||
|
|
44fcc21d9c | ||
|
|
5c1a6808d7 | ||
|
|
d461b1b8b6 | ||
|
|
d74b0448d5 | ||
|
|
ed2a37c615 | ||
|
|
34c51d3115 | ||
|
|
f85d36d14d | ||
|
|
9818f227d7 | ||
|
|
01353e05cc | ||
|
|
02eaedd6a0 | ||
|
|
c71c872aa2 | ||
|
|
d79dc0c630 | ||
|
|
46cf695bde | ||
|
|
c913a7eb9e | ||
|
|
887c46c87f | ||
|
|
e4d3501f93 | ||
|
|
add98bb630 | ||
|
|
05651584dc | ||
|
|
37171840d3 | ||
|
|
4ee8fbedbf | ||
|
|
274e6a0666 | ||
|
|
b26686823e | ||
|
|
64354ea511 | ||
|
|
07cce5bbad | ||
|
|
bbab9522df | ||
|
|
1a6d839ca0 | ||
|
|
0d666a633f | ||
|
|
b24679adbd | ||
|
|
90b4d643d4 | ||
|
|
469f2871f7 | ||
|
|
c7766de766 | ||
|
|
314de6a6a7 | ||
|
|
9c148dd58d | ||
|
|
1ae469facc | ||
|
|
eada6641e4 | ||
|
|
2eb50803b5 | ||
|
|
29e3e876c7 | ||
|
|
1c38dbaa0b | ||
|
|
31dcd349df | ||
|
|
ee504e3361 | ||
|
|
11426e1c4c | ||
|
|
13346f1124 | ||
|
|
f38f3989e7 | ||
|
|
5c33ca1c9a | ||
|
|
3599ffb805 | ||
|
|
344cd1305c | ||
|
|
84fe0b9cb7 | ||
|
|
e5963208b1 | ||
|
|
8bc84b404d | ||
|
|
80d75661c1 | ||
|
|
1c74a422bc | ||
|
|
f06c2d6805 | ||
|
|
fdbe06e8c5 | ||
|
|
15a9c4ee45 | ||
|
|
38c90f35f2 | ||
|
|
bf3ee4cce2 | ||
|
|
9553491040 | ||
|
|
0253d92c7f | ||
|
|
e2ac340b6f | ||
|
|
44b60185cc | ||
|
|
9b3ffd1f2c | ||
|
|
935c8e7d15 | ||
|
|
8f5094efef | ||
|
|
91accb6655 | ||
|
|
4f23cf5d8d | ||
|
|
39f76246c8 | ||
|
|
8ac2b027ec | ||
|
|
919d22ebf1 | ||
|
|
14a28c681a | ||
|
|
388bccc468 | ||
|
|
639d94795c | ||
|
|
51e2f44868 | ||
|
|
92b9b9879c | ||
|
|
c867a74aea | ||
|
|
e9a1bf22b1 | ||
|
|
46271fb0d2 | ||
|
|
7438b17366 | ||
|
|
8306640ed6 | ||
|
|
39b7623688 | ||
|
|
41b46035e4 | ||
|
|
10045494b8 | ||
|
|
ea67a022d8 | ||
|
|
203c89e3a8 | ||
|
|
1c88be6f82 | ||
|
|
2a19bcd73b | ||
|
|
9f29594ad6 | ||
|
|
9677e6ac80 | ||
|
|
1590ca4b80 | ||
|
|
effe7530ed | ||
|
|
19f270e320 | ||
|
|
25d876f8b9 | ||
|
|
179e470154 | ||
|
|
5cf122c30c | ||
|
|
36895de83b | ||
|
|
fed5285a31 | ||
|
|
b1fbefc09e | ||
|
|
2fd9982c37 | ||
|
|
89a108574a | ||
|
|
28ce6ee13e | ||
|
|
4441ea2c5d | ||
|
|
02489893ec | ||
|
|
62c3e9290e | ||
|
|
3f53710c5b | ||
|
|
389f27dfa1 | ||
|
|
e2d03eb928 | ||
|
|
37ec49ed69 | ||
|
|
4694245b51 | ||
|
|
60b77145a9 | ||
|
|
28a6f8cd2b | ||
|
|
02a3c1c54b | ||
|
|
09df7cc39b | ||
|
|
a4ce60c849 | ||
|
|
d74f18012b | ||
|
|
3609379284 | ||
|
|
19f9105640 | ||
|
|
24664d4e83 | ||
|
|
e16b5b0437 | ||
|
|
94747da3d0 | ||
|
|
df8c70d8e6 | ||
|
|
7fd3361608 | ||
|
|
d9522e4e89 | ||
|
|
a8c96fa7df | ||
|
|
5570933be4 | ||
|
|
fb6cb8d3fb | ||
|
|
4ca7b6b11c | ||
|
|
5c377d346e | ||
|
|
1dd0eeb2ed | ||
|
|
3f6abd6380 | ||
|
|
407c55dbdc | ||
|
|
74afa6c764 | ||
|
|
60ccd988cb | ||
|
|
505ba6e4e3 | ||
|
|
d4d6fe56a9 | ||
|
|
740fff2178 | ||
|
|
54a2ea64bc | ||
|
|
200882e13c | ||
|
|
dac28b9b6a | ||
|
|
7a8ae183da | ||
|
|
c163e24434 | ||
|
|
eed30084bc | ||
|
|
137a51dad0 | ||
|
|
b71d326620 | ||
|
|
371622770b | ||
|
|
2b6bcf6698 | ||
|
|
bc33ea84f2 | ||
|
|
3d7210ec08 | ||
|
|
e7bed5f5eb | ||
|
|
a3237a024e | ||
|
|
662fc6859b | ||
|
|
5bb61959bd | ||
|
|
8ae75101ef | ||
|
|
95fcab0980 | ||
|
|
d2b141e218 | ||
|
|
73eb91f4b4 | ||
|
|
61c51f8882 | ||
|
|
cb9f36dd52 | ||
|
|
80b0203af2 | ||
|
|
66155eed1c | ||
|
|
144e8a2951 | ||
|
|
7c1f521960 | ||
|
|
dbe528269d | ||
|
|
9b843e84b2 | ||
|
|
c9ef0e5406 | ||
|
|
1a49b3d00b | ||
|
|
33502c88db | ||
|
|
6554735c63 | ||
|
|
2360e6376e | ||
|
|
b1e186a5f1 | ||
|
|
ffd2b5a342 | ||
|
|
d5a16f50c5 | ||
|
|
5b03e67108 | ||
|
|
eac5b2641b | ||
|
|
e46008df55 | ||
|
|
07b1f39796 | ||
|
|
64d3849b62 | ||
|
|
9d766f47c5 | ||
|
|
64841e6e3b | ||
|
|
571fbabf4f | ||
|
|
12c3ad6d5f | ||
|
|
7c987ec868 | ||
|
|
27686e952a | ||
|
|
de06c24924 | ||
|
|
4e1b4ddf28 | ||
|
|
ca21b5e713 | ||
|
|
5a6a01f813 | ||
|
|
16c6353459 | ||
|
|
d1623d411a | ||
|
|
4e4b072c16 | ||
|
|
f2601fb672 | ||
|
|
125c467c1b | ||
|
|
0b95c340d6 | ||
|
|
79e0b33aad | ||
|
|
f1f7b8dc88 | ||
|
|
e97e539f92 | ||
|
|
4b562f98f0 | ||
|
|
bd06d76656 | ||
|
|
38ddca2342 | ||
|
|
1119798ce8 | ||
|
|
1eeab2f03d | ||
|
|
bfbe6b8e6a | ||
|
|
4905c955bc | ||
|
|
4cf698a10a | ||
|
|
4b66f58fd3 | ||
|
|
325909401c | ||
|
|
652d6a2f28 | ||
|
|
7672a82260 | ||
|
|
0f37d17bf3 | ||
|
|
c923d74fec | ||
|
|
2ba8640996 | ||
|
|
0b1a0cade8 | ||
|
|
78aab4f6c7 | ||
|
|
77502e1a7c | ||
|
|
b90f221ede | ||
|
|
ee68b421d6 | ||
|
|
88be232e70 | ||
|
|
da9de7a823 | ||
|
|
f08e124df6 | ||
|
|
ce888a0982 | ||
|
|
f59789a11e | ||
|
|
c8a3db8a3e | ||
|
|
23366c8ea1 | ||
|
|
6e65afa7e2 | ||
|
|
29b81aa90e | ||
|
|
d85090787f | ||
|
|
0eb3cc9073 | ||
|
|
dfd9af8ee3 | ||
|
|
1120c23709 | ||
|
|
975421044c | ||
|
|
802b63ed5a | ||
|
|
d32a0d6b7f | ||
|
|
0c5a1a6533 | ||
|
|
61796f4cd3 | ||
|
|
80726a7ff0 | ||
|
|
a2fdcc57f8 | ||
|
|
bffb32eafd | ||
|
|
2c452d236c | ||
|
|
e7e036f7c6 | ||
|
|
fbb702cacd | ||
|
|
598438a5f9 | ||
|
|
24a1c94f04 | ||
|
|
e4e053a49b | ||
|
|
8c0e217117 | ||
|
|
174e899ead | ||
|
|
84cc915d95 | ||
|
|
7668f568f0 | ||
|
|
35a7cc2067 | ||
|
|
efa0823293 | ||
|
|
1473f6326d | ||
|
|
861c05db44 | ||
|
|
09b92cc709 | ||
|
|
a2d9113be2 | ||
|
|
a64c7d9f22 | ||
|
|
97090a4dc6 | ||
|
|
cf2c5b7e82 | ||
|
|
6ee5b636c2 | ||
|
|
de9fa5be5a | ||
|
|
ffc3693674 | ||
|
|
a3abd224e8 | ||
|
|
ac680afad3 | ||
|
|
52c21319d6 | ||
|
|
7b38171a9d | ||
|
|
c9ef60db67 | ||
|
|
aff75c2dec | ||
|
|
63fcca3c7d | ||
|
|
2e3a148c7a | ||
|
|
a7b239f0b9 | ||
|
|
227cbd6fba | ||
|
|
8d19dffa01 | ||
|
|
f3e1400d4c | ||
|
|
ef891ea23d | ||
|
|
043a1d8fe7 | ||
|
|
e428695052 | ||
|
|
459dd50e91 | ||
|
|
4c286a279f | ||
|
|
88c394480e | ||
|
|
cdd5585124 | ||
|
|
b0346b4e9d | ||
|
|
beecd6b109 | ||
|
|
54d7abd880 | ||
|
|
9f77a4ce0a | ||
|
|
754a20ee3c | ||
|
|
b5b096aeae | ||
|
|
d0ecac07aa | ||
|
|
67e6387fa8 | ||
|
|
bc34f25a3c | ||
|
|
afc38c2de8 | ||
|
|
c020af3083 | ||
|
|
3f509f8c11 | ||
|
|
75eb25db18 | ||
|
|
79d173cb0d | ||
|
|
f3eb2c8c17 | ||
|
|
d15685e1ca | ||
|
|
11535f7d7b | ||
|
|
0b526040a3 | ||
|
|
15696f4e6e | ||
|
|
0c560518c8 | ||
|
|
302cba9f61 | ||
|
|
3a33a2425f | ||
|
|
a5df907bbe | ||
|
|
6879a02a63 | ||
|
|
d86d72212f | ||
|
|
de528ec277 | ||
|
|
6f41ddda51 | ||
|
|
ffaf8b9c46 | ||
|
|
aab1c12aed | ||
|
|
4e427f2761 | ||
|
|
2a6247a89d | ||
|
|
62c3e9fd99 | ||
|
|
1690651428 | ||
|
|
ea95b1c525 | ||
|
|
f67c80a3a3 | ||
|
|
6c1ffeacb2 | ||
|
|
753206c2fb | ||
|
|
2ae8265d05 | ||
|
|
7df7a783f6 | ||
|
|
2829d081cc | ||
|
|
bb3a88813b | ||
|
|
2da8cfde01 | ||
|
|
2e23167e94 | ||
|
|
9131f6f8cb | ||
|
|
a77a1fd3e1 | ||
|
|
9dfc1324ad | ||
|
|
c84e86a5a1 | ||
|
|
be867d5d07 | ||
|
|
5457044dd5 | ||
|
|
be2330f1b6 | ||
|
|
eb18e74884 | ||
|
|
fd05d03bca | ||
|
|
69db5bd400 | ||
|
|
a87d720ae3 | ||
|
|
7b81a9aa50 | ||
|
|
b07fd2bc4f | ||
|
|
3c64486c3b | ||
|
|
8cb4045589 | ||
|
|
7edac11d53 | ||
|
|
838f8ac98c | ||
|
|
3a57d43aa4 | ||
|
|
69870803f7 | ||
|
|
eef5e5485a | ||
|
|
ebbe26e5e6 | ||
|
|
0cd83d3e4c | ||
|
|
1c07c61307 | ||
|
|
b602fa1204 | ||
|
|
273bed9ba1 | ||
|
|
028405ecce | ||
|
|
ada4158c8e | ||
|
|
fc99c611a6 | ||
|
|
fce4a2751a | ||
|
|
557818e59f | ||
|
|
a85f3cbe0b | ||
|
|
5d8acd9577 | ||
|
|
e2bf887b94 | ||
|
|
4a0893c573 | ||
|
|
839d074df1 | ||
|
|
9be7705050 | ||
|
|
470a2baa6a | ||
|
|
fb8de517a0 | ||
|
|
635de44299 | ||
|
|
1d4bd9a294 | ||
|
|
a0b48a5cc7 | ||
|
|
eb726ccbf4 | ||
|
|
3f484a49e8 | ||
|
|
09cd08bfaa | ||
|
|
e6312a37c7 | ||
|
|
862b3e5e46 | ||
|
|
0042482107 | ||
|
|
85bc215e00 | ||
|
|
2db5a749a0 | ||
|
|
8c439b1167 | ||
|
|
4eb1a4141f | ||
|
|
4f47febc06 | ||
|
|
c61afc7a04 | ||
|
|
b59966e8a4 | ||
|
|
457cf2e856 | ||
|
|
4a7626c6f6 | ||
|
|
947452e3f1 | ||
|
|
b6de84c369 | ||
|
|
0adc43b243 | ||
|
|
0c9a8624bc | ||
|
|
09e9d3ff5a | ||
|
|
7240ca4eba | ||
|
|
0a2c29a693 | ||
|
|
bba875238c | ||
|
|
c33248b1bf | ||
|
|
24431051ae | ||
|
|
1758e25388 | ||
|
|
a27e8b99d9 | ||
|
|
a06e76e934 | ||
|
|
14609583b5 | ||
|
|
751a89c107 | ||
|
|
619c8f6deb | ||
|
|
c3835b8a65 | ||
|
|
5fd890cf9b | ||
|
|
40c6135214 | ||
|
|
cfa1ce8ab6 | ||
|
|
260dafcd79 | ||
|
|
73b3cd4625 | ||
|
|
d895a07583 | ||
|
|
b84872aca2 | ||
|
|
0ef4bccb7c | ||
|
|
dfc6c6a030 | ||
|
|
b62f1d0c9f | ||
|
|
8abb5d9fb4 | ||
|
|
5f13725173 | ||
|
|
7f8b41f998 | ||
|
|
1319060311 | ||
|
|
d1f914c2fa | ||
|
|
46cd1013fb | ||
|
|
2ed516cf85 | ||
|
|
2ce55b4aef | ||
|
|
df7071a22c | ||
|
|
707529972e | ||
|
|
cf2796ebaa | ||
|
|
9611d81969 | ||
|
|
fb31f627a1 | ||
|
|
4741e4f858 | ||
|
|
b44ddf980b | ||
|
|
47b97243c3 | ||
|
|
b695b06507 | ||
|
|
110fb9fb59 | ||
|
|
fe7c979d78 | ||
|
|
0d10899417 | ||
|
|
ff89afb8c1 | ||
|
|
188248c634 | ||
|
|
0d3c942984 | ||
|
|
2b520be693 | ||
|
|
4b831a2ee1 | ||
|
|
59037d60e2 | ||
|
|
61917285d5 | ||
|
|
453f77dd3e | ||
|
|
b40004d9ba | ||
|
|
f8f2d020eb | ||
|
|
4f09de8a69 | ||
|
|
2d20da70b8 | ||
|
|
cf95e7b034 | ||
|
|
b5709a49f4 | ||
|
|
75a7143442 | ||
|
|
3e47d82713 | ||
|
|
62f9361d25 | ||
|
|
3a97b93b6d | ||
|
|
3b9850b90d | ||
|
|
c0636e93c6 | ||
|
|
5ff1131dee | ||
|
|
8aca589b0f | ||
|
|
10f6bd4bf6 | ||
|
|
dbe84e8bda | ||
|
|
f4de403cdd | ||
|
|
9024afed19 | ||
|
|
d8921377b3 | ||
|
|
b80deafaa8 | ||
|
|
506c63380a | ||
|
|
9e4fc2e7af | ||
|
|
0a8df26549 | ||
|
|
d2bbd1b842 | ||
|
|
5974ce11a1 | ||
|
|
3ec700da56 | ||
|
|
cb7b601f58 | ||
|
|
8e08a4881f | ||
|
|
2fac1c8e4c | ||
|
|
d240fb7e05 | ||
|
|
326d378979 | ||
|
|
71f91bf054 | ||
|
|
40e4d40683 | ||
|
|
c9d439e748 | ||
|
|
0ec90655c0 | ||
|
|
c6949cd09b | ||
|
|
1e47170c3b | ||
|
|
b7d2e4e5da | ||
|
|
28c7a701ca | ||
|
|
52560b6b95 | ||
|
|
1c2c18bff1 | ||
|
|
ed1603eec4 | ||
|
|
2206dd85bc | ||
|
|
62509e1500 | ||
|
|
56cad66aec | ||
|
|
660d917f97 | ||
|
|
0ca5572684 | ||
|
|
cbebdb542d | ||
|
|
84d13fe9c5 | ||
|
|
c6919c39c6 | ||
|
|
92b6069654 | ||
|
|
804dffc81a | ||
|
|
5831761fc0 | ||
|
|
c887379b8b | ||
|
|
82c92203b6 | ||
|
|
881948554e | ||
|
|
b0357201a5 | ||
|
|
7ddeaf6d16 | ||
|
|
942abd7dbb | ||
|
|
9f78b69390 | ||
|
|
6e561ca9a9 | ||
|
|
cec86576c1 | ||
|
|
9eb8e984b6 | ||
|
|
20798b5d25 | ||
|
|
29fafdf216 | ||
|
|
2fbda42e53 | ||
|
|
285feb5f5b | ||
|
|
cfdb8793c6 | ||
|
|
55b3753e66 | ||
|
|
ad04681460 | ||
|
|
2e132f06b7 | ||
|
|
dc74266927 | ||
|
|
e002e15a66 | ||
|
|
e149c7065e | ||
|
|
107a5ce626 | ||
|
|
b6d69f7a02 | ||
|
|
6de6c89439 | ||
|
|
c1ca6dcd5d | ||
|
|
223ebd6acd | ||
|
|
cc8311e116 | ||
|
|
a66f53e562 | ||
|
|
de699dacfe | ||
|
|
431007a731 | ||
|
|
797d511c2c | ||
|
|
0c40be5da8 | ||
|
|
2fc04caa05 | ||
|
|
78ffe38f54 | ||
|
|
8152a04155 | ||
|
|
64b39275e2 | ||
|
|
23c6291cc8 | ||
|
|
60fe67b97a | ||
|
|
96264a28a6 | ||
|
|
b86cb676d6 | ||
|
|
a05fc8447d | ||
|
|
68a617b952 | ||
|
|
f18bfab35f | ||
|
|
c04f30a5b7 | ||
|
|
7a35d60b71 | ||
|
|
cd3fa38161 | ||
|
|
6a65eabf28 | ||
|
|
0905a4dfba | ||
|
|
c68c011e69 | ||
|
|
a57066b6db | ||
|
|
0b19cc71c9 | ||
|
|
38e6b60005 | ||
|
|
35a18ecc0f | ||
|
|
5fb2ec2fda | ||
|
|
61a2ae9431 | ||
|
|
cba05171af | ||
|
|
816d63e432 | ||
|
|
56c2e6fcde | ||
|
|
d6aee24295 | ||
|
|
13b28c0f38 | ||
|
|
2f69b942d9 | ||
|
|
5977d77381 | ||
|
|
fe336ebf6a | ||
|
|
c44776870e | ||
|
|
67d5942aff | ||
|
|
48e3b44658 | ||
|
|
89347768b3 | ||
|
|
2ed726427f | ||
|
|
8ee20070b6 | ||
|
|
ca9e1e93d9 | ||
|
|
d9ea549b51 | ||
|
|
0860bb488f | ||
|
|
8efc5401cb | ||
|
|
13e5649948 | ||
|
|
bb77c4ecfc | ||
|
|
3d16151bd2 | ||
|
|
9053b200b2 | ||
|
|
a450dd29f9 | ||
|
|
2f309fe9bb | ||
|
|
5f9f7d0ba7 | ||
|
|
6f1a08f2c7 | ||
|
|
563f6810be | ||
|
|
66ed7a04a4 | ||
|
|
626475a91f | ||
|
|
f99575771c | ||
|
|
bc5a0f9140 | ||
|
|
40958179ca | ||
|
|
d98006c2cd | ||
|
|
5134c9b378 | ||
|
|
1379953a9c | ||
|
|
cc02b69020 | ||
|
|
55b4edac4d | ||
|
|
b56f136da0 | ||
|
|
d2b5e5ec01 | ||
|
|
623ab63d8d | ||
|
|
3b1beba570 | ||
|
|
4e6210c1f8 | ||
|
|
281154be7a | ||
|
|
9b4477766c | ||
|
|
53bbabab75 | ||
|
|
b1671eacb7 | ||
|
|
b41e564411 | ||
|
|
48e12154c3 | ||
|
|
5c25e2801c | ||
|
|
c2d2c1c4f6 | ||
|
|
59959bb9ee | ||
|
|
3664ca846c | ||
|
|
8c6d28d6e2 | ||
|
|
b3acd1d603 | ||
|
|
d76e056b91 | ||
|
|
5de5dbabef | ||
|
|
866ea6369e | ||
|
|
ae2f7204fa | ||
|
|
5be2b77e42 | ||
|
|
8f1f76c3d1 | ||
|
|
6f488c1d00 | ||
|
|
ee7724e754 | ||
|
|
6c4848b6f9 | ||
|
|
b6c36c20b6 | ||
|
|
a29fc4ce94 | ||
|
|
6490598fc3 | ||
|
|
f3519f6f8a | ||
|
|
d44192079d | ||
|
|
140fac4f3b | ||
|
|
802db256c1 | ||
|
|
c8a9cfa8a3 | ||
|
|
2213969c6e | ||
|
|
524a3a94c4 | ||
|
|
4ec58a0f62 | ||
|
|
e25227e39d | ||
|
|
7efaa64562 | ||
|
|
a2b95f6c61 | ||
|
|
9a6aa1a591 | ||
|
|
de780635e4 | ||
|
|
3dbb40967f | ||
|
|
f39d17abc0 | ||
|
|
a015e54569 | ||
|
|
a256864c84 | ||
|
|
d74b5bff7b | ||
|
|
31e7943d22 | ||
|
|
b2d1660e95 | ||
|
|
5d13e29300 | ||
|
|
aaf9ef06dd | ||
|
|
6725ef992a | ||
|
|
b5baecf8d0 | ||
|
|
58d1ace612 | ||
|
|
a4eca58275 | ||
|
|
c97974eb72 | ||
|
|
c46c386fea | ||
|
|
3f4ca1bcbf | ||
|
|
e4e04a4508 | ||
|
|
6d87dc0b1c | ||
|
|
db16a0c17c | ||
|
|
8fc411a30b | ||
|
|
c4a15f8e00 | ||
|
|
90e6918db0 | ||
|
|
62d7d09886 | ||
|
|
d9c933bd0a | ||
|
|
06c3e3c8a0 | ||
|
|
f284ac71b5 | ||
|
|
cd969ac33b | ||
|
|
ac43df5e03 | ||
|
|
8ea6417ea6 | ||
|
|
19295e1d30 | ||
|
|
f84b10f2eb | ||
|
|
184edf9d4c | ||
|
|
257e247e23 | ||
|
|
a2f0b4a64f | ||
|
|
9f1ec2be7e | ||
|
|
046ba62256 | ||
|
|
c9f18b0b71 | ||
|
|
b61e1bdbe3 | ||
|
|
1a01caee2c | ||
|
|
2fed610470 | ||
|
|
2026843628 | ||
|
|
9997d31421 | ||
|
|
1079e4a759 | ||
|
|
ce5c258cf9 | ||
|
|
c1b76b35ec | ||
|
|
e9cb083672 | ||
|
|
034a5c2071 | ||
|
|
6c7e3019ff | ||
|
|
fc02902ccb | ||
|
|
f33ff6d380 | ||
|
|
2c30deb298 | ||
|
|
6ea635a1e9 | ||
|
|
858134927a | ||
|
|
0eec51ef8e | ||
|
|
de065076df | ||
|
|
ad4c418736 | ||
|
|
9ab368a760 | ||
|
|
59f3cf20a5 | ||
|
|
8a58b6ee0f | ||
|
|
d6816c89e5 | ||
|
|
7ca37ee54a | ||
|
|
4b4304629f | ||
|
|
dba557b942 | ||
|
|
fe158e7f62 | ||
|
|
ac7fed649a | ||
|
|
cb67a51686 | ||
|
|
4d85a2aa41 | ||
|
|
0df875d65a | ||
|
|
fff1ec0947 | ||
|
|
250a7ef25e | ||
|
|
805d22802c | ||
|
|
9745ce7d34 | ||
|
|
c165c15099 | ||
|
|
351231aab9 | ||
|
|
0e78494f39 | ||
|
|
886ce38543 | ||
|
|
f542c8a12e | ||
|
|
c35cac860f | ||
|
|
afcdc5ec5b | ||
|
|
b9f24001ed | ||
|
|
1f0319c242 | ||
|
|
5e8e95f716 | ||
|
|
dd73b20b3f | ||
|
|
c6a83ac6b2 | ||
|
|
6ea7a1405f | ||
|
|
774db8d3a4 | ||
|
|
a7187d62d3 | ||
|
|
e5788b9ec5 | ||
|
|
be96491091 | ||
|
|
ea0b83476f | ||
|
|
187f77d32f | ||
|
|
46655e3326 | ||
|
|
4f1615b736 | ||
|
|
8b3ab44c1c | ||
|
|
10b6258175 | ||
|
|
13b532c12a | ||
|
|
126f4238d6 | ||
|
|
9666feac57 | ||
|
|
d464d00067 | ||
|
|
6e96571cc8 | ||
|
|
2b70c983bf | ||
|
|
3a2c18d8a9 | ||
|
|
29fb40eecc | ||
|
|
684d25780e | ||
|
|
51a292e5d0 | ||
|
|
4f99107ac5 | ||
|
|
e4685c7018 | ||
|
|
6a42793a59 | ||
|
|
4a81df4174 | ||
|
|
512e961820 | ||
|
|
cbccf7e7fa | ||
|
|
f1890c2d3e | ||
|
|
0c30b20a66 | ||
|
|
14b3f13338 | ||
|
|
0f75f5ec69 | ||
|
|
bdbc5438aa | ||
|
|
525131dbaf | ||
|
|
f8938a46bb | ||
|
|
50ce18d201 | ||
|
|
bba06321c8 | ||
|
|
3439b684e1 | ||
|
|
0ffba596e5 | ||
|
|
c112322daf | ||
|
|
a942a487a0 | ||
|
|
7f02c27a3a | ||
|
|
a69edd5c55 | ||
|
|
f8a0d8b9c5 | ||
|
|
a7214740ec | ||
|
|
17fb0f724c | ||
|
|
5e14dad961 | ||
|
|
dc48363398 | ||
|
|
df4a8ec15e | ||
|
|
810e3ff5fe | ||
|
|
aef065a057 | ||
|
|
1824786a80 | ||
|
|
c8b7fed168 | ||
|
|
4118390283 | ||
|
|
13a9fd36d3 | ||
|
|
9ad933934f | ||
|
|
92240c6c2c | ||
|
|
689a78d2ee | ||
|
|
7ed0b93faa | ||
|
|
3a004c41f8 | ||
|
|
90ed83efd5 | ||
|
|
3a2ccf86fd | ||
|
|
4e6f906903 | ||
|
|
c73ca48e35 | ||
|
|
e1d7b3132d | ||
|
|
1f4f99079b | ||
|
|
bf495336d9 | ||
|
|
cc636bcae0 | ||
|
|
cf185a6148 | ||
|
|
f92ce637bf | ||
|
|
2a34d6eb8b | ||
|
|
a8e3f67371 | ||
|
|
4a7d4dedd0 | ||
|
|
7d3178015b | ||
|
|
54079990d0 | ||
|
|
a379391862 | ||
|
|
dfb2fbf88b | ||
|
|
68f201980a | ||
|
|
9a079083e9 | ||
|
|
1ee1b122fe | ||
|
|
25d4d5e393 | ||
|
|
1743caa869 | ||
|
|
958fdb19b4 | ||
|
|
4b63648a79 | ||
|
|
498b84df37 | ||
|
|
7a4e65259d | ||
|
|
8cb8dcbe0f | ||
|
|
da37b3cdff | ||
|
|
0a1768e481 | ||
|
|
818d16a32d | ||
|
|
e9a5d1cc7c | ||
|
|
dac56f3e32 | ||
|
|
d6cbcdc6cd | ||
|
|
c5c1170383 | ||
|
|
6ed3fb29d9 | ||
|
|
74c6bfa479 | ||
|
|
d44981a70c | ||
|
|
06e411d332 | ||
|
|
f419189749 | ||
|
|
aa1e2102fc | ||
|
|
306ce9ed21 | ||
|
|
544fcb2e88 | ||
|
|
cb01df4071 | ||
|
|
38310b7c5a | ||
|
|
fcd56ff4e9 | ||
|
|
41300a9fd4 | ||
|
|
0bd5f9dc31 | ||
|
|
004ecd0dd3 | ||
|
|
fc24a18ac5 | ||
|
|
a9a8c68b94 | ||
|
|
193d2f8d9e | ||
|
|
538da9b98f | ||
|
|
071b597552 | ||
|
|
8926d74378 | ||
|
|
39a4b03bc3 | ||
|
|
9202bbc7dc | ||
|
|
f5601ebca1 | ||
|
|
2f978b554e | ||
|
|
f48a90d941 | ||
|
|
4f0d9fa83c | ||
|
|
57a747ed9c | ||
|
|
746a045328 | ||
|
|
2a4c7823c2 | ||
|
|
b995510df1 | ||
|
|
a2852d6df9 | ||
|
|
47863580a0 | ||
|
|
9af6532331 | ||
|
|
36f411a031 | ||
|
|
00b6185188 | ||
|
|
a7db6c8613 | ||
|
|
86097ace72 | ||
|
|
b62dd1fcac | ||
|
|
9a3b91c610 | ||
|
|
0f25789d74 | ||
|
|
b50185639e | ||
|
|
95478a615e | ||
|
|
91164e4dd6 | ||
|
|
ea42fa5613 | ||
|
|
c620478e38 | ||
|
|
467ab0b5a2 | ||
|
|
1d14e3ceb4 | ||
|
|
c4ff48f60f | ||
|
|
196190314b | ||
|
|
4c7b4dbc51 | ||
|
|
b820159736 | ||
|
|
41991b8f22 | ||
|
|
6246d01247 | ||
|
|
3734d0c585 | ||
|
|
d70c5be15a | ||
|
|
814230f4aa | ||
|
|
2b64491e76 | ||
|
|
f770ac9ac9 | ||
|
|
a6a3219d1e | ||
|
|
c1eddb5876 | ||
|
|
37dcad7d6f | ||
|
|
d06cd5cc2d | ||
|
|
c39e8eb43c | ||
|
|
ae3caf84b5 | ||
|
|
185d47fcdf | ||
|
|
a63b2b3283 | ||
|
|
576ff1b007 | ||
|
|
7a20d7ca49 | ||
|
|
346b614999 | ||
|
|
6b0ac4bf0a | ||
|
|
4e859eefb8 | ||
|
|
578aff7dea | ||
|
|
f81d9de2c6 | ||
|
|
255de89a43 | ||
|
|
c561c223d6 | ||
|
|
ba7d501a6e | ||
|
|
5b75afbdc8 | ||
|
|
f7b9be3bc5 | ||
|
|
743bd951c8 | ||
|
|
3d2bbe1463 | ||
|
|
4b1adab0eb | ||
|
|
e8ad2f2185 | ||
|
|
8986289702 | ||
|
|
69ef88909e | ||
|
|
443cacca00 | ||
|
|
ae5286bebb | ||
|
|
c3facb9787 | ||
|
|
22d5832ba2 | ||
|
|
68d55f416e | ||
|
|
dfda4c0bc2 | ||
|
|
c7289d07a0 | ||
|
|
df1ff07745 | ||
|
|
8ef017fb94 | ||
|
|
4e896927a9 | ||
|
|
3aa9fddfd5 | ||
|
|
d3bb169cdc | ||
|
|
d8e168ed61 | ||
|
|
b924cc5341 | ||
|
|
bb6ed820a7 | ||
|
|
1bb0c1d537 | ||
|
|
6ec69ca989 | ||
|
|
65f19f0782 | ||
|
|
cd48f0aed8 | ||
|
|
b165e96a07 | ||
|
|
d15dd900cc | ||
|
|
ce2391b6f3 | ||
|
|
c786ff0087 | ||
|
|
577286eb56 | ||
|
|
f91c69906f | ||
|
|
a3bdb70ef1 | ||
|
|
5f9bdabf7e | ||
|
|
86ecb9b931 | ||
|
|
9da687f168 | ||
|
|
8efea01d78 | ||
|
|
f824aed3be | ||
|
|
8b01906f1e | ||
|
|
61aab22c02 | ||
|
|
16e1e20812 | ||
|
|
25931f9068 | ||
|
|
65d5377683 | ||
|
|
383c37323a | ||
|
|
aa2073194d | ||
|
|
a57e91cd0a | ||
|
|
56de696330 | ||
|
|
a6002712fd | ||
|
|
f752636c25 | ||
|
|
6656399112 | ||
|
|
780bab2125 | ||
|
|
681be33fed | ||
|
|
d30837665a | ||
|
|
a6cefed13f | ||
|
|
0299ca8b1f | ||
|
|
dd95878ba7 | ||
|
|
f0ac27b159 | ||
|
|
f39ca55379 | ||
|
|
738c76ccd7 | ||
|
|
012ae19ca2 | ||
|
|
bfb3329e83 | ||
|
|
ff480291fe | ||
|
|
775441d223 | ||
|
|
7c5f1da1fc | ||
|
|
71bd11a941 | ||
|
|
ca62b9f4bf | ||
|
|
9272ff9fbf | ||
|
|
366b106234 | ||
|
|
d333524559 | ||
|
|
3f9c57ad2d | ||
|
|
64e55be02f | ||
|
|
99ed2b35d3 | ||
|
|
f94a2350ab | ||
|
|
7abeba8b87 | ||
|
|
7d16ad2119 | ||
|
|
97e5636813 | ||
|
|
3d67e886d2 | ||
|
|
919c8c7ee0 | ||
|
|
a47b2b234b | ||
|
|
2b95ebede8 | ||
|
|
87a4b6a91b | ||
|
|
bac07abf1f | ||
|
|
3f2184766c | ||
|
|
53d317cfa4 | ||
|
|
8aa4c34794 | ||
|
|
797182fbf8 | ||
|
|
dcbc79fd80 | ||
|
|
711848f027 | ||
|
|
8eeacf49cb | ||
|
|
bdf99d01a6 | ||
|
|
0ed68b55b3 | ||
|
|
83ad66d27c | ||
|
|
15d7bc5037 | ||
|
|
e83d0b6c55 | ||
|
|
004d8a4bff | ||
|
|
969c9a66af | ||
|
|
8eec363581 | ||
|
|
cec0578b77 | ||
|
|
2ce2f0ee9b | ||
|
|
f2641adfd2 | ||
|
|
af9125792c | ||
|
|
a9c37ba8fb | ||
|
|
94ebb4573a | ||
|
|
5f14919755 | ||
|
|
ed673b5bc1 | ||
|
|
78d8ed922c | ||
|
|
e0797cd519 | ||
|
|
eb5f39def7 | ||
|
|
d200dd9cbe | ||
|
|
ec4446bb9b | ||
|
|
c20bc215a8 | ||
|
|
13705f9872 | ||
|
|
f02cd58a6b | ||
|
|
f36480d5d6 | ||
|
|
821f9f8037 | ||
|
|
ba8e517e98 | ||
|
|
abf7676ae7 | ||
|
|
45cc6acd9f | ||
|
|
32038531e1 | ||
|
|
7d74bdc3bd | ||
|
|
b310e98c5a | ||
|
|
ce0f160f31 | ||
|
|
b8c9040030 | ||
|
|
da21628222 | ||
|
|
17a99abece | ||
|
|
9d76132a5d | ||
|
|
86a2d34f8e | ||
|
|
0a5b9e3178 | ||
|
|
7665e86812 | ||
|
|
29e5db87d9 | ||
|
|
ffaa7c92e3 | ||
|
|
b74a57967c | ||
|
|
dd368f4925 | ||
|
|
fa6c55636b | ||
|
|
9fa98671ac | ||
|
|
60f917a52d | ||
|
|
0f848a3f92 | ||
|
|
bf03d3f15a | ||
|
|
b864eba08f | ||
|
|
a8988ac17b | ||
|
|
d72a44b9f2 | ||
|
|
f9ed777c7f | ||
|
|
2cc6e8a1a6 | ||
|
|
9efb8cf450 | ||
|
|
2befb766ca | ||
|
|
ded8e77f5d | ||
|
|
7ec9d9e1cf | ||
|
|
be1d80de0f | ||
|
|
7dc28f36dc | ||
|
|
98de1d89da | ||
|
|
8a542aebe2 | ||
|
|
e7c077c31e | ||
|
|
3c0da086f5 | ||
|
|
06dc33b126 | ||
|
|
817ed1ce8f | ||
|
|
ec027d3d98 | ||
|
|
29214b58c0 | ||
|
|
bbc8f6b15e | ||
|
|
4f597584fb | ||
|
|
2d40cf801d | ||
|
|
3bb4772aea | ||
|
|
5b44df4476 | ||
|
|
3762b69fed | ||
|
|
18c205dde2 | ||
|
|
caa4e07f8c | ||
|
|
a3ae2d98a5 | ||
|
|
0fd4cdd498 | ||
|
|
0e271bbbc2 | ||
|
|
ff18198cd1 | ||
|
|
9354ca7c68 | ||
|
|
e8ed55bb41 | ||
|
|
6a9648e7f5 | ||
|
|
b41097790d | ||
|
|
e91a3d74b3 | ||
|
|
4d5ffe1618 | ||
|
|
3b04624b88 | ||
|
|
21b3b66bcd | ||
|
|
69826ccb1f | ||
|
|
66f9bfd871 | ||
|
|
fdc1868cd4 | ||
|
|
917cb107ec | ||
|
|
d3b3467989 | ||
|
|
3f09122e6d | ||
|
|
bfd0361fd5 | ||
|
|
1c52e246f0 | ||
|
|
09a403cb53 | ||
|
|
e9699abc81 | ||
|
|
b186c47e07 | ||
|
|
f26f11f89b | ||
|
|
f8bbc2d931 | ||
|
|
cbe0d5c3dd | ||
|
|
c6a802a286 | ||
|
|
27fce7267f | ||
|
|
5b0c302530 | ||
|
|
47c29d9eb5 | ||
|
|
228dad8b85 | ||
|
|
70ad933435 | ||
|
|
b061219bac | ||
|
|
da25290fad | ||
|
|
9f55aa657b | ||
|
|
2740dd094b | ||
|
|
0089f232c4 | ||
|
|
64ffe1ee14 | ||
|
|
b3d1cc81cd | ||
|
|
f8691e3868 | ||
|
|
1ab14afeaa | ||
|
|
27a6b1a5c4 | ||
|
|
78c8034b4b | ||
|
|
3a9c6f65de | ||
|
|
f5bedf6239 | ||
|
|
6e3dcc5192 | ||
|
|
5f6c3f1078 | ||
|
|
5f67e5ab03 | ||
|
|
e7a9837da1 | ||
|
|
c80c892faf | ||
|
|
94dce083f1 | ||
|
|
bad39c697f | ||
|
|
c2a9ea96e9 | ||
|
|
aff110df5d | ||
|
|
428bed2cde | ||
|
|
f06da4c033 | ||
|
|
fd79d5d034 | ||
|
|
c4c4fdc647 | ||
|
|
661bf3ecc2 | ||
|
|
04c99a5a36 | ||
|
|
ded4e015bd | ||
|
|
97becdb7e3 | ||
|
|
929766b177 | ||
|
|
2db6f7a9ae | ||
|
|
b6d8a340e5 | ||
|
|
175f75c3a2 | ||
|
|
0eda9b109f | ||
|
|
f07be06dfe | ||
|
|
32a770b9b5 | ||
|
|
2f2b440196 | ||
|
|
379422f457 | ||
|
|
3519756da3 | ||
|
|
8746f04030 | ||
|
|
c7d9697b92 | ||
|
|
66053895ad | ||
|
|
d7c21e06ad | ||
|
|
799589874e | ||
|
|
97733ca337 | ||
|
|
1a0474420b | ||
|
|
f1c1f2dbe8 | ||
|
|
bfb5752622 | ||
|
|
b3e9f594dc | ||
|
|
f81ca0688e | ||
|
|
095a9149b4 | ||
|
|
322a86c105 | ||
|
|
015fb299ba | ||
|
|
9e7f407d35 | ||
|
|
96b891fbd0 | ||
|
|
0cdb35dcfe | ||
|
|
56be5c84cb | ||
|
|
2cb8fc25f5 | ||
|
|
941c5efd07 | ||
|
|
bbdb335e92 | ||
|
|
cd0c5c8e2a | ||
|
|
8924d36925 | ||
|
|
8a39bf6ac8 | ||
|
|
a6b4f05f7f | ||
|
|
34c39464ae | ||
|
|
3dd45c1628 | ||
|
|
b962c168c4 | ||
|
|
c12bd32682 | ||
|
|
ef20f1578d | ||
|
|
47c9e07857 | ||
|
|
6d8208d7f4 | ||
|
|
946e76c3cc | ||
|
|
08bd8176b9 | ||
|
|
2ea06425f4 | ||
|
|
95ca7b23d3 | ||
|
|
ca6eb03f1e | ||
|
|
8831a41bff | ||
|
|
6418beb186 | ||
|
|
ebbc5cdc2c | ||
|
|
abceb71dcb | ||
|
|
7ab898ee85 | ||
|
|
904840c4cb | ||
|
|
ecd39f5435 | ||
|
|
7742b2c570 | ||
|
|
89b20b3cda | ||
|
|
4b0f62e058 | ||
|
|
f7281a7481 | ||
|
|
ae38fecae7 | ||
|
|
f5577d45c5 | ||
|
|
0b45c41a99 | ||
|
|
9b74e7fdec | ||
|
|
b522360357 | ||
|
|
109cb776a0 | ||
|
|
9fdc55814d | ||
|
|
2079a90f02 | ||
|
|
7fdf90e87d | ||
|
|
f7bc2e2cf7 | ||
|
|
9d442b9b18 | ||
|
|
3c777905f5 | ||
|
|
c91bbc94fd | ||
|
|
e51142ae32 | ||
|
|
1fd7d7f602 | ||
|
|
6ceb50c0bd | ||
|
|
b63b189fda | ||
|
|
b8ff8cb535 | ||
|
|
2e9124c52d | ||
|
|
261ccdda51 | ||
|
|
974108088a | ||
|
|
ebc9d2d1b1 | ||
|
|
3733d827af | ||
|
|
1333aa10f8 | ||
|
|
8621de6d09 | ||
|
|
b48775d222 | ||
|
|
3b918c38fd | ||
|
|
e21e7d863d | ||
|
|
3b4329fcc2 | ||
|
|
08bc5ef72f | ||
|
|
f378ee441a | ||
|
|
bbf0fda484 | ||
|
|
8cb4d8149b | ||
|
|
eceadf9f10 | ||
|
|
ae63e09a92 | ||
|
|
b778578353 | ||
|
|
a2ec9c4a41 | ||
|
|
30fc4a91d6 | ||
|
|
1d6307d142 | ||
|
|
93524c0e4a | ||
|
|
30e2d310f3 | ||
|
|
d1c87a65b2 | ||
|
|
961615f1c4 | ||
|
|
9a92132981 | ||
|
|
d78120c80d | ||
|
|
c560b7cd1f | ||
|
|
f0a8e1c0bc | ||
|
|
9e77f104f6 | ||
|
|
029d6bf7f6 | ||
|
|
3cb0e3ecd4 | ||
|
|
8708897751 | ||
|
|
d920e8705f | ||
|
|
f5e9bf2459 | ||
|
|
6a88aaf782 | ||
|
|
9d9c09743c | ||
|
|
e076f34993 | ||
|
|
923ec7ce5e | ||
|
|
15ae3cecb1 | ||
|
|
3f8e26644a | ||
|
|
a6a2a6ebba | ||
|
|
4175816577 | ||
|
|
36679ffbc7 | ||
|
|
b2c4cd721c | ||
|
|
da9aeb54f0 | ||
|
|
0a9d7c5560 | ||
|
|
14843ddda7 | ||
|
|
dada671f97 | ||
|
|
1a7214c75b | ||
|
|
23eede12fc | ||
|
|
58910be98e | ||
|
|
f27319e8cb | ||
|
|
737c190107 | ||
|
|
6c2989a4d3 | ||
|
|
a5c05bd2f3 | ||
|
|
a136c5349e | ||
|
|
8b8d845068 | ||
|
|
7c41b5d4ed | ||
|
|
39336a447b | ||
|
|
f58c33354e | ||
|
|
9a9b5037ec | ||
|
|
effe9c281a | ||
|
|
c590ff875b | ||
|
|
3771c325a2 | ||
|
|
7746e95cad | ||
|
|
767c10f886 | ||
|
|
d97a15df57 | ||
|
|
55cd89a0e5 | ||
|
|
8ef7ac5a87 | ||
|
|
5b6a06b33b | ||
|
|
cd4971962a | ||
|
|
f18e2e1e55 | ||
|
|
0d8925c787 | ||
|
|
c773cd1842 | ||
|
|
bf9d2c82ac | ||
|
|
7958785588 | ||
|
|
56ea23c4bf | ||
|
|
c382f773a7 | ||
|
|
46995511f1 | ||
|
|
7d60037998 | ||
|
|
cdf53c812a | ||
|
|
b628755464 | ||
|
|
69da2f14c7 | ||
|
|
3ea0b0847a | ||
|
|
47da1bcdb4 | ||
|
|
691dc18f3b | ||
|
|
5ddd948ace | ||
|
|
b815c924ff | ||
|
|
f46d72a9eb | ||
|
|
9b58d1161b | ||
|
|
3208a34b75 | ||
|
|
e50bb39770 | ||
|
|
bcf9c7df30 | ||
|
|
e8f97beb84 | ||
|
|
d73ff60c36 | ||
|
|
6414f14420 | ||
|
|
5787753279 | ||
|
|
4a838597f8 | ||
|
|
c3c5e2b5b0 | ||
|
|
6a184462c6 | ||
|
|
10def6e48a | ||
|
|
29c97b9d79 | ||
|
|
d5e1f8814f | ||
|
|
972cb55801 | ||
|
|
a65a1a05f0 | ||
|
|
659afd9245 | ||
|
|
73b9b353e6 | ||
|
|
34337d18fa | ||
|
|
f57917e2b6 | ||
|
|
a39bc1182a | ||
|
|
795e42f609 | ||
|
|
b39b0a5ca6 | ||
|
|
dcea49c682 | ||
|
|
c1e7d043f9 | ||
|
|
f354b86d1d | ||
|
|
9d4977e2b3 | ||
|
|
595147bacc | ||
|
|
39681dcb8a | ||
|
|
31be6a2cca | ||
|
|
0286557701 | ||
|
|
805e3c920c | ||
|
|
26f05a0800 | ||
|
|
b944d073de | ||
|
|
56fdb2d4a8 | ||
|
|
c83bd885f6 | ||
|
|
d4ec177c28 | ||
|
|
e9839335c6 | ||
|
|
562a6d6ab8 | ||
|
|
4cfeb88bb3 | ||
|
|
54858261f8 | ||
|
|
8e4d3df400 | ||
|
|
dc47f68ff3 | ||
|
|
c1852f4728 | ||
|
|
0e9c7761f5 | ||
|
|
b4acb06665 | ||
|
|
98107e40bc | ||
|
|
d1d1da7875 | ||
|
|
a800094b21 | ||
|
|
89736d1d45 | ||
|
|
06650c14ad | ||
|
|
1c1066eff2 | ||
|
|
5bb63cf3e5 | ||
|
|
2ba39a9b80 | ||
|
|
7fef84a006 | ||
|
|
f6458cd8ee | ||
|
|
5c18dad1d8 | ||
|
|
3f4efc51c9 | ||
|
|
841ac0cb74 | ||
|
|
e2be9580c6 | ||
|
|
154cf18b34 | ||
|
|
0a93763c48 | ||
|
|
c4c654079d | ||
|
|
92f8e67a60 | ||
|
|
1814f06311 | ||
|
|
2dbc704448 | ||
|
|
e2478b4eb8 | ||
|
|
b7b3e8d4cb | ||
|
|
0a089351e9 | ||
|
|
386a991ad7 | ||
|
|
e028834ac3 | ||
|
|
695a4966b5 | ||
|
|
3973f5ef70 | ||
|
|
24ccf60870 | ||
|
|
c4a3f06b51 | ||
|
|
5dff1f7678 | ||
|
|
d3d07f9e4e | ||
|
|
e5500b978c | ||
|
|
2fea94ce9b | ||
|
|
90b6106fb4 | ||
|
|
6e15d1e480 | ||
|
|
d35588b993 | ||
|
|
957ecf0fe1 | ||
|
|
83dc47c3b5 | ||
|
|
fa4d35487c | ||
|
|
624a20c9bf | ||
|
|
58cd5c2896 | ||
|
|
bb8a802d65 | ||
|
|
f757e98da0 | ||
|
|
49661c0bf0 | ||
|
|
42f36b8e74 | ||
|
|
9bc3c9a902 | ||
|
|
1dd04740bb | ||
|
|
35201e6615 | ||
|
|
86d416bccf | ||
|
|
979841665a | ||
|
|
c29b8c114b | ||
|
|
a03eae3c87 | ||
|
|
704c2a261e | ||
|
|
8fabdd1926 | ||
|
|
f9df373a16 | ||
|
|
f959f98012 | ||
|
|
e12a93f36b | ||
|
|
c3aca0a88d | ||
|
|
add7819945 | ||
|
|
3c6d3bbd80 | ||
|
|
66e1315b08 | ||
|
|
9bbe010fc9 | ||
|
|
4f81d164c8 | ||
|
|
c808e9135d | ||
|
|
1e7861ef15 | ||
|
|
a70b8c6dff | ||
|
|
ce86638e8e | ||
|
|
06ab978f53 | ||
|
|
9c2026982c | ||
|
|
863b910311 | ||
|
|
68da3b7580 | ||
|
|
43556f219b | ||
|
|
6022144dce | ||
|
|
18a0e3fd9e | ||
|
|
6c7c6e4b22 | ||
|
|
ffa7a74575 | ||
|
|
37f9c28133 | ||
|
|
ea7a012e0a | ||
|
|
0d594da6c9 | ||
|
|
ed588bf26c | ||
|
|
b6673fd828 | ||
|
|
060bcc76ef | ||
|
|
8fc8dd2960 | ||
|
|
1dc36275aa | ||
|
|
f305e68202 | ||
|
|
5c481df41f | ||
|
|
e86c626536 | ||
|
|
44559bab1c | ||
|
|
2ae28f1c63 | ||
|
|
b3e16d2b2a | ||
|
|
6f186080df | ||
|
|
c9d9335b71 | ||
|
|
22c8a36224 | ||
|
|
37f705d517 | ||
|
|
8b9985a7dc | ||
|
|
f51e585d8d | ||
|
|
a6c204e444 | ||
|
|
a0a215400e | ||
|
|
37e3166f98 | ||
|
|
ddccdc2ade | ||
|
|
755a15d5e5 | ||
|
|
5c6716bd98 | ||
|
|
7d87417095 | ||
|
|
77bb6e9a82 | ||
|
|
019174d7e2 | ||
|
|
cac88cbb81 | ||
|
|
25500da486 | ||
|
|
53f2c7126b | ||
|
|
eb95026a47 | ||
|
|
6b0f8bc325 | ||
|
|
a80f41a89a | ||
|
|
8690f8aa8d | ||
|
|
d9c55a284b | ||
|
|
c8a10a8b75 | ||
|
|
8e8dc76c3d | ||
|
|
725679f5d4 | ||
|
|
dfce07d7eb | ||
|
|
73c9e37eba | ||
|
|
ccd5bd8394 | ||
|
|
fd9b7db999 | ||
|
|
f3fe115733 | ||
|
|
16f3f74a90 | ||
|
|
4a6b85003a | ||
|
|
bf651c7e40 | ||
|
|
473ff4d308 | ||
|
|
5d64e8c61b | ||
|
|
b559bb3904 | ||
|
|
359f250b3b | ||
|
|
a20336a11a | ||
|
|
0313c5705f | ||
|
|
14469638b3 | ||
|
|
d15c5fc9d1 | ||
|
|
16e7d266fe | ||
|
|
b716a98548 | ||
|
|
39f40ed906 | ||
|
|
a644a1cee1 | ||
|
|
61fd8dc778 | ||
|
|
145d5e6302 | ||
|
|
ad071e48df | ||
|
|
28b5717f5b | ||
|
|
41b818caa6 | ||
|
|
cf87a654fb | ||
|
|
9ffab097bb | ||
|
|
bdc3c2b6b5 | ||
|
|
3f39662ba1 | ||
|
|
aa485547a6 | ||
|
|
747f23bfe1 | ||
|
|
d885841826 | ||
|
|
0c457ef61d | ||
|
|
9462f1455b | ||
|
|
c07325e71e | ||
|
|
5eda7b3fc3 | ||
|
|
6b0c208b75 | ||
|
|
b0c6a26bea | ||
|
|
67a0893a97 | ||
|
|
d7438a26fb | ||
|
|
ee7ab38028 | ||
|
|
8d999ea278 | ||
|
|
0851cf50a0 | ||
|
|
0b6676aaa3 | ||
|
|
c64167c76a | ||
|
|
72a6419aff | ||
|
|
64e26a6b8b | ||
|
|
23184df1b9 | ||
|
|
dd123d7b87 | ||
|
|
0e5d1e2325 | ||
|
|
4939ce37c3 | ||
|
|
6e7e668d39 | ||
|
|
2d086a5c6e | ||
|
|
f7e592eac0 | ||
|
|
c13abafb09 | ||
|
|
eeed0720f7 | ||
|
|
f099b74aa6 | ||
|
|
f7f54692a7 | ||
|
|
b97eff4284 | ||
|
|
f234dc61bc | ||
|
|
83b40d2ccb | ||
|
|
a8d3d71ea9 | ||
|
|
621772f359 | ||
|
|
63cd60b237 | ||
|
|
0df8e8522f | ||
|
|
1ebbf6e349 | ||
|
|
1b71f6a60a | ||
|
|
a3241e48df | ||
|
|
69396f3d59 | ||
|
|
9042d065ae | ||
|
|
300505e127 | ||
|
|
f7bf1d624b | ||
|
|
d7b08a0181 | ||
|
|
3941f59bbc | ||
|
|
802a30e16c | ||
|
|
032563d7a4 | ||
|
|
fe7ad2032b | ||
|
|
fcde4b3fc2 | ||
|
|
1073ed6c24 | ||
|
|
e5ce3450e8 | ||
|
|
a6f1e91747 | ||
|
|
8dcf5a3654 | ||
|
|
22f9cf7c4c | ||
|
|
38f2879d82 | ||
|
|
4060695db6 | ||
|
|
81fab695ff | ||
|
|
5259428106 | ||
|
|
9774bd858f | ||
|
|
d30379251d | ||
|
|
0e6156e51c | ||
|
|
d610c9727d | ||
|
|
adba04e2dd | ||
|
|
b2aa6552b1 | ||
|
|
8b4b060425 | ||
|
|
2f11853f0d | ||
|
|
388685b784 | ||
|
|
d6939b2913 | ||
|
|
90ee3b749f | ||
|
|
e51c297a7d | ||
|
|
283e8f20b3 | ||
|
|
850c3fb8cd | ||
|
|
7046e994d7 | ||
|
|
099d802a03 | ||
|
|
453df64f69 | ||
|
|
8a2cb42546 | ||
|
|
6413ed67c6 | ||
|
|
4dc7a97322 | ||
|
|
a2d8189c74 | ||
|
|
f806c82c33 | ||
|
|
f46598cd74 | ||
|
|
919d34c90d | ||
|
|
e230af8991 | ||
|
|
09842f5d72 | ||
|
|
911ff31f69 | ||
|
|
f1c9c4e231 | ||
|
|
fa04ce5465 | ||
|
|
45ff03abfd | ||
|
|
20cebb8a05 | ||
|
|
f79e3ff51f | ||
|
|
45a67a7f3d | ||
|
|
281469fe5c | ||
|
|
461ad7fa42 | ||
|
|
899d221b67 | ||
|
|
b246e163d2 | ||
|
|
d83bb0f964 | ||
|
|
a9626475e6 | ||
|
|
d1374eca15 | ||
|
|
6289162684 | ||
|
|
25b3187094 | ||
|
|
bd2c9b172a | ||
|
|
246f953b4d | ||
|
|
433098a388 | ||
|
|
f442d9d030 | ||
|
|
61d7ae03f6 | ||
|
|
22e144cb3b | ||
|
|
a3f0d7092d | ||
|
|
27efdba185 | ||
|
|
59a1fa9992 | ||
|
|
a5140ca293 | ||
|
|
a639b02890 | ||
|
|
ead64d3c73 | ||
|
|
be761071f8 | ||
|
|
e48f19269f | ||
|
|
82ebfb99c5 | ||
|
|
4d69bf2aba | ||
|
|
4e4f77de90 | ||
|
|
fe0c3176d8 | ||
|
|
8cfbdf46e0 | ||
|
|
2234d056fc | ||
|
|
4a4c447bd2 | ||
|
|
933a95023c | ||
|
|
1d8b5f81a1 | ||
|
|
81df632e48 | ||
|
|
b0df7cbc68 | ||
|
|
25d90a3c78 | ||
|
|
384637efdf | ||
|
|
ef3d3e6443 | ||
|
|
675e98fa1a | ||
|
|
0b059c71c1 | ||
|
|
8988f08243 | ||
|
|
adb54d9d7c | ||
|
|
fdf58388a3 | ||
|
|
a5244cdb41 | ||
|
|
6caec5dbce | ||
|
|
4419ab154b | ||
|
|
67c529ffe9 | ||
|
|
057ba0c6e1 | ||
|
|
6117ea755f | ||
|
|
a56c923f0e | ||
|
|
3686241bf5 | ||
|
|
0311c6f52b | ||
|
|
f59dccd5fd | ||
|
|
01d8dabef4 | ||
|
|
773993c6f2 | ||
|
|
2c5646b1c2 | ||
|
|
b8d71e24e7 | ||
|
|
4db3f7a742 | ||
|
|
298203f909 | ||
|
|
a1cafe62cf | ||
|
|
cab75ef0d6 | ||
|
|
33a8d86684 | ||
|
|
b4d329725b | ||
|
|
6efe8922b3 | ||
|
|
f5bd097584 | ||
|
|
7492841b5f | ||
|
|
1430bd9e88 | ||
|
|
e0400305ab | ||
|
|
65d5120272 | ||
|
|
cbb398e58c | ||
|
|
57d8735624 | ||
|
|
fd99bd2ed1 | ||
|
|
46c89534fd | ||
|
|
5650ee580f | ||
|
|
62f126b5d9 | ||
|
|
51cb354f35 | ||
|
|
d4f591354d | ||
|
|
0895af0ecc | ||
|
|
fafe25fee4 | ||
|
|
3db6cc1a1c | ||
|
|
408f5a05fc | ||
|
|
28ee23c5f3 | ||
|
|
37804e67c1 | ||
|
|
a7bce9c8e9 | ||
|
|
bcf2d16a10 | ||
|
|
28d2b92abb | ||
|
|
2f3b6df529 | ||
|
|
fa2cbbb0cc | ||
|
|
d1ab9e77de | ||
|
|
3484261b50 | ||
|
|
7a03fb53ea | ||
|
|
d7f050efc4 | ||
|
|
2d11a29a79 | ||
|
|
0b5aecfdb5 | ||
|
|
487925b1f2 | ||
|
|
54c8183666 | ||
|
|
c878952237 | ||
|
|
26d6428836 | ||
|
|
cf31a31430 | ||
|
|
e10e1c665f | ||
|
|
0834ff26be | ||
|
|
014b8db20d | ||
|
|
34445e6f92 | ||
|
|
7d00e01e00 | ||
|
|
300fabca21 | ||
|
|
e17dc78aeb | ||
|
|
1b9e00efe1 | ||
|
|
152b4d3765 | ||
|
|
e0b95ab2ae | ||
|
|
e0520edccc | ||
|
|
581b32e8a2 | ||
|
|
e71d61ef37 | ||
|
|
0a51d48703 | ||
|
|
30c7f9e020 | ||
|
|
71f7771a97 | ||
|
|
b36e5b7906 | ||
|
|
bb25449b35 | ||
|
|
dc8053dfcd | ||
|
|
20be8e23ba | ||
|
|
d83f476439 | ||
|
|
29352b8838 | ||
|
|
c0390c3c5d | ||
|
|
81dd2eeb47 | ||
|
|
3beedf4dfe | ||
|
|
f5be71ecbd | ||
|
|
58ba5dfedc | ||
|
|
040d265f3c | ||
|
|
fccf4db163 | ||
|
|
1122498b54 | ||
|
|
6a98aea209 | ||
|
|
ae4d589c8e | ||
|
|
6ccb59957d | ||
|
|
edd4e865b3 | ||
|
|
6ff7614e94 | ||
|
|
065a14952a | ||
|
|
1e620931a2 | ||
|
|
a46a531a89 | ||
|
|
06c95b8d36 | ||
|
|
39967a9211 | ||
|
|
a18e6f4b63 | ||
|
|
ef475000c3 | ||
|
|
f08a2444be | ||
|
|
c746d58210 | ||
|
|
ccb48505bf | ||
|
|
c9ddd25e99 | ||
|
|
42234d9163 | ||
|
|
e058885c7c | ||
|
|
1e3556cc8e | ||
|
|
b1cda242df | ||
|
|
b593fce745 | ||
|
|
282cdeaad0 | ||
|
|
6e54c7d672 | ||
|
|
51a12ee5cb | ||
|
|
fcea40685c | ||
|
|
07450a7a51 | ||
|
|
19fa8d15a6 | ||
|
|
db2980f598 | ||
|
|
b3e4fd65aa | ||
|
|
d46eca750c | ||
|
|
d441e92adc | ||
|
|
5f70d71203 | ||
|
|
59ffb2ea8e | ||
|
|
ce59b8037f | ||
|
|
56e67ba70a | ||
|
|
108e9e216e | ||
|
|
b219b4e832 | ||
|
|
ef4e0d76ec | ||
|
|
61c75c06a9 | ||
|
|
091705b3f2 | ||
|
|
6aa5b06619 | ||
|
|
df8fc0b229 | ||
|
|
d7fcda1f83 | ||
|
|
b832c24185 | ||
|
|
3b04f8c695 | ||
|
|
0ef11b58d2 | ||
|
|
bf13bbf506 | ||
|
|
92c94aa22a | ||
|
|
1c0785432b | ||
|
|
dcb9a50061 | ||
|
|
de7f4bdb6e | ||
|
|
73d636dba6 | ||
|
|
3f1c453ff6 | ||
|
|
ecb6baaebb | ||
|
|
e1cba45486 | ||
|
|
ea4181b243 | ||
|
|
6c5b9f8851 | ||
|
|
c1fccaf240 | ||
|
|
e7c223da7d | ||
|
|
6bfe1ba876 | ||
|
|
574e5dab18 | ||
|
|
5dc9b83831 | ||
|
|
57a214a9a4 | ||
|
|
cf48eb94af | ||
|
|
683f1e488a | ||
|
|
e888ae4da7 | ||
|
|
4512f2a375 | ||
|
|
68442afa0f | ||
|
|
ddf4d0cbc3 | ||
|
|
4be185e428 | ||
|
|
f75e66ac19 | ||
|
|
abda781f02 | ||
|
|
c1533ec66d | ||
|
|
c8319446b0 | ||
|
|
7ae452cf13 | ||
|
|
4c024c5faa | ||
|
|
9d16e9d98c | ||
|
|
48357d08f7 | ||
|
|
8e0bcf40db | ||
|
|
85ef5f04dd | ||
|
|
18e0748d14 | ||
|
|
cdde5b098e | ||
|
|
f83964752d | ||
|
|
0c3e34bbf9 | ||
|
|
6dea7faac8 | ||
|
|
726f482c33 | ||
|
|
cb242f664a | ||
|
|
edc0345970 | ||
|
|
a50535dd76 | ||
|
|
505942aa25 | ||
|
|
38a593a9de | ||
|
|
da87fb2551 | ||
|
|
d4dc65a4ba | ||
|
|
53463caedd | ||
|
|
0707a0fad8 | ||
|
|
dd1024af27 | ||
|
|
7edc58a6da | ||
|
|
5a5da0cace | ||
|
|
53f02ed366 | ||
|
|
27cfa885e7 | ||
|
|
beb132d604 | ||
|
|
b1b10298b4 | ||
|
|
b1993ff7d2 | ||
|
|
2afe5fe5b2 | ||
|
|
52fa8f64cc | ||
|
|
4f7978070f | ||
|
|
a909983822 | ||
|
|
5267cad896 | ||
|
|
ce274cf65b | ||
|
|
55b6b2e34d | ||
|
|
5e4e2971b5 | ||
|
|
a933bcfb1e | ||
|
|
b4b38e27f3 | ||
|
|
bc70824b57 | ||
|
|
87ecaaa6a4 | ||
|
|
c4cd9cd802 | ||
|
|
bbe0e8c5a9 | ||
|
|
3f8984d2dc | ||
|
|
f695c4598a | ||
|
|
eada1bc023 | ||
|
|
0ebb55551c | ||
|
|
20bce419c9 | ||
|
|
ca3fc370c3 | ||
|
|
94a8b78d1a | ||
|
|
06e9ff6fcf | ||
|
|
699e74656d | ||
|
|
b3ad6ef8b8 | ||
|
|
673c8e25f5 | ||
|
|
333c8e812d | ||
|
|
f0f7a88cfb | ||
|
|
0661d78bce | ||
|
|
dc4aece272 | ||
|
|
57a312b0b4 | ||
|
|
b9897ed6ac | ||
|
|
733230f037 | ||
|
|
fc6ba3e6ad | ||
|
|
2d7c539c5f | ||
|
|
7f34965026 | ||
|
|
de8b915cff | ||
|
|
d56040581d | ||
|
|
9869b7bbb5 | ||
|
|
7df97c28c0 | ||
|
|
018a559f78 | ||
|
|
3b32ad5fed | ||
|
|
f796d2a842 | ||
|
|
2f7e84e126 | ||
|
|
996ddbf3db | ||
|
|
7779ba2ac5 | ||
|
|
4dadeab762 | ||
|
|
f4d3131ef3 | ||
|
|
efa2ac803e | ||
|
|
e0be9d46bd | ||
|
|
106b27dbec | ||
|
|
f764567523 | ||
|
|
245f8669bc | ||
|
|
b265d9bba6 | ||
|
|
72228574f9 | ||
|
|
fba1ac3d90 | ||
|
|
4a73fb565e | ||
|
|
13011ed4af | ||
|
|
b2eccdefd3 | ||
|
|
dd2d6a977b | ||
|
|
38cd1b6040 | ||
|
|
1a28bbcde8 | ||
|
|
91013daadc | ||
|
|
1ad435e79d | ||
|
|
fd5c300c53 | ||
|
|
aa7d9cf29c | ||
|
|
8db1c3400e | ||
|
|
e723336706 | ||
|
|
b5cd4c36ab | ||
|
|
d1928f2647 | ||
|
|
61621ae00b | ||
|
|
ac20755c45 | ||
|
|
610202bbbd | ||
|
|
58ce7134e1 | ||
|
|
71f91cd79e | ||
|
|
8c821ecad3 | ||
|
|
c704940462 | ||
|
|
6a7cd1b89a | ||
|
|
e29da0ba13 | ||
|
|
7791fa10f5 | ||
|
|
48ed3c8f31 | ||
|
|
7ad7a9b94e | ||
|
|
54b929ba24 | ||
|
|
7b655c6260 | ||
|
|
4e8d41b145 | ||
|
|
f036774e07 | ||
|
|
97d1bd7685 | ||
|
|
8e39449856 | ||
|
|
30f1a5a6eb | ||
|
|
627abb047c | ||
|
|
9284008afe | ||
|
|
9159f4616f | ||
|
|
73296b1430 | ||
|
|
c74e622d69 | ||
|
|
f48eb55516 | ||
|
|
b01f6ef8d3 | ||
|
|
167185ef45 | ||
|
|
777a8ffeaa | ||
|
|
b2b3e6c485 | ||
|
|
613d502fc1 | ||
|
|
79da457db4 | ||
|
|
b1a431ed82 | ||
|
|
b0f2776a23 | ||
|
|
900c346ee8 | ||
|
|
7541a87b21 | ||
|
|
2547c67ebd | ||
|
|
5ae6a0b287 | ||
|
|
f718fc0c89 | ||
|
|
57e69ba7be | ||
|
|
6168b3e047 | ||
|
|
3e500500e0 | ||
|
|
42f06ff84a | ||
|
|
a7824fc473 | ||
|
|
67e7fd6928 | ||
|
|
450e8badba | ||
|
|
704c211e11 | ||
|
|
0ad871cb5b | ||
|
|
9920605570 | ||
|
|
b1e8678dbf | ||
|
|
e2cd2ddc0d | ||
|
|
a3be0dfddf | ||
|
|
4b615ffc0b | ||
|
|
64cbd189ad | ||
|
|
0fae5a128f | ||
|
|
518b44216f | ||
|
|
9ef4512ef9 | ||
|
|
8bb5f1e955 | ||
|
|
8f8932f617 | ||
|
|
23fd1d75c4 | ||
|
|
593dcef550 | ||
|
|
d769fe9074 | ||
|
|
77a8fec790 | ||
|
|
34440edfaa | ||
|
|
3c3d8784ad | ||
|
|
1591abc92c | ||
|
|
0ffa0c34f0 | ||
|
|
c7dc94b61b | ||
|
|
a8b83871a4 | ||
|
|
6f547984ff | ||
|
|
3979c11317 | ||
|
|
2a1ec985f4 | ||
|
|
2a1d49e945 | ||
|
|
7b7e6140d2 | ||
|
|
907cfd9694 | ||
|
|
b51b1d1ec6 | ||
|
|
6a026300e4 | ||
|
|
8511907390 | ||
|
|
05a5be336e | ||
|
|
5434b1ce19 | ||
|
|
c2d4a4367c | ||
|
|
de2f277513 | ||
|
|
283e522037 | ||
|
|
caebe4c23b | ||
|
|
b195277c9a | ||
|
|
6b99cb6253 | ||
|
|
a822bb670a | ||
|
|
af7cc11647 | ||
|
|
0afe331d3d | ||
|
|
7af40f0cd7 | ||
|
|
52dc699ee2 | ||
|
|
ec28e21897 | ||
|
|
3283851dc4 | ||
|
|
ec5e0c7b25 | ||
|
|
13660cb70a | ||
|
|
ce008f5576 | ||
|
|
25f7e8b35c | ||
|
|
109398d955 | ||
|
|
4a8551087b | ||
|
|
34febe3545 | ||
|
|
53a0307a8e | ||
|
|
1c6f624fd1 | ||
|
|
780e5f08f9 | ||
|
|
1bb73b1147 | ||
|
|
09b0d4d6c4 | ||
|
|
7e3856fa05 | ||
|
|
fbcb3f5436 | ||
|
|
324b4ced06 | ||
|
|
79c2abe790 | ||
|
|
cdab9168fc | ||
|
|
ce272724de | ||
|
|
2fa0a19d3b | ||
|
|
38b9a6e04a | ||
|
|
22d3c2b6bf | ||
|
|
218a8397c4 | ||
|
|
fd990da71e | ||
|
|
4a70c89a4d | ||
|
|
7e3143678f | ||
|
|
d80e09dfba | ||
|
|
3b3b251c21 | ||
|
|
1e848bd70f | ||
|
|
fab2295445 | ||
|
|
a913bccc9e | ||
|
|
57e7f89814 | ||
|
|
f98fd5e5f1 | ||
|
|
e6af2e5c6b | ||
|
|
d219989ec7 | ||
|
|
b9daf608ff | ||
|
|
869da61fd0 | ||
|
|
9f79e2505c | ||
|
|
3000b36dbd | ||
|
|
1d21b0e5c4 | ||
|
|
8d6b0926d6 | ||
|
|
4c39d13c80 | ||
|
|
327dd1c73f | ||
|
|
b36b8f3234 | ||
|
|
5f6da284fb | ||
|
|
83d27e18cb | ||
|
|
e291bd58a8 | ||
|
|
23acdb6492 | ||
|
|
3b5e56b049 | ||
|
|
57d4967f2a | ||
|
|
80fcda149b | ||
|
|
1a86eef52c | ||
|
|
98d401f9c3 | ||
|
|
0f2fae886e | ||
|
|
f30a9093af | ||
|
|
b4334da202 | ||
|
|
416fb3bda9 | ||
|
|
7e0fc2e364 | ||
|
|
540d290be2 | ||
|
|
53974ad88d | ||
|
|
cd9b5e5a44 | ||
|
|
d9959bbcb2 | ||
|
|
d7dfd53244 | ||
|
|
84489bf61b | ||
|
|
3fdb56390e | ||
|
|
a34e766f70 | ||
|
|
d74023d4fa | ||
|
|
41572e98ba | ||
|
|
063087c87e | ||
|
|
4a5d53d713 | ||
|
|
9a262525ec | ||
|
|
e327b4e84b | ||
|
|
c128a2b518 | ||
|
|
a3263ab4af | ||
|
|
4a4efe4725 | ||
|
|
89d2433369 | ||
|
|
023175ce6d | ||
|
|
21c8d24d57 | ||
|
|
e49f5c95f4 | ||
|
|
6912e578ca | ||
|
|
8680cff2b2 | ||
|
|
aea75d44e3 | ||
|
|
80481f1778 | ||
|
|
3ea7ff8202 | ||
|
|
b5979c0528 | ||
|
|
f0f79a52b8 | ||
|
|
b549acc1de | ||
|
|
2505cc5d00 | ||
|
|
d5af66b3fc | ||
|
|
f680dc7e46 | ||
|
|
ffd8bbb1ce | ||
|
|
216a043094 | ||
|
|
021eb5f828 | ||
|
|
f3bf8849e9 | ||
|
|
128f7100d7 | ||
|
|
2cf53dd00f | ||
|
|
4a674e46e6 | ||
|
|
f6b0134fdb | ||
|
|
675a6b863e | ||
|
|
b570eeef93 | ||
|
|
71a8b4e607 | ||
|
|
89b866b0fc | ||
|
|
bcce20d9ac | ||
|
|
420e760fb3 | ||
|
|
a168c95d79 | ||
|
|
d8ccec45f9 | ||
|
|
1316875602 | ||
|
|
a85387c7c8 | ||
|
|
d357e83d06 | ||
|
|
51546f6fea | ||
|
|
b4aa5ec593 | ||
|
|
909380f592 | ||
|
|
d5f26643bf | ||
|
|
a15dc4afdf | ||
|
|
b317bc334e | ||
|
|
d0a8d08b26 | ||
|
|
f73a922a8e | ||
|
|
c6682ce718 | ||
|
|
764d1137ae | ||
|
|
02fc972a79 | ||
|
|
7fc727cf2e | ||
|
|
d77e1e6820 | ||
|
|
241d9daae9 | ||
|
|
462e0257a9 | ||
|
|
66fbc7e821 | ||
|
|
3c37f22027 | ||
|
|
0d24bc6602 | ||
|
|
5a50df8179 | ||
|
|
f1251fd150 | ||
|
|
16202efc7b | ||
|
|
26c6052286 | ||
|
|
7ce386a7b8 | ||
|
|
e43cd0a039 | ||
|
|
70be405032 | ||
|
|
9f3ad8142a | ||
|
|
51d9ece30c | ||
|
|
d8e79f879f | ||
|
|
76d50b56ee | ||
|
|
c8d1e957a1 | ||
|
|
b287af4824 | ||
|
|
416ef8d6d7 | ||
|
|
7c71abb985 | ||
|
|
900f2462a7 | ||
|
|
dd982c6cb9 | ||
|
|
927a011c9d | ||
|
|
ad0ad47a40 | ||
|
|
71a424c15d | ||
|
|
145b7049a8 | ||
|
|
323d258bc2 | ||
|
|
56ba52d7b9 | ||
|
|
54bd6f6ed8 | ||
|
|
f06167ba4b | ||
|
|
60438ae1ed | ||
|
|
1b87750b87 | ||
|
|
40cdc566c8 | ||
|
|
428ae07e7f | ||
|
|
481ad22b53 | ||
|
|
65f58b93ed | ||
|
|
45411fa14d | ||
|
|
8ba1ba4fb1 | ||
|
|
8427e1b3a5 | ||
|
|
32f0f2a0cf | ||
|
|
8b94997cde | ||
|
|
bd2d54f774 | ||
|
|
34be285510 | ||
|
|
7b906f3c3e | ||
|
|
82ba22cda2 | ||
|
|
b1a9601ae9 | ||
|
|
7c1a297a99 | ||
|
|
a8195c0e7c | ||
|
|
08713e3922 | ||
|
|
0485d52e3e | ||
|
|
8b1723e19b | ||
|
|
9cb683dc55 | ||
|
|
dce1589c19 | ||
|
|
107cf16d36 | ||
|
|
2bab97c829 | ||
|
|
5242d825c2 | ||
|
|
11d3799b03 | ||
|
|
55c7f6b896 | ||
|
|
a09d607177 | ||
|
|
626a101208 | ||
|
|
f4ca3acbf6 | ||
|
|
86835a3bd7 | ||
|
|
0ef46e2e11 | ||
|
|
04878447b7 | ||
|
|
3669d5d90e | ||
|
|
ee5e222a13 | ||
|
|
9ea44ff59a | ||
|
|
0474e2c0f5 | ||
|
|
4a909d4b93 |
No files matched your search
@@ -0,0 +1,4 @@
|
||||
[*.{kt,kts}]
|
||||
ij_kotlin_imports_layout = *
|
||||
ktlint_code_style = intellij_idea
|
||||
ktlint_function_naming_ignore_when_annotated_with = Composable
|
||||
@@ -6,10 +6,10 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢您愿意为 Ehviewer-Overhauled 做出贡献!
|
||||
感谢您愿意为 EhViewer 做出贡献!
|
||||
提交问题报告前,还请首先完成文末的自查步骤
|
||||
|
||||
Thanks for your contribution on Ehviewer-Overhauled Project!
|
||||
Thanks for your contribution on EhViewer Project!
|
||||
Please finish verify steps which list in the end first before create bug report
|
||||
|
||||
- type: textarea
|
||||
@@ -17,12 +17,16 @@ body:
|
||||
attributes:
|
||||
label: 复现步骤 / Step to reproduce
|
||||
description: |
|
||||
在此处写下复现的方式
|
||||
Describe how to reproduce here
|
||||
请从全新安装应用开始,在此处写下复现的方式。请尽量附带录屏
|
||||
如果不能稳定复现,请在下方上传应用日志
|
||||
Describe how to reproduce here with fresh installation, with screen recording if possible.
|
||||
If you can't reproduce it consistently, please upload app logs below
|
||||
placeholder: |
|
||||
0. 重新安装应用 / Fresh install
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
[录屏] / [Screen recording]
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -53,6 +57,15 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
label: 应用日志 / App logs
|
||||
description: 您可以通过设置-高级-导出日志来获得日志文件 / You can get logs file in Settings - Advanced - Dump logcat
|
||||
placeholder: 06-15 17:44:53.704 23382 23382 E ...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: more
|
||||
attributes:
|
||||
@@ -66,6 +79,15 @@ body:
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
id: site
|
||||
attributes:
|
||||
label: 浏览站点 / Browsing site
|
||||
description: E-Hentai / ExHentai
|
||||
placeholder: E-Hentai
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
@@ -79,8 +101,8 @@ body:
|
||||
id: ci
|
||||
attributes:
|
||||
label: EhViewer CI 版本 / EhViewer CI Version
|
||||
description: 直接将对应 GitHub Action CI 下载页面网址填入即可 / Simply drop GitHub Action CI download page url here
|
||||
placeholder: https://github.com/Ehviewer-Overhauled/Ehviewer/actions/runs/XXXXXXXXXX
|
||||
description: 位于设置 - 关于中的版本号后 / Next to the version code in Settings - About
|
||||
placeholder: 26f05a0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -111,15 +133,6 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
label: 应用日志 / App logs
|
||||
description: 您可以通过设置-高级-导出日志来获得日志文件 / You can get logs file in Settings - Advanced - Dump logcat
|
||||
placeholder: 06-15 17:44:53.704 23382 23382 E ...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: check
|
||||
attributes:
|
||||
@@ -128,17 +141,11 @@ body:
|
||||
请确认您已经遵守所有必选项
|
||||
Please ensure you have obtained all needed options
|
||||
options:
|
||||
- label: 如果您有足够的时间和能力,并愿意为此提交 PR ,请勾上此复选框 / Pull request is welcome. Check this if you want to start a pull request
|
||||
required: false
|
||||
|
||||
- label: 您已仔细查看并知情 [Q&A](https://github.com/Ehviewer-Overhauled/Ehviewer/issues/61) 中的内容 / You have checked [Q&A](https://github.com/Ehviewer-Overhauled/Ehviewer/issues/61) carefully
|
||||
required: true
|
||||
|
||||
- label: 您已搜索过 [Issue Tracker](https://github.com/Ehviewer-Overhauled/Ehviewer/issues),没有找到类似内容 / I have searched on [Issue Tracker](https://github.com/Ehviewer-Overhauled/Ehviewer/issues), No duplicate or related open issue has been found
|
||||
- label: 您已搜索过 [Issue Tracker](https://github.com/FooIbar/EhViewer/issues),没有找到类似内容 / I have searched on [Issue Tracker](https://github.com/FooIbar/EhViewer/issues), No duplicate or related open issue has been found
|
||||
required: true
|
||||
|
||||
- label: 您确保这个 Issue 只提及一个问题。如果您有多个问题报告,烦请发起多个 Issue / Ensure there is only one bug report in this issue. Please make mutiply issue for mutiply bugs
|
||||
required: true
|
||||
|
||||
- label: 您确保已使用最新 CI 版本测试,并且该问题在最新 CI 版本中并未解决 / This bug have not solved in latest CI version
|
||||
- label: 您确保已使用最新 [CI 版本](https://github.com/FooIbar/EhViewer/actions)测试,并且该问题在最新 CI 版本中并未解决 / This bug have not solved in latest [CI version](https://github.com/FooIbar/EhViewer/actions)
|
||||
required: true
|
||||
@@ -1,5 +1 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 所有其他问题 / All other questions
|
||||
url: https://github.com/Ehviewer-Overhauled/Ehviewer/discussions
|
||||
about: 转到 Discussions / Turn to discussions
|
||||
blank_issues_enabled: false
|
||||
@@ -1,94 +0,0 @@
|
||||
name: 功能请求 / Feature request
|
||||
description: 提出一个功能建议 / Suggest an idea
|
||||
labels:
|
||||
- "enhancement"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢您愿意为 Ehviewer-Overhauled 做出贡献!
|
||||
提交功能建议前,还请首先完成文末的自查步骤
|
||||
|
||||
Thanks for your contribution on Ehviewer-Overhauled Project!
|
||||
Please finish verify steps which list in the end first before suggest an idea
|
||||
|
||||
- type: textarea
|
||||
id: request
|
||||
attributes:
|
||||
label: 需求 / Requirement
|
||||
description: |
|
||||
在此处描述您的需求。这通常会是一个您想要的功能
|
||||
Ddescribe what you need here.
|
||||
placeholder: |
|
||||
我需要 XXX 功能 ...
|
||||
I want ABC feature ...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: impl
|
||||
attributes:
|
||||
label: 建议实现 / Suggested implements
|
||||
description: |
|
||||
在此处表述您建议的实现方式。如有可能,UI 类功能请求还请尽量附上图示
|
||||
Describe your suggested implements here, It's recommend to add a photo if you are making a UI feature request.
|
||||
placeholder: |
|
||||
建议在 XX 处添加 XX ...
|
||||
I recommend add ABC feature to DEF...
|
||||
图片(如果有)/ Photos (if exists)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: more
|
||||
attributes:
|
||||
label: 备注 / Addition details
|
||||
description: |
|
||||
在此处写下其他您想说的内容
|
||||
Describe addition details here
|
||||
placeholder: |
|
||||
其他有用的信息与附件
|
||||
Additional details and attachments
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: EhViewer 版本号 / EhViewer version code
|
||||
description: 您可以在设置 - 关于处找到版本号 / You can get version code in Settings - About
|
||||
placeholder: 1.6.9.13
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: ci
|
||||
attributes:
|
||||
label: EhViewer CI 版本 / EhViewer CI Version
|
||||
description: 直接将对应 GitHub Action CI 下载页面网址填入即可 / Simply drop GitHub Action CI download page url here
|
||||
placeholder: https://github.com/Ehviewer-Overhauled/Ehviewer/actions/runs/XXXXXXXXXX
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: check
|
||||
attributes:
|
||||
label: 自查步骤 / Verify steps
|
||||
description: |
|
||||
请确认您已经遵守所有必选项
|
||||
Please ensure you have obtained all needed options
|
||||
options:
|
||||
- label: 如果您有足够的时间和能力,并愿意为此提交 PR ,请勾上此复选框 / Pull request is welcome. Check this if you want to start a pull request
|
||||
required: false
|
||||
|
||||
- label: 您已仔细查看并知情 [Q&A](https://github.com/Ehviewer-Overhauled/Ehviewer/issues/61) 中的内容 / You have checked [Q&A](https://github.com/Ehviewer-Overhauled/Ehviewer/issues/61) carefully
|
||||
required: true
|
||||
|
||||
- label: 您已搜索过 [Issue Tracker](https://github.com/Ehviewer-Overhauled/Ehviewer/issues),没有找到类似内容 / I have searched on [Issue Tracker](https://github.com/Ehviewer-Overhauled/Ehviewer/issues), No duplicate or related open issue has been found
|
||||
required: true
|
||||
|
||||
- label: 您确保这个 Issue 只提及一个功能。如果您有多个功能请求,烦请发起多个 Issue / Ensure there is only one feature request in this issue. Please make mutiply issue for mutiply feature request
|
||||
required: true
|
||||
|
||||
- label: 您确保已使用最新 CI 版本测试,并且该功能在最新 CI 版本中并未按照预期实现 / This feature don't implement correctly in latest CI version
|
||||
required: true
|
||||
+169
-33
@@ -4,55 +4,191 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
tags-ignore:
|
||||
- "*"
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Build
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Java 19
|
||||
uses: actions/setup-java@v3
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 19
|
||||
java-version: 21
|
||||
|
||||
- name: Install NDK
|
||||
run: |
|
||||
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.1.8937393" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
|
||||
- name: Install Rust Toolchain
|
||||
run: rustup update && rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android && rustup component add rustfmt clippy
|
||||
|
||||
- name: Gradle Build
|
||||
uses: gradle/gradle-build-action@v2
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./app/src/main/rust"
|
||||
shared-key: ${{ runner.os }}
|
||||
|
||||
- name: Rustfmt Check
|
||||
working-directory: ./app/src/main/rust
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
- name: Clippy Check
|
||||
working-directory: ./app/src/main/rust
|
||||
run: cargo clippy --all-targets --all-features -- -D warnings
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
cache-read-only: true
|
||||
|
||||
- name: Spotless Check
|
||||
run: ./gradlew spotlessCheck
|
||||
|
||||
default:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
run: rustup update && rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android && rustup component add rustfmt clippy
|
||||
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./app/src/main/rust"
|
||||
shared-key: ${{ runner.os }}
|
||||
save-if: "false"
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.GradleEncryptionKey }}
|
||||
gradle-home-cache-cleanup: true
|
||||
arguments: assembleRelease
|
||||
|
||||
- name: Update ARM64
|
||||
uses: actions/upload-artifact@v3
|
||||
- name: CMake Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
name: arm64-v8a-${{ github.sha }}
|
||||
path: app/build/outputs/apk/release/app-arm64-v8a-release.apk
|
||||
path: app/.cxx
|
||||
key: cmake-default-${{ hashFiles('gradle/libs.versions.toml', 'app/build.gradle.kts', 'app/src/main/cpp/CMakeLists.txt') }}
|
||||
restore-keys: cmake-default-
|
||||
|
||||
- name: Update x86_64
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: x86_64-${{ github.sha }}
|
||||
path: app/build/outputs/apk/release/app-x86_64-release.apk
|
||||
- name: Build
|
||||
run: ./gradlew assembleDefaultRelease
|
||||
|
||||
- name: Update ARM32
|
||||
uses: actions/upload-artifact@v3
|
||||
- name: Upload ARM64
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: armeabi-v7a-${{ github.sha }}
|
||||
path: app/build/outputs/apk/release/app-armeabi-v7a-release.apk
|
||||
name: default-arm64-v8a-${{ github.sha }}
|
||||
path: app/build/outputs/apk/default/release/app-default-arm64-v8a-release.apk
|
||||
|
||||
- name: Update x86
|
||||
uses: actions/upload-artifact@v3
|
||||
- name: Upload x86_64
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: x86-${{ github.sha }}
|
||||
path: app/build/outputs/apk/release/app-x86-release.apk
|
||||
name: default-x86_64-${{ github.sha }}
|
||||
path: app/build/outputs/apk/default/release/app-default-x86_64-release.apk
|
||||
|
||||
- name: Upload ARM32
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: default-armeabi-v7a-${{ github.sha }}
|
||||
path: app/build/outputs/apk/default/release/app-default-armeabi-v7a-release.apk
|
||||
|
||||
- name: Upload x86
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: default-x86-${{ github.sha }}
|
||||
path: app/build/outputs/apk/default/release/app-default-x86-release.apk
|
||||
|
||||
- name: Upload mapping
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: default-mapping-${{ github.sha }}
|
||||
path: app/build/outputs/mapping/defaultRelease/mapping.txt
|
||||
|
||||
- name: Upload native debug symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: default-native-debug-symbols-${{ github.sha }}
|
||||
path: app/build/outputs/native-debug-symbols/defaultRelease/native-debug-symbols.zip
|
||||
|
||||
marshmallow:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
run: rustup update && rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android && rustup component add rustfmt clippy
|
||||
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./app/src/main/rust"
|
||||
shared-key: ${{ runner.os }}
|
||||
save-if: "false"
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
cache-encryption-key: ${{ secrets.GradleEncryptionKey }}
|
||||
gradle-home-cache-cleanup: true
|
||||
|
||||
- name: CMake Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: app/.cxx
|
||||
key: cmake-marshmallow-${{ hashFiles('gradle/libs.versions.toml', 'app/build.gradle.kts', 'app/src/main/cpp/CMakeLists.txt') }}
|
||||
restore-keys: cmake-marshmallow-
|
||||
|
||||
- name: Build
|
||||
run: ./gradlew assembleMarshmallowRelease
|
||||
|
||||
- name: Upload ARM64
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: marshmallow-arm64-v8a-${{ github.sha }}
|
||||
path: app/build/outputs/apk/marshmallow/release/app-marshmallow-arm64-v8a-release.apk
|
||||
|
||||
- name: Upload x86_64
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: marshmallow-x86_64-${{ github.sha }}
|
||||
path: app/build/outputs/apk/marshmallow/release/app-marshmallow-x86_64-release.apk
|
||||
|
||||
- name: Upload ARM32
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: marshmallow-armeabi-v7a-${{ github.sha }}
|
||||
path: app/build/outputs/apk/marshmallow/release/app-marshmallow-armeabi-v7a-release.apk
|
||||
|
||||
- name: Upload x86
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: marshmallow-x86-${{ github.sha }}
|
||||
path: app/build/outputs/apk/marshmallow/release/app-marshmallow-x86-release.apk
|
||||
|
||||
- name: Upload mapping
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: marshmallow-mapping-${{ github.sha }}
|
||||
path: app/build/outputs/mapping/marshmallowRelease/mapping.txt
|
||||
|
||||
- name: Upload native debug symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: marshmallow-native-debug-symbols-${{ github.sha }}
|
||||
path: app/build/outputs/native-debug-symbols/marshmallowRelease/native-debug-symbols.zip
|
||||
@@ -0,0 +1,21 @@
|
||||
name: 'Lock Threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: lock-threads
|
||||
|
||||
jobs:
|
||||
action:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v5
|
||||
with:
|
||||
issue-inactive-days: '1'
|
||||
process-only: 'issues'
|
||||
@@ -1,52 +0,0 @@
|
||||
name: Pull Request Check
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Setup Java 19
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 19
|
||||
|
||||
- name: Install NDK
|
||||
run: |
|
||||
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.1.8937393" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
|
||||
|
||||
- name: Gradle Build
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: assembleRelease
|
||||
|
||||
- name: Update ARM64
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: arm64-v8a-${{ github.sha }}
|
||||
path: app/build/outputs/apk/release/app-arm64-v8a-release.apk
|
||||
|
||||
- name: Update x86_64
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: x86_64-${{ github.sha }}
|
||||
path: app/build/outputs/apk/release/app-x86_64-release.apk
|
||||
|
||||
- name: Update ARM32
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: armeabi-v7a-${{ github.sha }}
|
||||
path: app/build/outputs/apk/release/app-armeabi-v7a-release.apk
|
||||
|
||||
- name: Update x86
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: x86-${{ github.sha }}
|
||||
path: app/build/outputs/apk/release/app-x86-release.apk
|
||||
@@ -6,66 +6,73 @@ on:
|
||||
- "*"
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Build
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Java 19
|
||||
uses: actions/setup-java@v3
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 19
|
||||
java-version: 21
|
||||
|
||||
- name: Install NDK
|
||||
run: |
|
||||
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.1.8937393" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
|
||||
- name: Install Rust Toolchain
|
||||
run: rustup update && rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android
|
||||
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./app/src/main/rust"
|
||||
|
||||
- name: CMake Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: app/.cxx
|
||||
key: cmake-${{ hashFiles('gradle/libs.versions.toml', 'app/build.gradle.kts', 'app/src/main/cpp/CMakeLists.txt') }}
|
||||
restore-keys: cmake-
|
||||
|
||||
- name: Gradle Build
|
||||
uses: gradle/gradle-build-action@v2
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
arguments: assembleRelease
|
||||
|
||||
- name: Rename Apks
|
||||
run: |
|
||||
cp app/build/outputs/apk/release/app-universal-release.apk app/build/outputs/apk/release/EhViewer-universal.apk
|
||||
cp app/build/outputs/apk/release/app-arm64-v8a-release.apk app/build/outputs/apk/release/EhViewer-arm64-v8a.apk
|
||||
cp app/build/outputs/apk/release/app-x86_64-release.apk app/build/outputs/apk/release/EhViewer-x86_64.apk
|
||||
cp app/build/outputs/apk/release/app-x86-release.apk app/build/outputs/apk/release/EhViewer-x86.apk
|
||||
cp app/build/outputs/apk/release/app-armeabi-v7a-release.apk app/build/outputs/apk/release/EhViewer-armeabi-v7a.apk
|
||||
mv app/build/outputs/apk/default/release/app-default-universal-release.apk EhViewer-${{ github.ref_name }}-default-universal.apk
|
||||
mv app/build/outputs/apk/default/release/app-default-arm64-v8a-release.apk EhViewer-${{ github.ref_name }}-default-arm64-v8a.apk
|
||||
mv app/build/outputs/apk/default/release/app-default-x86_64-release.apk EhViewer-${{ github.ref_name }}-default-x86_64.apk
|
||||
mv app/build/outputs/apk/default/release/app-default-x86-release.apk EhViewer-${{ github.ref_name }}-default-x86.apk
|
||||
mv app/build/outputs/apk/default/release/app-default-armeabi-v7a-release.apk EhViewer-${{ github.ref_name }}-default-armeabi-v7a.apk
|
||||
mv app/build/outputs/mapping/defaultRelease/mapping.txt EhViewer-${{ github.ref_name }}-default-mapping.txt
|
||||
mv app/build/outputs/native-debug-symbols/defaultRelease/native-debug-symbols.zip EhViewer-${{ github.ref_name }}-default-native-debug-symbols.zip
|
||||
|
||||
mv app/build/outputs/apk/marshmallow/release/app-marshmallow-universal-release.apk EhViewer-${{ github.ref_name }}-marshmallow-universal.apk
|
||||
mv app/build/outputs/apk/marshmallow/release/app-marshmallow-arm64-v8a-release.apk EhViewer-${{ github.ref_name }}-marshmallow-arm64-v8a.apk
|
||||
mv app/build/outputs/apk/marshmallow/release/app-marshmallow-x86_64-release.apk EhViewer-${{ github.ref_name }}-marshmallow-x86_64.apk
|
||||
mv app/build/outputs/apk/marshmallow/release/app-marshmallow-x86-release.apk EhViewer-${{ github.ref_name }}-marshmallow-x86.apk
|
||||
mv app/build/outputs/apk/marshmallow/release/app-marshmallow-armeabi-v7a-release.apk EhViewer-${{ github.ref_name }}-marshmallow-armeabi-v7a.apk
|
||||
mv app/build/outputs/mapping/marshmallowRelease/mapping.txt EhViewer-${{ github.ref_name }}-marshmallow-mapping.txt
|
||||
mv app/build/outputs/native-debug-symbols/marshmallowRelease/native-debug-symbols.zip EhViewer-${{ github.ref_name }}-marshmallow-native-debug-symbols.zip
|
||||
|
||||
- name: Releases
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body: Bump Version
|
||||
discussion_category_name: Announcements
|
||||
files: |
|
||||
app/build/outputs/apk/release/EhViewer-universal.apk
|
||||
app/build/outputs/apk/release/EhViewer-arm64-v8a.apk
|
||||
app/build/outputs/apk/release/EhViewer-x86_64.apk
|
||||
app/build/outputs/apk/release/EhViewer-x86.apk
|
||||
app/build/outputs/apk/release/EhViewer-armeabi-v7a.apk
|
||||
EhViewer-${{ github.ref_name }}-default-universal.apk
|
||||
EhViewer-${{ github.ref_name }}-default-arm64-v8a.apk
|
||||
EhViewer-${{ github.ref_name }}-default-x86_64.apk
|
||||
EhViewer-${{ github.ref_name }}-default-x86.apk
|
||||
EhViewer-${{ github.ref_name }}-default-armeabi-v7a.apk
|
||||
EhViewer-${{ github.ref_name }}-default-mapping.txt
|
||||
EhViewer-${{ github.ref_name }}-default-native-debug-symbols.zip
|
||||
|
||||
- name: Collect Apks
|
||||
run: |
|
||||
mkdir app/build/outputs/apk/release/fdroid
|
||||
cp app/build/outputs/apk/release/app-arm64-v8a-release.apk app/build/outputs/apk/release/fdroid/EhViewer-v$GITHUB_REF_NAME.apk
|
||||
cp app/build/outputs/apk/release/app-armeabi-v7a-release.apk app/build/outputs/apk/release/fdroid/EhViewer-v$GITHUB_REF_NAME-armv7.apk
|
||||
|
||||
- name: Push Apks
|
||||
uses: cpina/github-action-push-to-another-repository@v1.5
|
||||
env:
|
||||
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
|
||||
with:
|
||||
source-directory: app/build/outputs/apk/release/fdroid
|
||||
destination-github-username: Ehviewer-Overhauled
|
||||
destination-repository-name: fdroid-repo
|
||||
user-name: 'github-actions[bot]'
|
||||
user-email: 'github-actions[bot]@users.noreply.github.com'
|
||||
target-branch: deploy
|
||||
commit-message: Add apks from $GITHUB_REF
|
||||
target-directory: fdroid/tmp-apks
|
||||
EhViewer-${{ github.ref_name }}-marshmallow-universal.apk
|
||||
EhViewer-${{ github.ref_name }}-marshmallow-arm64-v8a.apk
|
||||
EhViewer-${{ github.ref_name }}-marshmallow-x86_64.apk
|
||||
EhViewer-${{ github.ref_name }}-marshmallow-x86.apk
|
||||
EhViewer-${{ github.ref_name }}-marshmallow-armeabi-v7a.apk
|
||||
EhViewer-${{ github.ref_name }}-marshmallow-mapping.txt
|
||||
EhViewer-${{ github.ref_name }}-marshmallow-native-debug-symbols.zip
|
||||
+1
-3
@@ -2,9 +2,7 @@
|
||||
/local.properties
|
||||
.DS_Store
|
||||
/build
|
||||
/src
|
||||
/.kotlin
|
||||
*.iml
|
||||
.idea
|
||||
/captures
|
||||
release
|
||||
google-services.json
|
||||
@@ -1,9 +0,0 @@
|
||||
[submodule "app/src/main/cpp/libarchive"]
|
||||
path = app/src/main/cpp/libarchive
|
||||
url = https://github.com/Ehviewer-Overhauled/libarchive
|
||||
[submodule "app/src/main/cpp/liblzma"]
|
||||
path = app/src/main/cpp/liblzma
|
||||
url = https://github.com/Ehviewer-Overhauled/xz
|
||||
[submodule "app/src/main/cpp/nettle/nettle"]
|
||||
path = app/src/main/cpp/nettle/nettle
|
||||
url = https://github.com/Ehviewer-Overhauled/nettle
|
||||
@@ -0,0 +1,245 @@
|
||||
# 变更日志
|
||||
|
||||
## [1.11.4] - 2024-04-21
|
||||
|
||||
### 新功能
|
||||
|
||||
* 更新前自动备份数据
|
||||
|
||||
### 改进
|
||||
|
||||
* 在 设置-高级 中加入了禁用列表项目动画的选项,该功能在部分设备上导致崩溃/卡顿 [#996](https://github.com/FooIbar/EhViewer/issues/996) [#1023](https://github.com/FooIbar/EhViewer/issues/1023)
|
||||
* 下载列表多选模式下避免误触 [#1016](https://github.com/FooIbar/EhViewer/issues/1016)
|
||||
* 杂项 UI 优化
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 重命名下载标签后删除该标签时崩溃 [#1008](https://github.com/FooIbar/EhViewer/issues/1008)
|
||||
* 搜索栏中某些输入法长按退格无法连续删除 [#606](https://github.com/FooIbar/EhViewer/issues/606)
|
||||
* 评论/屏蔽/搜索建议/下载标签/快速搜索列表卡顿 [#1041](https://github.com/FooIbar/EhViewer/issues/1041)
|
||||
|
||||
|
||||
## [1.11.3] - 2024-04-06
|
||||
|
||||
### 改进
|
||||
|
||||
* 优化预加载逻辑和图片加载顺序
|
||||
* 优化画廊详情和评论页面 UI
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 某些模式下搜索结果不显示画廊语言 [#923](https://github.com/FooIbar/EhViewer/issues/923)
|
||||
* 某些情况下在搜索结果中直接阅读画廊后崩溃 [#927](https://github.com/FooIbar/EhViewer/issues/927)
|
||||
* 更新至最新版本后仍提示有新版本 [#927](https://github.com/FooIbar/EhViewer/issues/927)
|
||||
* 从旧版本升级时包含不兼容数据导致崩溃/无法导出数据 [#940](https://github.com/FooIbar/EhViewer/issues/940) [#974](https://github.com/FooIbar/EhViewer/issues/974)
|
||||
* Android 10 以下的设备打开 设置-隐私 时崩溃 [#953](https://github.com/FooIbar/EhViewer/issues/953)
|
||||
* 下载标签无法拖动
|
||||
* 刷新 和 刷新(原图) 无法在已下载的图片上使用
|
||||
* 临时 IP 封禁错误显示为解析失败
|
||||
* 某些情况下下载时闪退 [#980](https://github.com/FooIbar/EhViewer/issues/980)
|
||||
* 某些设备上下载列表中的缩略图无法显示 [#977](https://github.com/FooIbar/EhViewer/issues/977)
|
||||
|
||||
|
||||
## [1.11.2] - 2024-03-17
|
||||
|
||||
### 重大变更
|
||||
|
||||
* Default 变种最低支持版本更改为 Android 8.0,重新添加了最低支持 Android 6.0 的 Marshmallow 变种
|
||||
|
||||
### 改进
|
||||
|
||||
* 重新添加了删除快速搜索/下载标签时的确认对话框
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 收藏页面 搜索栏中文标签转英文异常 [#902](https://github.com/FooIbar/EhViewer/issues/902)
|
||||
* 在收藏或者取消收藏之后,收藏按钮会无反应 [#908](https://github.com/FooIbar/EhViewer/issues/908)
|
||||
* 横屏页面下阅读设置UI重合 [#909](https://github.com/FooIbar/EhViewer/issues/909)
|
||||
* Search bar does not work properly in Japanese [#906](https://github.com/FooIbar/EhViewer/issues/906)
|
||||
* 搜索结果中的 Disowned 画廊不显示上传者
|
||||
* 使用 CI 频道更新时,有时会获取到错误的更新链接
|
||||
|
||||
|
||||
## [1.11.1] - 2024-03-12
|
||||
|
||||
### 重大变更
|
||||
|
||||
* 由于 E 站强制要求人机验证,仅支持通过网页登录
|
||||
* 默认支持 Android 6,不再提供 Marshmallow 变种
|
||||
* 集成 Cronet 库,不再提供 GMS 变种
|
||||
|
||||
### 改进
|
||||
|
||||
* 支持在排序下载列表前按下载标签分组
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 下载画廊时崩溃 [#893](https://github.com/FooIbar/EhViewer/issues/893)
|
||||
|
||||
|
||||
## [1.11.0] - 2024-03-09
|
||||
|
||||
### 重大变更
|
||||
|
||||
* 由于 E 站 Cookie 策略变更,不再支持 Cookie 登录
|
||||
* 登录时自动选择 exhentai (如果可用)
|
||||
* 不再提供默认下载路径
|
||||
* 手动排序更改为以添加时间/上传时间/标题/下载标签/页数对下载列表排序
|
||||
* 由于数据库结构变更,此版本导出的数据将无法被旧版本导入
|
||||
|
||||
### 新功能
|
||||
|
||||
* 下载画廊时生成 ComicInfo.xml 格式元数据
|
||||
* 归档下载时生成 ComicInfo.xml 格式元数据 [#711](https://github.com/FooIbar/EhViewer/issues/711)
|
||||
* 归档下载支持第三方下载管理器 [#79](https://github.com/FooIbar/EhViewer/issues/79)
|
||||
* 保存下载结果为 CBZ 压缩包 [#660](https://github.com/FooIbar/EhViewer/issues/660)
|
||||
* 清除 `igneous` Cookie (将于下次搜索时重新获取)
|
||||
* 随机打开本地收藏/下载中的画廊 [#695](https://github.com/FooIbar/EhViewer/issues/695)
|
||||
* 随机在搜索结果中跳转
|
||||
* 以网格模式查看下载列表
|
||||
* 本地收藏/历史/下载中的标签搜索 [#860](https://github.com/FooIbar/EhViewer/issues/860)
|
||||
|
||||
### 改进
|
||||
|
||||
* 搜索时优先显示已选择的类别卡片
|
||||
* 多处性能优化
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 显示模式为 Thumbnail 时无法点击上传者卡片 [#653](https://github.com/FooIbar/EhViewer/issues/653)
|
||||
* [Marshmallow] GIF 只显示第一帧
|
||||
* 无法在 `定时请求新闻页面` 关闭时开启 `隐藏 HV 事件通知`
|
||||
* 响应正文含有无效 UTF-8 字符导致解码失败 [#643](https://github.com/FooIbar/EhViewer/issues/643)
|
||||
* 某些情况下应用崩溃 [#710](https://github.com/FooIbar/EhViewer/issues/710)
|
||||
* 画廊名称包含非法路径字符时无法保存图片 [#815](https://github.com/FooIbar/EhViewer/issues/815)
|
||||
* 无法解码超长图片 [#732](https://github.com/FooIbar/EhViewer/issues/732)
|
||||
* E 站变更导致种子解析失败 [#880](https://github.com/FooIbar/EhViewer/issues/880)
|
||||
* E 站不再支持相似扫描导致图片搜索无法使用
|
||||
* 杂项修复
|
||||
|
||||
### 已知问题
|
||||
|
||||
* Android 14 上使用手势导航返回时过渡动画过早结束 [#775](https://github.com/FooIbar/EhViewer/issues/775)
|
||||
|
||||
|
||||
## [1.10.3] - 2024-01-15
|
||||
|
||||
### 新功能
|
||||
|
||||
* [Marshmallow] 支持裁剪边缘、打开压缩包和 GIF
|
||||
|
||||
### 改进
|
||||
|
||||
* 由于部分设备上的非预期行为 [#578](https://github.com/FooIbar/EhViewer/issues/578) [#596](https://github.com/FooIbar/EhViewer/issues/596),默认禁用预见式返回导航动画,可于 设置-高级 中开启
|
||||
* 杂项优化
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 刷新后页面无响应 [#579](https://github.com/FooIbar/EhViewer/issues/579)
|
||||
* 浏览中保存图片后点击操作被阻挡 [#581](https://github.com/FooIbar/EhViewer/issues/581)
|
||||
* 在画廊详情页面切换至后台后点击评论闪退 [#580](https://github.com/FooIbar/EhViewer/issues/580)
|
||||
* 已下载的画廊中未阅读缓存过的图片解码失败 [#592](https://github.com/FooIbar/EhViewer/issues/592)
|
||||
* 在收藏页多选并下载会使得下载状态出现问题 [#603](https://github.com/FooIbar/EhViewer/issues/603)
|
||||
* 未能在不重启情况下切换 Http 引擎 [#610](https://github.com/FooIbar/EhViewer/issues/610)
|
||||
* 在有进度的画廊阅读界面无法直接回到第一页 [#614](https://github.com/FooIbar/EhViewer/issues/614)
|
||||
* 请求新闻界面失效 [#605](https://github.com/FooIbar/EhViewer/issues/605)
|
||||
* 收藏夹为空解析失败 [#630](https://github.com/FooIbar/EhViewer/issues/630)
|
||||
|
||||
|
||||
## [1.10.2] - 2023-12-31
|
||||
|
||||
### 新功能
|
||||
|
||||
* [阅读器] 支持裁剪图片黑色/白色边缘
|
||||
|
||||
### 改进
|
||||
|
||||
* 切换 HTTP 引擎无需重启
|
||||
* 优化过渡动画
|
||||
* 杂项性能优化
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 修复搜索建议中出现关键词相同的条目时崩溃 [#533](https://github.com/FooIbar/EhViewer/issues/533) [#555](https://github.com/FooIbar/EhViewer/issues/555)
|
||||
* 修复重命名下载标签时不显示原标签 [#534](https://github.com/FooIbar/EhViewer/issues/534)
|
||||
* 修复调整下载项目顺序时卡顿 [#552](https://github.com/FooIbar/EhViewer/issues/552)
|
||||
* 修复新增或修改评论后黑屏 [#554](https://github.com/FooIbar/EhViewer/issues/554)
|
||||
* 修复剪贴板读取bug [#566](https://github.com/FooIbar/EhViewer/issues/566)
|
||||
* 修复画廊信息对话框无法通过返回按钮/手势关闭 [#413](https://github.com/FooIbar/EhViewer/issues/413)
|
||||
|
||||
|
||||
## [1.10.1] - 2023-12-19
|
||||
|
||||
### 重大变更
|
||||
|
||||
* 由于 Apache HttpClient 5 在 Android 10 以下无法使用,后备 HTTP 引擎恢复为 OkHttp [#514](https://github.com/FooIbar/EhViewer/issues/514)
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 修复获取 pToken 失败导致无限加载 [#508](https://github.com/FooIbar/EhViewer/issues/508)
|
||||
* 修复阅读页快速滑动滑块导致下载延时过多累计 [#512](https://github.com/FooIbar/EhViewer/issues/512)
|
||||
* 修复 Android 9 以下的设备上无法退出搜索栏 [#513](https://github.com/FooIbar/EhViewer/issues/513)
|
||||
|
||||
|
||||
## [1.10.0] - 2023-12-14 [YANKED]
|
||||
|
||||
### 重大变更
|
||||
|
||||
* 后备 HTTP 引擎变更为 Apache HttpClient 5
|
||||
* 类别和高级搜索选项移至搜索栏下方
|
||||
|
||||
### 新功能
|
||||
|
||||
* 支持在搜索时指定画廊语言
|
||||
|
||||
### 改进
|
||||
|
||||
* 在下载中阅读画廊时会更新历史记录
|
||||
* 多处性能改进
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 修复无法由外部应用进入画廊页面 [#436](https://github.com/FooIbar/EhViewer/issues/436)
|
||||
* 修复点击精确到页的画廊链接闪退 [#430](https://github.com/FooIbar/EhViewer/issues/430)
|
||||
* 修复无法搜索本地收藏 [#491](https://github.com/FooIbar/EhViewer/issues/491)
|
||||
* 修复 CI 版本不显示变更日志
|
||||
|
||||
|
||||
## [1.9.0] - 2023-12-01
|
||||
|
||||
### 重大变更
|
||||
|
||||
* 除阅读器外全部迁移至 Compose
|
||||
|
||||
### 新功能
|
||||
|
||||
* 设置-高级 中增加实验性滑动手势敏感度设置
|
||||
* 支持通过滑动手势打开右侧抽屉
|
||||
* 支持预见式返回动画,相关设置位于 设置-高级
|
||||
|
||||
### 改进
|
||||
|
||||
* [阅读器] 画廊页数过多时隐藏进度条刻度并禁用触感反馈
|
||||
* 优化原图下载重试策略
|
||||
* 优化小屏设备上的搜索类别布局
|
||||
* 优化过渡动画
|
||||
* 优化历史记录删除动画
|
||||
* 设置-EH 中的缩略图大小设置改为缩略图列数
|
||||
|
||||
### Bug 修复
|
||||
|
||||
* 修复点击通知栏的下载通知闪退 [#175](https://github.com/FooIbar/EhViewer/issues/175)
|
||||
* 修复收藏状态显示错误 [#189](https://github.com/FooIbar/EhViewer/issues/189)
|
||||
* 修复双击导航按钮后无法打开导航抽屉
|
||||
* 修复某些情况下闪退 [#142](https://github.com/FooIbar/EhViewer/issues/142) [#208](https://github.com/FooIbar/EhViewer/issues/208)
|
||||
* 修复收藏界面点击重试崩溃 [#193](https://github.com/FooIbar/EhViewer/issues/193)
|
||||
* 修复本地收藏滚动位置丢失 [#192](https://github.com/FooIbar/EhViewer/issues/192)
|
||||
* 修复手速过快页面切换过快使加载圈圈不自动消失 [#209](https://github.com/FooIbar/EhViewer/issues/209)
|
||||
* 修复打开并关闭右侧抽屉后,状态栏一片白色 [#101](https://github.com/FooIbar/EhViewer/issues/101)
|
||||
* 修复使用深色主题时,切换界面会闪过亮色界面 [#121](https://github.com/FooIbar/EhViewer/issues/121)
|
||||
* [Marshmallow] 修复小内存设备上图片解码失败 [#229](https://github.com/FooIbar/EhViewer/issues/229) [#372](https://github.com/FooIbar/EhViewer/issues/372)
|
||||
* 修复已舍弃画廊上传者解析
|
||||
|
||||
### 已知问题
|
||||
|
||||
* 画廊信息对话框无法通过返回关闭 [#413](https://github.com/FooIbar/EhViewer/issues/413)
|
||||
@@ -1,100 +1,107 @@
|
||||
<p align="right">
|
||||
<strong>English<strong>
|
||||
<strong>English</strong>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md">
|
||||
<a href="/docs/README/zh-cn.md">
|
||||
简体中文
|
||||
</a>
|
||||
<span> | <span>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md">
|
||||
<span> | </span>
|
||||
<a href="/docs/README/zh-tw.md">
|
||||
正體中文
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">
|
||||
<img src="art/launcher_icon-web.svg" width="200">
|
||||
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200" alt="EhViewer">
|
||||
<br>EhViewer<br>
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml">
|
||||
<img src="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
|
||||
<a href="https://github.com/FooIbar/EhViewer/actions/workflows/ci.yml">
|
||||
<img src="https://github.com/FooIbar/EhViewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
|
||||
</a>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Ehviewer-Overhauled/Ehviewer" alt="LICENSE">
|
||||
<a href="/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/FooIbar/EhViewer" alt="LICENSE">
|
||||
</a>
|
||||
<a href="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer">
|
||||
<img src="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer/badge" alt="CodeFactor">
|
||||
<a href="https://www.codefactor.io/repository/github/FooIbar/EhViewer">
|
||||
<img src="https://www.codefactor.io/repository/github/FooIbar/EhViewer/badge" alt="CodeFactor">
|
||||
</a>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases">
|
||||
<img src="https://img.shields.io/github/v/release/Ehviewer-Overhauled/ehviewer?include_prereleases" alt="Release">
|
||||
<a href="https://github.com/FooIbar/EhViewer/releases">
|
||||
<img src="https://img.shields.io/github/v/release/FooIbar/EhViewer" alt="Release">
|
||||
</a>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/issues">
|
||||
<img src="https://img.shields.io/github/issues/Ehviewer-Overhauled/ehviewer" alt="Issues">
|
||||
<a href="https://github.com/FooIbar/EhViewer/issues">
|
||||
<img src="https://img.shields.io/github/issues/FooIbar/EhViewer" alt="Issues">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
<h3>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#description">
|
||||
<a href="#description">
|
||||
Description
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#download">
|
||||
<a href="#download">
|
||||
Download
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#screenshot">
|
||||
<a href="#screenshot">
|
||||
Screenshot
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#thanks">
|
||||
<a href="#thanks">
|
||||
Thanks
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#license">
|
||||
<a href="#license">
|
||||
License
|
||||
</a>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
|
||||
# Description
|
||||
|
||||
EhViewer fork dedicated to lightweight and high-performance
|
||||
|
||||
with Material Design 3 and Dynamic Color Support
|
||||
with [Material Design 3](https://m3.material.io/)
|
||||
and [Dynamic Color](https://m3.material.io/styles/color/dynamic-color/overview) Support
|
||||
|
||||
# Download
|
||||
|
||||
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="art/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="art/get-it-on-fdroid.svg" width="200px"/></a>
|
||||
| Flavor | Feature |
|
||||
|-------------|----------------------------------|
|
||||
| Default | Android 8.0+, full support |
|
||||
| Marshmallow | Android 6.0-7.1, limited support |
|
||||
|
||||
<a href="https://github.com/FooIbar/EhViewer/releases">
|
||||
<img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/>
|
||||
</a>
|
||||
|
||||
# Screenshot
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
# Thanks
|
||||
|
||||
Here is the libraries
|
||||
|
||||
- [Arrow](https://arrow-kt.io/)
|
||||
- [AOSP & AndroidX](http://source.android.com/)
|
||||
- [Kotlin & KotlinX](https://kotlinlang.org/)
|
||||
- [Material Icons](https://github.com/google/material-design-icons)
|
||||
- [Ktor](https://ktor.io/)
|
||||
- [Coil](https://coil-kt.github.io/coil/)
|
||||
- [FullDraggableDrawer](https://github.com/PureWriter/FullDraggableDrawer)
|
||||
- [GnuTLS](https://gnutls.org/)
|
||||
- [material-components-android](https://github.com/material-components/material-components-android)
|
||||
- [material-design-icons](https://github.com/google/material-design-icons)
|
||||
- [jsoup](https://github.com/jhy/jsoup)
|
||||
- [okhttp](https://github.com/square/okhttp)
|
||||
- [RikkaX](https://github.com/RikkaApps/RikkaX)
|
||||
- [Compose Destinations](https://composedestinations.rafaelcosta.xyz/)
|
||||
- [libarchive](http://www.libarchive.org/)
|
||||
- [XZ Utils](https://tukaani.org/xz/)
|
||||
- [jsoup](https://jsoup.org/)
|
||||
|
||||
Specially thanks [Tachiyomi](https://tachiyomi.org/) for its reader implementation!
|
||||
|
||||
# License
|
||||
|
||||
Copyright 2014-2019 Hippo Seven
|
||||
Copyright 2020-2022 NekoInverter
|
||||
Copyright 2022 Tarsin Norbin
|
||||
Copyright 2022-2023 Tarsin Norbin
|
||||
Copyright 2023-2024 Foolbar
|
||||
|
||||
EhViewer is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
@@ -1,8 +1,2 @@
|
||||
/build
|
||||
/src/main/java-gen
|
||||
manifest-merger-release-report.txt
|
||||
/src/main/libs
|
||||
/src/main/obj
|
||||
# Intellij
|
||||
*.iml
|
||||
/.cxx
|
||||
@@ -1,209 +0,0 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'com.google.devtools.ksp'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
buildToolsVersion "33.0.1"
|
||||
ndkVersion "25.1.8937393"
|
||||
|
||||
splits {
|
||||
abi {
|
||||
enable = true
|
||||
reset()
|
||||
include 'arm64-v8a', 'x86_64', 'armeabi-v7a', 'x86'
|
||||
universalApk = true
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
sign {
|
||||
storeFile file(signStoreFile)
|
||||
storePassword signStorePassword
|
||||
keyAlias signkeyAlias
|
||||
keyPassword signkeyPassword
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "moe.tarsin.ehviewer"
|
||||
minSdkVersion 28
|
||||
targetSdkVersion 33
|
||||
versionCode 180027
|
||||
versionName "1.8.5.0-preview"
|
||||
resConfigs 'zh', 'zh-rCN', 'zh-rHK', 'zh-rTW', 'es', 'ja', 'ko', 'fr', 'de', 'th'
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path 'src/main/cpp/CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_19
|
||||
targetCompatibility JavaVersion.VERSION_19
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '19'
|
||||
freeCompilerArgs += [
|
||||
// https://kotlinlang.org/docs/compiler-reference.html#progressive
|
||||
"-progressive",
|
||||
// Generate smaller bytecode by not generating runtime not-null assertions.
|
||||
"-Xno-call-assertions",
|
||||
"-Xno-param-assertions",
|
||||
"-Xno-receiver-assertions",
|
||||
"-P",
|
||||
"plugin:androidx.compose.compiler.plugins.kotlin:suppressKotlinVersionCompatibilityCheck=true"
|
||||
]
|
||||
}
|
||||
|
||||
lint {
|
||||
abortOnError true
|
||||
checkReleaseBuilds false
|
||||
disable 'MissingTranslation'
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
resources {
|
||||
excludes += "/META-INF/**"
|
||||
excludes += "/kotlin/**"
|
||||
excludes += "**.txt"
|
||||
excludes += "**.bin"
|
||||
}
|
||||
}
|
||||
|
||||
dependenciesInfo.includeInApk false
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFiles 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.sign
|
||||
}
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig true
|
||||
compose true
|
||||
dataBinding true
|
||||
viewBinding true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.4.0-alpha02"
|
||||
}
|
||||
|
||||
namespace 'com.hippo.ehviewer'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
def activity_version = "1.6.1"
|
||||
implementation "androidx.activity:activity:$activity_version"
|
||||
implementation "androidx.activity:activity-ktx:$activity_version"
|
||||
|
||||
implementation "androidx.annotation:annotation:1.5.0"
|
||||
implementation "androidx.annotation:annotation-experimental:1.3.0"
|
||||
implementation "androidx.appcompat:appcompat:1.6.0-rc01"
|
||||
|
||||
def arch_core_version = "2.1.0"
|
||||
implementation "androidx.arch.core:core-common:$arch_core_version"
|
||||
implementation "androidx.arch.core:core-runtime:$arch_core_version"
|
||||
|
||||
implementation "androidx.biometric:biometric-ktx:1.2.0-alpha05"
|
||||
implementation "androidx.browser:browser:1.4.0"
|
||||
|
||||
def collection_version = "1.3.0-alpha02"
|
||||
implementation "androidx.collection:collection:$collection_version"
|
||||
implementation "androidx.collection:collection-ktx:$collection_version"
|
||||
|
||||
implementation platform("androidx.compose:compose-bom:2022.12.00")
|
||||
implementation "androidx.compose.animation:animation"
|
||||
implementation "androidx.compose.foundation:foundation"
|
||||
implementation "androidx.compose.foundation:foundation-layout"
|
||||
implementation "androidx.compose.material3:material3"
|
||||
implementation "androidx.compose.runtime:runtime"
|
||||
implementation "androidx.compose.runtime:runtime-saveable"
|
||||
implementation "androidx.compose.ui:ui"
|
||||
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha05"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
|
||||
|
||||
def core_version = "1.9.0"
|
||||
implementation "androidx.core:core:$core_version"
|
||||
implementation "androidx.core:core-ktx:$core_version"
|
||||
|
||||
implementation "androidx.customview:customview:1.2.0-alpha02"
|
||||
implementation "androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03"
|
||||
|
||||
def fragment_version = "1.6.0-alpha04"
|
||||
implementation "androidx.fragment:fragment:$fragment_version"
|
||||
implementation "androidx.fragment:fragment-ktx:$fragment_version"
|
||||
|
||||
def lifecycle_version = "2.6.0-alpha03"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-core-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
|
||||
|
||||
implementation "androidx.loader:loader:1.1.0"
|
||||
|
||||
def nav_version = "2.5.3"
|
||||
implementation "androidx.navigation:navigation-fragment:$nav_version"
|
||||
implementation "androidx.navigation:navigation-ui:$nav_version"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
|
||||
|
||||
implementation "androidx.paging:paging-runtime:3.2.0-alpha03"
|
||||
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.0-rc01'
|
||||
|
||||
def room_version = "2.5.0-rc01"
|
||||
implementation "androidx.room:room-runtime:$room_version"
|
||||
annotationProcessor "androidx.room:room-compiler:$room_version"
|
||||
implementation "androidx.room:room-paging:$room_version"
|
||||
|
||||
implementation 'androidx.startup:startup-runtime:1.2.0-alpha01'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01'
|
||||
implementation "androidx.transition:transition-ktx:1.4.1"
|
||||
implementation "androidx.vectordrawable:vectordrawable:1.2.0-beta01"
|
||||
implementation "androidx.vectordrawable:vectordrawable-animated:1.1.0"
|
||||
implementation 'androidx.viewpager:viewpager:1.1.0-alpha01'
|
||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
|
||||
|
||||
implementation 'com.drakeet.drawer:drawer:1.0.3'
|
||||
implementation 'com.google.android.material:material:1.8.0-beta01'
|
||||
|
||||
implementation 'com.squareup.okhttp3:okhttp-bom:5.0.0-alpha.10'
|
||||
implementation 'com.squareup.okhttp3:okhttp'
|
||||
|
||||
implementation 'dev.rikka.rikkax.core:core-ktx:1.4.1'
|
||||
implementation 'dev.rikka.rikkax.insets:insets:1.3.0'
|
||||
implementation 'dev.rikka.rikkax.layoutinflater:layoutinflater:1.2.0'
|
||||
implementation 'dev.rikka.rikkax.preference:simplemenu-preference:1.0.3'
|
||||
implementation 'dev.rikka.rikkax.material:material-preference:2.0.0'
|
||||
implementation 'io.coil-kt:coil:2.2.2'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
|
||||
implementation 'org.jsoup:jsoup:1.15.3'
|
||||
|
||||
// Tachiyomi Reader
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||
implementation 'dev.chrisbanes.insetter:insetter:0.6.1'
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
exclude group: 'dev.rikka.rikkax.appcompat', module: 'appcompat'
|
||||
exclude group: 'dev.rikka.rikkax.material', module: 'material'
|
||||
exclude group: 'androidx.compose.material'
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
import com.mikepenz.aboutlibraries.plugin.DuplicateMode.MERGE
|
||||
import com.mikepenz.aboutlibraries.plugin.DuplicateRule.GROUP
|
||||
import java.time.Instant
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
val isRelease: Boolean
|
||||
get() = gradle.startParameter.taskNames.any { it.contains("Release") }
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
alias(libs.plugins.kotlin.parcelize)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.ksp)
|
||||
alias(libs.plugins.spotless)
|
||||
alias(libs.plugins.aboutlibrariesPlugin)
|
||||
alias(libs.plugins.composeCompilerReportGenerator)
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk = 34
|
||||
ndkVersion = "26.2.11394342"
|
||||
|
||||
splits {
|
||||
abi {
|
||||
isEnable = true
|
||||
reset()
|
||||
if (isRelease) {
|
||||
include("arm64-v8a", "x86_64", "armeabi-v7a", "x86")
|
||||
isUniversalApk = true
|
||||
} else {
|
||||
include("arm64-v8a", "x86_64")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val signConfig = signingConfigs.create("release") {
|
||||
storeFile = File(projectDir.path + "/keystore/androidkey.jks")
|
||||
storePassword = "000000"
|
||||
keyAlias = "key0"
|
||||
keyPassword = "000000"
|
||||
enableV3Signing = true
|
||||
enableV4Signing = true
|
||||
}
|
||||
|
||||
val commitSha = providers.exec {
|
||||
commandLine = "git rev-parse --short=7 HEAD".split(' ')
|
||||
}.standardOutput.asText.get().trim()
|
||||
|
||||
val buildTime by lazy {
|
||||
val formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm").withZone(ZoneOffset.UTC)
|
||||
formatter.format(Instant.now())
|
||||
}
|
||||
|
||||
val repoName = providers.exec {
|
||||
commandLine = "git remote get-url origin".split(' ')
|
||||
}.standardOutput.asText.get().trim().removePrefix("https://github.com/").removePrefix("git@github.com:")
|
||||
.removeSuffix(".git")
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "moe.tarsin.ehviewer"
|
||||
minSdk = 26
|
||||
targetSdk = 34
|
||||
versionCode = 180055
|
||||
versionName = "1.11.4"
|
||||
// versionNameSuffix = "-SNAPSHOT"
|
||||
resourceConfigurations.addAll(
|
||||
listOf(
|
||||
"zh",
|
||||
"zh-rCN",
|
||||
"zh-rHK",
|
||||
"zh-rTW",
|
||||
"es",
|
||||
"ja",
|
||||
"ko",
|
||||
"fr",
|
||||
"de",
|
||||
"th",
|
||||
"tr",
|
||||
"nb-rNO",
|
||||
),
|
||||
)
|
||||
buildConfigField("String", "RAW_VERSION_NAME", "\"$versionName${versionNameSuffix.orEmpty()}\"")
|
||||
buildConfigField("String", "COMMIT_SHA", "\"$commitSha\"")
|
||||
buildConfigField("String", "REPO_NAME", "\"$repoName\"")
|
||||
ndk {
|
||||
debugSymbolLevel = "FULL"
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions += "api"
|
||||
|
||||
productFlavors {
|
||||
create("default")
|
||||
create("marshmallow") {
|
||||
minSdk = 23
|
||||
applicationIdSuffix = ".m"
|
||||
versionNameSuffix = "-M"
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path = File("src/main/cpp/CMakeLists.txt")
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = listOf(
|
||||
// https://kotlinlang.org/docs/compiler-reference.html#progressive
|
||||
"-progressive",
|
||||
"-Xjvm-default=all",
|
||||
"-Xlambdas=indy",
|
||||
"-Xcontext-receivers",
|
||||
|
||||
"-opt-in=coil3.annotation.ExperimentalCoilApi",
|
||||
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
|
||||
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
|
||||
"-opt-in=androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi",
|
||||
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
|
||||
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
|
||||
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
|
||||
"-opt-in=androidx.paging.ExperimentalPagingApi",
|
||||
"-opt-in=kotlin.contracts.ExperimentalContracts",
|
||||
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||
"-opt-in=kotlinx.coroutines.FlowPreview",
|
||||
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
|
||||
"-opt-in=splitties.experimental.ExperimentalSplittiesApi",
|
||||
"-opt-in=splitties.preferences.DataStorePreferencesPreview",
|
||||
)
|
||||
}
|
||||
|
||||
lint {
|
||||
disable += setOf("MissingTranslation", "MissingQuantity")
|
||||
fatal += setOf("NewApi", "InlinedApi")
|
||||
}
|
||||
|
||||
packaging {
|
||||
dex {
|
||||
useLegacyPackaging = false
|
||||
}
|
||||
}
|
||||
|
||||
dependenciesInfo.includeInApk = false
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
proguardFiles("proguard-rules.pro")
|
||||
signingConfig = signConfig
|
||||
buildConfigField("String", "BUILD_TIME", "\"$buildTime\"")
|
||||
}
|
||||
debug {
|
||||
applicationIdSuffix = ".debug"
|
||||
buildConfigField("String", "BUILD_TIME", "\"\"")
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
compose = true
|
||||
viewBinding = true
|
||||
}
|
||||
|
||||
namespace = "com.hippo.ehviewer"
|
||||
}
|
||||
|
||||
composeCompiler {
|
||||
// https://youtrack.jetbrains.com/issue/KT-67216
|
||||
suppressKotlinVersionCompatibilityCheck = libs.versions.kotlin.get()
|
||||
enableIntrinsicRemember = true
|
||||
enableNonSkippingGroupOptimization = true
|
||||
enableExperimentalStrongSkippingMode = true
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
onVariants(selector().withBuildType("release")) {
|
||||
it.packaging.resources.excludes.addAll(
|
||||
"/META-INF/**",
|
||||
"/kotlin/**",
|
||||
"**.txt",
|
||||
"**.bin",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://developer.android.com/jetpack/androidx/releases/activity
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.biometric)
|
||||
implementation(libs.androidx.browser)
|
||||
|
||||
// https://developer.android.com/jetpack/androidx/releases/compose-material3
|
||||
api(platform(libs.compose.bom))
|
||||
implementation(libs.bundles.compose)
|
||||
|
||||
implementation(libs.compose.destinations.core)
|
||||
ksp(libs.compose.destinations.compiler)
|
||||
|
||||
implementation(libs.androidx.core)
|
||||
implementation(libs.androidx.core.splashscreen)
|
||||
|
||||
implementation(libs.androidx.constraintlayout.compose)
|
||||
// https://developer.android.com/jetpack/androidx/releases/lifecycle
|
||||
implementation(libs.androidx.lifecycle.process)
|
||||
implementation(libs.androidx.lifecycle.compose)
|
||||
|
||||
// https://developer.android.com/jetpack/androidx/releases/navigation
|
||||
implementation(libs.androidx.navigation.compose)
|
||||
|
||||
// https://developer.android.com/jetpack/androidx/releases/paging
|
||||
implementation(libs.androidx.paging.compose)
|
||||
|
||||
implementation(libs.androidx.recyclerview)
|
||||
|
||||
// https://developer.android.com/jetpack/androidx/releases/room
|
||||
ksp(libs.androidx.room.compiler)
|
||||
implementation(libs.androidx.room.paging)
|
||||
|
||||
implementation(libs.androidx.work.runtime)
|
||||
implementation(libs.photoview) // Dead Dependency
|
||||
implementation(libs.directionalviewpager) // Dead Dependency
|
||||
implementation(libs.material.motion.core)
|
||||
|
||||
implementation(libs.bundles.splitties)
|
||||
|
||||
implementation(libs.okio.jvm)
|
||||
|
||||
implementation(libs.logcat)
|
||||
|
||||
implementation(libs.diff)
|
||||
|
||||
implementation(libs.aboutlibraries.core)
|
||||
implementation(libs.aboutlibraries.compose.m3)
|
||||
implementation(libs.accompanist.drawable.painter)
|
||||
|
||||
implementation(libs.insetter) // Dead Dependency
|
||||
|
||||
implementation(libs.reorderable)
|
||||
|
||||
implementation(platform(libs.arrow.stack))
|
||||
implementation(libs.arrow.fx.coroutines)
|
||||
|
||||
// https://coil-kt.github.io/coil/changelog/
|
||||
implementation(platform(libs.coil.bom))
|
||||
implementation(libs.bundles.coil)
|
||||
|
||||
implementation(libs.telephoto.zoomable)
|
||||
|
||||
implementation(libs.ktor.client.core)
|
||||
|
||||
implementation(libs.bundles.kotlinx.serialization)
|
||||
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
implementation(libs.kotlinx.datetime)
|
||||
implementation(libs.jsoup)
|
||||
|
||||
coreLibraryDesugaring(libs.desugar)
|
||||
|
||||
implementation(libs.cronet.embedded)
|
||||
|
||||
debugImplementation(libs.compose.ui.tooling)
|
||||
implementation(libs.compose.ui.tooling.preview)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(21)
|
||||
}
|
||||
|
||||
ksp {
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
arg("room.generateKotlin", "true")
|
||||
arg("compose-destinations.codeGenPackageName", "com.hippo.ehviewer.ui")
|
||||
}
|
||||
|
||||
aboutLibraries {
|
||||
duplicationMode = MERGE
|
||||
duplicationRule = GROUP
|
||||
}
|
||||
|
||||
spotless {
|
||||
kotlin {
|
||||
// https://github.com/diffplug/spotless/issues/111
|
||||
target("src/**/*.kt")
|
||||
ktlint()
|
||||
}
|
||||
kotlinGradle {
|
||||
ktlint()
|
||||
}
|
||||
}
|
||||
Vendored
+15
-16
@@ -1,23 +1,22 @@
|
||||
-keepclassmembers class * implements android.os.Parcelable {
|
||||
public static final ** CREATOR;
|
||||
}
|
||||
|
||||
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
|
||||
public static void check*(...);
|
||||
public static void throw*(...);
|
||||
}
|
||||
|
||||
-keepclasseswithmembernames,includedescriptorclasses class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
-keep,allowoptimization class com.hippo.ehviewer.ui.fragment.* extends com.hippo.ehviewer.ui.fragment.BaseFragment { }
|
||||
-keep,allowoptimization class com.hippo.ehviewer.ui.fragment.* extends com.hippo.ehviewer.ui.fragment.BasePreferenceFragment { }
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keep class androidx.viewpager.widget.ViewPager$LayoutParams { int position; }
|
||||
-keepclassmembers class * implements android.os.Parcelable {
|
||||
public static final ** CREATOR;
|
||||
}
|
||||
|
||||
# Ktor logger
|
||||
-dontwarn org.slf4j.impl.StaticLoggerBinder
|
||||
|
||||
-dontwarn org.conscrypt.Conscrypt
|
||||
|
||||
-keepattributes LineNumberTable
|
||||
|
||||
-renamesourcefileattribute
|
||||
-repackageclasses
|
||||
-allowaccessmodification
|
||||
-mergeinterfacesaggressively
|
||||
-overloadaggressively
|
||||
-repackageclasses
|
||||
@@ -0,0 +1,448 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 10,
|
||||
"identityHash": "613604f93bf815adeb87f03e2166e983",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `TIME` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `FAVORITE_SLOT` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '613604f93bf815adeb87f03e2166e983')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 11,
|
||||
"identityHash": "92915e937cb7ccc536d352fda5cf287f",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL DEFAULT 0, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `TIME` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL DEFAULT 0, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `FAVORITE_SLOT` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '92915e937cb7ccc536d352fda5cf287f')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 12,
|
||||
"identityHash": "d40b38b0ba3b1c53b773728cdee328c8",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `FAVORITE_SLOT` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd40b38b0ba3b1c53b773728cdee328c8')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 13,
|
||||
"identityHash": "df15d8f70f45047a738c8911212ea73c",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `FAVORITE_SLOT` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'df15d8f70f45047a738c8911212ea73c')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 14,
|
||||
"identityHash": "54e4f2704cc47c5a6a2f4b96de978cce",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '54e4f2704cc47c5a6a2f4b96de978cce')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 15,
|
||||
"identityHash": "991a3a3ddc4fe8d4dbcb39b975ab73b8",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOAD_LABELS_LABEL",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_DOWNLOAD_LABELS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '991a3a3ddc4fe8d4dbcb39b975ab73b8')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,433 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 16,
|
||||
"identityHash": "06e5ff8fd6797d5801e86753fa5831b2",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOAD_LABELS_LABEL",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_DOWNLOAD_LABELS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`LABEL`) REFERENCES `DOWNLOAD_LABELS`(`LABEL`) ON UPDATE CASCADE ON DELETE SET NULL )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOADS_LABEL",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_DOWNLOADS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "DOWNLOAD_LABELS",
|
||||
"onDelete": "SET NULL",
|
||||
"onUpdate": "CASCADE",
|
||||
"columns": [
|
||||
"LABEL"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"LABEL"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '06e5ff8fd6797d5801e86753fa5831b2')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 17,
|
||||
"identityHash": "d6375317a9298b7feae5925a23272bb9",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOAD_LABELS_LABEL",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_DOWNLOAD_LABELS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`LABEL`) REFERENCES `DOWNLOAD_LABELS`(`LABEL`) ON UPDATE CASCADE ON DELETE SET NULL )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOADS_LABEL",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_DOWNLOADS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "DOWNLOAD_LABELS",
|
||||
"onDelete": "SET NULL",
|
||||
"onUpdate": "CASCADE",
|
||||
"columns": [
|
||||
"LABEL"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"LABEL"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "PROGRESS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `PAGE` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd6375317a9298b7feae5925a23272bb9')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 18,
|
||||
"identityHash": "bc90acf4ffb4e7cce9a16cd5a0f662f3",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT NOT NULL, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOAD_LABELS_LABEL",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_DOWNLOAD_LABELS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`LABEL`) REFERENCES `DOWNLOAD_LABELS`(`LABEL`) ON UPDATE CASCADE ON DELETE SET NULL )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOADS_LABEL",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_DOWNLOADS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "DOWNLOAD_LABELS",
|
||||
"onDelete": "SET NULL",
|
||||
"onUpdate": "CASCADE",
|
||||
"columns": [
|
||||
"LABEL"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"LABEL"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "PROGRESS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `PAGE` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'bc90acf4ffb4e7cce9a16cd5a0f662f3')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 19,
|
||||
"identityHash": "edd2f8e628072889f7702b50eb2c44a1",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT NOT NULL, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOAD_LABELS_LABEL",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_DOWNLOAD_LABELS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`LABEL`) REFERENCES `DOWNLOAD_LABELS`(`LABEL`) ON UPDATE CASCADE ON DELETE SET NULL )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOADS_LABEL",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_DOWNLOADS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "DOWNLOAD_LABELS",
|
||||
"onDelete": "SET NULL",
|
||||
"onUpdate": "CASCADE",
|
||||
"columns": [
|
||||
"LABEL"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"LABEL"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "PROGRESS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `PAGE` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'edd2f8e628072889f7702b50eb2c44a1')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 20,
|
||||
"identityHash": "a8dd0226b286cc57a8c99ba7ad416730",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT NOT NULL, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `PAGES` INTEGER NOT NULL DEFAULT 0, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pages",
|
||||
"columnName": "PAGES",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOAD_LABELS_LABEL",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_DOWNLOAD_LABELS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`LABEL`) REFERENCES `DOWNLOAD_LABELS`(`LABEL`) ON UPDATE CASCADE ON DELETE SET NULL )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOADS_LABEL",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_DOWNLOADS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "DOWNLOAD_LABELS",
|
||||
"onDelete": "SET NULL",
|
||||
"onUpdate": "CASCADE",
|
||||
"columns": [
|
||||
"LABEL"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"LABEL"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "PROGRESS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `PAGE` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a8dd0226b286cc57a8c99ba7ad416730')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,513 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 21,
|
||||
"identityHash": "6a9926f6722f8fc6f9c4426b31260e33",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT NOT NULL, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `PAGES` INTEGER NOT NULL DEFAULT 0, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pages",
|
||||
"columnName": "PAGES",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOAD_LABELS_LABEL",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_DOWNLOAD_LABELS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`LABEL`) REFERENCES `DOWNLOAD_LABELS`(`LABEL`) ON UPDATE CASCADE ON DELETE SET NULL )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOADS_LABEL",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_DOWNLOADS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "DOWNLOAD_LABELS",
|
||||
"onDelete": "SET NULL",
|
||||
"onUpdate": "CASCADE",
|
||||
"columns": [
|
||||
"LABEL"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"LABEL"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "PROGRESS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `PAGE` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"ftsVersion": "FTS4",
|
||||
"ftsOptions": {
|
||||
"tokenizer": "simple",
|
||||
"tokenizerArgs": [],
|
||||
"contentTable": "GALLERIES",
|
||||
"languageIdColumnName": "",
|
||||
"matchInfo": "FTS4",
|
||||
"notIndexedColumns": [],
|
||||
"prefixSizes": [],
|
||||
"preferredOrder": "ASC"
|
||||
},
|
||||
"contentSyncTriggers": [
|
||||
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_GalleryFts_BEFORE_UPDATE BEFORE UPDATE ON `GALLERIES` BEGIN DELETE FROM `GalleryFts` WHERE `docid`=OLD.`rowid`; END",
|
||||
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_GalleryFts_BEFORE_DELETE BEFORE DELETE ON `GALLERIES` BEGIN DELETE FROM `GalleryFts` WHERE `docid`=OLD.`rowid`; END",
|
||||
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_GalleryFts_AFTER_UPDATE AFTER UPDATE ON `GALLERIES` BEGIN INSERT INTO `GalleryFts`(`docid`, `TITLE`, `TITLE_JPN`) VALUES (NEW.`rowid`, NEW.`TITLE`, NEW.`TITLE_JPN`); END",
|
||||
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_GalleryFts_AFTER_INSERT AFTER INSERT ON `GALLERIES` BEGIN INSERT INTO `GalleryFts`(`docid`, `TITLE`, `TITLE_JPN`) VALUES (NEW.`rowid`, NEW.`TITLE`, NEW.`TITLE_JPN`); END"
|
||||
],
|
||||
"tableName": "GalleryFts",
|
||||
"createSql": "CREATE VIRTUAL TABLE IF NOT EXISTS `${TABLE_NAME}` USING FTS4(`TITLE` TEXT NOT NULL, `TITLE_JPN` TEXT NOT NULL, content=`GALLERIES`)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": []
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6a9926f6722f8fc6f9c4426b31260e33')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,525 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 22,
|
||||
"identityHash": "f61ae3beef3739c0de7db945d2c9a4a4",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "GALLERIES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TOKEN` TEXT NOT NULL, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_TAGS` TEXT, `PAGES` INTEGER NOT NULL DEFAULT 0, `SIMPLE_LANGUAGE` TEXT, `FAVORITE_SLOT` INTEGER NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleTags",
|
||||
"columnName": "SIMPLE_TAGS",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "pages",
|
||||
"columnName": "PAGES",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlot",
|
||||
"columnName": "FAVORITE_SLOT",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `POSITION` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOAD_LABELS_LABEL",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_DOWNLOAD_LABELS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`LABEL`) REFERENCES `DOWNLOAD_LABELS`(`LABEL`) ON UPDATE CASCADE ON DELETE SET NULL )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_DOWNLOADS_LABEL",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"LABEL"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_DOWNLOADS_LABEL` ON `${TABLE_NAME}` (`LABEL`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "DOWNLOAD_LABELS",
|
||||
"onDelete": "SET NULL",
|
||||
"onUpdate": "CASCADE",
|
||||
"columns": [
|
||||
"LABEL"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"LABEL"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "PROGRESS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `PAGE` INTEGER NOT NULL, PRIMARY KEY(`GID`), FOREIGN KEY(`GID`) REFERENCES `GALLERIES`(`GID`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "GALLERIES",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"GID"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"GID"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT NOT NULL, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `POSITION` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "POSITION",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"ftsVersion": "FTS4",
|
||||
"ftsOptions": {
|
||||
"tokenizer": "simple",
|
||||
"tokenizerArgs": [],
|
||||
"contentTable": "GALLERIES",
|
||||
"languageIdColumnName": "",
|
||||
"matchInfo": "FTS4",
|
||||
"notIndexedColumns": [],
|
||||
"prefixSizes": [],
|
||||
"preferredOrder": "ASC"
|
||||
},
|
||||
"contentSyncTriggers": [
|
||||
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_GALLERIES_FTS_BEFORE_UPDATE BEFORE UPDATE ON `GALLERIES` BEGIN DELETE FROM `GALLERIES_FTS` WHERE `docid`=OLD.`rowid`; END",
|
||||
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_GALLERIES_FTS_BEFORE_DELETE BEFORE DELETE ON `GALLERIES` BEGIN DELETE FROM `GALLERIES_FTS` WHERE `docid`=OLD.`rowid`; END",
|
||||
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_GALLERIES_FTS_AFTER_UPDATE AFTER UPDATE ON `GALLERIES` BEGIN INSERT INTO `GALLERIES_FTS`(`docid`, `TITLE`, `TITLE_JPN`, `SIMPLE_TAGS`) VALUES (NEW.`rowid`, NEW.`TITLE`, NEW.`TITLE_JPN`, NEW.`SIMPLE_TAGS`); END",
|
||||
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_GALLERIES_FTS_AFTER_INSERT AFTER INSERT ON `GALLERIES` BEGIN INSERT INTO `GALLERIES_FTS`(`docid`, `TITLE`, `TITLE_JPN`, `SIMPLE_TAGS`) VALUES (NEW.`rowid`, NEW.`TITLE`, NEW.`TITLE_JPN`, NEW.`SIMPLE_TAGS`); END"
|
||||
],
|
||||
"tableName": "GALLERIES_FTS",
|
||||
"createSql": "CREATE VIRTUAL TABLE IF NOT EXISTS `${TABLE_NAME}` USING FTS4(`TITLE` TEXT NOT NULL, `TITLE_JPN` TEXT NOT NULL, `SIMPLE_TAGS` TEXT, content=`GALLERIES`)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleTags",
|
||||
"columnName": "SIMPLE_TAGS",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": []
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f61ae3beef3739c0de7db945d2c9a4a4')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 4,
|
||||
"identityHash": "f5752deda842dccabded1cdbf1c78384",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "BOOKMARKS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`PAGE` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumb",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumb",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `LABEL` TEXT, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT, `ENABLE` INTEGER, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `MODE` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlotBackingField",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumb",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumb",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f5752deda842dccabded1cdbf1c78384')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 5,
|
||||
"identityHash": "f5752deda842dccabded1cdbf1c78384",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "BOOKMARKS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`PAGE` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `LABEL` TEXT, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT, `ENABLE` INTEGER, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `MODE` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlotBackingField",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f5752deda842dccabded1cdbf1c78384')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 6,
|
||||
"identityHash": "e45f4380ef769c127604cb2a502a942b",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "BOOKMARKS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`PAGE` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "page",
|
||||
"columnName": "PAGE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `LABEL` TEXT, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT, `ENABLE` INTEGER, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `MODE` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlotBackingField",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e45f4380ef769c127604cb2a502a942b')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,448 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 7,
|
||||
"identityHash": "9563c2017be4341dc1bada115426df77",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `LABEL` TEXT, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT, `ENABLE` INTEGER, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `MODE` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlotBackingField",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9563c2017be4341dc1bada115426df77')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,448 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 8,
|
||||
"identityHash": "f09bae277bbdab54ecbb0d698c83e734",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `LABEL` TEXT, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `MODE` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlotBackingField",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f09bae277bbdab54ecbb0d698c83e734')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,448 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 9,
|
||||
"identityHash": "64f51a531e13d2b0b971f3d8da0876b0",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "DOWNLOADS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`STATE` INTEGER NOT NULL, `LEGACY` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, `LABEL` TEXT, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "STATE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "legacy",
|
||||
"columnName": "LEGACY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_LABELS",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`LABEL` TEXT NOT NULL, `TIME` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "label",
|
||||
"columnName": "LABEL",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "DOWNLOAD_DIRNAME",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`GID` INTEGER NOT NULL, `DIRNAME` TEXT NOT NULL, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dirname",
|
||||
"columnName": "DIRNAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "FILTER",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`MODE` INTEGER NOT NULL, `TEXT` TEXT NOT NULL, `ENABLE` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "TEXT",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "enable",
|
||||
"columnName": "ENABLE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "HISTORY",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `MODE` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "favoriteSlotBackingField",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "LOCAL_FAVORITES",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`TIME` INTEGER NOT NULL, `GID` INTEGER NOT NULL, `TOKEN` TEXT, `TITLE` TEXT, `TITLE_JPN` TEXT, `THUMB` TEXT, `CATEGORY` INTEGER NOT NULL, `POSTED` TEXT, `UPLOADER` TEXT, `RATING` REAL NOT NULL, `SIMPLE_LANGUAGE` TEXT, PRIMARY KEY(`GID`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gid",
|
||||
"columnName": "GID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "token",
|
||||
"columnName": "TOKEN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "TITLE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "titleJpn",
|
||||
"columnName": "TITLE_JPN",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "thumbKey",
|
||||
"columnName": "THUMB",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "posted",
|
||||
"columnName": "POSTED",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uploader",
|
||||
"columnName": "UPLOADER",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "rating",
|
||||
"columnName": "RATING",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "simpleLanguage",
|
||||
"columnName": "SIMPLE_LANGUAGE",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"GID"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "QUICK_SEARCH",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `NAME` TEXT, `MODE` INTEGER NOT NULL, `CATEGORY` INTEGER NOT NULL, `KEYWORD` TEXT, `ADVANCE_SEARCH` INTEGER NOT NULL, `MIN_RATING` INTEGER NOT NULL, `PAGE_FROM` INTEGER NOT NULL, `PAGE_TO` INTEGER NOT NULL, `TIME` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "NAME",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "mode",
|
||||
"columnName": "MODE",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "category",
|
||||
"columnName": "CATEGORY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "keyword",
|
||||
"columnName": "KEYWORD",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "advanceSearch",
|
||||
"columnName": "ADVANCE_SEARCH",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "minRating",
|
||||
"columnName": "MIN_RATING",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageFrom",
|
||||
"columnName": "PAGE_FROM",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pageTo",
|
||||
"columnName": "PAGE_TO",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "TIME",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '64f51a531e13d2b0b971f3d8da0876b0')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "69230710633494b4b331e10dae436fb7",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "suggestions",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `date` LONG, `query` TEXT, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "date",
|
||||
"columnName": "date",
|
||||
"affinity": "LONG",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "query",
|
||||
"columnName": "query",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '69230710633494b4b331e10dae436fb7')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 2,
|
||||
"identityHash": "bf4a5b5f3cb9bc7383488bae14f5d4bd",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "suggestions",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`date` INTEGER NOT NULL, `query` TEXT NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "date",
|
||||
"columnName": "date",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "query",
|
||||
"columnName": "query",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'bf4a5b5f3cb9bc7383488bae14f5d4bd')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Hippo Seven
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -15,6 +16,7 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<color name="divider">#20ffffff</color>
|
||||
<color name="navigation_bar_divider">#1fffffff</color>
|
||||
|
||||
<string name="app_name" translatable="false">EhViewer Debug</string>
|
||||
|
||||
</resources>
|
||||
@@ -1,20 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright 2016 Hippo Seven
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-feature
|
||||
android:name="android.software.leanback"
|
||||
@@ -26,18 +12,14 @@
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28" />
|
||||
|
||||
<uses-feature
|
||||
android:glEsVersion="0x00020000"
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:name="com.hippo.ehviewer.EhApplication"
|
||||
android:name=".EhApplication"
|
||||
android:allowBackup="true"
|
||||
android:appCategory="image"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
@@ -46,27 +28,31 @@
|
||||
android:hasFragileUserData="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:localeConfig="@xml/locales_config"
|
||||
android:largeHeap="@bool/large_heap"
|
||||
android:localeConfig="@xml/locale_config"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:theme="@style/AppTheme">
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
tools:targetApi="tiramisu">
|
||||
<profileable android:shell="true" />
|
||||
|
||||
<activity
|
||||
android:name="com.hippo.ehviewer.ui.MainActivity"
|
||||
android:name=".ui.MainActivity"
|
||||
android:banner="@mipmap/ic_leanback_banner"
|
||||
android:configChanges="screenSize"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme.Splash"
|
||||
android:windowSoftInputMode="adjustResize|stateAlwaysHidden">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
@@ -84,30 +70,27 @@
|
||||
<data android:scheme="https" />
|
||||
<data android:host="exhentai.org" />
|
||||
<data android:host="e-hentai.org" />
|
||||
<data android:host="g.e-hentai.org" />
|
||||
<data android:host="lofi.e-hentai.org" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="@string/keyword_search">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="@string/image_search">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="eu.kanade.tachiyomi.ui.reader.ReaderActivity"
|
||||
android:configChanges="screenSize"
|
||||
android:exported="true"
|
||||
android:colorMode="wideColorGamut"
|
||||
android:launchMode="singleTask">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
@@ -141,28 +124,27 @@
|
||||
<data android:mimeType="application/x-xz-compressed-tar" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.hippo.ehviewer.ui.SettingsActivity"
|
||||
android:name=".ui.SecurityActivity"
|
||||
android:configChanges="screenSize"
|
||||
android:label="@string/settings"
|
||||
android:theme="@style/AppTheme" />
|
||||
|
||||
android:label="@string/settings" />
|
||||
<activity
|
||||
android:name="com.hippo.ehviewer.ui.SecurityActivity"
|
||||
android:configChanges="screenSize"
|
||||
android:label="@string/settings"
|
||||
android:theme="@style/AppTheme" />
|
||||
|
||||
<activity
|
||||
android:name="com.hippo.ehviewer.shortcuts.ShortcutsActivity"
|
||||
android:name=".shortcuts.ShortcutsActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity=""
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||
|
||||
<service
|
||||
android:name="com.hippo.ehviewer.download.DownloadService"
|
||||
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
|
||||
android:enabled="false"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="autoStoreLocales"
|
||||
android:value="true" />
|
||||
</service>
|
||||
<service
|
||||
android:name=".download.DownloadService"
|
||||
android:foregroundServiceType="dataSync"
|
||||
android:label="@string/download_service_label" />
|
||||
|
||||
@@ -171,11 +153,10 @@
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/filepaths" />
|
||||
|
||||
</provider>
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,52 @@
|
||||
From d1db03ebd9989d10a5a905b792b712c6487a0057 Mon Sep 17 00:00:00 2001
|
||||
From: FooIbar <118464521+FooIbar@users.noreply.github.com>
|
||||
Date: Sat, 24 Feb 2024 12:03:15 +0000
|
||||
Subject: [PATCH] Don't build other binaries
|
||||
|
||||
---
|
||||
CMakeLists.txt | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index a346dd02..52b5d0d8 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -1567,7 +1567,7 @@ endif()
|
||||
# xzdec and lzmadec
|
||||
#############################################################################
|
||||
|
||||
-if(HAVE_DECODERS AND (NOT MSVC OR MSVC_VERSION GREATER_EQUAL 1900))
|
||||
+if(0)
|
||||
foreach(XZDEC xzdec lzmadec)
|
||||
add_executable("${XZDEC}"
|
||||
src/common/sysdefs.h
|
||||
@@ -1624,7 +1624,7 @@ endif()
|
||||
# lzmainfo
|
||||
#############################################################################
|
||||
|
||||
-if(HAVE_DECODERS AND (NOT MSVC OR MSVC_VERSION GREATER_EQUAL 1900))
|
||||
+if(0)
|
||||
add_executable(lzmainfo
|
||||
src/common/sysdefs.h
|
||||
src/common/tuklib_common.h
|
||||
@@ -1680,7 +1680,7 @@ endif()
|
||||
# xz
|
||||
#############################################################################
|
||||
|
||||
-if(NOT MSVC OR MSVC_VERSION GREATER_EQUAL 1900)
|
||||
+if(0)
|
||||
add_executable(xz
|
||||
src/common/mythread.h
|
||||
src/common/sysdefs.h
|
||||
@@ -1914,7 +1914,7 @@ endif()
|
||||
# Scripts
|
||||
#############################################################################
|
||||
|
||||
-if(UNIX)
|
||||
+if(0)
|
||||
# NOTE: This isn't as sophisticated as in the Autotools build which
|
||||
# uses posix-shell.m4 but hopefully this doesn't need to be either.
|
||||
# CMake likely won't be used on as many (old) obscure systems as the
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
project(ehviewer)
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(ehviewer C)
|
||||
include(FetchContent)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Ofast -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -funroll-loops -flto=thin \
|
||||
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Ofast -fvisibility=hidden -fvisibility-inlines-hidden -funroll-loops -flto \
|
||||
-mllvm -polly \
|
||||
-mllvm -polly-run-dce \
|
||||
-mllvm -polly-run-inliner \
|
||||
@@ -12,12 +14,34 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Ofast -fvisibility=hidden -fvisibility-inli
|
||||
-mllvm -polly-vectorizer=stripmine \
|
||||
-mllvm -polly-detect-profitability-min-per-loop-insts=40 \
|
||||
-mllvm -polly-invariant-load-hoisting")
|
||||
endif (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
||||
option(BUILD_TESTING OFF)
|
||||
|
||||
FetchContent_Declare(
|
||||
liblzma
|
||||
GIT_REPOSITORY https://git.tukaani.org/xz.git
|
||||
GIT_TAG v5.6.1
|
||||
PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/0001-Don-t-build-other-binaries.patch || cd .
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(liblzma)
|
||||
include_directories(${liblzma_SOURCE_DIR}/src/liblzma/api)
|
||||
|
||||
# Build GNUTLS libnettle
|
||||
FetchContent_Declare(
|
||||
nettle
|
||||
URL https://ftp.gnu.org/gnu/nettle/nettle-3.9.1.tar.gz
|
||||
URL_MD5 29fcd2dec6bf5b48e5e3ffb3cbc4779e
|
||||
SOURCE_DIR nettle-src/nettle
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(nettle)
|
||||
set(NETTLE_DIR ${nettle_SOURCE_DIR})
|
||||
add_subdirectory(nettle)
|
||||
|
||||
# Configure libnettle support for libarchive
|
||||
include_directories(nettle)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/nettle-src)
|
||||
include_directories(.)
|
||||
set(HAVE_LIBNETTLE 1)
|
||||
set(HAVE_NETTLE_AES_H 1)
|
||||
@@ -27,24 +51,41 @@ set(HAVE_NETTLE_PBKDF2_H 1)
|
||||
set(HAVE_NETTLE_RIPEMD160_H 1)
|
||||
set(HAVE_NETTLE_SHA_H 1)
|
||||
|
||||
# Build liblzma
|
||||
add_subdirectory(liblzma)
|
||||
|
||||
# Configure lzma support for libarchive
|
||||
include_directories(liblzma/src/liblzma/api)
|
||||
SET(HAVE_LIBLZMA 1)
|
||||
SET(HAVE_LZMA_H 1)
|
||||
SET(HAVE_LZMA_STREAM_ENCODER_MT 1)
|
||||
SET(HAVE_LZMADEC_H 1)
|
||||
SET(HAVE_LIBLZMADEC 1)
|
||||
|
||||
# Configure libarchive link's static lib
|
||||
SET(LIBARCHIVE_CUSTOM_LIBS "liblzma" "nettle")
|
||||
option(ENABLE_TAR OFF)
|
||||
option(ENABLE_CPIO OFF)
|
||||
option(ENABLE_CAT OFF)
|
||||
option(ENABLE_UNZIP OFF)
|
||||
option(ENABLE_TEST OFF)
|
||||
option(ENABLE_WERROR OFF)
|
||||
|
||||
# Build libarchive
|
||||
add_subdirectory(libarchive)
|
||||
# Configure libarchive link's static lib
|
||||
SET(LIBARCHIVE_CUSTOM_LIBS "nettle" "liblzma")
|
||||
|
||||
FetchContent_Declare(
|
||||
libarchive
|
||||
GIT_REPOSITORY https://github.com/FooIbar/libarchive.git
|
||||
GIT_TAG v3.7.3
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(libarchive)
|
||||
include_directories(${libarchive_SOURCE_DIR}/libarchive)
|
||||
|
||||
FetchContent_Declare(
|
||||
Corrosion
|
||||
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
|
||||
GIT_TAG 0a3bdf452995803c334d79dc9a2affbfad51b720
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(Corrosion)
|
||||
corrosion_import_crate(MANIFEST_PATH ../rust/Cargo.toml)
|
||||
|
||||
# Build and link our app's native lib
|
||||
add_library(${PROJECT_NAME} SHARED archive.c fdutils.c)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC libarchive/libarchive)
|
||||
target_link_libraries(${PROJECT_NAME} archive_static log jnigraphics GLESv2 -Wl,--gc-sections)
|
||||
add_library(${PROJECT_NAME} SHARED archive.c border.c gifutils.c natsort/strnatcmp.c)
|
||||
target_link_libraries(${PROJECT_NAME} ehviewer_rust archive_static log jnigraphics)
|
||||
+224
-72
@@ -17,14 +17,12 @@
|
||||
* EhViewer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/mman.h>
|
||||
#include <syscall.h>
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
@@ -34,6 +32,7 @@
|
||||
|
||||
#define LOG_TAG "libarchive_wrapper"
|
||||
|
||||
#include "natsort/strnatcmp.h"
|
||||
#include "ehviewer.h"
|
||||
|
||||
typedef struct {
|
||||
@@ -43,18 +42,35 @@ typedef struct {
|
||||
struct archive_entry *entry;
|
||||
} archive_ctx;
|
||||
|
||||
pthread_mutex_t ctx_lock;
|
||||
typedef struct {
|
||||
const char *filename;
|
||||
int index;
|
||||
size_t size;
|
||||
} entry;
|
||||
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static archive_ctx **ctx_pool;
|
||||
#define CTX_POOL_SIZE 20
|
||||
|
||||
static void *mempool = NULL;
|
||||
static size_t *mempoolofs = NULL;
|
||||
|
||||
#define PAGE_ALIGN(x) ((x + ~PAGE_MASK) & PAGE_MASK)
|
||||
|
||||
#define MEMPOOL_ADDR_BY_SORTED_IDX(x) (mempool + (index ? mempoolofs[index - 1] : 0))
|
||||
#define MEMPOOL_SIZE (mempoolofs[entryCount - 1])
|
||||
|
||||
#define PROT_RW (PROT_WRITE | PROT_READ)
|
||||
#define MAP_ANON_POOL (MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE | MAP_UNINITIALIZED)
|
||||
|
||||
static bool need_encrypt = false;
|
||||
static char *passwd = NULL;
|
||||
static void *archiveAddr = NULL;
|
||||
static size_t archiveSize = 0;
|
||||
static entry *entries = NULL;
|
||||
static size_t entryCount = 0;
|
||||
|
||||
#define POPULATE_THRESHOLD (512 * 1024 * 1024) // 512 MiB
|
||||
|
||||
const char supportExt[9][6] = {
|
||||
const char supportExt[10][6] = {
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"png",
|
||||
@@ -63,27 +79,96 @@ const char supportExt[9][6] = {
|
||||
"bmp",
|
||||
"ico",
|
||||
"wbmp",
|
||||
"heif"
|
||||
"heif",
|
||||
"avif"
|
||||
};
|
||||
|
||||
static inline int filename_is_playable_file(const char *name) {
|
||||
if (!name)
|
||||
return false;
|
||||
const char *dotptr = strrchr(name, '.');
|
||||
if (!dotptr++)
|
||||
return false;
|
||||
int i;
|
||||
for (i = 0; i < 9; i++)
|
||||
for (i = 0; i < 10; i++)
|
||||
if (strcmp(dotptr, supportExt[i]) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline const char *archive_entry_pathname2(struct archive_entry *entry) {
|
||||
const char *name = archive_entry_pathname_utf8(entry);
|
||||
return name ? name : archive_entry_pathname(entry);
|
||||
}
|
||||
|
||||
static inline bool archive_entry_is_file(struct archive_entry *entry) {
|
||||
return archive_entry_filetype(entry) == AE_IFREG;
|
||||
}
|
||||
|
||||
static inline bool archive_entry_is_playable(struct archive_entry *entry) {
|
||||
return archive_entry_is_file(entry) &&
|
||||
filename_is_playable_file(archive_entry_pathname2(entry));
|
||||
}
|
||||
|
||||
static inline int compare_entries(const void *a, const void *b) {
|
||||
const char *fa = ((entry *) a)->filename;
|
||||
const char *fb = ((entry *) b)->filename;
|
||||
return strnatcmp(fa, fb);
|
||||
}
|
||||
|
||||
static long archive_map_entries_index(archive_ctx *ctx, bool sort) {
|
||||
long count = 0;
|
||||
while (archive_read_next_header(ctx->arc, &ctx->entry) == ARCHIVE_OK) {
|
||||
const char *name = archive_entry_pathname2(ctx->entry);
|
||||
if (archive_entry_is_file(ctx->entry) && filename_is_playable_file(name)) {
|
||||
entries[count].filename = strdup(name);
|
||||
entries[count].index = count;
|
||||
entries[count].size = archive_entry_size(ctx->entry);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (sort)
|
||||
qsort(entries, entryCount, sizeof(entry), compare_entries);
|
||||
return count;
|
||||
}
|
||||
|
||||
static bool archive_prealloc_mempool() {
|
||||
mempoolofs = calloc(entryCount, sizeof(size_t));
|
||||
for (int i = 0; i < entryCount; ++i) {
|
||||
if (!i)
|
||||
mempoolofs[i] = PAGE_ALIGN(entries[i].size);
|
||||
else
|
||||
mempoolofs[i] = PAGE_ALIGN(entries[i].size) + mempoolofs[i - 1];
|
||||
}
|
||||
mempool = mmap(0, MEMPOOL_SIZE, PROT_RW, MAP_ANON_POOL, -1, 0);
|
||||
if (mempool == MAP_FAILED) {
|
||||
LOGE("%s%s", "mmap failed with error ", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define ADDR_IN_FILE_MAPPING(addr) (addr >= archiveAddr && addr < archiveAddr + archiveSize)
|
||||
|
||||
static void mempool_release_pages(void *addr, size_t size) {
|
||||
size = PAGE_ALIGN(size);
|
||||
madvise_log_if_error(addr, size, MADV_DONTNEED);
|
||||
}
|
||||
|
||||
static bool kernel_can_prefault = true;
|
||||
|
||||
static void mempool_prefault_pages(void *addr, size_t size) {
|
||||
size = PAGE_ALIGN(size);
|
||||
if (kernel_can_prefault) {
|
||||
if (madvise(addr, size, MADV_POPULATE_WRITE)) kernel_can_prefault = false;
|
||||
}
|
||||
}
|
||||
|
||||
static long archive_list_all_entries(archive_ctx *ctx) {
|
||||
long count = 0;
|
||||
while (archive_read_next_header(ctx->arc, &ctx->entry) == ARCHIVE_OK)
|
||||
if (filename_is_playable_file(archive_entry_pathname(ctx->entry)))
|
||||
if (archive_entry_is_playable(ctx->entry))
|
||||
count++;
|
||||
if (!count)
|
||||
LOGE("%s", archive_error_string(ctx->arc));
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -127,9 +212,8 @@ static int archive_alloc_ctx(archive_ctx **ctxptr) {
|
||||
}
|
||||
|
||||
static int archive_skip_to_index(archive_ctx *ctx, int index) {
|
||||
assert(!(ctx->next_index > index));
|
||||
while (archive_read_next_header(ctx->arc, &ctx->entry) == ARCHIVE_OK) {
|
||||
if (!filename_is_playable_file(archive_entry_pathname(ctx->entry)))
|
||||
if (!archive_entry_is_playable(ctx->entry))
|
||||
continue;
|
||||
if (ctx->next_index++ == index) {
|
||||
return ctx->next_index - 1;
|
||||
@@ -141,7 +225,7 @@ static int archive_skip_to_index(archive_ctx *ctx, int index) {
|
||||
static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
|
||||
int ret;
|
||||
archive_ctx *ctx = NULL;
|
||||
pthread_mutex_lock(&ctx_lock);
|
||||
pthread_mutex_lock(&mutex);
|
||||
for (int i = 0; i < CTX_POOL_SIZE; i++) {
|
||||
if (!ctx_pool[i])
|
||||
continue;
|
||||
@@ -156,7 +240,7 @@ static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
|
||||
}
|
||||
if (ctx)
|
||||
ctx->using = 1;
|
||||
pthread_mutex_unlock(&ctx_lock);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
if (!ctx) {
|
||||
archive_ctx *victimCtx = NULL;
|
||||
@@ -165,7 +249,7 @@ static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
|
||||
ret = archive_alloc_ctx(&ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
pthread_mutex_lock(&ctx_lock);
|
||||
pthread_mutex_lock(&mutex);
|
||||
for (int i = 0; i < CTX_POOL_SIZE; i++) {
|
||||
if (!ctx_pool[i]) {
|
||||
ctx_pool[i] = ctx;
|
||||
@@ -179,11 +263,9 @@ static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
|
||||
victimIdx = i;
|
||||
}
|
||||
}
|
||||
if (replace) {
|
||||
archive_release_ctx(victimCtx);
|
||||
ctx_pool[victimIdx] = ctx;
|
||||
}
|
||||
pthread_mutex_unlock(&ctx_lock);
|
||||
if (replace) ctx_pool[victimIdx] = ctx;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
if (replace) archive_release_ctx(victimCtx);
|
||||
}
|
||||
ret = archive_skip_to_index(ctx, idx);
|
||||
if (ret != idx) {
|
||||
@@ -197,21 +279,16 @@ static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd, jlong size) {
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_openArchive(JNIEnv *env, jclass thiz, jint fd, jlong size, jboolean sort_entries) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
archive_ctx *ctx = NULL;
|
||||
int mmap_flags = MAP_PRIVATE;
|
||||
if (size <= POPULATE_THRESHOLD)
|
||||
mmap_flags |= MAP_POPULATE;
|
||||
archiveAddr = mmap64(0, size, PROT_READ, mmap_flags, fd, 0);
|
||||
archiveAddr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (archiveAddr == MAP_FAILED) {
|
||||
LOGE("%s%s", "mmap64 failed with error ", strerror(errno));
|
||||
LOGE("%s%s", "mmap failed with error ", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
archiveSize = size;
|
||||
madvise_log_if_error(archiveAddr, archiveSize, MADV_WILLNEED);
|
||||
pthread_mutex_init(&ctx_lock, 0);
|
||||
ctx_pool = calloc(CTX_POOL_SIZE, sizeof(archive_ctx **));
|
||||
if (!ctx_pool) {
|
||||
LOGE("Allocate archive ctx pool failed:ENOMEM");
|
||||
@@ -221,11 +298,15 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd
|
||||
if (r) {
|
||||
if (r == -ENOMEM)
|
||||
LOGE("%s", "Mem alloc failed");
|
||||
r = 0;
|
||||
LOGE("%s%s", "Archive open failed:", archive_error_string(ctx->arc));
|
||||
} else {
|
||||
r = archive_list_all_entries(ctx);
|
||||
LOGI("%s%ld%s", "Found ", r, " image entries in archive");
|
||||
entryCount = archive_list_all_entries(ctx);
|
||||
LOGI("%s%zu%s", "Found ", entryCount, " image entries in archive");
|
||||
if (!entryCount) {
|
||||
LOGE("%s%s", "Archive open failed:", archive_error_string(ctx->arc));
|
||||
archive_release_ctx(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We must read through the file|vm then we can know whether it is encrypted
|
||||
int encryptRet = archive_read_has_encrypted_entries(ctx->arc);
|
||||
@@ -251,61 +332,99 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd
|
||||
}
|
||||
}
|
||||
|
||||
archive_release_ctx(ctx);
|
||||
|
||||
r = archive_alloc_ctx(&ctx);
|
||||
if (r) {
|
||||
if (r == -ENOMEM)
|
||||
LOGE("%s", "Mem alloc failed");
|
||||
r = 0;
|
||||
LOGE("%s%s", "Archive open failed:", archive_error_string(ctx->arc));
|
||||
} else {
|
||||
entries = calloc(entryCount, sizeof(entry));
|
||||
r = archive_map_entries_index(ctx, sort_entries);
|
||||
if (!archive_prealloc_mempool()) {
|
||||
r = 0;
|
||||
for (int i = 0; i < entryCount; ++i) {
|
||||
free((void *) entries[i].filename);
|
||||
}
|
||||
free(entries);
|
||||
}
|
||||
}
|
||||
|
||||
archive_release_ctx(ctx);
|
||||
return r;
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_extractToByteBuffer(JNIEnv *env, jobject thiz, jint index) {
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_extractToByteBuffer(JNIEnv *env, jclass thiz, jint index) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
void *addr = MEMPOOL_ADDR_BY_SORTED_IDX(index);
|
||||
size_t size = entries[index].size;
|
||||
index = entries[index].index;
|
||||
archive_ctx *ctx = NULL;
|
||||
int ret;
|
||||
ret = archive_get_ctx(&ctx, index);
|
||||
if (ret)
|
||||
return 0;
|
||||
long long size = archive_entry_size(ctx->entry);
|
||||
void *buffer = malloc(size);
|
||||
if (!buffer) {
|
||||
int ret = archive_get_ctx(&ctx, index);
|
||||
if (ret) return 0;
|
||||
void *buffer = NULL;
|
||||
size_t buffer_size = 0;
|
||||
la_int64_t output_ofs = 0;
|
||||
archive_read_data_block(ctx->arc, (const void **) &buffer, &buffer_size, &output_ofs);
|
||||
bool zero_copy = ADDR_IN_FILE_MAPPING(buffer) && !output_ofs && buffer_size == size;
|
||||
if (zero_copy) {
|
||||
ctx->using = 0;
|
||||
LOGE("Allocate buffer for decompression failed:ENOMEM");
|
||||
return 0;
|
||||
return (*env)->NewDirectByteBuffer(env, buffer, buffer_size);
|
||||
} else {
|
||||
size_t bytes = 0;
|
||||
mempool_prefault_pages(addr, size);
|
||||
do {
|
||||
memcpy(addr + output_ofs, buffer, buffer_size);
|
||||
bytes += buffer_size;
|
||||
ret = archive_read_data_block(ctx->arc, (const void **) &buffer, &buffer_size, &output_ofs);
|
||||
} while (bytes != size && !ret);
|
||||
ctx->using = 0;
|
||||
if (bytes == size) {
|
||||
return (*env)->NewDirectByteBuffer(env, addr, size);
|
||||
} else {
|
||||
if (ret < 0) {
|
||||
LOGE("%s%s", "Archive read failed:", archive_error_string(ctx->arc));
|
||||
} else {
|
||||
LOGE("%s", "No enough data read, WTF?");
|
||||
}
|
||||
}
|
||||
mempool_release_pages(addr, size);
|
||||
}
|
||||
ret = archive_read_data(ctx->arc, buffer, size);
|
||||
ctx->using = 0;
|
||||
if (ret == size)
|
||||
return (*env)->NewDirectByteBuffer(env, buffer, size);
|
||||
if (ret != size)
|
||||
LOGE("%s", "No enough data read, WTF?");
|
||||
if (ret < 0)
|
||||
LOGE("%s%s", "Archive read failed:", archive_error_string(ctx->arc));
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *env, jobject thiz) {
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_closeArchive(JNIEnv *env, jclass thiz) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
for (int i = 0; i < CTX_POOL_SIZE; i++)
|
||||
archive_release_ctx(ctx_pool[i]);
|
||||
free(passwd);
|
||||
free(ctx_pool);
|
||||
pthread_mutex_destroy(&ctx_lock);
|
||||
passwd = NULL;
|
||||
need_encrypt = false;
|
||||
munmap(archiveAddr, archiveSize);
|
||||
munmap(mempool, MEMPOOL_SIZE);
|
||||
free(mempoolofs);
|
||||
for (int i = 0; i < entryCount; ++i) {
|
||||
free((void *) entries[i].filename);
|
||||
}
|
||||
free(entries);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_needPassword(JNIEnv *env, jobject thiz) {
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_needPassword(JNIEnv *env, jclass thiz) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
return need_encrypt;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jstring str) {
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_providePassword(JNIEnv *env, jclass thiz, jstring str) {
|
||||
EH_UNUSED(thiz);
|
||||
struct archive_entry *entry;
|
||||
archive_ctx *ctx;
|
||||
@@ -316,11 +435,11 @@ Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jst
|
||||
LOGE("Allocate passwd buffer failed");
|
||||
return false;
|
||||
}
|
||||
strcpy(passwd, (*env)->GetStringUTFChars(env, str, NULL));
|
||||
(*env)->GetStringUTFRegion(env, str, 0, len, passwd);
|
||||
archive_alloc_ctx(&ctx);
|
||||
void *tmpBuf = alloca(4096);
|
||||
while (archive_read_next_header(ctx->arc, &entry) == ARCHIVE_OK) {
|
||||
if (!filename_is_playable_file(archive_entry_pathname(entry)))
|
||||
if (!archive_entry_is_playable(entry))
|
||||
continue;
|
||||
if (!archive_entry_is_encrypted(entry))
|
||||
continue;
|
||||
@@ -335,34 +454,67 @@ Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jst
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_getFilename(JNIEnv *env, jobject thiz, jint index) {
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_getExtension(JNIEnv *env, jclass thiz, jint index) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
archive_ctx *ctx = NULL;
|
||||
int ret;
|
||||
ret = archive_get_ctx(&ctx, index);
|
||||
if (ret)
|
||||
return NULL;
|
||||
jstring str = (*env)->NewStringUTF(env, archive_entry_pathname(ctx->entry));
|
||||
ctx->using = 0;
|
||||
return str;
|
||||
const char *ext = strrchr(entries[index].filename, '.') + 1;
|
||||
return (*env)->NewStringUTF(env, ext);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint index, jint fd) {
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_extractToFd(JNIEnv *env, jclass thiz, jint index, jint fd) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
index = entries[index].index;
|
||||
archive_ctx *ctx = NULL;
|
||||
int ret;
|
||||
ret = archive_get_ctx(&ctx, index);
|
||||
if (!ret) {
|
||||
archive_read_data_into_fd(ctx->arc, fd);
|
||||
ret = archive_read_data_into_fd(ctx->arc, fd);
|
||||
ctx->using = 0;
|
||||
}
|
||||
return ret == ARCHIVE_OK;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_releaseByteBuffer(JNIEnv *env, jobject thiz, jobject buffer) {
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_releaseByteBuffer(JNIEnv *env, jclass thiz, jobject buffer) {
|
||||
EH_UNUSED(thiz);
|
||||
void *addr = (*env)->GetDirectBufferAddress(env, buffer);
|
||||
free(addr);
|
||||
}
|
||||
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
|
||||
if (!ADDR_IN_FILE_MAPPING(addr)) mempool_release_pages(addr, size);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_hippo_ehviewer_jni_ArchiveKt_archiveFdBatch(JNIEnv *env, jclass clazz, jintArray fd_batch, jobjectArray names, jint arc_fd, jint size) {
|
||||
EH_UNUSED(clazz);
|
||||
struct archive *arc = archive_write_new();
|
||||
struct stat st;
|
||||
char buff[8192];
|
||||
jint fdBatch[size];
|
||||
(*env)->GetIntArrayRegion(env, fd_batch, 0, size, fdBatch);
|
||||
archive_write_set_format_zip(arc);
|
||||
archive_write_zip_set_compression_store(arc);
|
||||
archive_write_open_fd(arc, arc_fd);
|
||||
struct archive_entry *entry = archive_entry_new();
|
||||
for (int i = 0; i < size; i++) {
|
||||
int fd = fdBatch[i];
|
||||
jobject name = (*env)->GetObjectArrayElement(env, names, i);
|
||||
const char *cname = (*env)->GetStringUTFChars(env, name, false);
|
||||
archive_entry_set_pathname(entry, cname);
|
||||
(*env)->ReleaseStringUTFChars(env, name, cname);
|
||||
fstat(fd, &st);
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
archive_entry_set_perm(entry, 0644);
|
||||
archive_write_header(arc, entry);
|
||||
int len = read(fd, buff, sizeof(buff));
|
||||
while (len > 0) {
|
||||
archive_write_data(arc, buff, len);
|
||||
len = read(fd, buff, sizeof(buff));
|
||||
}
|
||||
archive_write_finish_entry(arc);
|
||||
archive_entry_clear(entry);
|
||||
}
|
||||
archive_write_close(arc);
|
||||
archive_write_free(arc);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
#include <jni.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <android/bitmap.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/** A line will be considered as having content if 0.25% of it is filled. */
|
||||
const float filledRatioLimit = 0.0025;
|
||||
|
||||
/** When the threshold is closer to 1, less content will be cropped. **/
|
||||
#define THRESHOLD 0.75
|
||||
|
||||
const uint8_t thresholdForBlack = (uint8_t) (255.0 * THRESHOLD);
|
||||
|
||||
const uint8_t thresholdForWhite = (uint8_t) (255.0 - 255.0 * THRESHOLD);
|
||||
|
||||
static uint8_t inline grey(uint32_t pixel) {
|
||||
const uint8_t r = ((uint8_t *) &pixel)[0];
|
||||
const uint8_t g = ((uint8_t *) &pixel)[1];
|
||||
const uint8_t b = ((uint8_t *) &pixel)[2];
|
||||
return (r * 77 + g * 151 + b * 28) >> 8;
|
||||
}
|
||||
|
||||
static bool inline isBlackPixel(const uint32_t *pixels, uint32_t width, uint32_t x, uint32_t y) {
|
||||
const uint32_t pixel = *((uint32_t *) pixels + (y * width + x));
|
||||
return grey(pixel) < thresholdForBlack;
|
||||
}
|
||||
|
||||
static bool inline isWhitePixel(const uint32_t *pixels, uint32_t width, uint32_t x, uint32_t y) {
|
||||
const uint32_t pixel = *((uint32_t *) pixels + (y * width + x));
|
||||
return grey(pixel) > thresholdForWhite;
|
||||
}
|
||||
|
||||
/** Return the first x position where there is a substantial amount of fill,
|
||||
* starting the search from the left. */
|
||||
uint32_t findBorderLeft(uint32_t *pixels, uint32_t width, uint32_t height,
|
||||
uint32_t top, uint32_t bottom) {
|
||||
int x, y;
|
||||
const uint32_t filledLimit = round(height * filledRatioLimit / 2);
|
||||
|
||||
// Scan first line to detect dominant color
|
||||
uint32_t whitePixels = 0;
|
||||
uint32_t blackPixels = 0;
|
||||
|
||||
for (y = top; y < bottom; y += 2) {
|
||||
if (isBlackPixel(pixels, width, 0, y)) {
|
||||
blackPixels++;
|
||||
} else if (isWhitePixel(pixels, width, 0, y)) {
|
||||
whitePixels++;
|
||||
}
|
||||
}
|
||||
|
||||
bool (*detectFunc)(const uint32_t *, uint32_t, uint32_t, uint32_t) = isBlackPixel;
|
||||
if (whitePixels > filledLimit && blackPixels > filledLimit) {
|
||||
// Mixed fill found... don't crop anything
|
||||
return 0;
|
||||
} else if (blackPixels > filledLimit) {
|
||||
detectFunc = isWhitePixel;
|
||||
}
|
||||
|
||||
// Scan vertical lines in search of filled lines
|
||||
for (x = 1; x < width; x++) {
|
||||
uint32_t filledCount = 0;
|
||||
|
||||
for (y = top; y < bottom; y += 2) {
|
||||
if (detectFunc(pixels, width, x, y)) {
|
||||
filledCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (filledCount > filledLimit) {
|
||||
// This line contains enough fill
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
// No fill found... don't crop anything
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return the first x position where there is a substantial amount of fill,
|
||||
* starting the search from the right. */
|
||||
uint32_t findBorderRight(uint32_t *pixels, uint32_t width, uint32_t height,
|
||||
uint32_t top, uint32_t bottom) {
|
||||
int x, y;
|
||||
const uint32_t filledLimit = round(height * filledRatioLimit / 2);
|
||||
|
||||
// Scan first line to detect dominant color
|
||||
uint32_t whitePixels = 0;
|
||||
uint32_t blackPixels = 0;
|
||||
|
||||
uint32_t lastX = width - 1;
|
||||
for (y = top; y < bottom; y += 2) {
|
||||
if (isBlackPixel(pixels, width, lastX, y)) {
|
||||
blackPixels++;
|
||||
} else if (isWhitePixel(pixels, width, lastX, y)) {
|
||||
whitePixels++;
|
||||
}
|
||||
}
|
||||
|
||||
bool (*detectFunc)(const uint32_t *, uint32_t, uint32_t, uint32_t) = isBlackPixel;
|
||||
if (whitePixels > filledLimit && blackPixels > filledLimit) {
|
||||
// Mixed fill found... don't crop anything
|
||||
return width;
|
||||
} else if (blackPixels > filledLimit) {
|
||||
detectFunc = isWhitePixel;
|
||||
}
|
||||
|
||||
// Scan vertical lines in search of filled lines
|
||||
for (x = width - 2; x > 0; x--) {
|
||||
uint32_t filledCount = 0;
|
||||
|
||||
for (y = top; y < bottom; y += 2) {
|
||||
if (detectFunc(pixels, width, x, y)) {
|
||||
filledCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (filledCount > filledLimit) {
|
||||
// This line contains enough fill
|
||||
return x + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// No fill found... don't crop anything
|
||||
return width;
|
||||
}
|
||||
|
||||
/** Return the first y position where there is a substantial amount of fill,
|
||||
* starting the search from the top. */
|
||||
uint32_t findBorderTop(uint32_t *pixels, uint32_t width, uint32_t height) {
|
||||
int x, y;
|
||||
const uint32_t filledLimit = round(width * filledRatioLimit / 2);
|
||||
|
||||
// Scan first line to detect dominant color
|
||||
uint32_t whitePixels = 0;
|
||||
uint32_t blackPixels = 0;
|
||||
|
||||
for (x = 0; x < width; x += 2) {
|
||||
if (isBlackPixel(pixels, width, x, 0)) {
|
||||
blackPixels++;
|
||||
} else if (isWhitePixel(pixels, width, x, 0)) {
|
||||
whitePixels++;
|
||||
}
|
||||
}
|
||||
|
||||
bool (*detectFunc)(const uint32_t *, uint32_t, uint32_t, uint32_t) = isBlackPixel;
|
||||
if (whitePixels > filledLimit && blackPixels > filledLimit) {
|
||||
// Mixed fill found... don't crop anything
|
||||
return 0;
|
||||
} else if (blackPixels > filledLimit) {
|
||||
detectFunc = isWhitePixel;
|
||||
}
|
||||
|
||||
// Scan horizontal lines in search of filled lines
|
||||
for (y = 1; y < height; y++) {
|
||||
uint32_t filledCount = 0;
|
||||
|
||||
for (x = 0; x < width; x += 2) {
|
||||
if (detectFunc(pixels, width, x, y)) {
|
||||
filledCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (filledCount > filledLimit) {
|
||||
// This line contains enough fill
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
// No fill found... don't crop anything
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return the first y position where there is a substantial amount of fill,
|
||||
* starting the search from the bottom. */
|
||||
uint32_t findBorderBottom(uint32_t *pixels, uint32_t width, uint32_t height) {
|
||||
int x, y;
|
||||
const uint32_t filledLimit = round(width * filledRatioLimit / 2);
|
||||
|
||||
// Scan first line to detect dominant color
|
||||
uint32_t whitePixels = 0;
|
||||
uint32_t blackPixels = 0;
|
||||
uint32_t lastY = height - 1;
|
||||
|
||||
for (x = 0; x < width; x += 2) {
|
||||
if (isBlackPixel(pixels, width, x, lastY)) {
|
||||
blackPixels++;
|
||||
} else if (isWhitePixel(pixels, width, x, lastY)) {
|
||||
whitePixels++;
|
||||
}
|
||||
}
|
||||
|
||||
bool (*detectFunc)(const uint32_t *, uint32_t, uint32_t, uint32_t) = isBlackPixel;
|
||||
if (whitePixels > filledLimit && blackPixels > filledLimit) {
|
||||
// Mixed fill found... don't crop anything
|
||||
return height;
|
||||
} else if (blackPixels > filledLimit) {
|
||||
detectFunc = isWhitePixel;
|
||||
}
|
||||
|
||||
// Scan horizontal lines in search of filled lines
|
||||
for (y = height - 2; y > 0; y--) {
|
||||
uint32_t filledCount = 0;
|
||||
|
||||
for (x = 0; x < width; x += 2) {
|
||||
if (detectFunc(pixels, width, x, y)) {
|
||||
filledCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (filledCount > filledLimit) {
|
||||
// This line contains enough fill
|
||||
return y + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// No fill found... don't crop anything
|
||||
return height;
|
||||
}
|
||||
|
||||
JNIEXPORT jintArray JNICALL
|
||||
Java_com_hippo_ehviewer_image_ImageKt_detectBorder(JNIEnv *env, jclass clazz, jobject bitmap) {
|
||||
void *pixels = NULL;
|
||||
AndroidBitmapInfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
AndroidBitmap_getInfo(env, bitmap, &info);
|
||||
AndroidBitmap_lockPixels(env, bitmap, &pixels);
|
||||
uint32_t width = info.width;
|
||||
uint32_t height = info.height;
|
||||
uint32_t top = findBorderTop(pixels, width, height);
|
||||
uint32_t bottom = findBorderBottom(pixels, width, height);
|
||||
uint32_t left = findBorderLeft(pixels, width, height, top, bottom);
|
||||
uint32_t right = findBorderRight(pixels, width, height, top, bottom);
|
||||
int array[4] = {left, top, right, bottom};
|
||||
AndroidBitmap_unlockPixels(env, bitmap);
|
||||
jintArray ret = (*env)->NewIntArray(env, 4);
|
||||
(*env)->SetIntArrayRegion(env, ret, 0, 4, array);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#include <jni.h>
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_hippo_Native_getFd(JNIEnv *env, jclass clazz, jobject fileDescriptor) {
|
||||
jint fd = -1;
|
||||
jclass fdClass = (*env)->FindClass(env, "java/io/FileDescriptor");
|
||||
|
||||
if (fdClass != NULL) {
|
||||
jfieldID fdClassDescriptorFieldID = (*env)->GetFieldID(env, fdClass, "descriptor", "I");
|
||||
if (fdClassDescriptorFieldID != NULL && fileDescriptor != NULL) {
|
||||
fd = (*env)->GetIntField(env, fileDescriptor, fdClassDescriptorFieldID);
|
||||
}
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#include <jni.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <android/log.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define LOG_TAG "gifUtils"
|
||||
|
||||
#include "ehviewer.h"
|
||||
|
||||
#define GIF_HEADER_87A "GIF87a"
|
||||
#define GIF_HEADER_89A "GIF89a"
|
||||
#define GIF_HEADER_LENGTH 6
|
||||
|
||||
static int FRAME_DELAY_START_MARKER = 0x0021F904;
|
||||
|
||||
typedef signed char byte;
|
||||
|
||||
#define FRAME_DELAY_START_MARKER ((byte*)(&FRAME_DELAY_START_MARKER))
|
||||
#define MINIMUM_FRAME_DELAY 2
|
||||
#define DEFAULT_FRAME_DELAY 10
|
||||
|
||||
static inline bool isGif(void *addr) {
|
||||
return !memcmp(addr, GIF_HEADER_87A, GIF_HEADER_LENGTH) ||
|
||||
!memcmp(addr, GIF_HEADER_89A, GIF_HEADER_LENGTH);
|
||||
}
|
||||
|
||||
static void doRewrite(byte *addr, size_t size) {
|
||||
if (size < 7 || !isGif(addr)) return;
|
||||
for (size_t i = 0; i < size - 8; i++) {
|
||||
// TODO: Optimize this hex find with SIMD?
|
||||
if (addr[i] == FRAME_DELAY_START_MARKER[3] && addr[i + 1] == FRAME_DELAY_START_MARKER[2] &&
|
||||
addr[i + 2] == FRAME_DELAY_START_MARKER[1] &&
|
||||
addr[i + 3] == FRAME_DELAY_START_MARKER[0]) {
|
||||
byte *end = addr + i + 4;
|
||||
if (end[4] != 0) continue;
|
||||
int frameDelay = end[2] << 8 | end[1];
|
||||
if (frameDelay > MINIMUM_FRAME_DELAY)
|
||||
break; // Quit if the first block looks normal, for performance
|
||||
end[1] = DEFAULT_FRAME_DELAY;
|
||||
end[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_hippo_ehviewer_jni_GifUtilsKt_isGif(JNIEnv *env, jclass clazz, jint fd) {
|
||||
byte buffer[GIF_HEADER_LENGTH];
|
||||
return read(fd, buffer, GIF_HEADER_LENGTH) == GIF_HEADER_LENGTH &&
|
||||
isGif(buffer);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_ehviewer_jni_GifUtilsKt_rewriteGifSource(JNIEnv *env, jclass clazz, jobject buffer) {
|
||||
byte *addr = (*env)->GetDirectBufferAddress(env, buffer);
|
||||
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
|
||||
doRewrite(addr, size);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_hippo_ehviewer_jni_GifUtilsKt_mmap(JNIEnv *env, jclass clazz, jint fd) {
|
||||
struct stat64 st;
|
||||
fstat64(fd, &st);
|
||||
size_t size = st.st_size;
|
||||
byte *addr = mmap64(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (addr == MAP_FAILED) return NULL;
|
||||
return (*env)->NewDirectByteBuffer(env, addr, size);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_ehviewer_jni_GifUtilsKt_munmap(JNIEnv *env, jclass clazz, jobject buffer) {
|
||||
byte *addr = (*env)->GetDirectBufferAddress(env, buffer);
|
||||
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
|
||||
munmap(addr, size);
|
||||
}
|
||||
Submodule app/src/main/cpp/libarchive deleted from c9298fd6dc.
Submodule app/src/main/cpp/liblzma deleted from b35079d589.
@@ -0,0 +1,146 @@
|
||||
/* -*- mode: c; c-file-style: "k&r" -*-
|
||||
|
||||
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
|
||||
Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
/* partial change history:
|
||||
*
|
||||
* 2004-10-10 mbp: Lift out character type dependencies into macros.
|
||||
*
|
||||
* Eric Sosman pointed out that ctype functions take a parameter whose
|
||||
* value must be that of an unsigned int, even on platforms that have
|
||||
* negative chars in their default char type.
|
||||
*/
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <ctype.h>
|
||||
|
||||
#include "strnatcmp.h"
|
||||
|
||||
|
||||
/* These are defined as macros to make it easier to adapt this code to
|
||||
* different characters types or comparison functions. */
|
||||
static inline int
|
||||
nat_isdigit(nat_char a)
|
||||
{
|
||||
return isdigit((unsigned char) a);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
nat_isspace(nat_char a)
|
||||
{
|
||||
return isspace((unsigned char) a);
|
||||
}
|
||||
|
||||
|
||||
static inline nat_char
|
||||
nat_toupper(nat_char a)
|
||||
{
|
||||
return toupper((unsigned char) a);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
compare_right(nat_char const *a, nat_char const *b)
|
||||
{
|
||||
int bias = 0;
|
||||
|
||||
/* The longest run of digits wins. That aside, the greatest
|
||||
value wins, but we can't know that it will until we've scanned
|
||||
both numbers to know that they have the same magnitude, so we
|
||||
remember it in BIAS. */
|
||||
for (;; a++, b++) {
|
||||
if (!nat_isdigit(*a) && !nat_isdigit(*b))
|
||||
return bias;
|
||||
if (!nat_isdigit(*a))
|
||||
return -1;
|
||||
if (!nat_isdigit(*b))
|
||||
return +1;
|
||||
if (*a < *b) {
|
||||
if (!bias)
|
||||
bias = -1;
|
||||
} else if (*a > *b) {
|
||||
if (!bias)
|
||||
bias = +1;
|
||||
} else if (!*a && !*b)
|
||||
return bias;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
|
||||
{
|
||||
int ai, bi;
|
||||
nat_char ca, cb;
|
||||
int result;
|
||||
|
||||
ai = bi = 0;
|
||||
while (1) {
|
||||
ca = a[ai]; cb = b[bi];
|
||||
|
||||
/* skip over leading spaces or zeros */
|
||||
while (nat_isspace(ca) || ca == '0')
|
||||
ca = a[++ai];
|
||||
|
||||
while (nat_isspace(cb) || cb == '0')
|
||||
cb = b[++bi];
|
||||
|
||||
/* process run of digits */
|
||||
if (nat_isdigit(ca) && nat_isdigit(cb)) {
|
||||
if ((result = compare_right(a+ai, b+bi)) != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!ca && !cb) {
|
||||
/* The strings compare the same. Perhaps the caller
|
||||
will want to call strcmp to break the tie. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fold_case) {
|
||||
ca = nat_toupper(ca);
|
||||
cb = nat_toupper(cb);
|
||||
}
|
||||
|
||||
if (ca < cb)
|
||||
return -1;
|
||||
|
||||
if (ca > cb)
|
||||
return +1;
|
||||
|
||||
++ai; ++bi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
strnatcmp(nat_char const *a, nat_char const *b) {
|
||||
return strnatcmp0(a, b, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Compare, recognizing numeric string and ignoring case. */
|
||||
int
|
||||
strnatcasecmp(nat_char const *a, nat_char const *b) {
|
||||
return strnatcmp0(a, b, 1);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/* -*- mode: c; c-file-style: "k&r" -*-
|
||||
|
||||
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
|
||||
Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* CUSTOMIZATION SECTION
|
||||
*
|
||||
* You can change this typedef, but must then also change the inline
|
||||
* functions in strnatcmp.c */
|
||||
typedef char nat_char;
|
||||
|
||||
int strnatcmp(nat_char const *a, nat_char const *b);
|
||||
int strnatcasecmp(nat_char const *a, nat_char const *b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -5,233 +5,232 @@ set(LIBNETTLE_DEFINITIONS
|
||||
-DHAVE_CONFIG_H)
|
||||
|
||||
set(LIBNETTLE_SOURCES
|
||||
nettle/aes-decrypt-internal.c
|
||||
nettle/aes-decrypt.c
|
||||
nettle/aes-decrypt-table.c
|
||||
nettle/aes128-decrypt.c
|
||||
nettle/aes192-decrypt.c
|
||||
nettle/aes256-decrypt.c
|
||||
nettle/aes-encrypt-internal.c
|
||||
nettle/aes-encrypt.c
|
||||
nettle/aes-encrypt-table.c
|
||||
nettle/aes128-encrypt.c
|
||||
nettle/aes192-encrypt.c
|
||||
nettle/aes256-encrypt.c
|
||||
nettle/aes-invert-internal.c
|
||||
nettle/aes-set-key-internal.c
|
||||
nettle/aes-set-encrypt-key.c
|
||||
nettle/aes-set-decrypt-key.c
|
||||
nettle/aes128-set-encrypt-key.c
|
||||
nettle/aes128-set-decrypt-key.c
|
||||
nettle/aes128-meta.c
|
||||
nettle/aes192-set-encrypt-key.c
|
||||
nettle/aes192-set-decrypt-key.c
|
||||
nettle/aes192-meta.c
|
||||
nettle/aes256-set-encrypt-key.c
|
||||
nettle/aes256-set-decrypt-key.c
|
||||
nettle/aes256-meta.c
|
||||
nettle/nist-keywrap.c
|
||||
nettle/arcfour.c
|
||||
nettle/arcfour-crypt.c
|
||||
nettle/arctwo.c
|
||||
nettle/arctwo-meta.c
|
||||
nettle/blowfish.c
|
||||
nettle/blowfish-bcrypt.c
|
||||
nettle/base16-encode.c
|
||||
nettle/base16-decode.c
|
||||
nettle/base16-meta.c
|
||||
nettle/base64-encode.c
|
||||
nettle/base64-decode.c
|
||||
nettle/base64-meta.c
|
||||
nettle/base64url-encode.c
|
||||
nettle/base64url-decode.c
|
||||
nettle/base64url-meta.c
|
||||
nettle/buffer.c
|
||||
nettle/buffer-init.c
|
||||
nettle/camellia-crypt-internal.c
|
||||
nettle/camellia-table.c
|
||||
nettle/camellia-absorb.c
|
||||
nettle/camellia-invert-key.c
|
||||
nettle/camellia128-set-encrypt-key.c
|
||||
nettle/camellia128-crypt.c
|
||||
nettle/camellia128-set-decrypt-key.c
|
||||
nettle/camellia128-meta.c
|
||||
nettle/camellia192-meta.c
|
||||
nettle/camellia256-set-encrypt-key.c
|
||||
nettle/camellia256-crypt.c
|
||||
nettle/camellia256-set-decrypt-key.c
|
||||
nettle/camellia256-meta.c
|
||||
nettle/cast128.c
|
||||
nettle/cast128-meta.c
|
||||
nettle/cbc.c
|
||||
nettle/cbc-aes128-encrypt.c
|
||||
nettle/cbc-aes192-encrypt.c
|
||||
nettle/cbc-aes256-encrypt.c
|
||||
nettle/ccm.c
|
||||
nettle/ccm-aes128.c
|
||||
nettle/ccm-aes192.c
|
||||
nettle/ccm-aes256.c
|
||||
nettle/cfb.c
|
||||
nettle/siv-cmac.c
|
||||
nettle/siv-cmac-aes128.c
|
||||
nettle/siv-cmac-aes256.c
|
||||
nettle/cnd-memcpy.c
|
||||
nettle/chacha-crypt.c
|
||||
nettle/chacha-core-internal.c
|
||||
nettle/chacha-poly1305.c
|
||||
nettle/chacha-poly1305-meta.c
|
||||
nettle/chacha-set-key.c
|
||||
nettle/chacha-set-nonce.c
|
||||
nettle/ctr.c
|
||||
nettle/ctr16.c
|
||||
nettle/des.c
|
||||
nettle/des3.c
|
||||
nettle/eax.c
|
||||
nettle/eax-aes128.c
|
||||
nettle/eax-aes128-meta.c
|
||||
nettle/ghash-set-key.c
|
||||
nettle/ghash-update.c
|
||||
nettle/gcm.c
|
||||
nettle/gcm-aes.c
|
||||
nettle/gcm-aes128.c
|
||||
nettle/gcm-aes128-meta.c
|
||||
nettle/gcm-aes192.c
|
||||
nettle/gcm-aes192-meta.c
|
||||
nettle/gcm-aes256.c
|
||||
nettle/gcm-aes256-meta.c
|
||||
nettle/gcm-camellia128.c
|
||||
nettle/gcm-camellia128-meta.c
|
||||
nettle/gcm-camellia256.c
|
||||
nettle/gcm-camellia256-meta.c
|
||||
nettle/cmac.c
|
||||
nettle/cmac64.c
|
||||
nettle/cmac-aes128.c
|
||||
nettle/cmac-aes256.c
|
||||
nettle/cmac-des3.c
|
||||
nettle/cmac-aes128-meta.c
|
||||
nettle/cmac-aes256-meta.c
|
||||
nettle/cmac-des3-meta.c
|
||||
nettle/gost28147.c
|
||||
nettle/gosthash94.c
|
||||
nettle/gosthash94-meta.c
|
||||
nettle/hmac.c
|
||||
nettle/hmac-gosthash94.c
|
||||
nettle/hmac-md5.c
|
||||
nettle/hmac-ripemd160.c
|
||||
nettle/hmac-sha1.c
|
||||
nettle/hmac-sha224.c
|
||||
nettle/hmac-sha256.c
|
||||
nettle/hmac-sha384.c
|
||||
nettle/hmac-sha512.c
|
||||
nettle/hmac-streebog.c
|
||||
nettle/hmac-sm3.c
|
||||
nettle/hmac-md5-meta.c
|
||||
nettle/hmac-ripemd160-meta.c
|
||||
nettle/hmac-sha1-meta.c
|
||||
nettle/hmac-sha224-meta.c
|
||||
nettle/hmac-sha256-meta.c
|
||||
nettle/hmac-sha384-meta.c
|
||||
nettle/hmac-sha512-meta.c
|
||||
nettle/hmac-streebog-meta.c
|
||||
nettle/hmac-sm3-meta.c
|
||||
nettle/knuth-lfib.c
|
||||
nettle/hkdf.c
|
||||
nettle/md2.c
|
||||
nettle/md2-meta.c
|
||||
nettle/md4.c
|
||||
nettle/md4-meta.c
|
||||
nettle/md5.c
|
||||
nettle/md5-compress.c
|
||||
nettle/md5-compat.c
|
||||
nettle/md5-meta.c
|
||||
nettle/memeql-sec.c
|
||||
nettle/memxor.c
|
||||
nettle/memxor3.c
|
||||
nettle/nettle-lookup-hash.c
|
||||
nettle/nettle-meta-aeads.c
|
||||
nettle/nettle-meta-armors.c
|
||||
nettle/nettle-meta-ciphers.c
|
||||
nettle/nettle-meta-hashes.c
|
||||
nettle/nettle-meta-macs.c
|
||||
nettle/pbkdf2.c
|
||||
nettle/pbkdf2-hmac-gosthash94.c
|
||||
nettle/pbkdf2-hmac-sha1.c
|
||||
nettle/pbkdf2-hmac-sha256.c
|
||||
nettle/pbkdf2-hmac-sha384.c
|
||||
nettle/pbkdf2-hmac-sha512.c
|
||||
nettle/poly1305-aes.c
|
||||
nettle/poly1305-internal.c
|
||||
nettle/realloc.c
|
||||
nettle/ripemd160.c
|
||||
nettle/ripemd160-compress.c
|
||||
nettle/ripemd160-meta.c
|
||||
nettle/salsa20-core-internal.c
|
||||
nettle/salsa20-crypt-internal.c
|
||||
nettle/salsa20-crypt.c
|
||||
nettle/salsa20r12-crypt.c
|
||||
nettle/salsa20-set-key.c
|
||||
nettle/salsa20-set-nonce.c
|
||||
nettle/salsa20-128-set-key.c
|
||||
nettle/salsa20-256-set-key.c
|
||||
nettle/sha1.c
|
||||
nettle/sha1-compress.c
|
||||
nettle/sha1-meta.c
|
||||
nettle/sha256.c
|
||||
nettle/sha256-compress.c
|
||||
nettle/sha224-meta.c
|
||||
nettle/sha256-meta.c
|
||||
nettle/sha512.c
|
||||
nettle/sha512-compress.c
|
||||
nettle/sha384-meta.c
|
||||
nettle/sha512-meta.c
|
||||
nettle/sha512-224-meta.c
|
||||
nettle/sha512-256-meta.c
|
||||
nettle/sha3.c
|
||||
nettle/sha3-permute.c
|
||||
nettle/sha3-224.c
|
||||
nettle/sha3-224-meta.c
|
||||
nettle/sha3-256.c
|
||||
nettle/sha3-256-meta.c
|
||||
nettle/sha3-384.c
|
||||
nettle/sha3-384-meta.c
|
||||
nettle/sha3-512.c
|
||||
nettle/sha3-512-meta.c
|
||||
nettle/shake256.c
|
||||
nettle/sm3.c
|
||||
nettle/sm3-meta.c
|
||||
nettle/serpent-set-key.c
|
||||
nettle/serpent-encrypt.c
|
||||
nettle/serpent-decrypt.c
|
||||
nettle/serpent-meta.c
|
||||
nettle/streebog.c
|
||||
nettle/streebog-meta.c
|
||||
nettle/twofish.c
|
||||
nettle/twofish-meta.c
|
||||
nettle/umac-nh.c
|
||||
nettle/umac-nh-n.c
|
||||
nettle/umac-l2.c
|
||||
nettle/umac-l3.c
|
||||
nettle/umac-poly64.c
|
||||
nettle/umac-poly128.c
|
||||
nettle/umac-set-key.c
|
||||
nettle/umac32.c
|
||||
nettle/umac64.c
|
||||
nettle/umac96.c
|
||||
nettle/umac128.c
|
||||
nettle/version.c
|
||||
nettle/write-be32.c
|
||||
nettle/write-le32.c
|
||||
nettle/write-le64.c
|
||||
nettle/yarrow256.c
|
||||
nettle/yarrow_key_event.c
|
||||
nettle/xts.c
|
||||
nettle/xts-aes128.c
|
||||
nettle/xts-aes256.c
|
||||
${NETTLE_DIR}/aes-decrypt-internal.c
|
||||
${NETTLE_DIR}/aes-decrypt.c
|
||||
${NETTLE_DIR}/aes-decrypt-table.c
|
||||
${NETTLE_DIR}/aes128-decrypt.c
|
||||
${NETTLE_DIR}/aes192-decrypt.c
|
||||
${NETTLE_DIR}/aes256-decrypt.c
|
||||
${NETTLE_DIR}/aes-encrypt-internal.c
|
||||
${NETTLE_DIR}/aes-encrypt.c
|
||||
${NETTLE_DIR}/aes-encrypt-table.c
|
||||
${NETTLE_DIR}/aes128-encrypt.c
|
||||
${NETTLE_DIR}/aes192-encrypt.c
|
||||
${NETTLE_DIR}/aes256-encrypt.c
|
||||
${NETTLE_DIR}/aes-invert-internal.c
|
||||
${NETTLE_DIR}/aes-set-key-internal.c
|
||||
${NETTLE_DIR}/aes-set-encrypt-key.c
|
||||
${NETTLE_DIR}/aes-set-decrypt-key.c
|
||||
${NETTLE_DIR}/aes128-set-encrypt-key.c
|
||||
${NETTLE_DIR}/aes128-set-decrypt-key.c
|
||||
${NETTLE_DIR}/aes128-meta.c
|
||||
${NETTLE_DIR}/aes192-set-encrypt-key.c
|
||||
${NETTLE_DIR}/aes192-set-decrypt-key.c
|
||||
${NETTLE_DIR}/aes192-meta.c
|
||||
${NETTLE_DIR}/aes256-set-encrypt-key.c
|
||||
${NETTLE_DIR}/aes256-set-decrypt-key.c
|
||||
${NETTLE_DIR}/aes256-meta.c
|
||||
${NETTLE_DIR}/nist-keywrap.c
|
||||
${NETTLE_DIR}/arcfour.c
|
||||
${NETTLE_DIR}/arctwo.c
|
||||
${NETTLE_DIR}/arctwo-meta.c
|
||||
${NETTLE_DIR}/blowfish.c
|
||||
${NETTLE_DIR}/blowfish-bcrypt.c
|
||||
${NETTLE_DIR}/base16-encode.c
|
||||
${NETTLE_DIR}/base16-decode.c
|
||||
${NETTLE_DIR}/base16-meta.c
|
||||
${NETTLE_DIR}/base64-encode.c
|
||||
${NETTLE_DIR}/base64-decode.c
|
||||
${NETTLE_DIR}/base64-meta.c
|
||||
${NETTLE_DIR}/base64url-encode.c
|
||||
${NETTLE_DIR}/base64url-decode.c
|
||||
${NETTLE_DIR}/base64url-meta.c
|
||||
${NETTLE_DIR}/buffer.c
|
||||
${NETTLE_DIR}/buffer-init.c
|
||||
${NETTLE_DIR}/camellia-crypt-internal.c
|
||||
${NETTLE_DIR}/camellia-table.c
|
||||
${NETTLE_DIR}/camellia-absorb.c
|
||||
${NETTLE_DIR}/camellia-invert-key.c
|
||||
${NETTLE_DIR}/camellia128-set-encrypt-key.c
|
||||
${NETTLE_DIR}/camellia128-crypt.c
|
||||
${NETTLE_DIR}/camellia128-set-decrypt-key.c
|
||||
${NETTLE_DIR}/camellia128-meta.c
|
||||
${NETTLE_DIR}/camellia192-meta.c
|
||||
${NETTLE_DIR}/camellia256-set-encrypt-key.c
|
||||
${NETTLE_DIR}/camellia256-crypt.c
|
||||
${NETTLE_DIR}/camellia256-set-decrypt-key.c
|
||||
${NETTLE_DIR}/camellia256-meta.c
|
||||
${NETTLE_DIR}/cast128.c
|
||||
${NETTLE_DIR}/cast128-meta.c
|
||||
${NETTLE_DIR}/cbc.c
|
||||
${NETTLE_DIR}/cbc-aes128-encrypt.c
|
||||
${NETTLE_DIR}/cbc-aes192-encrypt.c
|
||||
${NETTLE_DIR}/cbc-aes256-encrypt.c
|
||||
${NETTLE_DIR}/ccm.c
|
||||
${NETTLE_DIR}/ccm-aes128.c
|
||||
${NETTLE_DIR}/ccm-aes192.c
|
||||
${NETTLE_DIR}/ccm-aes256.c
|
||||
${NETTLE_DIR}/cfb.c
|
||||
${NETTLE_DIR}/siv-cmac.c
|
||||
${NETTLE_DIR}/siv-cmac-aes128.c
|
||||
${NETTLE_DIR}/siv-cmac-aes256.c
|
||||
${NETTLE_DIR}/cnd-memcpy.c
|
||||
${NETTLE_DIR}/chacha-crypt.c
|
||||
${NETTLE_DIR}/chacha-core-internal.c
|
||||
${NETTLE_DIR}/chacha-poly1305.c
|
||||
${NETTLE_DIR}/chacha-poly1305-meta.c
|
||||
${NETTLE_DIR}/chacha-set-key.c
|
||||
${NETTLE_DIR}/chacha-set-nonce.c
|
||||
${NETTLE_DIR}/ctr.c
|
||||
${NETTLE_DIR}/ctr16.c
|
||||
${NETTLE_DIR}/des.c
|
||||
${NETTLE_DIR}/des3.c
|
||||
${NETTLE_DIR}/eax.c
|
||||
${NETTLE_DIR}/eax-aes128.c
|
||||
${NETTLE_DIR}/eax-aes128-meta.c
|
||||
${NETTLE_DIR}/ghash-set-key.c
|
||||
${NETTLE_DIR}/ghash-update.c
|
||||
${NETTLE_DIR}/gcm.c
|
||||
${NETTLE_DIR}/gcm-aes.c
|
||||
${NETTLE_DIR}/gcm-aes128.c
|
||||
${NETTLE_DIR}/gcm-aes128-meta.c
|
||||
${NETTLE_DIR}/gcm-aes192.c
|
||||
${NETTLE_DIR}/gcm-aes192-meta.c
|
||||
${NETTLE_DIR}/gcm-aes256.c
|
||||
${NETTLE_DIR}/gcm-aes256-meta.c
|
||||
${NETTLE_DIR}/gcm-camellia128.c
|
||||
${NETTLE_DIR}/gcm-camellia128-meta.c
|
||||
${NETTLE_DIR}/gcm-camellia256.c
|
||||
${NETTLE_DIR}/gcm-camellia256-meta.c
|
||||
${NETTLE_DIR}/cmac.c
|
||||
${NETTLE_DIR}/cmac64.c
|
||||
${NETTLE_DIR}/cmac-aes128.c
|
||||
${NETTLE_DIR}/cmac-aes256.c
|
||||
${NETTLE_DIR}/cmac-des3.c
|
||||
${NETTLE_DIR}/cmac-aes128-meta.c
|
||||
${NETTLE_DIR}/cmac-aes256-meta.c
|
||||
${NETTLE_DIR}/cmac-des3-meta.c
|
||||
${NETTLE_DIR}/gost28147.c
|
||||
${NETTLE_DIR}/gosthash94.c
|
||||
${NETTLE_DIR}/gosthash94-meta.c
|
||||
${NETTLE_DIR}/hmac.c
|
||||
${NETTLE_DIR}/hmac-gosthash94.c
|
||||
${NETTLE_DIR}/hmac-md5.c
|
||||
${NETTLE_DIR}/hmac-ripemd160.c
|
||||
${NETTLE_DIR}/hmac-sha1.c
|
||||
${NETTLE_DIR}/hmac-sha224.c
|
||||
${NETTLE_DIR}/hmac-sha256.c
|
||||
${NETTLE_DIR}/hmac-sha384.c
|
||||
${NETTLE_DIR}/hmac-sha512.c
|
||||
${NETTLE_DIR}/hmac-streebog.c
|
||||
${NETTLE_DIR}/hmac-sm3.c
|
||||
${NETTLE_DIR}/hmac-md5-meta.c
|
||||
${NETTLE_DIR}/hmac-ripemd160-meta.c
|
||||
${NETTLE_DIR}/hmac-sha1-meta.c
|
||||
${NETTLE_DIR}/hmac-sha224-meta.c
|
||||
${NETTLE_DIR}/hmac-sha256-meta.c
|
||||
${NETTLE_DIR}/hmac-sha384-meta.c
|
||||
${NETTLE_DIR}/hmac-sha512-meta.c
|
||||
${NETTLE_DIR}/hmac-streebog-meta.c
|
||||
${NETTLE_DIR}/hmac-sm3-meta.c
|
||||
${NETTLE_DIR}/knuth-lfib.c
|
||||
${NETTLE_DIR}/hkdf.c
|
||||
${NETTLE_DIR}/md2.c
|
||||
${NETTLE_DIR}/md2-meta.c
|
||||
${NETTLE_DIR}/md4.c
|
||||
${NETTLE_DIR}/md4-meta.c
|
||||
${NETTLE_DIR}/md5.c
|
||||
${NETTLE_DIR}/md5-compress.c
|
||||
${NETTLE_DIR}/md5-compat.c
|
||||
${NETTLE_DIR}/md5-meta.c
|
||||
${NETTLE_DIR}/memeql-sec.c
|
||||
${NETTLE_DIR}/memxor.c
|
||||
${NETTLE_DIR}/memxor3.c
|
||||
${NETTLE_DIR}/nettle-lookup-hash.c
|
||||
${NETTLE_DIR}/nettle-meta-aeads.c
|
||||
${NETTLE_DIR}/nettle-meta-armors.c
|
||||
${NETTLE_DIR}/nettle-meta-ciphers.c
|
||||
${NETTLE_DIR}/nettle-meta-hashes.c
|
||||
${NETTLE_DIR}/nettle-meta-macs.c
|
||||
${NETTLE_DIR}/pbkdf2.c
|
||||
${NETTLE_DIR}/pbkdf2-hmac-gosthash94.c
|
||||
${NETTLE_DIR}/pbkdf2-hmac-sha1.c
|
||||
${NETTLE_DIR}/pbkdf2-hmac-sha256.c
|
||||
${NETTLE_DIR}/pbkdf2-hmac-sha384.c
|
||||
${NETTLE_DIR}/pbkdf2-hmac-sha512.c
|
||||
${NETTLE_DIR}/poly1305-aes.c
|
||||
${NETTLE_DIR}/poly1305-internal.c
|
||||
${NETTLE_DIR}/realloc.c
|
||||
${NETTLE_DIR}/ripemd160.c
|
||||
${NETTLE_DIR}/ripemd160-compress.c
|
||||
${NETTLE_DIR}/ripemd160-meta.c
|
||||
${NETTLE_DIR}/salsa20-core-internal.c
|
||||
${NETTLE_DIR}/salsa20-crypt-internal.c
|
||||
${NETTLE_DIR}/salsa20-crypt.c
|
||||
${NETTLE_DIR}/salsa20r12-crypt.c
|
||||
${NETTLE_DIR}/salsa20-set-key.c
|
||||
${NETTLE_DIR}/salsa20-set-nonce.c
|
||||
${NETTLE_DIR}/salsa20-128-set-key.c
|
||||
${NETTLE_DIR}/salsa20-256-set-key.c
|
||||
${NETTLE_DIR}/sha1.c
|
||||
${NETTLE_DIR}/sha1-compress.c
|
||||
${NETTLE_DIR}/sha1-meta.c
|
||||
${NETTLE_DIR}/sha256.c
|
||||
${NETTLE_DIR}/sha256-compress-n.c
|
||||
${NETTLE_DIR}/sha224-meta.c
|
||||
${NETTLE_DIR}/sha256-meta.c
|
||||
${NETTLE_DIR}/sha512.c
|
||||
${NETTLE_DIR}/sha512-compress.c
|
||||
${NETTLE_DIR}/sha384-meta.c
|
||||
${NETTLE_DIR}/sha512-meta.c
|
||||
${NETTLE_DIR}/sha512-224-meta.c
|
||||
${NETTLE_DIR}/sha512-256-meta.c
|
||||
${NETTLE_DIR}/sha3.c
|
||||
${NETTLE_DIR}/sha3-permute.c
|
||||
${NETTLE_DIR}/sha3-224.c
|
||||
${NETTLE_DIR}/sha3-224-meta.c
|
||||
${NETTLE_DIR}/sha3-256.c
|
||||
${NETTLE_DIR}/sha3-256-meta.c
|
||||
${NETTLE_DIR}/sha3-384.c
|
||||
${NETTLE_DIR}/sha3-384-meta.c
|
||||
${NETTLE_DIR}/sha3-512.c
|
||||
${NETTLE_DIR}/sha3-512-meta.c
|
||||
${NETTLE_DIR}/shake256.c
|
||||
${NETTLE_DIR}/sm3.c
|
||||
${NETTLE_DIR}/sm3-meta.c
|
||||
${NETTLE_DIR}/serpent-set-key.c
|
||||
${NETTLE_DIR}/serpent-encrypt.c
|
||||
${NETTLE_DIR}/serpent-decrypt.c
|
||||
${NETTLE_DIR}/serpent-meta.c
|
||||
${NETTLE_DIR}/streebog.c
|
||||
${NETTLE_DIR}/streebog-meta.c
|
||||
${NETTLE_DIR}/twofish.c
|
||||
${NETTLE_DIR}/twofish-meta.c
|
||||
${NETTLE_DIR}/umac-nh.c
|
||||
${NETTLE_DIR}/umac-nh-n.c
|
||||
${NETTLE_DIR}/umac-l2.c
|
||||
${NETTLE_DIR}/umac-l3.c
|
||||
${NETTLE_DIR}/umac-poly64.c
|
||||
${NETTLE_DIR}/umac-poly128.c
|
||||
${NETTLE_DIR}/umac-set-key.c
|
||||
${NETTLE_DIR}/umac32.c
|
||||
${NETTLE_DIR}/umac64.c
|
||||
${NETTLE_DIR}/umac96.c
|
||||
${NETTLE_DIR}/umac128.c
|
||||
${NETTLE_DIR}/version.c
|
||||
${NETTLE_DIR}/write-be32.c
|
||||
${NETTLE_DIR}/write-le32.c
|
||||
${NETTLE_DIR}/write-le64.c
|
||||
${NETTLE_DIR}/yarrow256.c
|
||||
${NETTLE_DIR}/yarrow_key_event.c
|
||||
${NETTLE_DIR}/xts.c
|
||||
${NETTLE_DIR}/xts-aes128.c
|
||||
${NETTLE_DIR}/xts-aes256.c
|
||||
)
|
||||
|
||||
set(LIBNETTLE_INCLUDES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/nettle
|
||||
${NETTLE_DIR}
|
||||
)
|
||||
|
||||
add_library(nettle STATIC ${LIBNETTLE_SOURCES})
|
||||
|
||||
@@ -4,13 +4,19 @@
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Define to 1 if using 'alloca.c'. */
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
/* #undef CRAY_STACKSEG_END */
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
/* #undef C_ALLOCA */
|
||||
|
||||
/* Define to 1 if you have 'alloca', as a function or macro. */
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define to 1 if <alloca.h> works. */
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
#define HAVE_ALLOCA_H 1
|
||||
|
||||
/* Define if __builtin_bswap64 is available */
|
||||
@@ -46,6 +52,9 @@
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 each of the following for which a native (ie. CPU specific)
|
||||
implementation of the corresponding routine exists. */
|
||||
/* #undef HAVE_NATIVE_memxor3 */
|
||||
@@ -71,7 +80,7 @@
|
||||
/* #undef HAVE_NATIVE_cbc_aes256_encrypt */
|
||||
/* #undef HAVE_NATIVE_chacha_core */
|
||||
/* #undef HAVE_NATIVE_chacha_2core */
|
||||
/* #undef HAVE_NATIVE_chacha_3core */
|
||||
#define HAVE_NATIVE_chacha_3core 1
|
||||
/* #undef HAVE_NATIVE_chacha_4core */
|
||||
/* #undef HAVE_NATIVE_fat_chacha_2core */
|
||||
/* #undef HAVE_NATIVE_fat_chacha_3core */
|
||||
@@ -88,13 +97,18 @@
|
||||
/* #undef HAVE_NATIVE_ecc_secp384r1_redc */
|
||||
/* #undef HAVE_NATIVE_ecc_secp521r1_modp */
|
||||
/* #undef HAVE_NATIVE_ecc_secp521r1_redc */
|
||||
/* #undef HAVE_NATIVE_poly1305_set_key */
|
||||
/* #undef HAVE_NATIVE_poly1305_block */
|
||||
/* #undef HAVE_NATIVE_poly1305_digest */
|
||||
/* #undef HAVE_NATIVE_poly1305_blocks */
|
||||
/* #undef HAVE_NATIVE_fat_poly1305_blocks */
|
||||
/* #undef HAVE_NATIVE_ghash_set_key */
|
||||
/* #undef HAVE_NATIVE_ghash_update */
|
||||
/* #undef HAVE_NATIVE_salsa20_core */
|
||||
/* #undef HAVE_NATIVE_salsa20_2core */
|
||||
#define HAVE_NATIVE_salsa20_2core 1
|
||||
/* #undef HAVE_NATIVE_fat_salsa20_2core */
|
||||
/* #undef HAVE_NATIVE_sha1_compress */
|
||||
/* #undef HAVE_NATIVE_sha256_compress */
|
||||
/* #undef HAVE_NATIVE_sha256_compress_n */
|
||||
/* #undef HAVE_NATIVE_sha512_compress */
|
||||
/* #undef HAVE_NATIVE_sha3_permute */
|
||||
/* #undef HAVE_NATIVE_umac_nh */
|
||||
@@ -107,14 +121,11 @@
|
||||
/* #undef HAVE_OPENSSL_EVP_H */
|
||||
|
||||
/* Define to 1 if you have the `secure_getenv' function. */
|
||||
/* #undef HAVE_SECURE_GETENV */
|
||||
#define HAVE_SECURE_GETENV 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
@@ -130,9 +141,6 @@
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
@@ -149,7 +157,7 @@
|
||||
#define PACKAGE_NAME "nettle"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "nettle 3.8.1"
|
||||
#define PACKAGE_STRING "nettle 3.9.1"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "nettle"
|
||||
@@ -158,7 +166,7 @@
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "3.8.1"
|
||||
#define PACKAGE_VERSION "3.9.1"
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG __SIZEOF_LONG__
|
||||
@@ -174,13 +182,10 @@
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
/* #undef STACK_DIRECTION */
|
||||
|
||||
/* Define to 1 if all of the C90 standard headers exist (not just the ones
|
||||
required in a freestanding environment). This macro is provided for
|
||||
backward compatibility; new code need not use it. */
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. This
|
||||
macro is obsolete. */
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Defined if public key features are enabled */
|
||||
|
||||
Submodule app/src/main/cpp/nettle/nettle deleted from 990abad16c.
@@ -41,7 +41,7 @@ extern "C" {
|
||||
|
||||
/* Individual version numbers in decimal */
|
||||
#define NETTLE_VERSION_MAJOR 3
|
||||
#define NETTLE_VERSION_MINOR 8
|
||||
#define NETTLE_VERSION_MINOR 9
|
||||
|
||||
#define NETTLE_USE_MINI_GMP 0
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,160 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import com.davemorrissey.labs.subscaleview.provider.AssetInputProvider
|
||||
import com.davemorrissey.labs.subscaleview.provider.InputProvider
|
||||
import com.davemorrissey.labs.subscaleview.provider.OpenStreamProvider
|
||||
import com.davemorrissey.labs.subscaleview.provider.ResourceInputProvider
|
||||
import com.davemorrissey.labs.subscaleview.provider.UriInputProvider
|
||||
import java.io.InputStream
|
||||
|
||||
/**
|
||||
* Helper class used to set the source and additional attributes from a variety of sources. Supports
|
||||
* use of a bitmap, asset, resource, external file or any other URI.
|
||||
*
|
||||
*
|
||||
* When you are using a preview image, you must set the dimensions of the full size image on the
|
||||
* ImageSource object for the full size image using the [.dimensions] method.
|
||||
*/
|
||||
class ImageSource {
|
||||
val bitmap: Bitmap?
|
||||
val provider: InputProvider?
|
||||
|
||||
private var sWidth = 0
|
||||
private var sHeight = 0
|
||||
|
||||
var sRegion = Rect(0, 0, 0, 0)
|
||||
private set
|
||||
var isCached = false
|
||||
private set
|
||||
|
||||
private constructor(bitmap: Bitmap, cached: Boolean) {
|
||||
this.bitmap = bitmap
|
||||
provider = null
|
||||
sWidth = bitmap.width
|
||||
sHeight = bitmap.height
|
||||
isCached = cached
|
||||
}
|
||||
|
||||
private constructor(provider: InputProvider) {
|
||||
bitmap = null
|
||||
this.provider = provider
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a region of the source image. Region must be set independently for the full size image and the preview if
|
||||
* you are using one.
|
||||
*
|
||||
* @param sRegion the region of the source image to be displayed.
|
||||
* @return this instance for chaining.
|
||||
*/
|
||||
fun region(sRegion: Rect): ImageSource {
|
||||
this.sRegion = sRegion
|
||||
setInvariants()
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare the dimensions of the image. This is only required for a full size image, when you are specifying a URI
|
||||
* and also a preview image. When displaying a bitmap object, or not using a preview, you do not need to declare
|
||||
* the image dimensions. Note if the declared dimensions are found to be incorrect, the view will reset.
|
||||
*
|
||||
* @param sWidth width of the source image.
|
||||
* @param sHeight height of the source image.
|
||||
* @return this instance for chaining.
|
||||
*/
|
||||
fun dimensions(sWidth: Int, sHeight: Int): ImageSource {
|
||||
if (bitmap == null) {
|
||||
this.sWidth = sWidth
|
||||
this.sHeight = sHeight
|
||||
}
|
||||
setInvariants()
|
||||
return this
|
||||
}
|
||||
|
||||
private fun setInvariants() {
|
||||
if (!sRegion.isEmpty) {
|
||||
sWidth = sRegion.width()
|
||||
sHeight = sRegion.height()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Create an instance from a resource. The correct resource for the device screen resolution will be used.
|
||||
*
|
||||
* @param resId resource ID.
|
||||
* @return an [ImageSource] instance.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun resource(context: Context, resId: Int): ImageSource {
|
||||
return ImageSource(ResourceInputProvider(context, resId))
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance from an asset name.
|
||||
*
|
||||
* @param assetName asset name.
|
||||
* @return an [ImageSource] instance.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun asset(context: Context, assetName: String): ImageSource {
|
||||
return ImageSource(AssetInputProvider(context, assetName))
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance from a URI.
|
||||
*
|
||||
* @param uri image URI.
|
||||
* @return an [ImageSource] instance.
|
||||
*/
|
||||
fun uri(context: Context, uri: Uri): ImageSource {
|
||||
return ImageSource(UriInputProvider(context, uri))
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance from an input provider.
|
||||
*
|
||||
* @param provider input stream provider.
|
||||
* @return an [ImageSource] instance.
|
||||
*/
|
||||
fun provider(provider: InputProvider): ImageSource {
|
||||
return ImageSource(provider)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance from an input stream.
|
||||
*
|
||||
* @param stream open input stream.
|
||||
* @return an [ImageSource] instance.
|
||||
*/
|
||||
fun inputStream(stream: InputStream): ImageSource {
|
||||
return ImageSource(OpenStreamProvider(stream))
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a loaded bitmap for display.
|
||||
*
|
||||
* @param bitmap bitmap to be displayed.
|
||||
* @return an [ImageSource] instance.
|
||||
*/
|
||||
fun bitmap(bitmap: Bitmap): ImageSource {
|
||||
return ImageSource(bitmap, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a loaded and cached bitmap for display. This bitmap will not be recycled when it is no
|
||||
* longer needed. Use this method if you loaded the bitmap with an image loader such as Picasso
|
||||
* or Volley.
|
||||
*
|
||||
* @param bitmap bitmap to be displayed.
|
||||
* @return an [ImageSource] instance.
|
||||
*/
|
||||
fun cachedBitmap(bitmap: Bitmap): ImageSource {
|
||||
return ImageSource(bitmap, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview
|
||||
|
||||
import android.graphics.PointF
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Wraps the scale, center and orientation of a displayed image for easy restoration on screen rotate.
|
||||
*/
|
||||
class ImageViewState(val scale: Float, center: PointF) : Serializable {
|
||||
private val centerX: Float = center.x
|
||||
private val centerY: Float = center.y
|
||||
|
||||
val center: PointF
|
||||
get() = PointF(centerX, centerY)
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview.decoder
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Point
|
||||
import android.graphics.Rect
|
||||
import kotlin.Throws
|
||||
import com.davemorrissey.labs.subscaleview.provider.InputProvider
|
||||
import java.lang.Exception
|
||||
|
||||
/**
|
||||
* Interface for image decoding classes.
|
||||
*/
|
||||
interface Decoder {
|
||||
/**
|
||||
* Initialise the decoder. When possible, perform initial setup work once in this method. The
|
||||
* dimensions of the image must be returned.
|
||||
*
|
||||
* @param context Application context. A reference may be held, but must be cleared on recycle.
|
||||
* @param provider Provider of the image.
|
||||
* @return Dimensions of the image.
|
||||
* @throws Exception if initialisation fails.
|
||||
*/
|
||||
@Throws(Exception::class)
|
||||
fun init(context: Context, provider: InputProvider): Point
|
||||
|
||||
/**
|
||||
* Decode a region of the image with the given sample size. This method is called off the UI
|
||||
* thread so it can safely load the image on the current thread. It is called from
|
||||
* [android.os.AsyncTask]s running in an executor that may have multiple threads, so
|
||||
* implementations must be thread safe. Adding `synchronized` to the method signature
|
||||
* is the simplest way to achieve this, but bear in mind the [.recycle] method can be
|
||||
* called concurrently.
|
||||
*
|
||||
* @param sRect Source image rectangle to decode.
|
||||
* @param sampleSize Sample size.
|
||||
* @return The decoded region. It is safe to return null if decoding fails.
|
||||
*/
|
||||
fun decodeRegion(sRect: Rect, sampleSize: Int): Bitmap
|
||||
|
||||
/**
|
||||
* Status check. Should return false before initialisation and after recycle.
|
||||
*
|
||||
* @return true if the decoder is ready to be used.
|
||||
*/
|
||||
val isReady: Boolean
|
||||
|
||||
/**
|
||||
* This method will be called when the decoder is no longer required. It should clean up any
|
||||
* resources still in use.
|
||||
*/
|
||||
fun recycle()
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview.decoder
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Point
|
||||
import android.graphics.Rect
|
||||
import kotlin.Throws
|
||||
import com.davemorrissey.labs.subscaleview.provider.InputProvider
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import java.lang.Exception
|
||||
|
||||
class ImageDecoder @JvmOverloads constructor(
|
||||
private val cropBorders: Boolean,
|
||||
bitmapConfig: Bitmap.Config? = null
|
||||
) : Decoder {
|
||||
init {
|
||||
val globalBitmapConfig = SubsamplingScaleImageView.preferredBitmapConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the decoder. When possible, perform initial setup work once in this method. The
|
||||
* dimensions of the image must be returned.
|
||||
*
|
||||
* @param context Application context. A reference may be held, but must be cleared on recycle.
|
||||
* @param provider Provider of the image.
|
||||
* @return Dimensions of the image.
|
||||
* @throws Exception if initialisation fails.
|
||||
*/
|
||||
@Throws(Exception::class)
|
||||
override fun init(context: Context, provider: InputProvider): Point {
|
||||
TODO()
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a region of the image with the given sample size. This method is called off the UI
|
||||
* thread so it can safely load the image on the current thread. It is called from
|
||||
* [android.os.AsyncTask]s running in an executor that may have multiple threads, so
|
||||
* implementations must be thread safe. Adding `synchronized` to the method signature
|
||||
* is the simplest way to achieve this, but bear in mind the [.recycle] method can be
|
||||
* called concurrently.
|
||||
*
|
||||
* @param sRect Source image rectangle to decode.
|
||||
* @param sampleSize Sample size.
|
||||
* @return The decoded region. It is safe to return null if decoding fails.
|
||||
*/
|
||||
override fun decodeRegion(sRect: Rect, sampleSize: Int): Bitmap {
|
||||
TODO()
|
||||
}
|
||||
|
||||
/**
|
||||
* Status check. Should return false before initialisation and after recycle.
|
||||
*
|
||||
* @return true if the decoder is ready to be used.
|
||||
*/
|
||||
override val isReady: Boolean = TODO()
|
||||
|
||||
/**
|
||||
* This method will be called when the decoder is no longer required. It should clean up any
|
||||
* resources still in use.
|
||||
*/
|
||||
override fun recycle() {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview.provider
|
||||
|
||||
import android.content.Context
|
||||
import java.io.IOException
|
||||
|
||||
class AssetInputProvider(context: Context, val assetName: String) : InputProvider {
|
||||
private val assets = context.assets
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun openStream() = assets.open(assetName)
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview.provider
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import kotlin.Throws
|
||||
|
||||
interface InputProvider {
|
||||
@Throws(IOException::class)
|
||||
fun openStream(): InputStream?
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview.provider
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import kotlin.Throws
|
||||
|
||||
/**
|
||||
* Provider from an already open input stream.
|
||||
*
|
||||
*
|
||||
* Please keep in mind this provider is not reusable.
|
||||
*/
|
||||
class OpenStreamProvider(private val stream: InputStream) : InputProvider {
|
||||
@Throws(IOException::class)
|
||||
override fun openStream() = stream
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview.provider
|
||||
|
||||
import android.content.Context
|
||||
import java.io.IOException
|
||||
|
||||
class ResourceInputProvider(context: Context, val resource: Int) : InputProvider {
|
||||
private val resources = context.resources
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun openStream() = resources.openRawResource(resource)
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.davemorrissey.labs.subscaleview.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import java.io.IOException
|
||||
import kotlin.Throws
|
||||
|
||||
class UriInputProvider(context: Context, val uri: Uri) : InputProvider {
|
||||
private val resolver = context.contentResolver
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun openStream() = resolver.openInputStream(uri)
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Tarsin Norbin
|
||||
*
|
||||
* This file is part of EhViewer
|
||||
*
|
||||
* EhViewer is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* EhViewer is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with EhViewer.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.hippo
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
class UriArchiveAccessor(ctx: Context, uri: Uri) {
|
||||
val pfd by lazy { ctx.contentResolver.openFileDescriptor(uri, "r")!! }
|
||||
fun open(): Int {
|
||||
return openArchive(pfd.fd, pfd.statSize)
|
||||
}
|
||||
|
||||
private external fun openArchive(fd: Int, size: Long): Int
|
||||
external fun extractToByteBuffer(index: Int): ByteBuffer?
|
||||
|
||||
external fun releaseByteBuffer(buffer: ByteBuffer)
|
||||
external fun extractToFd(index: Int, fd: Int)
|
||||
external fun getFilename(index: Int): String
|
||||
external fun needPassword(): Boolean
|
||||
external fun providePassword(str: String): Boolean
|
||||
private external fun closeArchive()
|
||||
fun close() {
|
||||
closeArchive()
|
||||
pfd.close()
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.hippo.app
|
||||
|
||||
import android.content.Context
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
||||
open class BaseDialogBuilder constructor(
|
||||
context: Context
|
||||
) : MaterialAlertDialogBuilder(context)
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.hippo.app
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.CheckBox
|
||||
import com.hippo.ehviewer.R
|
||||
|
||||
class CheckBoxDialogBuilder constructor(
|
||||
context: Context,
|
||||
message: String?,
|
||||
checkText: String?,
|
||||
checked: Boolean
|
||||
) : BaseDialogBuilder(
|
||||
context
|
||||
) {
|
||||
private val mCheckBox: CheckBox
|
||||
val isChecked: Boolean
|
||||
get() = mCheckBox.isChecked
|
||||
|
||||
init {
|
||||
val view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_checkbox_builder, null)
|
||||
setView(view)
|
||||
setMessage(message)
|
||||
mCheckBox = view.findViewById(R.id.checkbox)
|
||||
mCheckBox.text = checkText
|
||||
mCheckBox.isChecked = checked
|
||||
view.setOnClickListener { mCheckBox.toggle() }
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.hippo.app
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import android.widget.TextView.OnEditorActionListener
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.hippo.ehviewer.R
|
||||
|
||||
class EditTextDialogBuilder constructor(
|
||||
context: Context,
|
||||
text: String?,
|
||||
hint: String?
|
||||
) : BaseDialogBuilder(
|
||||
context
|
||||
), OnEditorActionListener {
|
||||
private val mTextInputLayout: TextInputLayout
|
||||
val editText: EditText
|
||||
private var mDialog: AlertDialog? = null
|
||||
val text: String
|
||||
get() = editText.text.toString()
|
||||
|
||||
fun setError(error: CharSequence?) {
|
||||
mTextInputLayout.error = error
|
||||
}
|
||||
|
||||
override fun create(): AlertDialog {
|
||||
mDialog = super.create()
|
||||
return mDialog as AlertDialog
|
||||
}
|
||||
|
||||
override fun onEditorAction(v: TextView?, p1: Int, event: KeyEvent?): Boolean {
|
||||
return if (mDialog != null) {
|
||||
val button = mDialog!!.getButton(DialogInterface.BUTTON_POSITIVE)
|
||||
button?.performClick()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
val view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_edittext_builder, null)
|
||||
setView(view)
|
||||
mTextInputLayout = view as TextInputLayout
|
||||
editText = view.findViewById(R.id.edit_text)
|
||||
editText.setText(text)
|
||||
editText.setSelection(editText.text.length)
|
||||
editText.setOnEditorActionListener(this)
|
||||
mTextInputLayout.hint = hint
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.hippo.app
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.HapticFeedbackConstants
|
||||
import com.google.android.material.slider.Slider
|
||||
|
||||
class HapticSlider @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
) : Slider(context, attrs) {
|
||||
init {
|
||||
addOnChangeListener { _, _, _ -> performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK) }
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.hippo.app
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.CheckBox
|
||||
import android.widget.ListView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.yorozuya.ViewUtils
|
||||
|
||||
class ListCheckBoxDialogBuilder constructor(
|
||||
context: Context, items: Array<CharSequence>,
|
||||
listener: OnItemClickListener?, checkText: String?, checked: Boolean
|
||||
) : BaseDialogBuilder(
|
||||
context
|
||||
) {
|
||||
private val mCheckBox: CheckBox
|
||||
private var mDialog: AlertDialog? = null
|
||||
val isChecked: Boolean
|
||||
get() = mCheckBox.isChecked
|
||||
|
||||
override fun create(): AlertDialog {
|
||||
mDialog = super.create()
|
||||
return mDialog as AlertDialog
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(builder: ListCheckBoxDialogBuilder?, dialog: AlertDialog?, position: Int)
|
||||
}
|
||||
|
||||
init {
|
||||
val view =
|
||||
LayoutInflater.from(getContext()).inflate(R.layout.dialog_list_checkbox_builder, null)
|
||||
setView(view)
|
||||
val listView = ViewUtils.`$$`(view, R.id.list_view) as ListView
|
||||
mCheckBox = ViewUtils.`$$`(view, R.id.checkbox) as CheckBox
|
||||
listView.adapter = ArrayAdapter(getContext(), R.layout.item_select_dialog, items)
|
||||
listView.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, position: Int, _: Long ->
|
||||
listener?.onItemClick(this@ListCheckBoxDialogBuilder, mDialog, position)
|
||||
mDialog?.dismiss()
|
||||
}
|
||||
mCheckBox.text = checkText
|
||||
mCheckBox.isChecked = checked
|
||||
}
|
||||
}
|
||||
@@ -1,985 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.beerbelly;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.Closeable;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A cache that uses a bounded amount of space on a filesystem. Each cache
|
||||
* entry has a string key and a fixed number of values. Each key must match
|
||||
* the regex <strong>[a-z0-9_-]{1,120}</strong>. Values are byte sequences,
|
||||
* accessible as streams or files. Each value must be between {@code 0} and
|
||||
* {@code Integer.MAX_VALUE} bytes in length.
|
||||
*
|
||||
* <p>The cache stores its data in a directory on the filesystem. This
|
||||
* directory must be exclusive to the cache; the cache may delete or overwrite
|
||||
* files from its directory. It is an error for multiple processes to use the
|
||||
* same cache directory at the same time.
|
||||
*
|
||||
* <p>This cache limits the number of bytes that it will store on the
|
||||
* filesystem. When the number of stored bytes exceeds the limit, the cache will
|
||||
* remove entries in the background until the limit is satisfied. The limit is
|
||||
* not strict: the cache may temporarily exceed it while waiting for files to be
|
||||
* deleted. The limit does not include filesystem overhead or the cache
|
||||
* journal so space-sensitive applications should set a conservative limit.
|
||||
*
|
||||
* <p>Clients call {@link #edit} to create or update the values of an entry. An
|
||||
* entry may have only one editor at one time; if a value is not available to be
|
||||
* edited then {@link #edit} will return null.
|
||||
* <ul>
|
||||
* <li>When an entry is being <strong>created</strong> it is necessary to
|
||||
* supply a full set of values; the empty value should be used as a
|
||||
* placeholder if necessary.
|
||||
* <li>When an entry is being <strong>edited</strong>, it is not necessary
|
||||
* to supply data for every value; values default to their previous
|
||||
* value.
|
||||
* </ul>
|
||||
* Every {@link #edit} call must be matched by a call to {@link Editor#commit}
|
||||
* or {@link Editor#abort}. Committing is atomic: a read observes the full set
|
||||
* of values as they were before or after the commit, but never a mix of values.
|
||||
*
|
||||
* <p>Clients call {@link #get} to read a snapshot of an entry. The read will
|
||||
* observe the value at the time that {@link #get} was called. Updates and
|
||||
* removals after the call do not impact ongoing reads.
|
||||
*
|
||||
* <p>This class is tolerant of some I/O errors. If files are missing from the
|
||||
* filesystem, the corresponding entries will be dropped from the cache. If
|
||||
* an error occurs while writing a cache value, the edit will fail silently.
|
||||
* Callers should handle other problems by catching {@code IOException} and
|
||||
* responding appropriately.
|
||||
*/
|
||||
public final class DiskLruCache implements Closeable {
|
||||
static final String JOURNAL_FILE = "journal";
|
||||
static final String JOURNAL_FILE_TEMP = "journal.tmp";
|
||||
static final String JOURNAL_FILE_BACKUP = "journal.bkp";
|
||||
static final String MAGIC = "libcore.io.DiskLruCache";
|
||||
static final String VERSION_1 = "1";
|
||||
static final long ANY_SEQUENCE_NUMBER = -1;
|
||||
static final String STRING_KEY_PATTERN = "[a-z0-9_-]{1,120}";
|
||||
static final Pattern LEGAL_KEY_PATTERN = Pattern.compile(STRING_KEY_PATTERN);
|
||||
private static final String CLEAN = "CLEAN";
|
||||
private static final String DIRTY = "DIRTY";
|
||||
private static final String REMOVE = "REMOVE";
|
||||
private static final String READ = "READ";
|
||||
|
||||
/*
|
||||
* This cache uses a journal file named "journal". A typical journal file
|
||||
* looks like this:
|
||||
* libcore.io.DiskLruCache
|
||||
* 1
|
||||
* 100
|
||||
* 2
|
||||
*
|
||||
* CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054
|
||||
* DIRTY 335c4c6028171cfddfbaae1a9c313c52
|
||||
* CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342
|
||||
* REMOVE 335c4c6028171cfddfbaae1a9c313c52
|
||||
* DIRTY 1ab96a171faeeee38496d8b330771a7a
|
||||
* CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234
|
||||
* READ 335c4c6028171cfddfbaae1a9c313c52
|
||||
* READ 3400330d1dfc7f3f7f4b8d4d803dfcf6
|
||||
*
|
||||
* The first five lines of the journal form its header. They are the
|
||||
* constant string "libcore.io.DiskLruCache", the disk cache's version,
|
||||
* the application's version, the value count, and a blank line.
|
||||
*
|
||||
* Each of the subsequent lines in the file is a record of the state of a
|
||||
* cache entry. Each line contains space-separated values: a state, a key,
|
||||
* and optional state-specific values.
|
||||
* o DIRTY lines track that an entry is actively being created or updated.
|
||||
* Every successful DIRTY action should be followed by a CLEAN or REMOVE
|
||||
* action. DIRTY lines without a matching CLEAN or REMOVE indicate that
|
||||
* temporary files may need to be deleted.
|
||||
* o CLEAN lines track a cache entry that has been successfully published
|
||||
* and may be read. A publish line is followed by the lengths of each of
|
||||
* its values.
|
||||
* o READ lines track accesses for LRU.
|
||||
* o REMOVE lines track entries that have been deleted.
|
||||
*
|
||||
* The journal file is appended to as cache operations occur. The journal may
|
||||
* occasionally be compacted by dropping redundant lines. A temporary file named
|
||||
* "journal.tmp" will be used during compaction; that file should be deleted if
|
||||
* it exists when the cache is opened.
|
||||
*/
|
||||
private static final OutputStream NULL_OUTPUT_STREAM = new OutputStream() {
|
||||
@Override
|
||||
public void write(int b) {
|
||||
// Eat all writes silently. Nom nom.
|
||||
}
|
||||
};
|
||||
/**
|
||||
* This cache uses a single background thread to evict entries.
|
||||
*/
|
||||
final ThreadPoolExecutor executorService =
|
||||
new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
|
||||
private final File directory;
|
||||
private final File journalFile;
|
||||
private final File journalFileTmp;
|
||||
private final File journalFileBackup;
|
||||
private final int appVersion;
|
||||
private final int valueCount;
|
||||
private final LinkedHashMap<String, Entry> lruEntries =
|
||||
new LinkedHashMap<>(0, 0.75f, true);
|
||||
private long maxSize;
|
||||
private long size = 0;
|
||||
private Writer journalWriter;
|
||||
private int redundantOpCount;
|
||||
/**
|
||||
* To differentiate between old and current snapshots, each entry is given
|
||||
* a sequence number each time an edit is committed. A snapshot is stale if
|
||||
* its sequence number is not equal to its entry's sequence number.
|
||||
*/
|
||||
private long nextSequenceNumber = 0;
|
||||
|
||||
private DiskLruCache(File directory, int appVersion, int valueCount, long maxSize) {
|
||||
this.directory = directory;
|
||||
this.appVersion = appVersion;
|
||||
this.journalFile = new File(directory, JOURNAL_FILE);
|
||||
this.journalFileTmp = new File(directory, JOURNAL_FILE_TEMP);
|
||||
this.journalFileBackup = new File(directory, JOURNAL_FILE_BACKUP);
|
||||
this.valueCount = valueCount;
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the cache in {@code directory}, creating a cache if none exists
|
||||
* there.
|
||||
*
|
||||
* @param directory a writable directory
|
||||
* @param valueCount the number of values per cache entry. Must be positive.
|
||||
* @param maxSize the maximum number of bytes this cache should use to store
|
||||
* @throws IOException if reading or writing the cache directory fails
|
||||
*/
|
||||
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
|
||||
throws IOException {
|
||||
if (maxSize <= 0) {
|
||||
throw new IllegalArgumentException("maxSize <= 0");
|
||||
}
|
||||
if (valueCount <= 0) {
|
||||
throw new IllegalArgumentException("valueCount <= 0");
|
||||
}
|
||||
|
||||
// If a bkp file exists, use it instead.
|
||||
File backupFile = new File(directory, JOURNAL_FILE_BACKUP);
|
||||
if (backupFile.exists()) {
|
||||
File journalFile = new File(directory, JOURNAL_FILE);
|
||||
// If journal file also exists just delete backup file.
|
||||
if (journalFile.exists()) {
|
||||
backupFile.delete();
|
||||
} else {
|
||||
renameTo(backupFile, journalFile, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer to pick up where we left off.
|
||||
DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
|
||||
if (cache.journalFile.exists()) {
|
||||
try {
|
||||
cache.readJournal();
|
||||
cache.processJournal();
|
||||
return cache;
|
||||
} catch (IOException journalIsCorrupt) {
|
||||
System.out
|
||||
.println("DiskLruCache "
|
||||
+ directory
|
||||
+ " is corrupt: "
|
||||
+ journalIsCorrupt.getMessage()
|
||||
+ ", removing");
|
||||
cache.delete();
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new empty cache.
|
||||
directory.mkdirs();
|
||||
cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
|
||||
cache.rebuildJournal();
|
||||
return cache;
|
||||
}
|
||||
|
||||
private static void deleteIfExists(File file) throws IOException {
|
||||
if (file.exists() && !file.delete()) {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
private static void renameTo(File from, File to, boolean deleteDestination) throws IOException {
|
||||
if (deleteDestination) {
|
||||
deleteIfExists(to);
|
||||
}
|
||||
if (!from.renameTo(to)) {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
private static String inputStreamToString(InputStream in) throws IOException {
|
||||
return Util.readFully(new InputStreamReader(in, Util.UTF_8));
|
||||
}
|
||||
|
||||
private void readJournal() throws IOException {
|
||||
StrictLineReader reader = new StrictLineReader(new FileInputStream(journalFile), Util.US_ASCII);
|
||||
try {
|
||||
String magic = reader.readLine();
|
||||
String version = reader.readLine();
|
||||
String appVersionString = reader.readLine();
|
||||
String valueCountString = reader.readLine();
|
||||
String blank = reader.readLine();
|
||||
if (!MAGIC.equals(magic)
|
||||
|| !VERSION_1.equals(version)
|
||||
|| !Integer.toString(appVersion).equals(appVersionString)
|
||||
|| !Integer.toString(valueCount).equals(valueCountString)
|
||||
|| !"".equals(blank)) {
|
||||
throw new IOException("unexpected journal header: [" + magic + ", " + version + ", "
|
||||
+ valueCountString + ", " + blank + "]");
|
||||
}
|
||||
|
||||
int lineCount = 0;
|
||||
while (true) {
|
||||
try {
|
||||
readJournalLine(reader.readLine());
|
||||
lineCount++;
|
||||
} catch (EOFException endOfJournal) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
redundantOpCount = lineCount - lruEntries.size();
|
||||
|
||||
// If we ended on a truncated line, rebuild the journal before appending to it.
|
||||
if (reader.hasUnterminatedLine()) {
|
||||
rebuildJournal();
|
||||
} else {
|
||||
journalWriter = new BufferedWriter(new OutputStreamWriter(
|
||||
new FileOutputStream(journalFile, true), Util.US_ASCII));
|
||||
}
|
||||
} finally {
|
||||
Util.closeQuietly(reader);
|
||||
}
|
||||
}
|
||||
|
||||
private void readJournalLine(String line) throws IOException {
|
||||
int firstSpace = line.indexOf(' ');
|
||||
if (firstSpace == -1) {
|
||||
throw new IOException("unexpected journal line: " + line);
|
||||
}
|
||||
|
||||
int keyBegin = firstSpace + 1;
|
||||
int secondSpace = line.indexOf(' ', keyBegin);
|
||||
final String key;
|
||||
if (secondSpace == -1) {
|
||||
key = line.substring(keyBegin);
|
||||
if (firstSpace == REMOVE.length() && line.startsWith(REMOVE)) {
|
||||
lruEntries.remove(key);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
key = line.substring(keyBegin, secondSpace);
|
||||
}
|
||||
|
||||
Entry entry = lruEntries.get(key);
|
||||
if (entry == null) {
|
||||
entry = new Entry(key);
|
||||
lruEntries.put(key, entry);
|
||||
}
|
||||
|
||||
if (secondSpace != -1 && firstSpace == CLEAN.length() && line.startsWith(CLEAN)) {
|
||||
String[] parts = line.substring(secondSpace + 1).split(" ");
|
||||
entry.readable = true;
|
||||
entry.currentEditor = null;
|
||||
entry.setLengths(parts);
|
||||
} else if (secondSpace == -1 && firstSpace == DIRTY.length() && line.startsWith(DIRTY)) {
|
||||
entry.currentEditor = new Editor(entry);
|
||||
} else if (secondSpace == -1 && firstSpace == READ.length() && line.startsWith(READ)) {
|
||||
// This work was already done by calling lruEntries.get().
|
||||
} else {
|
||||
throw new IOException("unexpected journal line: " + line);
|
||||
}
|
||||
} private final Callable<Void> cleanupCallable = new Callable<>() {
|
||||
public Void call() throws Exception {
|
||||
synchronized (DiskLruCache.this) {
|
||||
if (journalWriter == null) {
|
||||
return null; // Closed.
|
||||
}
|
||||
trimToSize();
|
||||
if (journalRebuildRequired()) {
|
||||
rebuildJournal();
|
||||
redundantOpCount = 0;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Computes the initial size and collects garbage as a part of opening the
|
||||
* cache. Dirty entries are assumed to be inconsistent and will be deleted.
|
||||
*/
|
||||
private void processJournal() throws IOException {
|
||||
deleteIfExists(journalFileTmp);
|
||||
for (Iterator<Entry> i = lruEntries.values().iterator(); i.hasNext(); ) {
|
||||
Entry entry = i.next();
|
||||
if (entry.currentEditor == null) {
|
||||
for (int t = 0; t < valueCount; t++) {
|
||||
size += entry.lengths[t];
|
||||
}
|
||||
} else {
|
||||
entry.currentEditor = null;
|
||||
for (int t = 0; t < valueCount; t++) {
|
||||
deleteIfExists(entry.getCleanFile(t));
|
||||
deleteIfExists(entry.getDirtyFile(t));
|
||||
}
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new journal that omits redundant information. This replaces the
|
||||
* current journal if it exists.
|
||||
*/
|
||||
private synchronized void rebuildJournal() throws IOException {
|
||||
if (journalWriter != null) {
|
||||
journalWriter.close();
|
||||
}
|
||||
|
||||
try (Writer writer = new BufferedWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(journalFileTmp), Util.US_ASCII))) {
|
||||
writer.write(MAGIC);
|
||||
writer.write("\n");
|
||||
writer.write(VERSION_1);
|
||||
writer.write("\n");
|
||||
writer.write(Integer.toString(appVersion));
|
||||
writer.write("\n");
|
||||
writer.write(Integer.toString(valueCount));
|
||||
writer.write("\n");
|
||||
writer.write("\n");
|
||||
|
||||
for (Entry entry : lruEntries.values()) {
|
||||
if (entry.currentEditor != null) {
|
||||
writer.write(DIRTY + ' ' + entry.key + '\n');
|
||||
} else {
|
||||
writer.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (journalFile.exists()) {
|
||||
renameTo(journalFile, journalFileBackup, true);
|
||||
}
|
||||
renameTo(journalFileTmp, journalFile, false);
|
||||
journalFileBackup.delete();
|
||||
|
||||
journalWriter = new BufferedWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(journalFile, true), Util.US_ASCII));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if it contains the key
|
||||
*/
|
||||
public synchronized boolean contain(String key) {
|
||||
checkNotClosed();
|
||||
validateKey(key);
|
||||
Entry entry = lruEntries.get(key);
|
||||
return entry != null && entry.readable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a snapshot of the entry named {@code key}, or null if it doesn't
|
||||
* exist is not currently readable. If a value is returned, it is moved to
|
||||
* the head of the LRU queue.
|
||||
*/
|
||||
public synchronized Snapshot get(String key) throws IOException {
|
||||
checkNotClosed();
|
||||
validateKey(key);
|
||||
Entry entry = lruEntries.get(key);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!entry.readable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Open all streams eagerly to guarantee that we see a single published
|
||||
// snapshot. If we opened streams lazily then the streams could come
|
||||
// from different edits.
|
||||
InputStream[] ins = new InputStream[valueCount];
|
||||
try {
|
||||
for (int i = 0; i < valueCount; i++) {
|
||||
ins[i] = new FileInputStream(entry.getCleanFile(i));
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
// A file must have been deleted manually!
|
||||
for (int i = 0; i < valueCount; i++) {
|
||||
if (ins[i] != null) {
|
||||
Util.closeQuietly(ins[i]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
redundantOpCount++;
|
||||
journalWriter.append(READ + ' ').append(key).append(String.valueOf('\n'));
|
||||
if (journalRebuildRequired()) {
|
||||
executorService.submit(cleanupCallable);
|
||||
}
|
||||
|
||||
return new Snapshot(key, entry.sequenceNumber, ins, entry.lengths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an editor for the entry named {@code key}, or null if another
|
||||
* edit is in progress.
|
||||
*/
|
||||
public Editor edit(String key) throws IOException {
|
||||
return edit(key, ANY_SEQUENCE_NUMBER);
|
||||
}
|
||||
|
||||
private synchronized Editor edit(String key, long expectedSequenceNumber) throws IOException {
|
||||
checkNotClosed();
|
||||
validateKey(key);
|
||||
Entry entry = lruEntries.get(key);
|
||||
if (expectedSequenceNumber != ANY_SEQUENCE_NUMBER && (entry == null
|
||||
|| entry.sequenceNumber != expectedSequenceNumber)) {
|
||||
return null; // Snapshot is stale.
|
||||
}
|
||||
if (entry == null) {
|
||||
entry = new Entry(key);
|
||||
lruEntries.put(key, entry);
|
||||
} else if (entry.currentEditor != null) {
|
||||
return null; // Another edit is in progress.
|
||||
}
|
||||
|
||||
Editor editor = new Editor(entry);
|
||||
entry.currentEditor = editor;
|
||||
|
||||
// Flush the journal before creating files to prevent file leaks.
|
||||
journalWriter.write(DIRTY + ' ' + key + '\n');
|
||||
journalWriter.flush();
|
||||
return editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory where this cache stores its data.
|
||||
*/
|
||||
public File getDirectory() {
|
||||
return directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of bytes that this cache should use to store
|
||||
* its data.
|
||||
*/
|
||||
public synchronized long getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the maximum number of bytes the cache can store and queues a job
|
||||
* to trim the existing store, if necessary.
|
||||
*/
|
||||
public synchronized void setMaxSize(long maxSize) {
|
||||
this.maxSize = maxSize;
|
||||
executorService.submit(cleanupCallable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes currently being used to store the values in
|
||||
* this cache. This may be greater than the max size if a background
|
||||
* deletion is pending.
|
||||
*/
|
||||
public synchronized long size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
private synchronized void completeEdit(Editor editor, boolean success) throws IOException {
|
||||
Entry entry = editor.entry;
|
||||
if (entry.currentEditor != editor) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
// If this edit is creating the entry for the first time, every index must have a value.
|
||||
if (success && !entry.readable) {
|
||||
for (int i = 0; i < valueCount; i++) {
|
||||
if (!editor.written[i]) {
|
||||
editor.abort();
|
||||
throw new IllegalStateException("Newly created entry didn't create value for index " + i);
|
||||
}
|
||||
if (!entry.getDirtyFile(i).exists()) {
|
||||
editor.abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < valueCount; i++) {
|
||||
File dirty = entry.getDirtyFile(i);
|
||||
if (success) {
|
||||
if (dirty.exists()) {
|
||||
File clean = entry.getCleanFile(i);
|
||||
dirty.renameTo(clean);
|
||||
long oldLength = entry.lengths[i];
|
||||
long newLength = clean.length();
|
||||
entry.lengths[i] = newLength;
|
||||
size = size - oldLength + newLength;
|
||||
}
|
||||
} else {
|
||||
deleteIfExists(dirty);
|
||||
}
|
||||
}
|
||||
|
||||
redundantOpCount++;
|
||||
entry.currentEditor = null;
|
||||
if (entry.readable | success) {
|
||||
entry.readable = true;
|
||||
journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
|
||||
if (success) {
|
||||
entry.sequenceNumber = nextSequenceNumber++;
|
||||
}
|
||||
} else {
|
||||
lruEntries.remove(entry.key);
|
||||
journalWriter.write(REMOVE + ' ' + entry.key + '\n');
|
||||
}
|
||||
journalWriter.flush();
|
||||
|
||||
if (size > maxSize || journalRebuildRequired()) {
|
||||
executorService.submit(cleanupCallable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We only rebuild the journal when it will halve the size of the journal
|
||||
* and eliminate at least 2000 ops.
|
||||
*/
|
||||
private boolean journalRebuildRequired() {
|
||||
final int redundantOpCompactThreshold = 2000;
|
||||
return redundantOpCount >= redundantOpCompactThreshold //
|
||||
&& redundantOpCount >= lruEntries.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the entry for {@code key} if it exists and can be removed. Entries
|
||||
* actively being edited cannot be removed.
|
||||
*
|
||||
* @return true if an entry was removed.
|
||||
*/
|
||||
public synchronized boolean remove(String key) throws IOException {
|
||||
checkNotClosed();
|
||||
validateKey(key);
|
||||
Entry entry = lruEntries.get(key);
|
||||
if (entry == null || entry.currentEditor != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < valueCount; i++) {
|
||||
File file = entry.getCleanFile(i);
|
||||
if (file.exists() && !file.delete()) {
|
||||
throw new IOException("failed to delete " + file);
|
||||
}
|
||||
size -= entry.lengths[i];
|
||||
entry.lengths[i] = 0;
|
||||
}
|
||||
|
||||
redundantOpCount++;
|
||||
journalWriter.append(REMOVE + ' ').append(key).append(String.valueOf('\n'));
|
||||
lruEntries.remove(key);
|
||||
|
||||
if (journalRebuildRequired()) {
|
||||
executorService.submit(cleanupCallable);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this cache has been closed.
|
||||
*/
|
||||
public synchronized boolean isClosed() {
|
||||
return journalWriter == null;
|
||||
}
|
||||
|
||||
private void checkNotClosed() {
|
||||
if (journalWriter == null) {
|
||||
throw new IllegalStateException("cache is closed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force buffered operations to the filesystem.
|
||||
*/
|
||||
public synchronized void flush() throws IOException {
|
||||
checkNotClosed();
|
||||
trimToSize();
|
||||
journalWriter.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this cache. Stored values will remain on the filesystem.
|
||||
*/
|
||||
public synchronized void close() throws IOException {
|
||||
if (journalWriter == null) {
|
||||
return; // Already closed.
|
||||
}
|
||||
for (Entry entry : new ArrayList<>(lruEntries.values())) {
|
||||
if (entry.currentEditor != null) {
|
||||
entry.currentEditor.abort();
|
||||
}
|
||||
}
|
||||
trimToSize();
|
||||
journalWriter.close();
|
||||
journalWriter = null;
|
||||
}
|
||||
|
||||
private void trimToSize() throws IOException {
|
||||
while (size > maxSize) {
|
||||
Map.Entry<String, Entry> toEvict = lruEntries.entrySet().iterator().next();
|
||||
remove(toEvict.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the cache and deletes all of its stored values. This will delete
|
||||
* all files in the cache directory including files that weren't created by
|
||||
* the cache.
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
close();
|
||||
Util.deleteContents(directory);
|
||||
}
|
||||
|
||||
private void validateKey(String key) {
|
||||
Matcher matcher = LEGAL_KEY_PATTERN.matcher(key);
|
||||
if (!matcher.matches()) {
|
||||
throw new IllegalArgumentException("keys must match regex "
|
||||
+ STRING_KEY_PATTERN + ": \"" + key + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A snapshot of the values for an entry.
|
||||
*/
|
||||
public final class Snapshot implements Closeable {
|
||||
private final String key;
|
||||
private final long sequenceNumber;
|
||||
private final InputStream[] ins;
|
||||
private final long[] lengths;
|
||||
|
||||
private Snapshot(String key, long sequenceNumber, InputStream[] ins, long[] lengths) {
|
||||
this.key = key;
|
||||
this.sequenceNumber = sequenceNumber;
|
||||
this.ins = ins;
|
||||
this.lengths = lengths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an editor for this snapshot's entry, or null if either the
|
||||
* entry has changed since this snapshot was created or if another edit
|
||||
* is in progress.
|
||||
*/
|
||||
public Editor edit() throws IOException {
|
||||
return DiskLruCache.this.edit(key, sequenceNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unbuffered stream with the value for {@code index}.
|
||||
*/
|
||||
public InputStream getInputStream(int index) {
|
||||
return ins[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string value for {@code index}.
|
||||
*/
|
||||
public String getString(int index) throws IOException {
|
||||
return inputStreamToString(getInputStream(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the byte length of the value for {@code index}.
|
||||
*/
|
||||
public long getLength(int index) {
|
||||
return lengths[index];
|
||||
}
|
||||
|
||||
public void close() {
|
||||
for (InputStream in : ins) {
|
||||
Util.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the values for an entry.
|
||||
*/
|
||||
public final class Editor {
|
||||
private final Entry entry;
|
||||
private final boolean[] written;
|
||||
private boolean hasErrors;
|
||||
private boolean committed;
|
||||
|
||||
private Editor(Entry entry) {
|
||||
this.entry = entry;
|
||||
this.written = (entry.readable) ? null : new boolean[valueCount];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unbuffered input stream to read the last committed value,
|
||||
* or null if no value has been committed.
|
||||
*/
|
||||
public InputStream newInputStream(int index) {
|
||||
synchronized (DiskLruCache.this) {
|
||||
if (entry.currentEditor != this) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (!entry.readable) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new FileInputStream(entry.getCleanFile(index));
|
||||
} catch (FileNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last committed value as a string, or null if no value
|
||||
* has been committed.
|
||||
*/
|
||||
public String getString(int index) throws IOException {
|
||||
InputStream in = newInputStream(index);
|
||||
return in != null ? inputStreamToString(in) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new unbuffered output stream to write the value at
|
||||
* {@code index}. If the underlying output stream encounters errors
|
||||
* when writing to the filesystem, this edit will be aborted when
|
||||
* {@link #commit} is called. The returned output stream does not throw
|
||||
* IOExceptions.
|
||||
*/
|
||||
public OutputStream newOutputStream(int index) throws IOException {
|
||||
if (index < 0 || index >= valueCount) {
|
||||
throw new IllegalArgumentException("Expected index " + index + " to "
|
||||
+ "be greater than 0 and less than the maximum value count "
|
||||
+ "of " + valueCount);
|
||||
}
|
||||
synchronized (DiskLruCache.this) {
|
||||
if (entry.currentEditor != this) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (!entry.readable) {
|
||||
written[index] = true;
|
||||
}
|
||||
File dirtyFile = entry.getDirtyFile(index);
|
||||
FileOutputStream outputStream;
|
||||
try {
|
||||
outputStream = new FileOutputStream(dirtyFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
// Attempt to recreate the cache directory.
|
||||
directory.mkdirs();
|
||||
try {
|
||||
outputStream = new FileOutputStream(dirtyFile);
|
||||
} catch (FileNotFoundException e2) {
|
||||
// We are unable to recover. Silently eat the writes.
|
||||
return NULL_OUTPUT_STREAM;
|
||||
}
|
||||
}
|
||||
return new FaultHidingOutputStream(outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value at {@code index} to {@code value}.
|
||||
*/
|
||||
public void set(int index, String value) throws IOException {
|
||||
Writer writer = null;
|
||||
try {
|
||||
writer = new OutputStreamWriter(newOutputStream(index), Util.UTF_8);
|
||||
writer.write(value);
|
||||
} finally {
|
||||
Util.closeQuietly(writer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits this edit so it is visible to readers. This releases the
|
||||
* edit lock so another edit may be started on the same key.
|
||||
*/
|
||||
public void commit() throws IOException {
|
||||
if (hasErrors) {
|
||||
completeEdit(this, false);
|
||||
remove(entry.key); // The previous entry is stale.
|
||||
} else {
|
||||
completeEdit(this, true);
|
||||
}
|
||||
committed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Aborts this edit. This releases the edit lock so another edit may be
|
||||
* started on the same key.
|
||||
*/
|
||||
public void abort() throws IOException {
|
||||
completeEdit(this, false);
|
||||
}
|
||||
|
||||
public void abortUnlessCommitted() {
|
||||
if (!committed) {
|
||||
try {
|
||||
abort();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FaultHidingOutputStream extends FilterOutputStream {
|
||||
private FaultHidingOutputStream(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int oneByte) {
|
||||
try {
|
||||
out.write(oneByte);
|
||||
} catch (IOException e) {
|
||||
hasErrors = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] buffer, int offset, int length) {
|
||||
try {
|
||||
out.write(buffer, offset, length);
|
||||
} catch (IOException e) {
|
||||
hasErrors = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
hasErrors = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
try {
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
hasErrors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class Entry {
|
||||
private final String key;
|
||||
|
||||
/**
|
||||
* Lengths of this entry's files.
|
||||
*/
|
||||
private final long[] lengths;
|
||||
|
||||
/**
|
||||
* True if this entry has ever been published.
|
||||
*/
|
||||
private boolean readable;
|
||||
|
||||
/**
|
||||
* The ongoing edit or null if this entry is not being edited.
|
||||
*/
|
||||
private Editor currentEditor;
|
||||
|
||||
/**
|
||||
* The sequence number of the most recently committed edit to this entry.
|
||||
*/
|
||||
private long sequenceNumber;
|
||||
|
||||
private Entry(String key) {
|
||||
this.key = key;
|
||||
this.lengths = new long[valueCount];
|
||||
}
|
||||
|
||||
public String getLengths() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (long size : lengths) {
|
||||
result.append(' ').append(size);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lengths using decimal numbers like "10123".
|
||||
*/
|
||||
private void setLengths(String[] strings) throws IOException {
|
||||
if (strings.length != valueCount) {
|
||||
throw invalidLengths(strings);
|
||||
}
|
||||
|
||||
try {
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
lengths[i] = Long.parseLong(strings[i]);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw invalidLengths(strings);
|
||||
}
|
||||
}
|
||||
|
||||
private IOException invalidLengths(String[] strings) throws IOException {
|
||||
throw new IOException("unexpected journal line: " + java.util.Arrays.toString(strings));
|
||||
}
|
||||
|
||||
public File getCleanFile(int i) {
|
||||
return new File(directory, key + "." + i);
|
||||
}
|
||||
|
||||
public File getDirtyFile(int i) {
|
||||
return new File(directory, key + "." + i + ".tmp");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,522 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015-2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.beerbelly;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.hippo.streampipe.InputStreamPipe;
|
||||
import com.hippo.streampipe.OutputStreamPipe;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class SimpleDiskCache {
|
||||
|
||||
private static final String TAG = SimpleDiskCache.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Disk cache is free
|
||||
*/
|
||||
private static final int STATE_DISK_CACHE_NONE = 0;
|
||||
|
||||
/**
|
||||
* Disk cache is flushing or clearing
|
||||
*/
|
||||
private static final int STATE_DISK_CACHE_IN_USE = 1;
|
||||
|
||||
/**
|
||||
* Disk cache is reading or writing
|
||||
*/
|
||||
private static final int STATE_DISK_CACHE_BUSY = 2;
|
||||
|
||||
private final File mCacheDir;
|
||||
private final int mSize;
|
||||
@NonNull
|
||||
private final Map<String, CounterLock> mLockMap = new HashMap<>();
|
||||
@NonNull
|
||||
private final LockPool mLockPool = new LockPool();
|
||||
private int mDiskCacheState;
|
||||
@Nullable
|
||||
private DiskLruCache mDiskLruCache;
|
||||
|
||||
public SimpleDiskCache(File cacheDir, int size) {
|
||||
mCacheDir = cacheDir;
|
||||
mSize = size;
|
||||
|
||||
try {
|
||||
init();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A hashing method that changes a string (like a URL) into a hash suitable
|
||||
* for using as a disk filename.
|
||||
*
|
||||
* @param key The key used to store the file
|
||||
*/
|
||||
private static String hashKeyForDisk(final String key) {
|
||||
String cacheKey;
|
||||
try {
|
||||
final MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
digest.update(key.getBytes());
|
||||
cacheKey = bytesToHexString(digest.digest());
|
||||
} catch (final NoSuchAlgorithmException e) {
|
||||
cacheKey = String.valueOf(key.hashCode());
|
||||
}
|
||||
return cacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* http://stackoverflow.com/questions/332079
|
||||
*
|
||||
* @param bytes The bytes to convert.
|
||||
* @return A {@link String} converted from the bytes of a hashable key used
|
||||
* to store a filename on the disk, to hex digits.
|
||||
*/
|
||||
private static String bytesToHexString(final byte[] bytes) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (final byte b : bytes) {
|
||||
final String hex = Integer.toHexString(0xFF & b);
|
||||
if (hex.length() == 1) {
|
||||
builder.append('0');
|
||||
}
|
||||
builder.append(hex);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public synchronized boolean isValid() {
|
||||
return mDiskLruCache != null;
|
||||
}
|
||||
|
||||
private synchronized void init() throws IOException {
|
||||
if (!isValid()) {
|
||||
mDiskLruCache = DiskLruCache.open(mCacheDir, 1, 1, mSize);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized long size() {
|
||||
if (null != mDiskLruCache) {
|
||||
return mDiskLruCache.size();
|
||||
} else {
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void flush() {
|
||||
// Wait for cache available
|
||||
while (mDiskCacheState != STATE_DISK_CACHE_NONE) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mDiskCacheState = STATE_DISK_CACHE_BUSY;
|
||||
|
||||
if (null != mDiskLruCache) {
|
||||
try {
|
||||
mDiskLruCache.flush();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "SimpleDiskCache flush", e);
|
||||
}
|
||||
}
|
||||
|
||||
mDiskCacheState = STATE_DISK_CACHE_NONE;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
public synchronized boolean clear() {
|
||||
boolean result = true;
|
||||
if (null == mDiskLruCache) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for cache available
|
||||
while (mDiskCacheState != STATE_DISK_CACHE_NONE) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mDiskCacheState = STATE_DISK_CACHE_BUSY;
|
||||
|
||||
try {
|
||||
mDiskLruCache.delete();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "SimpleDiskCache clearCache", e);
|
||||
}
|
||||
mDiskLruCache = null;
|
||||
try {
|
||||
init();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "SimpleDiskCache init", e);
|
||||
result = false;
|
||||
}
|
||||
|
||||
mDiskCacheState = STATE_DISK_CACHE_NONE;
|
||||
notifyAll();
|
||||
return result;
|
||||
}
|
||||
|
||||
private synchronized CounterLock obtainLock(String key) {
|
||||
// Wait for clear over
|
||||
while (mDiskCacheState == STATE_DISK_CACHE_BUSY) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
// Empty
|
||||
}
|
||||
}
|
||||
mDiskCacheState = STATE_DISK_CACHE_IN_USE;
|
||||
|
||||
// Get lock from key
|
||||
CounterLock lock;
|
||||
lock = mLockMap.get(key);
|
||||
if (lock == null) {
|
||||
lock = mLockPool.get();
|
||||
mLockMap.put(key, lock);
|
||||
}
|
||||
lock.obtain();
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
private synchronized void releaseLock(String key, CounterLock lock) {
|
||||
lock.release();
|
||||
if (lock.isFree()) {
|
||||
mLockMap.remove(key);
|
||||
mLockPool.push(lock);
|
||||
}
|
||||
|
||||
if (mLockMap.isEmpty()) {
|
||||
mDiskCacheState = STATE_DISK_CACHE_NONE;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contain(@NonNull String key) {
|
||||
String diskKey = hashKeyForDisk(key);
|
||||
CounterLock lock = obtainLock(diskKey);
|
||||
if (null == mDiskLruCache) {
|
||||
releaseLock(diskKey, lock);
|
||||
return false;
|
||||
}
|
||||
lock.readLock().lock();
|
||||
|
||||
boolean result = mDiskLruCache.contain(diskKey);
|
||||
|
||||
lock.readLock().unlock();
|
||||
releaseLock(diskKey, lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean remove(@NonNull String key) {
|
||||
String diskKey = hashKeyForDisk(key);
|
||||
CounterLock lock = obtainLock(diskKey);
|
||||
if (null == mDiskLruCache) {
|
||||
releaseLock(diskKey, lock);
|
||||
return false;
|
||||
}
|
||||
lock.writeLock().lock();
|
||||
|
||||
boolean result;
|
||||
try {
|
||||
result = mDiskLruCache.remove(diskKey);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
result = false;
|
||||
}
|
||||
|
||||
lock.writeLock().unlock();
|
||||
releaseLock(diskKey, lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean put(@NonNull String key, @NonNull InputStream is) {
|
||||
String diskKey = hashKeyForDisk(key);
|
||||
CounterLock lock = obtainLock(diskKey);
|
||||
if (null == mDiskLruCache) {
|
||||
releaseLock(diskKey, lock);
|
||||
return false;
|
||||
}
|
||||
lock.writeLock().lock();
|
||||
|
||||
boolean result = false;
|
||||
if (isValid()) {
|
||||
result = putToDisk(diskKey, is);
|
||||
}
|
||||
|
||||
lock.writeLock().unlock();
|
||||
releaseLock(diskKey, lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean putToDisk(String key, InputStream is) {
|
||||
DiskLruCache.Editor editor = null;
|
||||
OutputStream os = null;
|
||||
boolean completeEdit = false;
|
||||
try {
|
||||
//noinspection ConstantConditions
|
||||
editor = mDiskLruCache.edit(key);
|
||||
if (editor == null) {
|
||||
// The editor is in progress
|
||||
return false;
|
||||
}
|
||||
|
||||
os = editor.newOutputStream(0);
|
||||
if (os != null) {
|
||||
Util.copy(is, os);
|
||||
completeEdit = true;
|
||||
editor.commit();
|
||||
return true;
|
||||
} else {
|
||||
// Can't get OutputStream
|
||||
completeEdit = true;
|
||||
editor.abort();
|
||||
return false;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Util.closeQuietly(os);
|
||||
try {
|
||||
if (!completeEdit && editor != null) {
|
||||
editor.abort();
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key the key of the target
|
||||
* @return the InputStreamPipe, <code>null</code> for missing
|
||||
*/
|
||||
@Nullable
|
||||
public InputStreamPipe getInputStreamPipe(@NonNull String key) {
|
||||
if (contain(key)) {
|
||||
String diskKey = hashKeyForDisk(key);
|
||||
return new CacheInputStreamPipe(diskKey);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public OutputStreamPipe getOutputStreamPipe(@NonNull String key) {
|
||||
String diskKey = hashKeyForDisk(key);
|
||||
return new CacheOutputStreamPipe(diskKey);
|
||||
}
|
||||
|
||||
private class CacheInputStreamPipe implements InputStreamPipe {
|
||||
|
||||
private final String mKey;
|
||||
private CounterLock mLock;
|
||||
private DiskLruCache.Snapshot mCurrentSnapshot;
|
||||
|
||||
private CacheInputStreamPipe(String key) {
|
||||
mKey = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void obtain() {
|
||||
if (mLock == null) {
|
||||
mLock = obtainLock(mKey);
|
||||
mLock.readLock().lock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
if (mCurrentSnapshot != null) {
|
||||
throw new IllegalStateException("Please close it first");
|
||||
}
|
||||
|
||||
if (mLock != null) {
|
||||
mLock.readLock().unlock();
|
||||
releaseLock(mKey, mLock);
|
||||
mLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull
|
||||
InputStream open() throws IOException {
|
||||
if (mLock == null) {
|
||||
throw new IllegalStateException("Please obtain it first");
|
||||
}
|
||||
if (mCurrentSnapshot != null) {
|
||||
throw new IllegalStateException("Please close it before reopen");
|
||||
}
|
||||
if (null == mDiskLruCache) {
|
||||
throw new IOException("Can't find disk lru cache");
|
||||
}
|
||||
|
||||
DiskLruCache.Snapshot snapshot;
|
||||
snapshot = mDiskLruCache.get(mKey);
|
||||
if (snapshot == null) {
|
||||
throw new IOException("Miss the key " + mKey);
|
||||
}
|
||||
mCurrentSnapshot = snapshot;
|
||||
return snapshot.getInputStream(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
Util.closeQuietly(mCurrentSnapshot);
|
||||
mCurrentSnapshot = null;
|
||||
}
|
||||
}
|
||||
|
||||
private class CacheOutputStreamPipe implements OutputStreamPipe {
|
||||
|
||||
private final String mKey;
|
||||
private CounterLock mLock;
|
||||
private DiskLruCache.Editor mCurrentEditor;
|
||||
|
||||
private CacheOutputStreamPipe(String key) {
|
||||
mKey = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void obtain() {
|
||||
if (mLock == null) {
|
||||
mLock = obtainLock(mKey);
|
||||
mLock.writeLock().lock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
if (mCurrentEditor != null) {
|
||||
throw new IllegalStateException("Please close it first");
|
||||
}
|
||||
|
||||
if (mLock != null) {
|
||||
mLock.writeLock().unlock();
|
||||
releaseLock(mKey, mLock);
|
||||
mLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull
|
||||
OutputStream open() throws IOException {
|
||||
if (mLock == null) {
|
||||
throw new IllegalStateException("Please obtain it first");
|
||||
}
|
||||
if (mCurrentEditor != null) {
|
||||
throw new IllegalStateException("Please close it before reopen");
|
||||
}
|
||||
if (null == mDiskLruCache) {
|
||||
throw new IOException("Can't find disk lru cache");
|
||||
}
|
||||
|
||||
DiskLruCache.Editor editor = mDiskLruCache.edit(mKey);
|
||||
if (editor == null) {
|
||||
throw new IOException("Miss the key " + mKey);
|
||||
}
|
||||
|
||||
OutputStream os;
|
||||
try {
|
||||
os = editor.newOutputStream(0);
|
||||
mCurrentEditor = editor;
|
||||
return os;
|
||||
} catch (IOException e) {
|
||||
// Get trouble
|
||||
try {
|
||||
editor.abort();
|
||||
} catch (IOException ex) {
|
||||
// Ignore
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (mCurrentEditor != null) {
|
||||
try {
|
||||
mCurrentEditor.commit();
|
||||
} catch (IOException e) {
|
||||
// Empty
|
||||
}
|
||||
mCurrentEditor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CounterLock extends ReentrantReadWriteLock {
|
||||
|
||||
private int mCount;
|
||||
|
||||
public boolean isFree() {
|
||||
return mCount == 0;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if (--mCount < 0) {
|
||||
throw new IllegalStateException("Release time is more than occupy time");
|
||||
}
|
||||
}
|
||||
|
||||
public void obtain() {
|
||||
++mCount;
|
||||
}
|
||||
}
|
||||
|
||||
private class LockPool {
|
||||
|
||||
private static final int MAX_SIZE = 10;
|
||||
|
||||
private final CounterLock[] mArray = new CounterLock[MAX_SIZE];
|
||||
private final int mMaxSize = MAX_SIZE;
|
||||
private int mSize;
|
||||
|
||||
public void push(CounterLock lock) {
|
||||
if (lock != null && mSize < mMaxSize) {
|
||||
mArray[mSize++] = lock;
|
||||
}
|
||||
}
|
||||
|
||||
public CounterLock get() {
|
||||
if (mSize > 0) {
|
||||
CounterLock lock = mArray[--mSize];
|
||||
mArray[mSize] = null;
|
||||
return lock;
|
||||
} else {
|
||||
return new CounterLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.beerbelly;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Buffers input from an {@link InputStream} for reading lines.
|
||||
*
|
||||
* <p>This class is used for buffered reading of lines. For purposes of this class, a line ends
|
||||
* with "\n" or "\r\n". End of input is reported by throwing {@code EOFException}. Unterminated
|
||||
* line at end of input is invalid and will be ignored, the caller may use {@code
|
||||
* hasUnterminatedLine()} to detect it after catching the {@code EOFException}.
|
||||
*
|
||||
* <p>This class is intended for reading input that strictly consists of lines, such as line-based
|
||||
* cache entries or cache journal. Unlike the {@link java.io.BufferedReader} which in conjunction
|
||||
* with {@link java.io.InputStreamReader} provides similar functionality, this class uses different
|
||||
* end-of-input reporting and a more restrictive definition of a line.
|
||||
*
|
||||
* <p>This class supports only charsets that encode '\r' and '\n' as a single byte with value 13
|
||||
* and 10, respectively, and the representation of no other character contains these values.
|
||||
* We currently check in constructor that the charset is one of US-ASCII, UTF-8 and ISO-8859-1.
|
||||
* The default charset is US_ASCII.
|
||||
*/
|
||||
class StrictLineReader implements Closeable {
|
||||
private static final byte CR = (byte) '\r';
|
||||
private static final byte LF = (byte) '\n';
|
||||
|
||||
private final InputStream in;
|
||||
private final Charset charset;
|
||||
|
||||
/*
|
||||
* Buffered data is stored in {@code buf}. As long as no exception occurs, 0 <= pos <= end
|
||||
* and the data in the range [pos, end) is buffered for reading. At end of input, if there is
|
||||
* an unterminated line, we set end == -1, otherwise end == pos. If the underlying
|
||||
* {@code InputStream} throws an {@code IOException}, end may remain as either pos or -1.
|
||||
*/
|
||||
private byte[] buf;
|
||||
private int pos;
|
||||
private int end;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LineReader} with the specified charset and the default capacity.
|
||||
*
|
||||
* @param in the {@code InputStream} to read data from.
|
||||
* @param charset the charset used to decode data. Only US-ASCII, UTF-8 and ISO-8859-1 are
|
||||
* supported.
|
||||
* @throws NullPointerException if {@code in} or {@code charset} is null.
|
||||
* @throws IllegalArgumentException if the specified charset is not supported.
|
||||
*/
|
||||
public StrictLineReader(InputStream in, Charset charset) {
|
||||
this(in, 8192, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LineReader} with the specified capacity and charset.
|
||||
*
|
||||
* @param in the {@code InputStream} to read data from.
|
||||
* @param capacity the capacity of the buffer.
|
||||
* @param charset the charset used to decode data. Only US-ASCII, UTF-8 and ISO-8859-1 are
|
||||
* supported.
|
||||
* @throws NullPointerException if {@code in} or {@code charset} is null.
|
||||
* @throws IllegalArgumentException if {@code capacity} is negative or zero
|
||||
* or the specified charset is not supported.
|
||||
*/
|
||||
public StrictLineReader(InputStream in, int capacity, Charset charset) {
|
||||
if (in == null || charset == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (capacity < 0) {
|
||||
throw new IllegalArgumentException("capacity <= 0");
|
||||
}
|
||||
if (!(charset.equals(Util.US_ASCII))) {
|
||||
throw new IllegalArgumentException("Unsupported encoding");
|
||||
}
|
||||
|
||||
this.in = in;
|
||||
this.charset = charset;
|
||||
buf = new byte[capacity];
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the reader by closing the underlying {@code InputStream} and
|
||||
* marking this reader as closed.
|
||||
*
|
||||
* @throws IOException for errors when closing the underlying {@code InputStream}.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
synchronized (in) {
|
||||
if (buf != null) {
|
||||
buf = null;
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next line. A line ends with {@code "\n"} or {@code "\r\n"},
|
||||
* this end of line marker is not included in the result.
|
||||
*
|
||||
* @return the next line from the input.
|
||||
* @throws IOException for underlying {@code InputStream} errors.
|
||||
* @throws EOFException for the end of source stream.
|
||||
*/
|
||||
public String readLine() throws IOException {
|
||||
synchronized (in) {
|
||||
if (buf == null) {
|
||||
throw new IOException("LineReader is closed");
|
||||
}
|
||||
|
||||
// Read more data if we are at the end of the buffered data.
|
||||
// Though it's an error to read after an exception, we will let {@code fillBuf()}
|
||||
// throw again if that happens; thus we need to handle end == -1 as well as end == pos.
|
||||
if (pos >= end) {
|
||||
fillBuf();
|
||||
}
|
||||
// Try to find LF in the buffered data and return the line if successful.
|
||||
for (int i = pos; i != end; ++i) {
|
||||
if (buf[i] == LF) {
|
||||
int lineEnd = (i != pos && buf[i - 1] == CR) ? i - 1 : i;
|
||||
String res = new String(buf, pos, lineEnd - pos, charset);
|
||||
pos = i + 1;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// Let's anticipate up to 80 characters on top of those already read.
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(end - pos + 80) {
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
int length = (count > 0 && buf[count - 1] == CR) ? count - 1 : count;
|
||||
return new String(buf, 0, length, charset);
|
||||
}
|
||||
};
|
||||
|
||||
while (true) {
|
||||
out.write(buf, pos, end - pos);
|
||||
// Mark unterminated line in case fillBuf throws EOFException or IOException.
|
||||
end = -1;
|
||||
fillBuf();
|
||||
// Try to find LF in the buffered data and return the line if successful.
|
||||
for (int i = pos; i != end; ++i) {
|
||||
if (buf[i] == LF) {
|
||||
if (i != pos) {
|
||||
out.write(buf, pos, i - pos);
|
||||
}
|
||||
pos = i + 1;
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasUnterminatedLine() {
|
||||
return end == -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads new input data into the buffer. Call only with pos == end or end == -1,
|
||||
* depending on the desired outcome if the function throws.
|
||||
*/
|
||||
private void fillBuf() throws IOException {
|
||||
int result = in.read(buf, 0, buf.length);
|
||||
if (result == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
pos = 0;
|
||||
end = result;
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.beerbelly;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Junk drawer of utility methods.
|
||||
*/
|
||||
final class Util {
|
||||
static final Charset US_ASCII = StandardCharsets.US_ASCII;
|
||||
static final Charset UTF_8 = StandardCharsets.UTF_8;
|
||||
private static final int EOF = -1;
|
||||
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
|
||||
|
||||
private Util() {
|
||||
}
|
||||
|
||||
static String readFully(Reader reader) throws IOException {
|
||||
try (reader) {
|
||||
StringWriter writer = new StringWriter();
|
||||
char[] buffer = new char[1024];
|
||||
int count;
|
||||
while ((count = reader.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, count);
|
||||
}
|
||||
return writer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the contents of {@code dir}. Throws an IOException if any file
|
||||
* could not be deleted, or if {@code dir} is not a readable directory.
|
||||
*/
|
||||
static void deleteContents(File dir) throws IOException {
|
||||
File[] files = dir.listFiles();
|
||||
if (files == null) {
|
||||
throw new IOException("not a readable directory: " + dir);
|
||||
}
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
deleteContents(file);
|
||||
}
|
||||
if (!file.delete()) {
|
||||
throw new IOException("failed to delete file: " + file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void closeQuietly(/*Auto*/Closeable closeable) {
|
||||
if (closeable != null) {
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (RuntimeException rethrown) {
|
||||
throw rethrown;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy bytes from an <code>InputStream</code> to an
|
||||
* <code>OutputStream</code>.
|
||||
*
|
||||
* @param input the InputStream
|
||||
* @param output the OutputStream
|
||||
* @return the number of bytes copied
|
||||
*/
|
||||
public static long copy(InputStream input, OutputStream output)
|
||||
throws IOException {
|
||||
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||
long count = 0;
|
||||
int n;
|
||||
while (EOF != (n = input.read(buffer))) {
|
||||
output.write(buffer, 0, n);
|
||||
count += n;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.hippo.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import android.util.SparseArray
|
||||
|
||||
class MSQLiteBuilder {
|
||||
companion object {
|
||||
const val COLUMN_ID = "_id"
|
||||
private val JAVA_TYPE_TO_SQLITE_TYPE: MutableMap<Class<*>?, String> = HashMap()
|
||||
private fun javaTypeToSQLiteType(clazz: Class<*>?): String {
|
||||
return JAVA_TYPE_TO_SQLITE_TYPE[clazz]
|
||||
?: throw IllegalStateException("Unknown type: $clazz")
|
||||
}
|
||||
|
||||
init {
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Boolean::class.javaPrimitiveType] =
|
||||
"INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Byte::class.javaPrimitiveType] =
|
||||
"INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Short::class.javaPrimitiveType] =
|
||||
"INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Int::class.javaPrimitiveType] = "INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Long::class.javaPrimitiveType] =
|
||||
"INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Float::class.javaPrimitiveType] =
|
||||
"REAL NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Double::class.javaPrimitiveType] = "REAL NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[String::class.java] = "TEXT"
|
||||
}
|
||||
}
|
||||
|
||||
private val statementsMap = SparseArray<List<String>?>()
|
||||
private var version = 0
|
||||
private var statements: MutableList<String>? = null
|
||||
|
||||
/**
|
||||
* Bump database version.
|
||||
*/
|
||||
fun version(version: Int): MSQLiteBuilder {
|
||||
check(version > this.version) {
|
||||
("New version must be bigger than current version. "
|
||||
+ "current version: " + this.version + ", new version: " + version + ".")
|
||||
}
|
||||
this.version = version
|
||||
statements = ArrayList()
|
||||
statementsMap.put(version, statements)
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* Creates a table.
|
||||
*/
|
||||
/**
|
||||
* Creates a table with int [.COLUMN_ID] primary key.
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun createTable(
|
||||
table: String,
|
||||
column: String = COLUMN_ID,
|
||||
clazz: Class<*>? = Int::class.javaPrimitiveType
|
||||
): MSQLiteBuilder {
|
||||
return statement("CREATE TABLE " + table + " (" + column + " " + javaTypeToSQLiteType(clazz) + " PRIMARY KEY);")
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a table.
|
||||
*/
|
||||
fun dropTable(table: String): MSQLiteBuilder {
|
||||
return statement("DROP TABLE $table;")
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a column to the table.
|
||||
*/
|
||||
fun insertColumn(table: String, column: String, clazz: Class<*>?): MSQLiteBuilder {
|
||||
return statement(
|
||||
"ALTER TABLE $table ADD COLUMN $column " + javaTypeToSQLiteType(
|
||||
clazz
|
||||
) + ";"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a statement.
|
||||
*/
|
||||
fun statement(statement: String): MSQLiteBuilder {
|
||||
check(!(version == 0 || statements == null)) { "Call version() first!" }
|
||||
statements!!.add(statement)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a SQLiteOpenHelper from it.
|
||||
*/
|
||||
fun build(context: Context?, name: String?, version: Int): SQLiteOpenHelper {
|
||||
return MSQLiteOpenHelper(context, name, version, this)
|
||||
}
|
||||
|
||||
fun getStatements(oldVersion: Int, newVersion: Int): List<String> {
|
||||
val result: MutableList<String> = ArrayList()
|
||||
for (i in oldVersion + 1..newVersion) {
|
||||
val list = statementsMap[i]
|
||||
if (list != null) {
|
||||
result.addAll(list)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.hippo.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import com.hippo.util.SqlUtils
|
||||
|
||||
internal class MSQLiteOpenHelper(
|
||||
context: Context?,
|
||||
name: String?,
|
||||
private val version: Int,
|
||||
private val builder: MSQLiteBuilder
|
||||
) : SQLiteOpenHelper(context, name, null, version) {
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
onUpgrade(db, 0, version)
|
||||
}
|
||||
|
||||
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
for (command in builder.getStatements(oldVersion, newVersion)) {
|
||||
db.execSQL(command)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDowngrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
SqlUtils.dropAllTable(db)
|
||||
onCreate(db)
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.drawable;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import com.hippo.ehviewer.R;
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
|
||||
public class AddDeleteDrawable extends Drawable {
|
||||
|
||||
private final Paint mPaint = new Paint();
|
||||
private final Path mPath = new Path();
|
||||
|
||||
private final int mSize;
|
||||
|
||||
private float mProgress;
|
||||
|
||||
private boolean mAutoUpdateMirror = false;
|
||||
private boolean mVerticalMirror = false;
|
||||
|
||||
/**
|
||||
* @param context used to get the configuration for the drawable from
|
||||
*/
|
||||
public AddDeleteDrawable(Context context, int color) {
|
||||
Resources resources = context.getResources();
|
||||
|
||||
mSize = resources.getDimensionPixelSize(R.dimen.add_size);
|
||||
float barThickness = Math.round(resources.getDimension(R.dimen.add_thickness));
|
||||
|
||||
mPaint.setColor(color);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
mPaint.setStrokeJoin(Paint.Join.MITER);
|
||||
mPaint.setStrokeCap(Paint.Cap.BUTT);
|
||||
mPaint.setStrokeWidth(barThickness);
|
||||
|
||||
float halfSize = mSize / 2;
|
||||
mPath.moveTo(0f, -halfSize);
|
||||
mPath.lineTo(0, halfSize);
|
||||
mPath.moveTo(-halfSize, 0);
|
||||
mPath.lineTo(halfSize, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
Rect bounds = getBounds();
|
||||
float canvasRotate;
|
||||
if (mVerticalMirror) {
|
||||
canvasRotate = MathUtils.lerp(270, 135f, mProgress);
|
||||
} else {
|
||||
canvasRotate = MathUtils.lerp(0f, 135f, mProgress);
|
||||
}
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(bounds.centerX(), bounds.centerY());
|
||||
canvas.rotate(canvasRotate);
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
mPaint.setColor(color);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
mPaint.setColorFilter(cf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mSize * 6 / 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mSize * 6 / 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, canvas is flipped when progress reached to end and going back to start.
|
||||
*/
|
||||
protected void setVerticalMirror(boolean verticalMirror) {
|
||||
mVerticalMirror = verticalMirror;
|
||||
}
|
||||
|
||||
public void setAutoUpdateMirror(boolean autoUpdateMirror) {
|
||||
mAutoUpdateMirror = autoUpdateMirror;
|
||||
}
|
||||
|
||||
@Keep
|
||||
public float getProgress() {
|
||||
return mProgress;
|
||||
}
|
||||
|
||||
@Keep
|
||||
public void setProgress(float progress) {
|
||||
if (mAutoUpdateMirror) {
|
||||
if (progress == 1f) {
|
||||
setVerticalMirror(true);
|
||||
} else if (progress == 0f) {
|
||||
setVerticalMirror(false);
|
||||
}
|
||||
}
|
||||
mProgress = progress;
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
public void setAdd(long duration) {
|
||||
setShape(false, duration);
|
||||
}
|
||||
|
||||
public void setDelete(long duration) {
|
||||
setShape(true, duration);
|
||||
}
|
||||
|
||||
public void setShape(boolean delete, long duration) {
|
||||
if (!((!delete && mProgress == 0f) || (delete && mProgress == 1f))) {
|
||||
float endProgress = delete ? 1f : 0f;
|
||||
if (duration <= 0) {
|
||||
setProgress(endProgress);
|
||||
} else {
|
||||
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "progress", endProgress);
|
||||
oa.setDuration(duration);
|
||||
oa.setAutoCancel(true);
|
||||
oa.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.drawable;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
|
||||
public class BatteryDrawable extends Drawable {
|
||||
|
||||
public static final int WARN_LIMIT = 15;
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = BatteryDrawable.class.getSimpleName();
|
||||
private final Paint mPaint;
|
||||
private final Rect mTopRect;
|
||||
private final Rect mBottomRect;
|
||||
private final Rect mRightRect;
|
||||
private final Rect mHeadRect;
|
||||
private final Rect mElectRect;
|
||||
private int mColor = Color.WHITE;
|
||||
private int mWarningColor = Color.RED;
|
||||
private int mElect = -1;
|
||||
private int mStart;
|
||||
private int mStop;
|
||||
|
||||
public BatteryDrawable() {
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
|
||||
mTopRect = new Rect();
|
||||
mBottomRect = new Rect();
|
||||
mRightRect = new Rect();
|
||||
mHeadRect = new Rect();
|
||||
mElectRect = new Rect();
|
||||
updatePaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("SuspiciousNameCombination")
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
int width = bounds.width();
|
||||
int height = bounds.height();
|
||||
int strokeWidth = (int) (Math.sqrt(width * width + height * height) * 0.06f);
|
||||
int turn1 = width * 6 / 7;
|
||||
int turn2 = height / 3;
|
||||
int secBottom = height - strokeWidth;
|
||||
mStart = strokeWidth;
|
||||
mStop = turn1 - strokeWidth;
|
||||
|
||||
mTopRect.set(0, 0, turn1, strokeWidth);
|
||||
mBottomRect.set(0, secBottom, turn1, height);
|
||||
mRightRect.set(turn1 - strokeWidth, strokeWidth, turn1, secBottom);
|
||||
mHeadRect.set(turn1, turn2, width, height - turn2);
|
||||
mElectRect.set(0, strokeWidth, mStop, secBottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* How to draw:<br>
|
||||
* |------------------------------|<br>
|
||||
* |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|<br>
|
||||
* |------------------------------|---|<br>
|
||||
* |/////////////////| |//|\\\|<br>
|
||||
* |/////////////////| |//|\\\|<br>
|
||||
* |------------------------------|---|<br>
|
||||
* |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|<br>
|
||||
* |------------------------------|
|
||||
*/
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (mElect == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
mElectRect.right = MathUtils.lerp(mStart, mStop, mElect / 100.0f);
|
||||
|
||||
canvas.drawRect(mTopRect, mPaint);
|
||||
canvas.drawRect(mBottomRect, mPaint);
|
||||
canvas.drawRect(mRightRect, mPaint);
|
||||
canvas.drawRect(mHeadRect, mPaint);
|
||||
canvas.drawRect(mElectRect, mPaint);
|
||||
}
|
||||
|
||||
private boolean isWarn() {
|
||||
return mElect <= WARN_LIMIT;
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
if (mColor == color) {
|
||||
return;
|
||||
}
|
||||
|
||||
mColor = color;
|
||||
if (!isWarn()) {
|
||||
mPaint.setColor(mColor);
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
public void setWarningColor(int color) {
|
||||
if (mWarningColor == color) {
|
||||
return;
|
||||
}
|
||||
|
||||
mWarningColor = color;
|
||||
if (isWarn()) {
|
||||
mPaint.setColor(mWarningColor);
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
public void setElect(int elect) {
|
||||
if (mElect == elect) {
|
||||
return;
|
||||
}
|
||||
|
||||
mElect = elect;
|
||||
updatePaint();
|
||||
}
|
||||
|
||||
public void setElect(int elect, boolean warn) {
|
||||
if (mElect == elect) {
|
||||
return;
|
||||
}
|
||||
|
||||
mElect = elect;
|
||||
updatePaint(warn);
|
||||
}
|
||||
|
||||
private void updatePaint() {
|
||||
updatePaint(isWarn());
|
||||
}
|
||||
|
||||
private void updatePaint(boolean warn) {
|
||||
if (warn) {
|
||||
mPaint.setColor(mWarningColor);
|
||||
} else {
|
||||
mPaint.setColor(mColor);
|
||||
}
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
mPaint.setColorFilter(cf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.drawable;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
|
||||
public class DrawableWrapper extends Drawable implements Drawable.Callback {
|
||||
private Drawable mDrawable;
|
||||
private Rect mBounds;
|
||||
|
||||
public DrawableWrapper(Drawable drawable) {
|
||||
this.setWrappedDrawable(drawable);
|
||||
}
|
||||
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
if (mDrawable instanceof BitmapDrawable bitmapDrawable) {
|
||||
canvas.drawBitmap(bitmapDrawable.getBitmap(), null, mBounds, bitmapDrawable.getPaint());
|
||||
} else {
|
||||
synchronized (mDrawable) {
|
||||
mDrawable.setBounds(mBounds);
|
||||
mDrawable.draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
mBounds = bounds;
|
||||
}
|
||||
|
||||
public int getChangingConfigurations() {
|
||||
return this.mDrawable.getChangingConfigurations();
|
||||
}
|
||||
|
||||
public void setChangingConfigurations(int configs) {
|
||||
this.mDrawable.setChangingConfigurations(configs);
|
||||
}
|
||||
|
||||
public void setDither(boolean dither) {
|
||||
this.mDrawable.setDither(dither);
|
||||
}
|
||||
|
||||
public void setFilterBitmap(boolean filter) {
|
||||
this.mDrawable.setFilterBitmap(filter);
|
||||
}
|
||||
|
||||
public void setAlpha(int alpha) {
|
||||
this.mDrawable.setAlpha(alpha);
|
||||
}
|
||||
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
this.mDrawable.setColorFilter(cf);
|
||||
}
|
||||
|
||||
public boolean isStateful() {
|
||||
return this.mDrawable.isStateful();
|
||||
}
|
||||
|
||||
public boolean setState(@NonNull int[] stateSet) {
|
||||
return this.mDrawable.setState(stateSet);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public int[] getState() {
|
||||
return this.mDrawable.getState();
|
||||
}
|
||||
|
||||
public void jumpToCurrentState() {
|
||||
this.mDrawable.jumpToCurrentState();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Drawable getCurrent() {
|
||||
return this.mDrawable.getCurrent();
|
||||
}
|
||||
|
||||
public boolean setVisible(boolean visible, boolean restart) {
|
||||
return super.setVisible(visible, restart) || this.mDrawable.setVisible(visible, restart);
|
||||
}
|
||||
|
||||
public int getOpacity() {
|
||||
return this.mDrawable.getOpacity();
|
||||
}
|
||||
|
||||
public Region getTransparentRegion() {
|
||||
return this.mDrawable.getTransparentRegion();
|
||||
}
|
||||
|
||||
public int getIntrinsicWidth() {
|
||||
return this.mDrawable.getIntrinsicWidth();
|
||||
}
|
||||
|
||||
public int getIntrinsicHeight() {
|
||||
return this.mDrawable.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
public int getMinimumWidth() {
|
||||
return this.mDrawable.getMinimumWidth();
|
||||
}
|
||||
|
||||
public int getMinimumHeight() {
|
||||
return this.mDrawable.getMinimumHeight();
|
||||
}
|
||||
|
||||
public boolean getPadding(@NonNull Rect padding) {
|
||||
return this.mDrawable.getPadding(padding);
|
||||
}
|
||||
|
||||
public void invalidateDrawable(@NonNull Drawable who) {
|
||||
this.invalidateSelf();
|
||||
}
|
||||
|
||||
public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
|
||||
this.scheduleSelf(what, when);
|
||||
}
|
||||
|
||||
public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
|
||||
this.unscheduleSelf(what);
|
||||
}
|
||||
|
||||
protected boolean onLevelChange(int level) {
|
||||
return this.mDrawable.setLevel(level);
|
||||
}
|
||||
|
||||
public boolean isAutoMirrored() {
|
||||
return DrawableCompat.isAutoMirrored(this.mDrawable);
|
||||
}
|
||||
|
||||
public void setAutoMirrored(boolean mirrored) {
|
||||
DrawableCompat.setAutoMirrored(this.mDrawable, mirrored);
|
||||
}
|
||||
|
||||
public void setTint(int tint) {
|
||||
DrawableCompat.setTint(this.mDrawable, tint);
|
||||
}
|
||||
|
||||
public void setTintList(ColorStateList tint) {
|
||||
DrawableCompat.setTintList(this.mDrawable, tint);
|
||||
}
|
||||
|
||||
public void setTintMode(@NonNull PorterDuff.Mode tintMode) {
|
||||
DrawableCompat.setTintMode(this.mDrawable, tintMode);
|
||||
}
|
||||
|
||||
public void setHotspot(float x, float y) {
|
||||
DrawableCompat.setHotspot(this.mDrawable, x, y);
|
||||
}
|
||||
|
||||
public void setHotspotBounds(int left, int top, int right, int bottom) {
|
||||
DrawableCompat.setHotspotBounds(this.mDrawable, left, top, right, bottom);
|
||||
}
|
||||
|
||||
public Drawable getWrappedDrawable() {
|
||||
return this.mDrawable;
|
||||
}
|
||||
|
||||
public void setWrappedDrawable(Drawable drawable) {
|
||||
if (this.mDrawable != null) {
|
||||
this.mDrawable.setCallback(null);
|
||||
}
|
||||
|
||||
this.mDrawable = drawable;
|
||||
if (drawable != null) {
|
||||
drawable.setCallback(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.drawable;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
|
||||
/**
|
||||
* Show a part of the original drawable
|
||||
*/
|
||||
public class PreciselyClipDrawable extends DrawableWrapper {
|
||||
|
||||
private final boolean mClip;
|
||||
private RectF mScale;
|
||||
private Rect mTemp;
|
||||
|
||||
public PreciselyClipDrawable(Drawable drawable, int offsetX, int offsetY, int width, int height) {
|
||||
super(drawable);
|
||||
float originWidth = drawable.getIntrinsicWidth();
|
||||
float originHeight = drawable.getIntrinsicHeight();
|
||||
|
||||
if (originWidth <= 0 || originHeight <= 0) {
|
||||
// Can not clip
|
||||
mClip = false;
|
||||
} else {
|
||||
mClip = true;
|
||||
mScale = new RectF();
|
||||
mScale.set(MathUtils.clamp(offsetX / originWidth, 0.0f, 1.0f),
|
||||
MathUtils.clamp(offsetY / originHeight, 0.0f, 1.0f),
|
||||
MathUtils.clamp((offsetX + width) / originWidth, 0.0f, 1.0f),
|
||||
MathUtils.clamp((offsetY + height) / originHeight, 0.0f, 1.0f));
|
||||
mTemp = new Rect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
if (mClip) {
|
||||
if (!mScale.isEmpty()) {
|
||||
mTemp.left = (int) ((mScale.left * bounds.right - mScale.right * bounds.left) /
|
||||
(mScale.left * (1 - mScale.right) - mScale.right * (1 - mScale.left)));
|
||||
mTemp.right = (int) (((1 - mScale.right) * bounds.left - (1 - mScale.left) * bounds.right) /
|
||||
(mScale.left * (1 - mScale.right) - mScale.right * (1 - mScale.left)));
|
||||
mTemp.top = (int) ((mScale.top * bounds.bottom - mScale.bottom * bounds.top) /
|
||||
(mScale.top * (1 - mScale.bottom) - mScale.bottom * (1 - mScale.top)));
|
||||
mTemp.bottom = (int) (((1 - mScale.bottom) * bounds.top - (1 - mScale.top) * bounds.bottom) /
|
||||
(mScale.top * (1 - mScale.bottom) - mScale.bottom * (1 - mScale.top)));
|
||||
super.onBoundsChange(mTemp);
|
||||
}
|
||||
} else {
|
||||
super.onBoundsChange(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
if (mClip) {
|
||||
return (int) (super.getIntrinsicWidth() * mScale.width());
|
||||
} else {
|
||||
return super.getIntrinsicWidth();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
if (mClip) {
|
||||
return (int) (super.getIntrinsicHeight() * mScale.height());
|
||||
} else {
|
||||
return super.getIntrinsicHeight();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (mClip) {
|
||||
if (!mScale.isEmpty()) {
|
||||
int saveCount = canvas.save();
|
||||
canvas.clipRect(getBounds());
|
||||
super.draw(canvas);
|
||||
canvas.restoreToCount(saveCount);
|
||||
}
|
||||
} else {
|
||||
super.draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.drawable;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class TriangleDrawable extends Drawable {
|
||||
|
||||
private final Paint mPaint;
|
||||
private final Path mPath;
|
||||
|
||||
public TriangleDrawable(int color) {
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
|
||||
mPaint.setColor(color);
|
||||
mPath = new Path();
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
mPaint.setColor(color);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
super.onBoundsChange(bounds);
|
||||
mPath.reset();
|
||||
mPath.moveTo(bounds.left, bounds.top);
|
||||
mPath.lineTo(bounds.right, bounds.top);
|
||||
mPath.lineTo(bounds.right, bounds.bottom);
|
||||
mPath.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter colorFilter) {
|
||||
mPaint.setColorFilter(colorFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.OPAQUE;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.drawable;
|
||||
|
||||
import android.graphics.drawable.AnimatedImageDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.hippo.widget.ObservedTextView;
|
||||
|
||||
import coil.Coil;
|
||||
import coil.request.Disposable;
|
||||
import coil.request.ImageRequest;
|
||||
|
||||
public class UnikeryDrawable extends WrapDrawable implements ObservedTextView.OnWindowAttachListener {
|
||||
|
||||
private static final String TAG = UnikeryDrawable.class.getSimpleName();
|
||||
private final ObservedTextView mTextView;
|
||||
private String mUrl;
|
||||
private Disposable task;
|
||||
|
||||
public UnikeryDrawable(ObservedTextView textView) {
|
||||
mTextView = textView;
|
||||
mTextView.setOnWindowAttachListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
load(mUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
if (task != null && !task.isDisposed())
|
||||
task.dispose();
|
||||
clearDrawable();
|
||||
}
|
||||
|
||||
public void load(String url) {
|
||||
if (url != null) {
|
||||
mUrl = url;
|
||||
var imageLoader = Coil.imageLoader(mTextView.getContext());
|
||||
var request = new ImageRequest.Builder(mTextView.getContext()).data(url).memoryCacheKey(url).diskCacheKey(url).target(
|
||||
drawable -> null,
|
||||
drawable -> null,
|
||||
drawable -> {
|
||||
onGetValue(drawable);
|
||||
return null;
|
||||
}
|
||||
).build();
|
||||
task = imageLoader.enqueue(request);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDrawable() {
|
||||
setDrawable(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDrawable(Drawable drawable) {
|
||||
// Remove old callback
|
||||
Drawable oldDrawable = getDrawable();
|
||||
if (oldDrawable != null) {
|
||||
oldDrawable.setCallback(null);
|
||||
}
|
||||
|
||||
super.setDrawable(drawable);
|
||||
|
||||
if (drawable != null) {
|
||||
drawable.setCallback(mTextView);
|
||||
}
|
||||
|
||||
updateBounds();
|
||||
if (drawable != null) {
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateSelf() {
|
||||
CharSequence cs = mTextView.getText();
|
||||
mTextView.setText(cs);
|
||||
}
|
||||
|
||||
public void onGetValue(Drawable drawable) {
|
||||
clearDrawable();
|
||||
setDrawable(drawable);
|
||||
if (drawable instanceof AnimatedImageDrawable animatedImageDrawable)
|
||||
animatedImageDrawable.start();
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.drawable;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class WrapDrawable extends Drawable {
|
||||
|
||||
private Drawable mDrawable;
|
||||
|
||||
public Drawable getDrawable() {
|
||||
return mDrawable;
|
||||
}
|
||||
|
||||
public void setDrawable(Drawable drawable) {
|
||||
mDrawable = drawable;
|
||||
}
|
||||
|
||||
public void updateBounds() {
|
||||
setBounds(0, 0, getIntrinsicWidth(), getIntrinsicHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (mDrawable != null) {
|
||||
mDrawable.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(int left, int top, int right, int bottom) {
|
||||
super.setBounds(left, top, right, bottom);
|
||||
|
||||
if (mDrawable != null) {
|
||||
mDrawable.setBounds(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(Rect bounds) {
|
||||
super.setBounds(bounds);
|
||||
|
||||
if (mDrawable != null) {
|
||||
mDrawable.setBounds(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChangingConfigurations() {
|
||||
if (mDrawable != null) {
|
||||
return mDrawable.getChangingConfigurations();
|
||||
} else {
|
||||
return super.getChangingConfigurations();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChangingConfigurations(int configs) {
|
||||
super.setChangingConfigurations(configs);
|
||||
|
||||
if (mDrawable != null) {
|
||||
mDrawable.setChangingConfigurations(configs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDither(boolean dither) {
|
||||
super.setDither(dither);
|
||||
|
||||
if (mDrawable != null) {
|
||||
mDrawable.setDither(dither);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilterBitmap(boolean filter) {
|
||||
super.setFilterBitmap(filter);
|
||||
|
||||
if (mDrawable != null) {
|
||||
mDrawable.setFilterBitmap(filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
if (mDrawable != null) {
|
||||
mDrawable.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
if (mDrawable != null) {
|
||||
mDrawable.setColorFilter(cf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
if (mDrawable != null) {
|
||||
return mDrawable.getOpacity();
|
||||
} else {
|
||||
return PixelFormat.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
if (mDrawable != null) {
|
||||
return mDrawable.getIntrinsicWidth();
|
||||
} else {
|
||||
return super.getIntrinsicWidth();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
if (mDrawable != null) {
|
||||
return mDrawable.getIntrinsicHeight();
|
||||
} else {
|
||||
return super.getIntrinsicHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,675 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.easyrecyclerview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.ActionMode;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Checkable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.collection.LongSparseArray;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.hippo.yorozuya.NumberUtils;
|
||||
|
||||
/**
|
||||
* Add setChoiceMode for RecyclerView
|
||||
*/
|
||||
// Get some code from twoway-view and AbsListView.
|
||||
public class EasyRecyclerView extends RecyclerView {
|
||||
|
||||
/**
|
||||
* Normal list that does not indicate choices
|
||||
*/
|
||||
public static final int CHOICE_MODE_NONE = 0;
|
||||
|
||||
/**
|
||||
* The list allows up to one choice
|
||||
*/
|
||||
public static final int CHOICE_MODE_SINGLE = 1;
|
||||
|
||||
/**
|
||||
* The list allows multiple choices
|
||||
*/
|
||||
public static final int CHOICE_MODE_MULTIPLE = 2;
|
||||
|
||||
/**
|
||||
* The list allows multiple choices in a modal selection mode
|
||||
*/
|
||||
public static final int CHOICE_MODE_MULTIPLE_MODAL = 3;
|
||||
|
||||
/**
|
||||
* The list allows multiple choices in custom action
|
||||
*/
|
||||
public static final int CHOICE_MODE_MULTIPLE_CUSTOM = 4;
|
||||
// Fling friction
|
||||
public float pageScrollThreshold;
|
||||
/**
|
||||
* Wrapper for the multiple choice mode callback; AbsListView needs to perform
|
||||
* a few extra actions around what application code does.
|
||||
*/
|
||||
MultiChoiceModeWrapper mMultiChoiceModeCallback;
|
||||
/**
|
||||
* Controls if/how the user may choose/check items in the list
|
||||
*/
|
||||
private int mChoiceMode = CHOICE_MODE_NONE;
|
||||
/**
|
||||
* Controls CHOICE_MODE_MULTIPLE_MODAL. null when inactive.
|
||||
*/
|
||||
private ActionMode mChoiceActionMode;
|
||||
/**
|
||||
* Listener for custom multiple choices
|
||||
*/
|
||||
private CustomChoiceListener mCustomChoiceListener;
|
||||
|
||||
private boolean mCustomChoice = false;
|
||||
|
||||
/**
|
||||
* A lock, avoid OutOfCustomChoiceMode when doing OutOfCustomChoiceMode
|
||||
*/
|
||||
private boolean mOutOfCustomChoiceModing = false;
|
||||
|
||||
private SparseBooleanArray mTempCheckStates;
|
||||
|
||||
/**
|
||||
* Running count of how many items are currently checked
|
||||
*/
|
||||
private int mCheckedItemCount;
|
||||
|
||||
/**
|
||||
* Running state of which positions are currently checked
|
||||
*/
|
||||
private SparseBooleanArray mCheckStates;
|
||||
|
||||
/**
|
||||
* Running state of which IDs are currently checked.
|
||||
* If there is a value for a given key, the checked state for that ID is true
|
||||
* and the value holds the last known position in the adapter for that id.
|
||||
*/
|
||||
private LongSparseArray<Integer> mCheckedIdStates;
|
||||
|
||||
private Adapter<?> mAdapter;
|
||||
|
||||
public EasyRecyclerView(Context context) {
|
||||
super(context);
|
||||
EasyRecyclerView.this.init(context);
|
||||
}
|
||||
|
||||
public EasyRecyclerView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
EasyRecyclerView.this.init(context);
|
||||
}
|
||||
|
||||
public EasyRecyclerView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
EasyRecyclerView.this.init(context);
|
||||
}
|
||||
|
||||
public static void setViewChecked(View view, boolean checked) {
|
||||
if (view instanceof Checkable) {
|
||||
((Checkable) view).setChecked(checked);
|
||||
} else {
|
||||
view.setActivated(checked);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setAdapter(RecyclerView.Adapter adapter) {
|
||||
|
||||
super.setAdapter(adapter);
|
||||
|
||||
mAdapter = adapter;
|
||||
if (adapter != null) {
|
||||
if (mChoiceMode != CHOICE_MODE_NONE && adapter.hasStableIds() &&
|
||||
mCheckedIdStates == null) {
|
||||
mCheckedIdStates = new LongSparseArray<>();
|
||||
}
|
||||
}
|
||||
|
||||
if (mCheckStates != null) {
|
||||
mCheckStates.clear();
|
||||
}
|
||||
|
||||
if (mCheckedIdStates != null) {
|
||||
mCheckedIdStates.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChildAttachedToWindow(@NonNull View child) {
|
||||
super.onChildAttachedToWindow(child);
|
||||
|
||||
if (mCheckStates != null) {
|
||||
int position = getChildAdapterPosition(child);
|
||||
if (position >= 0) {
|
||||
setViewChecked(child, mCheckStates.get(position));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getCheckedItemCount() {
|
||||
return mCheckedItemCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the checked state of the specified position. The result is only
|
||||
* valid if the choice mode has been set to {@link #CHOICE_MODE_SINGLE}
|
||||
* or {@link #CHOICE_MODE_MULTIPLE}.
|
||||
*
|
||||
* @param position The item whose checked state to return
|
||||
* @return The item's checked state or <code>false</code> if choice mode
|
||||
* is invalid
|
||||
* @see #setChoiceMode(int)
|
||||
*/
|
||||
public boolean isItemChecked(int position) {
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
|
||||
return mCheckStates.get(position);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of checked items in the list. The result is only valid if
|
||||
* the choice mode has not been set to {@link #CHOICE_MODE_NONE}.
|
||||
*
|
||||
* @return A SparseBooleanArray which will return true for each call to
|
||||
* get(int position) where position is a checked position in the
|
||||
* list and false otherwise, or <code>null</code> if the choice
|
||||
* mode is set to {@link #CHOICE_MODE_NONE}.
|
||||
*/
|
||||
public SparseBooleanArray getCheckedItemPositions() {
|
||||
if (mChoiceMode != CHOICE_MODE_NONE) {
|
||||
return mCheckStates;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isInCustomChoice() {
|
||||
return mCustomChoice;
|
||||
}
|
||||
|
||||
public void intoCustomChoiceMode() {
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && !mCustomChoice) {
|
||||
mCustomChoice = true;
|
||||
|
||||
mCustomChoiceListener.onIntoCustomChoice(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void outOfCustomChoiceMode() {
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && mCustomChoice && !mOutOfCustomChoiceModing) {
|
||||
mOutOfCustomChoiceModing = true;
|
||||
|
||||
// Copy mCheckStates
|
||||
mTempCheckStates.clear();
|
||||
for (int i = 0, n = mCheckStates.size(); i < n; i++) {
|
||||
mTempCheckStates.put(mCheckStates.keyAt(i), mCheckStates.valueAt(i));
|
||||
}
|
||||
// Uncheck remain checked items
|
||||
for (int i = 0, n = mTempCheckStates.size(); i < n; i++) {
|
||||
if (mTempCheckStates.valueAt(i)) {
|
||||
setItemChecked(mTempCheckStates.keyAt(i), false);
|
||||
}
|
||||
}
|
||||
|
||||
mCustomChoice = false;
|
||||
mCustomChoiceListener.onOutOfCustomChoice(this);
|
||||
|
||||
mOutOfCustomChoiceModing = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any choices previously set
|
||||
*/
|
||||
private void clearChoices() {
|
||||
if (mCheckStates != null) {
|
||||
mCheckStates.clear();
|
||||
}
|
||||
if (mCheckedIdStates != null) {
|
||||
mCheckedIdStates.clear();
|
||||
}
|
||||
mCheckedItemCount = 0;
|
||||
updateOnScreenCheckedViews();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all items checked.
|
||||
*/
|
||||
public void checkAll() {
|
||||
if (mChoiceMode == CHOICE_MODE_NONE || mChoiceMode == CHOICE_MODE_SINGLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check is intoCheckMode
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && !mCustomChoice) {
|
||||
throw new IllegalStateException("Call intoCheckMode first");
|
||||
}
|
||||
|
||||
// Start selection mode if needed. We don't need to if we're unchecking something.
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) {
|
||||
if (mMultiChoiceModeCallback == null ||
|
||||
!mMultiChoiceModeCallback.hasWrappedCallback()) {
|
||||
throw new IllegalStateException("EasyRecyclerView: attempted to start selection mode " +
|
||||
"for CHOICE_MODE_MULTIPLE_MODAL but no choice mode callback was " +
|
||||
"supplied. Call setMultiChoiceModeListener to set a callback.");
|
||||
}
|
||||
mChoiceActionMode = startActionMode(mMultiChoiceModeCallback);
|
||||
}
|
||||
|
||||
for (int i = 0, n = mAdapter.getItemCount(); i < n; i++) {
|
||||
boolean oldValue = mCheckStates.get(i);
|
||||
mCheckStates.put(i, true);
|
||||
if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
|
||||
mCheckedIdStates.put(mAdapter.getItemId(i), i);
|
||||
}
|
||||
if (!oldValue) {
|
||||
mCheckedItemCount++;
|
||||
}
|
||||
if (mChoiceActionMode != null) {
|
||||
final long id = mAdapter.getItemId(i);
|
||||
mMultiChoiceModeCallback.onItemCheckedStateChanged(mChoiceActionMode, i, id, true);
|
||||
}
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM) {
|
||||
final long id = mAdapter.getItemId(i);
|
||||
mCustomChoiceListener.onItemCheckedStateChanged(this, i, id, true);
|
||||
}
|
||||
}
|
||||
|
||||
updateOnScreenCheckedViews();
|
||||
}
|
||||
|
||||
public void toggleItemChecked(int position) {
|
||||
if (mCheckStates != null) {
|
||||
setItemChecked(position, !mCheckStates.get(position));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the checked state of the specified position. The is only valid if
|
||||
* the choice mode has been set to {@link #CHOICE_MODE_SINGLE} or
|
||||
* {@link #CHOICE_MODE_MULTIPLE}.
|
||||
*
|
||||
* @param position The item whose checked state is to be checked
|
||||
* @param value The new checked state for the item
|
||||
*/
|
||||
public void setItemChecked(int position, boolean value) {
|
||||
if (mChoiceMode == CHOICE_MODE_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check is intoCheckMode
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && !mCustomChoice) {
|
||||
throw new IllegalStateException("Call intoCheckMode first");
|
||||
}
|
||||
|
||||
// Start selection mode if needed. We don't need to if we're unchecking something.
|
||||
if (value && mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) {
|
||||
if (mMultiChoiceModeCallback == null ||
|
||||
!mMultiChoiceModeCallback.hasWrappedCallback()) {
|
||||
throw new IllegalStateException("EasyRecyclerView: attempted to start selection mode " +
|
||||
"for CHOICE_MODE_MULTIPLE_MODAL but no choice mode callback was " +
|
||||
"supplied. Call setMultiChoiceModeListener to set a callback.");
|
||||
}
|
||||
mChoiceActionMode = startActionMode(mMultiChoiceModeCallback);
|
||||
}
|
||||
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE || mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL || mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM) {
|
||||
boolean oldValue = mCheckStates.get(position);
|
||||
mCheckStates.put(position, value);
|
||||
if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
|
||||
if (value) {
|
||||
mCheckedIdStates.put(mAdapter.getItemId(position), position);
|
||||
} else {
|
||||
mCheckedIdStates.remove(mAdapter.getItemId(position));
|
||||
}
|
||||
}
|
||||
if (oldValue != value) {
|
||||
if (value) {
|
||||
mCheckedItemCount++;
|
||||
} else {
|
||||
mCheckedItemCount--;
|
||||
}
|
||||
}
|
||||
if (mChoiceActionMode != null) {
|
||||
final long id = mAdapter.getItemId(position);
|
||||
mMultiChoiceModeCallback.onItemCheckedStateChanged(mChoiceActionMode,
|
||||
position, id, value);
|
||||
}
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM) {
|
||||
final long id = mAdapter.getItemId(position);
|
||||
mCustomChoiceListener.onItemCheckedStateChanged(this, position, id, value);
|
||||
}
|
||||
} else {
|
||||
boolean updateIds = mCheckedIdStates != null && mAdapter.hasStableIds();
|
||||
// Clear all values if we're checking something, or unchecking the currently
|
||||
// selected item
|
||||
if (value || isItemChecked(position)) {
|
||||
mCheckStates.clear();
|
||||
if (updateIds) {
|
||||
mCheckedIdStates.clear();
|
||||
}
|
||||
}
|
||||
// this may end up selecting the value we just cleared but this way
|
||||
// we ensure length of mCheckStates is 1, a fact getCheckedItemPosition relies on
|
||||
if (value) {
|
||||
mCheckStates.put(position, true);
|
||||
if (updateIds) {
|
||||
mCheckedIdStates.put(mAdapter.getItemId(position), position);
|
||||
}
|
||||
mCheckedItemCount = 1;
|
||||
} else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) {
|
||||
mCheckedItemCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
updateOnScreenCheckedViews();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the choice behavior for the List. By default, Lists do not have any choice behavior
|
||||
* ({@link #CHOICE_MODE_NONE}). By setting the choiceMode to {@link #CHOICE_MODE_SINGLE}, the
|
||||
* List allows up to one item to be in a chosen state. By setting the choiceMode to
|
||||
* {@link #CHOICE_MODE_MULTIPLE}, the list allows any number of items to be chosen.
|
||||
*
|
||||
* @param choiceMode One of {@link #CHOICE_MODE_NONE}, {@link #CHOICE_MODE_SINGLE}, or
|
||||
* {@link #CHOICE_MODE_MULTIPLE}
|
||||
*/
|
||||
public void setChoiceMode(int choiceMode) {
|
||||
mChoiceMode = choiceMode;
|
||||
if (mChoiceActionMode != null) {
|
||||
mChoiceActionMode.finish();
|
||||
mChoiceActionMode = null;
|
||||
}
|
||||
if (mChoiceMode != CHOICE_MODE_NONE) {
|
||||
if (mCheckStates == null) {
|
||||
mCheckStates = new SparseBooleanArray(0);
|
||||
}
|
||||
if (mCheckedIdStates == null && mAdapter != null && mAdapter.hasStableIds()) {
|
||||
mCheckedIdStates = new LongSparseArray<>(0);
|
||||
}
|
||||
// Modal multi-choice mode only has choices when the mode is active. Clear them.
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
|
||||
clearChoices();
|
||||
setLongClickable(true);
|
||||
} else if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM) {
|
||||
if (mTempCheckStates == null) {
|
||||
mTempCheckStates = new SparseBooleanArray(0);
|
||||
}
|
||||
clearChoices();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCustomCheckedListener(CustomChoiceListener listener) {
|
||||
mCustomChoiceListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a quick, in-place update of the checked or activated state
|
||||
* on all visible item views. This should only be called when a valid
|
||||
* choice mode is active.
|
||||
*/
|
||||
private void updateOnScreenCheckedViews() {
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
final int position = getChildAdapterPosition(child);
|
||||
setViewChecked(child, mCheckStates.get(position));
|
||||
}
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
float scale = context.getResources().getDisplayMetrics().density;
|
||||
// g (m/s^2)
|
||||
// inch/meter
|
||||
// A context-specific coefficient adjusted to physical values.
|
||||
// look and feel tuning
|
||||
pageScrollThreshold = scale * 80;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState() {
|
||||
final SavedState ss = new SavedState(super.onSaveInstanceState());
|
||||
|
||||
ss.choiceMode = mChoiceMode;
|
||||
ss.customChoice = mCustomChoice;
|
||||
ss.checkedItemCount = mCheckedItemCount;
|
||||
ss.checkState = mCheckStates;
|
||||
ss.checkIdState = mCheckedIdStates;
|
||||
|
||||
return ss;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state) {
|
||||
SavedState ss = (SavedState) state;
|
||||
super.onRestoreInstanceState(ss.getSuperState());
|
||||
|
||||
setChoiceMode(ss.choiceMode);
|
||||
mCustomChoice = ss.customChoice;
|
||||
mCheckedItemCount = ss.checkedItemCount;
|
||||
if (ss.checkState != null) {
|
||||
mCheckStates = ss.checkState;
|
||||
}
|
||||
if (ss.checkIdState != null) {
|
||||
mCheckedIdStates = ss.checkIdState;
|
||||
}
|
||||
|
||||
if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mCheckedItemCount > 0) {
|
||||
mChoiceActionMode = startActionMode(mMultiChoiceModeCallback);
|
||||
}
|
||||
updateOnScreenCheckedViews();
|
||||
}
|
||||
|
||||
/**
|
||||
* A MultiChoiceModeListener receives events for {@link android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL}.
|
||||
* It acts as the {@link android.view.ActionMode.Callback} for the selection mode and also receives
|
||||
* {@link #onItemCheckedStateChanged(android.view.ActionMode, int, long, boolean)} events when the user
|
||||
* selects and deselects list items.
|
||||
*/
|
||||
public interface MultiChoiceModeListener extends ActionMode.Callback {
|
||||
/**
|
||||
* Called when an item is checked or unchecked during selection mode.
|
||||
*
|
||||
* @param mode The {@link android.view.ActionMode} providing the selection mode
|
||||
* @param position Adapter position of the item that was checked or unchecked
|
||||
* @param id Adapter ID of the item that was checked or unchecked
|
||||
* @param checked <code>true</code> if the item is now checked, <code>false</code>
|
||||
* if the item is now unchecked.
|
||||
*/
|
||||
void onItemCheckedStateChanged(ActionMode mode,
|
||||
int position, long id, boolean checked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom checked
|
||||
*/
|
||||
public interface CustomChoiceListener {
|
||||
|
||||
void onIntoCustomChoice(EasyRecyclerView view);
|
||||
|
||||
void onOutOfCustomChoice(EasyRecyclerView view);
|
||||
|
||||
void onItemCheckedStateChanged(EasyRecyclerView view, int position, long id, boolean checked);
|
||||
}
|
||||
|
||||
/**
|
||||
* This saved state class is a Parcelable and should not extend
|
||||
* {@link android.view.View.BaseSavedState} nor {@link android.view.AbsSavedState}
|
||||
* because its super class AbsSavedState's constructor
|
||||
* currently passes null
|
||||
* as a class loader to read its superstate from Parcelable.
|
||||
* This causes {@link android.os.BadParcelableException} when restoring saved states.
|
||||
* <p/>
|
||||
* The super class "RecyclerView" is a part of the support library,
|
||||
* and restoring its saved state requires the class loader that loaded the RecyclerView.
|
||||
* It seems that the class loader is not required when restoring from RecyclerView itself,
|
||||
* but it is required when restoring from RecyclerView's subclasses.
|
||||
*/
|
||||
static class SavedState implements Parcelable {
|
||||
|
||||
public static final SavedState EMPTY_STATE = new SavedState() {
|
||||
};
|
||||
public static final Parcelable.Creator<SavedState> CREATOR
|
||||
= new Parcelable.Creator<SavedState>() {
|
||||
@Override
|
||||
public SavedState createFromParcel(Parcel in) {
|
||||
return new SavedState(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavedState[] newArray(int size) {
|
||||
return new SavedState[size];
|
||||
}
|
||||
};
|
||||
int choiceMode;
|
||||
boolean customChoice;
|
||||
int checkedItemCount;
|
||||
SparseBooleanArray checkState;
|
||||
LongSparseArray<Integer> checkIdState;
|
||||
// This keeps the parent(RecyclerView)'s state
|
||||
Parcelable mSuperState;
|
||||
|
||||
SavedState() {
|
||||
mSuperState = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called from {@link #onSaveInstanceState()}
|
||||
*/
|
||||
SavedState(Parcelable superState) {
|
||||
mSuperState = superState != EMPTY_STATE ? superState : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called from {@link #CREATOR}
|
||||
*/
|
||||
private SavedState(Parcel in) {
|
||||
// Parcel 'in' has its parent(RecyclerView)'s saved state.
|
||||
// To restore it, class loader that loaded RecyclerView is required.
|
||||
Parcelable superState = in.readParcelable(RecyclerView.class.getClassLoader());
|
||||
mSuperState = superState != null ? superState : EMPTY_STATE;
|
||||
|
||||
choiceMode = in.readInt();
|
||||
customChoice = NumberUtils.int2boolean(in.readInt());
|
||||
checkedItemCount = in.readInt();
|
||||
checkState = in.readSparseBooleanArray();
|
||||
final int N = in.readInt();
|
||||
if (N > 0) {
|
||||
checkIdState = new LongSparseArray<>();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final long key = in.readLong();
|
||||
final int value = in.readInt();
|
||||
checkIdState.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel out, int flags) {
|
||||
out.writeParcelable(mSuperState, flags);
|
||||
|
||||
out.writeInt(choiceMode);
|
||||
out.writeInt(NumberUtils.boolean2int(customChoice));
|
||||
out.writeInt(checkedItemCount);
|
||||
out.writeSparseBooleanArray(checkState);
|
||||
final int N = checkIdState != null ? checkIdState.size() : 0;
|
||||
out.writeInt(N);
|
||||
for (int i = 0; i < N; i++) {
|
||||
out.writeLong(checkIdState.keyAt(i));
|
||||
out.writeInt(checkIdState.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
public Parcelable getSuperState() {
|
||||
return mSuperState;
|
||||
}
|
||||
}
|
||||
|
||||
class MultiChoiceModeWrapper implements MultiChoiceModeListener {
|
||||
private MultiChoiceModeListener mWrapped;
|
||||
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean hasWrappedCallback() {
|
||||
return mWrapped != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
if (mWrapped.onCreateActionMode(mode, menu)) {
|
||||
// Initialize checked graphic state?
|
||||
setLongClickable(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return mWrapped.onPrepareActionMode(mode, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
return mWrapped.onActionItemClicked(mode, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode) {
|
||||
mWrapped.onDestroyActionMode(mode);
|
||||
mChoiceActionMode = null;
|
||||
|
||||
// Ending selection mode means deselecting everything.
|
||||
clearChoices();
|
||||
|
||||
requestLayout();
|
||||
|
||||
setLongClickable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemCheckedStateChanged(ActionMode mode,
|
||||
int position, long id, boolean checked) {
|
||||
mWrapped.onItemCheckedStateChanged(mode, position, id, checked);
|
||||
|
||||
// If there are no items selected we no longer need the selection mode.
|
||||
if (getCheckedItemCount() == 0) {
|
||||
mode.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,404 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.easyrecyclerview;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.hippo.ehviewer.R;
|
||||
import com.hippo.yorozuya.AnimationUtils;
|
||||
import com.hippo.yorozuya.LayoutUtils;
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
import com.hippo.yorozuya.SimpleAnimatorListener;
|
||||
import com.hippo.yorozuya.SimpleHandler;
|
||||
|
||||
public class FastScroller extends View {
|
||||
|
||||
private static final int INVALID = -1;
|
||||
|
||||
private static final int SCROLL_BAR_FADE_DURATION = 500;
|
||||
private static final int SCROLL_BAR_DELAY = 1000;
|
||||
|
||||
private static final int MIN_HANDLER_HEIGHT_DP = 32;
|
||||
|
||||
private Handler mSimpleHandler;
|
||||
|
||||
private boolean mDraggable;
|
||||
|
||||
private int mMinHandlerHeight;
|
||||
|
||||
private RecyclerView mRecyclerView;
|
||||
private RecyclerView.OnScrollListener mOnScrollChangeListener;
|
||||
private RecyclerView.Adapter<?> mAdapter;
|
||||
private RecyclerView.AdapterDataObserver mAdapterDataObserver;
|
||||
|
||||
private Drawable mHandler;
|
||||
private int mHandlerOffset = INVALID;
|
||||
private int mHandlerHeight = INVALID;
|
||||
|
||||
private float mDownX = INVALID;
|
||||
private float mDownY = INVALID;
|
||||
|
||||
private float mLastMotionY = INVALID;
|
||||
|
||||
private boolean mDragged = false;
|
||||
|
||||
private boolean mCantDrag = false;
|
||||
|
||||
private int mTouchSlop;
|
||||
|
||||
private OnDragHandlerListener mListener;
|
||||
|
||||
private ObjectAnimator mShowAnimator;
|
||||
private ObjectAnimator mHideAnimator;
|
||||
|
||||
private final Runnable mHideRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mHideAnimator.start();
|
||||
}
|
||||
};
|
||||
|
||||
public FastScroller(Context context) {
|
||||
super(context);
|
||||
init(context, null, 0);
|
||||
}
|
||||
|
||||
public FastScroller(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs, 0);
|
||||
}
|
||||
|
||||
public FastScroller(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
mSimpleHandler = SimpleHandler.getInstance();
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FastScroller, defStyleAttr, 0);
|
||||
mHandler = a.getDrawable(R.styleable.FastScroller_handler);
|
||||
mDraggable = a.getBoolean(R.styleable.FastScroller_draggable, true);
|
||||
a.recycle();
|
||||
|
||||
setAlpha(0.0f);
|
||||
setVisibility(INVISIBLE);
|
||||
|
||||
mMinHandlerHeight = LayoutUtils.dp2pix(context, MIN_HANDLER_HEIGHT_DP);
|
||||
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||
|
||||
mShowAnimator = ObjectAnimator.ofFloat(this, "alpha", 1.0f);
|
||||
mShowAnimator.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR);
|
||||
mShowAnimator.setDuration(SCROLL_BAR_FADE_DURATION);
|
||||
|
||||
mHideAnimator = ObjectAnimator.ofFloat(this, "alpha", 0.0f);
|
||||
mHideAnimator.setInterpolator(AnimationUtils.SLOW_FAST_INTERPOLATOR);
|
||||
mHideAnimator.setDuration(SCROLL_BAR_FADE_DURATION);
|
||||
mHideAnimator.addListener(new SimpleAnimatorListener() {
|
||||
|
||||
private boolean mCancel;
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
mCancel = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mCancel) {
|
||||
mCancel = false;
|
||||
} else {
|
||||
setVisibility(INVISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setOnDragHandlerListener(OnDragHandlerListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
private void updatePosition(boolean show) {
|
||||
if (mRecyclerView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int paddingTop = getPaddingTop();
|
||||
int paddingBottom = getPaddingBottom();
|
||||
int height = getHeight() - paddingTop - paddingBottom;
|
||||
int offset = mRecyclerView.computeVerticalScrollOffset();
|
||||
int extent = mRecyclerView.computeVerticalScrollExtent();
|
||||
int range = mRecyclerView.computeVerticalScrollRange();
|
||||
|
||||
if (height <= 0 || extent >= range || extent <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int endOffset = height * offset / range;
|
||||
int endHeight = height * extent / range;
|
||||
|
||||
endHeight = Math.max(endHeight, mMinHandlerHeight);
|
||||
endOffset = Math.min(endOffset, height - endHeight);
|
||||
|
||||
mHandlerOffset = endOffset + paddingTop;
|
||||
mHandlerHeight = endHeight;
|
||||
|
||||
if (show) {
|
||||
if (mHideAnimator.isRunning()) {
|
||||
mHideAnimator.cancel();
|
||||
mShowAnimator.start();
|
||||
} else if (getVisibility() != VISIBLE && !mShowAnimator.isRunning()) {
|
||||
setVisibility(VISIBLE);
|
||||
mShowAnimator.start();
|
||||
}
|
||||
|
||||
Handler handler = mSimpleHandler;
|
||||
handler.removeCallbacks(mHideRunnable);
|
||||
|
||||
if (!mDragged) {
|
||||
handler.postDelayed(mHideRunnable, SCROLL_BAR_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setHandlerDrawable(Drawable drawable) {
|
||||
mHandler = drawable;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public boolean isDraggable() {
|
||||
return mDraggable;
|
||||
}
|
||||
|
||||
public void setDraggable(boolean draggable) {
|
||||
mDraggable = draggable;
|
||||
if (mDragged) {
|
||||
mDragged = false;
|
||||
}
|
||||
mSimpleHandler.removeCallbacks(mHideRunnable);
|
||||
mHideRunnable.run();
|
||||
}
|
||||
|
||||
public boolean isAttached() {
|
||||
return mRecyclerView != null;
|
||||
}
|
||||
|
||||
public void attachToRecyclerView(RecyclerView recyclerView) {
|
||||
if (recyclerView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRecyclerView != null) {
|
||||
throw new IllegalStateException("The FastScroller is already attached to a RecyclerView, " +
|
||||
"call detachedFromRecyclerView first");
|
||||
}
|
||||
|
||||
mRecyclerView = recyclerView;
|
||||
mOnScrollChangeListener = new RecyclerView.OnScrollListener() {
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
updatePosition(true);
|
||||
invalidate();
|
||||
}
|
||||
};
|
||||
|
||||
recyclerView.addOnScrollListener(mOnScrollChangeListener);
|
||||
|
||||
mAdapter = recyclerView.getAdapter();
|
||||
if (mAdapter != null) {
|
||||
mAdapterDataObserver = new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onItemRangeChanged(int positionStart, int itemCount) {
|
||||
super.onItemRangeChanged(positionStart, itemCount);
|
||||
updatePosition(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
|
||||
super.onItemRangeChanged(positionStart, itemCount, payload);
|
||||
updatePosition(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||
super.onItemRangeInserted(positionStart, itemCount);
|
||||
updatePosition(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeRemoved(int positionStart, int itemCount) {
|
||||
super.onItemRangeRemoved(positionStart, itemCount);
|
||||
updatePosition(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
|
||||
super.onItemRangeMoved(fromPosition, toPosition, itemCount);
|
||||
updatePosition(false);
|
||||
invalidate();
|
||||
}
|
||||
};
|
||||
mAdapter.registerAdapterDataObserver(mAdapterDataObserver);
|
||||
}
|
||||
}
|
||||
|
||||
public void detachedFromRecyclerView() {
|
||||
if (mRecyclerView != null && mOnScrollChangeListener != null) {
|
||||
mRecyclerView.removeOnScrollListener(mOnScrollChangeListener);
|
||||
}
|
||||
mRecyclerView = null;
|
||||
mOnScrollChangeListener = null;
|
||||
|
||||
if (mAdapter != null && mAdapterDataObserver != null) {
|
||||
mAdapter.unregisterAdapterDataObserver(mAdapterDataObserver);
|
||||
}
|
||||
mAdapter = null;
|
||||
mAdapterDataObserver = null;
|
||||
|
||||
setAlpha(0.0f);
|
||||
setVisibility(INVISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mRecyclerView == null || mHandler == null) {
|
||||
return;
|
||||
}
|
||||
if (mHandlerHeight == INVALID) {
|
||||
updatePosition(false);
|
||||
}
|
||||
if (mHandlerHeight == INVALID) {
|
||||
return;
|
||||
}
|
||||
|
||||
int paddingLeft = getPaddingLeft();
|
||||
int saved = canvas.save();
|
||||
canvas.translate(paddingLeft, mHandlerOffset);
|
||||
mHandler.setBounds(0, 0, getWidth() - paddingLeft - getPaddingRight(), mHandlerHeight);
|
||||
mHandler.draw(canvas);
|
||||
canvas.restoreToCount(saved);
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (!mDraggable || getVisibility() != VISIBLE || mRecyclerView == null || mHandlerHeight == INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int action = event.getAction();
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
mCantDrag = false;
|
||||
}
|
||||
|
||||
if (mCantDrag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mDragged = false;
|
||||
mDownX = event.getX();
|
||||
mDownY = event.getY();
|
||||
if (mDownY < mHandlerOffset || mDownY > mHandlerOffset + mHandlerHeight) {
|
||||
mCantDrag = true;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
if (!mDragged) {
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
// Check touch slop
|
||||
if (MathUtils.dist(x, y, mDownX, mDownY) < mTouchSlop) {
|
||||
return true;
|
||||
}
|
||||
if (Math.abs(x - mDownX) > Math.abs(y - mDownY) ||
|
||||
y < mHandlerOffset || y > mHandlerOffset + mHandlerHeight) {
|
||||
mCantDrag = true;
|
||||
return false;
|
||||
} else {
|
||||
mDragged = true;
|
||||
mSimpleHandler.removeCallbacks(mHideRunnable);
|
||||
// Update mLastMotionY
|
||||
if (mDownY < mHandlerOffset || mDownY >= mHandlerOffset + mHandlerHeight) {
|
||||
// the point out of handler, make the point in handler center
|
||||
mLastMotionY = mHandlerOffset + mHandlerHeight / 2;
|
||||
} else {
|
||||
mLastMotionY = mDownY;
|
||||
}
|
||||
// Notify
|
||||
if (mListener != null) {
|
||||
mListener.onStartDragHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int range = mRecyclerView.computeVerticalScrollRange();
|
||||
if (range <= 0) {
|
||||
break;
|
||||
}
|
||||
float y = event.getY();
|
||||
int scroll = (int) (range * (y - mLastMotionY) / (getHeight() - getPaddingTop() - getPaddingBottom()));
|
||||
mRecyclerView.scrollBy(0, scroll);
|
||||
mLastMotionY = y;
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
// Notify
|
||||
if (mDragged && mListener != null) {
|
||||
mListener.onEndDragHandler();
|
||||
}
|
||||
mDragged = false;
|
||||
mSimpleHandler.postDelayed(mHideRunnable, SCROLL_BAR_DELAY);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public interface OnDragHandlerListener {
|
||||
void onStartDragHandler();
|
||||
|
||||
void onEndDragHandler();
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.easyrecyclerview;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class HandlerDrawable extends Drawable {
|
||||
|
||||
private final Paint mPaint;
|
||||
private final RectF mTemp = new RectF();
|
||||
private int mColor = Color.BLACK;
|
||||
|
||||
public HandlerDrawable() {
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaint.setColor(mColor);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
int width = getBounds().width();
|
||||
int height = getBounds().height();
|
||||
|
||||
if (width > height) {
|
||||
canvas.drawRect(0, 0, width, height, mPaint);
|
||||
} else {
|
||||
mTemp.set(0, 0, width, width);
|
||||
canvas.drawArc(mTemp, -180, 180, true, mPaint);
|
||||
mTemp.set(0, height - width, width, height);
|
||||
canvas.drawArc(mTemp, 0, 180, true, mPaint);
|
||||
float halfWidth = (float) width / 2.0f;
|
||||
canvas.drawRect(0, halfWidth, width, height - halfWidth, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
if (mColor != color) {
|
||||
mColor = color;
|
||||
mPaint.setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter colorFilter) {
|
||||
mPaint.setColorFilter(colorFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
int alpha = Color.alpha(mColor);
|
||||
if (alpha == 0xff) {
|
||||
return PixelFormat.OPAQUE;
|
||||
} else if (alpha == 0x00) {
|
||||
return PixelFormat.TRANSPARENT;
|
||||
} else {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.easyrecyclerview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
import com.hippo.yorozuya.SimpleHandler;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class LayoutManagerUtils {
|
||||
|
||||
private static Method sCsdfp = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
sCsdfp = StaggeredGridLayoutManager.class.getDeclaredMethod("calculateScrollDirectionForPosition", int.class);
|
||||
sCsdfp.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// Ignore
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void scrollToPositionWithOffset(
|
||||
RecyclerView.LayoutManager layoutManager, int position, int offset) {
|
||||
if (layoutManager instanceof LinearLayoutManager) {
|
||||
((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(position, offset);
|
||||
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
|
||||
((StaggeredGridLayoutManager) layoutManager).scrollToPositionWithOffset(position, offset);
|
||||
} else {
|
||||
throw new IllegalStateException("Can't do scrollToPositionWithOffset for " +
|
||||
layoutManager.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static void smoothScrollToPosition(
|
||||
RecyclerView.LayoutManager layoutManager, Context context, int position) {
|
||||
smoothScrollToPosition(layoutManager, context, position, -1);
|
||||
}
|
||||
|
||||
public static void smoothScrollToPosition(
|
||||
RecyclerView.LayoutManager layoutManager, Context context, int position,
|
||||
int millisecondsPerInch) {
|
||||
SimpleSmoothScroller smoothScroller;
|
||||
if (layoutManager instanceof final LinearLayoutManager linearLayoutManager) {
|
||||
smoothScroller = new SimpleSmoothScroller(context, millisecondsPerInch) {
|
||||
@Override
|
||||
public PointF computeScrollVectorForPosition(int targetPosition) {
|
||||
return linearLayoutManager.computeScrollVectorForPosition(targetPosition);
|
||||
}
|
||||
};
|
||||
|
||||
} else if (layoutManager instanceof final StaggeredGridLayoutManager staggeredGridLayoutManager) {
|
||||
smoothScroller = new SimpleSmoothScroller(context, millisecondsPerInch) {
|
||||
@Override
|
||||
public PointF computeScrollVectorForPosition(int targetPosition) {
|
||||
int direction = 0;
|
||||
try {
|
||||
direction = (Integer) sCsdfp.invoke(staggeredGridLayoutManager, targetPosition);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (direction == 0) {
|
||||
return null;
|
||||
}
|
||||
if (staggeredGridLayoutManager.getOrientation() == StaggeredGridLayoutManager.HORIZONTAL) {
|
||||
return new PointF(direction, 0);
|
||||
} else {
|
||||
return new PointF(0, direction);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException("Can't do smoothScrollToPosition for " +
|
||||
layoutManager.getClass().getName());
|
||||
}
|
||||
smoothScroller.setTargetPosition(position);
|
||||
layoutManager.startSmoothScroll(smoothScroller);
|
||||
}
|
||||
|
||||
public static void scrollToPositionProperly(final RecyclerView.LayoutManager layoutManager,
|
||||
final Context context, final int position, final OnScrollToPositionListener listener) {
|
||||
SimpleHandler.getInstance().postDelayed(() -> {
|
||||
int first = getFirstVisibleItemPosition(layoutManager);
|
||||
int last = getLastVisibleItemPosition(layoutManager);
|
||||
int offset = Math.abs(position - first);
|
||||
int max = last - first;
|
||||
if (offset < max && max > 0) {
|
||||
smoothScrollToPosition(layoutManager, context, position,
|
||||
MathUtils.lerp(100, 25, (offset / max)));
|
||||
} else {
|
||||
scrollToPositionWithOffset(layoutManager, position, 0);
|
||||
if (listener != null) {
|
||||
listener.onScrollToPosition(position);
|
||||
}
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
public static int getFirstVisibleItemPosition(RecyclerView.LayoutManager layoutManager) {
|
||||
if (layoutManager instanceof LinearLayoutManager) {
|
||||
return ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
|
||||
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
|
||||
int[] positions = ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(null);
|
||||
return MathUtils.min(positions);
|
||||
} else {
|
||||
throw new IllegalStateException("Can't do getFirstVisibleItemPosition for " +
|
||||
layoutManager.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static int getLastVisibleItemPosition(RecyclerView.LayoutManager layoutManager) {
|
||||
if (layoutManager instanceof LinearLayoutManager) {
|
||||
return ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
|
||||
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
|
||||
int[] positions = ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(null);
|
||||
return MathUtils.max(positions);
|
||||
} else {
|
||||
throw new IllegalStateException("Can't do getLastVisibleItemPosition for " +
|
||||
layoutManager.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnScrollToPositionListener {
|
||||
void onScrollToPosition(int position);
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.easyrecyclerview;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class MarginItemDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private int mMargin;
|
||||
private int mPaddingLeft;
|
||||
private int mPaddingTop;
|
||||
private int mPaddingRight;
|
||||
private int mPaddingBottom;
|
||||
|
||||
public MarginItemDecoration(int margin, int paddingLeft, int paddingTop,
|
||||
int paddingRight, int paddingBottom) {
|
||||
setMargin(margin, paddingLeft, paddingTop, paddingRight, paddingBottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view,
|
||||
RecyclerView parent, RecyclerView.State state) {
|
||||
outRect.set(mMargin, mMargin, mMargin, mMargin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param margin gap between two item
|
||||
* @param paddingLeft gap between RecyclerView left and left item left
|
||||
* @param paddingTop gap between RecyclerView top and top item top
|
||||
* @param paddingRight gap between RecyclerView right and right item right
|
||||
* @param paddingBottom gap between RecyclerView bottom and bottom item bottom
|
||||
*/
|
||||
public void setMargin(int margin, int paddingLeft, int paddingTop,
|
||||
int paddingRight, int paddingBottom) {
|
||||
int halfMargin = margin / 2;
|
||||
mMargin = halfMargin;
|
||||
mPaddingLeft = paddingLeft - halfMargin;
|
||||
mPaddingTop = paddingTop - halfMargin;
|
||||
mPaddingRight = paddingRight - halfMargin;
|
||||
mPaddingBottom = paddingBottom - halfMargin;
|
||||
}
|
||||
|
||||
public void applyPaddings(View view) {
|
||||
view.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.easyrecyclerview;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class SimpleHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public SimpleHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.easyrecyclerview;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.recyclerview.widget.LinearSmoothScroller;
|
||||
|
||||
public abstract class SimpleSmoothScroller extends LinearSmoothScroller {
|
||||
|
||||
private final float mMillisecondsPerPx;
|
||||
|
||||
public SimpleSmoothScroller(Context context, float millisecondsPerInch) {
|
||||
super(context);
|
||||
mMillisecondsPerPx = millisecondsPerInch / context.getResources().getDisplayMetrics().densityDpi;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateTimeForScrolling(int dx) {
|
||||
if (mMillisecondsPerPx <= 0) {
|
||||
return super.calculateTimeForScrolling(dx);
|
||||
} else {
|
||||
return (int) Math.ceil(Math.abs(dx) * mMillisecondsPerPx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.hippo.ehviewer.client.exception.ParseException;
|
||||
import com.hippo.util.ReadableTime;
|
||||
import com.hippo.yorozuya.FileUtils;
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class AppConfig {
|
||||
|
||||
public static final String APP_DIRNAME = "EhViewer";
|
||||
|
||||
private static final String DOWNLOAD = "download";
|
||||
private static final String TEMP = "temp";
|
||||
private static final String PARSE_ERROR = "parse_error";
|
||||
private static final String CRASH = "crash";
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static Context sContext;
|
||||
|
||||
public static void initialize(Context context) {
|
||||
sContext = context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getExternalAppDir() {
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||
File dir = sContext.getExternalFilesDir(null);
|
||||
return FileUtils.ensureDirectory(dir) ? dir : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* mkdirs and get
|
||||
*/
|
||||
@Nullable
|
||||
public static File getDirInExternalAppDir(String filename) {
|
||||
File appFolder = getExternalAppDir();
|
||||
if (appFolder != null) {
|
||||
File dir = new File(appFolder, filename);
|
||||
return FileUtils.ensureDirectory(dir) ? dir : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getFileInExternalAppDir(String filename) {
|
||||
File appFolder = getExternalAppDir();
|
||||
if (appFolder != null) {
|
||||
File file = new File(appFolder, filename);
|
||||
return FileUtils.ensureFile(file) ? file : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getDefaultDownloadDir() {
|
||||
return getDirInExternalAppDir(DOWNLOAD);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getExternalTempDir() {
|
||||
File dir = sContext.getExternalCacheDir();
|
||||
File file;
|
||||
if (null != dir && FileUtils.ensureDirectory(file = new File(dir, TEMP))) {
|
||||
return file;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getExternalCopyTempDir() {
|
||||
File dir = sContext.getExternalCacheDir();
|
||||
File file;
|
||||
if (null != dir && FileUtils.ensureDirectory(file = new File(dir, "copy"))) {
|
||||
return file;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getExternalParseErrorDir() {
|
||||
return getDirInExternalAppDir(PARSE_ERROR);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getExternalCrashDir() {
|
||||
return getDirInExternalAppDir(CRASH);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getTempDir() {
|
||||
File dir = sContext.getCacheDir();
|
||||
File file;
|
||||
if (null != dir && FileUtils.ensureDirectory(file = new File(dir, TEMP))) {
|
||||
return file;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File createTempFile() {
|
||||
return FileUtils.createTempFile(getTempDir(), null);
|
||||
}
|
||||
|
||||
public static void saveParseErrorBody(ParseException e) {
|
||||
File dir = getExternalParseErrorDir();
|
||||
if (null == dir) {
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(dir, ReadableTime.getFilenamableTime(System.currentTimeMillis()) + ".txt");
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(file);
|
||||
String message = e.getMessage();
|
||||
String body = e.getBody();
|
||||
if (null != message) {
|
||||
os.write(message.getBytes(StandardCharsets.UTF_8));
|
||||
os.write('\n');
|
||||
}
|
||||
if (null != body) {
|
||||
os.write(body.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
os.flush();
|
||||
} catch (IOException e1) {
|
||||
// Ignore
|
||||
} finally {
|
||||
IOUtils.closeQuietly(os);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getFilesDir(String name) {
|
||||
File dir = sContext.getFilesDir();
|
||||
if (dir == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
dir = new File(dir, name);
|
||||
if (dir.isDirectory() || dir.mkdirs()) {
|
||||
return dir;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Debug;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.hippo.scene.StageActivity;
|
||||
import com.hippo.util.PackageUtils;
|
||||
import com.hippo.util.ReadableTime;
|
||||
import com.hippo.yorozuya.FileUtils;
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
import com.hippo.yorozuya.OSUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class Crash {
|
||||
private Crash() {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static String avoidNull(String str) {
|
||||
return null != str ? str : "null";
|
||||
}
|
||||
|
||||
private static void collectInfo(Context context, FileWriter fw) throws IOException {
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
|
||||
if (pi != null) {
|
||||
String versionName = pi.versionName == null ? "null" : pi.versionName;
|
||||
String versionCode = String.valueOf(pi.versionCode);
|
||||
fw.write("======== PackageInfo ========\r\n");
|
||||
fw.write("PackageName=");
|
||||
fw.write(pi.packageName);
|
||||
fw.write("\r\n");
|
||||
fw.write("VersionName=");
|
||||
fw.write(versionName);
|
||||
fw.write("\r\n");
|
||||
fw.write("VersionCode=");
|
||||
fw.write(versionCode);
|
||||
fw.write("\r\n");
|
||||
String signature = PackageUtils.getSignature(context, pi.packageName);
|
||||
fw.write("Signature=");
|
||||
fw.write(null != signature ? signature : "null");
|
||||
fw.write("\r\n");
|
||||
fw.write("\r\n");
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
fw.write("======== PackageInfo ========\r\n");
|
||||
fw.write("Can't get package information\r\n");
|
||||
fw.write("\r\n");
|
||||
}
|
||||
|
||||
// Runtime
|
||||
String topActivityClazzName = "null";
|
||||
String topSceneClazzName = "null";
|
||||
try {
|
||||
Activity topActivity = ((EhApplication) context.getApplicationContext()).getTopActivity();
|
||||
if (null != topActivity) {
|
||||
topActivityClazzName = topActivity.getClass().getName();
|
||||
if (topActivity instanceof StageActivity) {
|
||||
Class<?> clazz = ((StageActivity) topActivity).getTopSceneClass();
|
||||
if (clazz != null) {
|
||||
topSceneClazzName = clazz.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
// Ignore
|
||||
}
|
||||
fw.write("======== Runtime ========\r\n");
|
||||
fw.write("TopActivity=");
|
||||
fw.write(avoidNull(topActivityClazzName));
|
||||
fw.write("\r\n");
|
||||
fw.write("TopScene=");
|
||||
fw.write(avoidNull(topSceneClazzName));
|
||||
fw.write("\r\n");
|
||||
fw.write("\r\n");
|
||||
|
||||
// Device info
|
||||
fw.write("======== DeviceInfo ========\r\n");
|
||||
fw.write("BOARD=");
|
||||
fw.write(Build.BOARD);
|
||||
fw.write("\r\n");
|
||||
fw.write("BOOTLOADER=");
|
||||
fw.write(Build.BOOTLOADER);
|
||||
fw.write("\r\n");
|
||||
fw.write("SUPPORTED_ABIS=");
|
||||
fw.write(Arrays.toString(Build.SUPPORTED_ABIS));
|
||||
fw.write("\r\n");
|
||||
fw.write("DEVICE=");
|
||||
fw.write(Build.DEVICE);
|
||||
fw.write("\r\n");
|
||||
fw.write("DISPLAY=");
|
||||
fw.write(Build.DISPLAY);
|
||||
fw.write("\r\n");
|
||||
fw.write("FINGERPRINT=");
|
||||
fw.write(Build.FINGERPRINT);
|
||||
fw.write("\r\n");
|
||||
fw.write("HARDWARE=");
|
||||
fw.write(Build.HARDWARE);
|
||||
fw.write("\r\n");
|
||||
fw.write("HOST=");
|
||||
fw.write(Build.HOST);
|
||||
fw.write("\r\n");
|
||||
fw.write("ID=");
|
||||
fw.write(Build.ID);
|
||||
fw.write("\r\n");
|
||||
fw.write("MANUFACTURER=");
|
||||
fw.write(Build.MANUFACTURER);
|
||||
fw.write("\r\n");
|
||||
fw.write("MODEL=");
|
||||
fw.write(Build.MODEL);
|
||||
fw.write("\r\n");
|
||||
fw.write("PRODUCT=");
|
||||
fw.write(Build.PRODUCT);
|
||||
fw.write("\r\n");
|
||||
fw.write("RADIO=");
|
||||
fw.write(Build.getRadioVersion());
|
||||
fw.write("\r\n");
|
||||
fw.write("TAGS=");
|
||||
fw.write(Build.TAGS);
|
||||
fw.write("\r\n");
|
||||
fw.write("TYPE=");
|
||||
fw.write(Build.TYPE);
|
||||
fw.write("\r\n");
|
||||
fw.write("USER=");
|
||||
fw.write(Build.USER);
|
||||
fw.write("\r\n");
|
||||
fw.write("CODENAME=");
|
||||
fw.write(Build.VERSION.CODENAME);
|
||||
fw.write("\r\n");
|
||||
fw.write("INCREMENTAL=");
|
||||
fw.write(Build.VERSION.INCREMENTAL);
|
||||
fw.write("\r\n");
|
||||
fw.write("RELEASE=");
|
||||
fw.write(Build.VERSION.RELEASE);
|
||||
fw.write("\r\n");
|
||||
fw.write("SDK=");
|
||||
fw.write(Integer.toString(Build.VERSION.SDK_INT));
|
||||
fw.write("\r\n");
|
||||
fw.write("MEMORY=");
|
||||
fw.write(
|
||||
FileUtils.humanReadableByteCount(OSUtils.getAppAllocatedMemory(), false));
|
||||
fw.write("\r\n");
|
||||
fw.write("MEMORY_NATIVE=");
|
||||
fw.write(FileUtils.humanReadableByteCount(Debug.getNativeHeapAllocatedSize(), false));
|
||||
fw.write("\r\n");
|
||||
fw.write("MEMORY_MAX=");
|
||||
fw.write(FileUtils.humanReadableByteCount(OSUtils.getAppMaxMemory(), false));
|
||||
fw.write("\r\n");
|
||||
fw.write("MEMORY_TOTAL=");
|
||||
fw.write(FileUtils.humanReadableByteCount(OSUtils.getTotalMemory(), false));
|
||||
fw.write("\r\n");
|
||||
fw.write("\r\n");
|
||||
}
|
||||
|
||||
private static void getThrowableInfo(Throwable t, FileWriter fw) {
|
||||
PrintWriter printWriter = new PrintWriter(fw);
|
||||
t.printStackTrace(printWriter);
|
||||
Throwable cause = t.getCause();
|
||||
while (cause != null) {
|
||||
cause.printStackTrace(printWriter);
|
||||
cause = cause.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveCrashLog(Context context, Throwable t) {
|
||||
File dir = AppConfig.getExternalCrashDir();
|
||||
if (dir == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String nowString = ReadableTime.getFilenamableTime(System.currentTimeMillis());
|
||||
String fileName = "crash-" + nowString + ".log";
|
||||
File file = new File(dir, fileName);
|
||||
|
||||
FileWriter fw = null;
|
||||
try {
|
||||
fw = new FileWriter(file);
|
||||
fw.write("TIME=");
|
||||
fw.write(nowString);
|
||||
fw.write("\r\n");
|
||||
fw.write("\r\n");
|
||||
collectInfo(context, fw);
|
||||
fw.write("======== CrashInfo ========\r\n");
|
||||
getThrowableInfo(t, fw);
|
||||
fw.write("\r\n");
|
||||
fw.flush();
|
||||
} catch (Exception e) {
|
||||
file.delete();
|
||||
} finally {
|
||||
IOUtils.closeQuietly(fw);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,353 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.ActivityManager
|
||||
import android.content.ComponentCallbacks2
|
||||
import android.os.Build
|
||||
import android.text.Html
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.collection.LruCache
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.ProcessLifecycleOwner
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import com.hippo.Native
|
||||
import com.hippo.app.BaseDialogBuilder
|
||||
import com.hippo.beerbelly.SimpleDiskCache
|
||||
import com.hippo.ehviewer.client.EhClient
|
||||
import com.hippo.ehviewer.client.EhCookieStore
|
||||
import com.hippo.ehviewer.client.EhDns
|
||||
import com.hippo.ehviewer.client.EhEngine
|
||||
import com.hippo.ehviewer.client.EhRequestBuilder
|
||||
import com.hippo.ehviewer.client.EhSSLSocketFactory
|
||||
import com.hippo.ehviewer.client.EhUrl
|
||||
import com.hippo.ehviewer.client.EhX509TrustManager
|
||||
import com.hippo.ehviewer.client.data.GalleryDetail
|
||||
import com.hippo.ehviewer.client.parser.EventPaneParser
|
||||
import com.hippo.ehviewer.download.DownloadManager
|
||||
import com.hippo.ehviewer.spider.SpiderDen
|
||||
import com.hippo.ehviewer.ui.CommonOperations
|
||||
import com.hippo.ehviewer.ui.EhActivity
|
||||
import com.hippo.scene.SceneApplication
|
||||
import com.hippo.util.BitmapUtils
|
||||
import com.hippo.util.ExceptionUtils
|
||||
import com.hippo.util.ReadableTime
|
||||
import com.hippo.yorozuya.FileUtils
|
||||
import com.hippo.yorozuya.IntIdGenerator
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.Cache
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import java.io.File
|
||||
import java.net.Proxy
|
||||
import java.security.KeyStore
|
||||
import java.util.Arrays
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
import javax.net.ssl.X509TrustManager
|
||||
|
||||
class EhApplication : SceneApplication(), DefaultLifecycleObserver, ImageLoaderFactory {
|
||||
private val mIdGenerator = IntIdGenerator()
|
||||
private val mGlobalStuffMap = HashMap<Int, Any>()
|
||||
private val mActivityList = ArrayList<Activity>()
|
||||
private var initialized = false
|
||||
val topActivity: EhActivity?
|
||||
get() = if (mActivityList.isNotEmpty()) {
|
||||
mActivityList[mActivityList.size - 1] as EhActivity
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
fun recreateAllActivity() {
|
||||
mActivityList.forEach { it.recreate() }
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
override fun onCreate() {
|
||||
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
|
||||
application = this
|
||||
val handler = Thread.getDefaultUncaughtExceptionHandler()
|
||||
Thread.setDefaultUncaughtExceptionHandler { t, e ->
|
||||
try {
|
||||
if (Settings.getSaveCrashLog()) {
|
||||
Crash.saveCrashLog(application, e)
|
||||
}
|
||||
} catch (ignored: Throwable) {
|
||||
}
|
||||
handler?.uncaughtException(t, e)
|
||||
}
|
||||
super<SceneApplication>.onCreate()
|
||||
Native.initialize()
|
||||
GetText.initialize(this)
|
||||
Settings.initialize(this)
|
||||
ReadableTime.initialize(this)
|
||||
AppConfig.initialize(this)
|
||||
SpiderDen.initialize(this)
|
||||
EhDB.initialize(this)
|
||||
EhEngine.initialize()
|
||||
BitmapUtils.initialize(this)
|
||||
|
||||
// Locales can be managed by system automatically above Snow Cone v2
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
|
||||
AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Settings.getLocale()))
|
||||
AppCompatDelegate.setDefaultNightMode(Settings.getTheme())
|
||||
|
||||
GlobalScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
val downloadLocation = Settings.getDownloadLocation()
|
||||
if (Settings.getMediaScan()) {
|
||||
CommonOperations.removeNoMediaFile(downloadLocation)
|
||||
} else {
|
||||
CommonOperations.ensureNoMediaFile(downloadLocation)
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
ExceptionUtils.throwIfFatal(t)
|
||||
}
|
||||
|
||||
// Clear temp files
|
||||
try {
|
||||
clearTempDir()
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
ExceptionUtils.throwIfFatal(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
GlobalScope.launch {
|
||||
theDawnOfNewDay()
|
||||
}
|
||||
mIdGenerator.setNextId(Settings.getInt(KEY_GLOBAL_STUFF_NEXT_ID, 0))
|
||||
initialized = true
|
||||
}
|
||||
|
||||
private suspend fun theDawnOfNewDay() {
|
||||
if (!Settings.getRequestNews()) {
|
||||
return
|
||||
}
|
||||
val store = ehCookieStore
|
||||
val eh = EhUrl.HOST_E.toHttpUrl()
|
||||
|
||||
if (store.contains(eh, EhCookieStore.KEY_IPD_MEMBER_ID) || store.contains(
|
||||
eh,
|
||||
EhCookieStore.KEY_IPD_PASS_HASH
|
||||
)
|
||||
) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val referer = EhUrl.REFERER_E
|
||||
val request = EhRequestBuilder(EhUrl.HOST_E + "news.php", referer).build()
|
||||
val call = okHttpClient.newCall(request)
|
||||
try {
|
||||
call.execute().use { response ->
|
||||
val responseBody = response.body
|
||||
val body = responseBody.string()
|
||||
val html = EventPaneParser.parse(body)
|
||||
if (html != null) {
|
||||
showEventPane(html)
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun showEventPane(html: String) {
|
||||
if (Settings.getHideHvEvents() && html.contains("You have encountered a monster!")) {
|
||||
return
|
||||
}
|
||||
val activity = topActivity
|
||||
activity?.runOnUiThread {
|
||||
val dialog = BaseDialogBuilder(activity)
|
||||
.setMessage(Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY))
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.create()
|
||||
dialog.setOnShowListener {
|
||||
val messageView = dialog.findViewById<View>(android.R.id.message)
|
||||
if (messageView is TextView) {
|
||||
messageView.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
}
|
||||
try {
|
||||
dialog.show()
|
||||
} catch (t: Throwable) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearTempDir() {
|
||||
var dir = AppConfig.getTempDir()
|
||||
if (null != dir) {
|
||||
FileUtils.deleteContent(dir)
|
||||
}
|
||||
dir = AppConfig.getExternalTempDir()
|
||||
if (null != dir) {
|
||||
FileUtils.deleteContent(dir)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTrimMemory(level: Int) {
|
||||
super.onTrimMemory(level)
|
||||
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) {
|
||||
galleryDetailCache.evictAll()
|
||||
}
|
||||
}
|
||||
|
||||
fun putGlobalStuff(o: Any): Int {
|
||||
val id = mIdGenerator.nextId()
|
||||
mGlobalStuffMap[id] = o
|
||||
Settings.putInt(KEY_GLOBAL_STUFF_NEXT_ID, mIdGenerator.nextId())
|
||||
return id
|
||||
}
|
||||
|
||||
fun containGlobalStuff(id: Int): Boolean {
|
||||
return mGlobalStuffMap.containsKey(id)
|
||||
}
|
||||
|
||||
fun getGlobalStuff(id: Int): Any? {
|
||||
return mGlobalStuffMap[id]
|
||||
}
|
||||
|
||||
fun removeGlobalStuff(id: Int): Any? {
|
||||
return mGlobalStuffMap.remove(id)
|
||||
}
|
||||
|
||||
fun removeGlobalStuff(o: Any) {
|
||||
mGlobalStuffMap.values.removeAll(setOf(o))
|
||||
}
|
||||
|
||||
fun registerActivity(activity: Activity) {
|
||||
mActivityList.add(activity)
|
||||
}
|
||||
|
||||
fun unregisterActivity(activity: Activity) {
|
||||
mActivityList.remove(activity)
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
if (!locked)
|
||||
locked_last_leave_time = System.currentTimeMillis() / 1000
|
||||
locked = true
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun newImageLoader(): ImageLoader {
|
||||
return ImageLoader.Builder(this).apply {
|
||||
okHttpClient(okHttpClient)
|
||||
allowRgb565(getSystemService<ActivityManager>()!!.isLowRamDevice)
|
||||
// Coil spawns a new thread for every image load by default
|
||||
fetcherDispatcher(Dispatchers.IO.limitedParallelism(8))
|
||||
decoderDispatcher(Dispatchers.IO.limitedParallelism(2))
|
||||
transformationDispatcher(Dispatchers.IO.limitedParallelism(2))
|
||||
}.build()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_GLOBAL_STUFF_NEXT_ID = "global_stuff_next_id"
|
||||
var locked = true
|
||||
var locked_last_leave_time: Long = 0
|
||||
|
||||
@JvmStatic
|
||||
lateinit var application: EhApplication
|
||||
private set
|
||||
|
||||
@JvmStatic
|
||||
val ehCookieStore by lazy { EhCookieStore(application) }
|
||||
|
||||
@JvmStatic
|
||||
val ehClient by lazy { EhClient() }
|
||||
|
||||
@JvmStatic
|
||||
val ehProxySelector by lazy { EhProxySelector() }
|
||||
|
||||
@JvmStatic
|
||||
val okHttpClient by lazy {
|
||||
val builder = OkHttpClient.Builder()
|
||||
.cookieJar(ehCookieStore)
|
||||
.cache(Cache(File(application.cacheDir, "http_cache"), 50L * 1024L * 1024L))
|
||||
.dns(EhDns())
|
||||
.proxySelector(ehProxySelector)
|
||||
|
||||
if (Settings.getDF()) {
|
||||
var trustManager: X509TrustManager
|
||||
try {
|
||||
val trustManagerFactory = TrustManagerFactory.getInstance(
|
||||
TrustManagerFactory.getDefaultAlgorithm()
|
||||
)
|
||||
trustManagerFactory.init(null as KeyStore?)
|
||||
val trustManagers = trustManagerFactory.trustManagers
|
||||
check(!(trustManagers.size != 1 || trustManagers[0] !is X509TrustManager)) {
|
||||
"Unexpected default trust managers:" + Arrays.toString(
|
||||
trustManagers
|
||||
)
|
||||
}
|
||||
trustManager = trustManagers[0] as X509TrustManager
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
trustManager = EhX509TrustManager()
|
||||
}
|
||||
|
||||
builder.sslSocketFactory(EhSSLSocketFactory(), trustManager)
|
||||
builder.proxy(Proxy.NO_PROXY)
|
||||
}
|
||||
builder.build()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
val galleryDetailCache by lazy {
|
||||
LruCache<Long, GalleryDetail>(25).also {
|
||||
favouriteStatusRouter.addListener { gid, slot ->
|
||||
it[gid]?.favoriteSlot = slot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
val spiderInfoCache by lazy {
|
||||
SimpleDiskCache(
|
||||
File(application.cacheDir, "spider_info"),
|
||||
20 * 1024 * 1024
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
val downloadManager by lazy { DownloadManager(application) }
|
||||
|
||||
@JvmStatic
|
||||
val hosts by lazy { Hosts(application, "hosts.db") }
|
||||
|
||||
@JvmStatic
|
||||
val favouriteStatusRouter by lazy { FavouriteStatusRouter() }
|
||||
}
|
||||
}
|
||||
@@ -1,575 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.paging.PagingSource;
|
||||
import androidx.room.Room;
|
||||
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo;
|
||||
import com.hippo.ehviewer.dao.BasicDao;
|
||||
import com.hippo.ehviewer.dao.DownloadDirname;
|
||||
import com.hippo.ehviewer.dao.DownloadDirnameDao;
|
||||
import com.hippo.ehviewer.dao.DownloadInfo;
|
||||
import com.hippo.ehviewer.dao.DownloadLabel;
|
||||
import com.hippo.ehviewer.dao.DownloadLabelDao;
|
||||
import com.hippo.ehviewer.dao.DownloadsDao;
|
||||
import com.hippo.ehviewer.dao.EhDatabase;
|
||||
import com.hippo.ehviewer.dao.Filter;
|
||||
import com.hippo.ehviewer.dao.HistoryDao;
|
||||
import com.hippo.ehviewer.dao.HistoryInfo;
|
||||
import com.hippo.ehviewer.dao.LocalFavoriteInfo;
|
||||
import com.hippo.ehviewer.dao.LocalFavoritesDao;
|
||||
import com.hippo.ehviewer.dao.QuickSearch;
|
||||
import com.hippo.ehviewer.dao.QuickSearchDao;
|
||||
import com.hippo.ehviewer.download.DownloadManager;
|
||||
import com.hippo.util.ExceptionUtils;
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
import com.hippo.yorozuya.ObjectUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EhDB {
|
||||
private static final int CUR_DB_VER = 4;
|
||||
|
||||
private static EhDatabase db;
|
||||
|
||||
private static void upgradeDB(SQLiteDatabase db, int oldVersion) {
|
||||
switch (oldVersion) {
|
||||
case 1: // 1 to 2, add FILTER
|
||||
db.execSQL("CREATE TABLE IF NOT EXISTS \"FILTER\" (" + //
|
||||
"\"_id\" INTEGER PRIMARY KEY ," + // 0: id
|
||||
"\"MODE\" INTEGER NOT NULL ," + // 1: mode
|
||||
"\"TEXT\" TEXT," + // 2: text
|
||||
"\"ENABLE\" INTEGER);"); // 3: enable
|
||||
case 2: // 2 to 3, add ENABLE column to table FILTER
|
||||
db.execSQL("CREATE TABLE " + "\"FILTER2\" (" +
|
||||
"\"_id\" INTEGER PRIMARY KEY ," +
|
||||
"\"MODE\" INTEGER NOT NULL ," +
|
||||
"\"TEXT\" TEXT," +
|
||||
"\"ENABLE\" INTEGER);");
|
||||
db.execSQL("INSERT INTO \"FILTER2\" (" +
|
||||
"_id, MODE, TEXT, ENABLE)" +
|
||||
"SELECT _id, MODE, TEXT, 1 FROM FILTER;");
|
||||
db.execSQL("DROP TABLE FILTER");
|
||||
db.execSQL("ALTER TABLE FILTER2 RENAME TO FILTER");
|
||||
case 3: // 3 to 4, add PAGE_FROM and PAGE_TO column to QUICK_SEARCH
|
||||
db.execSQL("CREATE TABLE " + "\"QUICK_SEARCH2\" (" +
|
||||
"\"_id\" INTEGER PRIMARY KEY ," +
|
||||
"\"NAME\" TEXT," +
|
||||
"\"MODE\" INTEGER NOT NULL ," +
|
||||
"\"CATEGORY\" INTEGER NOT NULL ," +
|
||||
"\"KEYWORD\" TEXT," +
|
||||
"\"ADVANCE_SEARCH\" INTEGER NOT NULL ," +
|
||||
"\"MIN_RATING\" INTEGER NOT NULL ," +
|
||||
"\"PAGE_FROM\" INTEGER NOT NULL ," +
|
||||
"\"PAGE_TO\" INTEGER NOT NULL ," +
|
||||
"\"TIME\" INTEGER NOT NULL );");
|
||||
db.execSQL("INSERT INTO \"QUICK_SEARCH2\" (" +
|
||||
"_id, NAME, MODE, CATEGORY, KEYWORD, ADVANCE_SEARCH, MIN_RATING, PAGE_FROM, PAGE_TO, TIME)" +
|
||||
"SELECT _id, NAME, MODE, CATEGORY, KEYWORD, ADVANCE_SEARCH, MIN_RATING, -1, -1, TIME FROM QUICK_SEARCH;");
|
||||
db.execSQL("DROP TABLE QUICK_SEARCH");
|
||||
db.execSQL("ALTER TABLE QUICK_SEARCH2 RENAME TO QUICK_SEARCH");
|
||||
}
|
||||
}
|
||||
|
||||
public static void initialize(Context context) {
|
||||
db = Room.databaseBuilder(context, EhDatabase.class, "eh.db").allowMainThreadQueries().build();
|
||||
}
|
||||
|
||||
public static synchronized List<DownloadInfo> getAllDownloadInfo() {
|
||||
DownloadsDao dao = db.downloadsDao();
|
||||
List<DownloadInfo> list = dao.list();
|
||||
// Fix state
|
||||
for (DownloadInfo info : list) {
|
||||
if (info.state == DownloadInfo.STATE_WAIT || info.state == DownloadInfo.STATE_DOWNLOAD) {
|
||||
info.state = DownloadInfo.STATE_NONE;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// Insert or update
|
||||
public static synchronized void putDownloadInfo(DownloadInfo downloadInfo) {
|
||||
DownloadsDao dao = db.downloadsDao();
|
||||
if (null != dao.load(downloadInfo.gid)) {
|
||||
// Update
|
||||
dao.update(downloadInfo);
|
||||
} else {
|
||||
// Insert
|
||||
dao.insert(downloadInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void removeDownloadInfo(DownloadInfo downloadInfo) {
|
||||
db.downloadsDao().delete(downloadInfo);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static synchronized String getDownloadDirname(long gid) {
|
||||
DownloadDirnameDao dao = db.downloadDirnameDao();
|
||||
DownloadDirname raw = dao.load(gid);
|
||||
if (raw != null) {
|
||||
return raw.getDirname();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert or update
|
||||
*/
|
||||
public static synchronized void putDownloadDirname(long gid, String dirname) {
|
||||
DownloadDirnameDao dao = db.downloadDirnameDao();
|
||||
DownloadDirname raw = dao.load(gid);
|
||||
if (raw != null) { // Update
|
||||
raw.setDirname(dirname);
|
||||
dao.update(raw);
|
||||
} else { // Insert
|
||||
raw = new DownloadDirname();
|
||||
raw.setGid(gid);
|
||||
raw.setDirname(dirname);
|
||||
dao.insert(raw);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void removeDownloadDirname(long gid) {
|
||||
DownloadDirnameDao dao = db.downloadDirnameDao();
|
||||
dao.deleteByKey(gid);
|
||||
}
|
||||
|
||||
public static synchronized void clearDownloadDirname() {
|
||||
DownloadDirnameDao dao = db.downloadDirnameDao();
|
||||
dao.deleteAll();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static synchronized List<DownloadLabel> getAllDownloadLabelList() {
|
||||
DownloadLabelDao dao = db.downloadLabelDao();
|
||||
return dao.list();
|
||||
}
|
||||
|
||||
public static synchronized DownloadLabel addDownloadLabel(String label) {
|
||||
DownloadLabelDao dao = db.downloadLabelDao();
|
||||
DownloadLabel raw = new DownloadLabel();
|
||||
raw.setLabel(label);
|
||||
raw.setTime(System.currentTimeMillis());
|
||||
raw.setId(dao.insert(raw));
|
||||
return raw;
|
||||
}
|
||||
|
||||
public static synchronized DownloadLabel addDownloadLabel(DownloadLabel raw) {
|
||||
// Reset id
|
||||
raw.setId(null);
|
||||
DownloadLabelDao dao = db.downloadLabelDao();
|
||||
raw.setId(dao.insert(raw));
|
||||
return raw;
|
||||
}
|
||||
|
||||
public static synchronized void updateDownloadLabel(DownloadLabel raw) {
|
||||
DownloadLabelDao dao = db.downloadLabelDao();
|
||||
dao.update(raw);
|
||||
}
|
||||
|
||||
public static synchronized void moveDownloadLabel(int fromPosition, int toPosition) {
|
||||
if (fromPosition == toPosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean reverse = fromPosition > toPosition;
|
||||
int offset = reverse ? toPosition : fromPosition;
|
||||
int limit = reverse ? fromPosition - toPosition + 1 : toPosition - fromPosition + 1;
|
||||
|
||||
DownloadLabelDao dao = db.downloadLabelDao();
|
||||
List<DownloadLabel> list = dao.list(offset, limit);
|
||||
|
||||
int step = reverse ? 1 : -1;
|
||||
int start = reverse ? limit - 1 : 0;
|
||||
int end = reverse ? 0 : limit - 1;
|
||||
long toTime = list.get(end).getTime();
|
||||
for (int i = end; reverse ? i < start : i > start; i += step) {
|
||||
list.get(i).setTime(list.get(i + step).getTime());
|
||||
}
|
||||
list.get(start).setTime(toTime);
|
||||
|
||||
dao.update(list);
|
||||
}
|
||||
|
||||
public static synchronized void removeDownloadLabel(DownloadLabel raw) {
|
||||
DownloadLabelDao dao = db.downloadLabelDao();
|
||||
dao.delete(raw);
|
||||
}
|
||||
|
||||
public static synchronized List<GalleryInfo> getAllLocalFavorites() {
|
||||
LocalFavoritesDao dao = db.localFavoritesDao();
|
||||
List<LocalFavoriteInfo> list = dao.list();
|
||||
return new ArrayList<>(list);
|
||||
}
|
||||
|
||||
public static synchronized List<GalleryInfo> searchLocalFavorites(String query) {
|
||||
LocalFavoritesDao dao = db.localFavoritesDao();
|
||||
List<LocalFavoriteInfo> list = dao.list("%" + query + "%");
|
||||
return new ArrayList<>(list);
|
||||
}
|
||||
|
||||
public static synchronized void removeLocalFavorites(long gid) {
|
||||
db.localFavoritesDao().deleteByKey(gid);
|
||||
}
|
||||
|
||||
public static synchronized void removeLocalFavorites(long[] gidArray) {
|
||||
LocalFavoritesDao dao = db.localFavoritesDao();
|
||||
for (long gid : gidArray) {
|
||||
dao.deleteByKey(gid);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized boolean containLocalFavorites(long gid) {
|
||||
LocalFavoritesDao dao = db.localFavoritesDao();
|
||||
return null != dao.load(gid);
|
||||
}
|
||||
|
||||
public static synchronized void putLocalFavorites(GalleryInfo galleryInfo) {
|
||||
LocalFavoritesDao dao = db.localFavoritesDao();
|
||||
if (null == dao.load(galleryInfo.gid)) {
|
||||
LocalFavoriteInfo info;
|
||||
if (galleryInfo instanceof LocalFavoriteInfo) {
|
||||
info = (LocalFavoriteInfo) galleryInfo;
|
||||
} else {
|
||||
info = new LocalFavoriteInfo(galleryInfo);
|
||||
info.time = System.currentTimeMillis();
|
||||
}
|
||||
dao.insert(info);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void putLocalFavorites(List<GalleryInfo> galleryInfoList) {
|
||||
for (GalleryInfo gi : galleryInfoList) {
|
||||
putLocalFavorites(gi);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized List<QuickSearch> getAllQuickSearch() {
|
||||
QuickSearchDao dao = db.quickSearchDao();
|
||||
return dao.list();
|
||||
}
|
||||
|
||||
public static synchronized void insertQuickSearch(QuickSearch quickSearch) {
|
||||
QuickSearchDao dao = db.quickSearchDao();
|
||||
quickSearch.id = null;
|
||||
quickSearch.time = System.currentTimeMillis();
|
||||
quickSearch.id = dao.insert(quickSearch);
|
||||
}
|
||||
|
||||
public static synchronized void importQuickSearch(List<QuickSearch> quickSearchList) {
|
||||
QuickSearchDao dao = db.quickSearchDao();
|
||||
for (QuickSearch quickSearch : quickSearchList) {
|
||||
dao.insert(quickSearch);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void deleteQuickSearch(QuickSearch quickSearch) {
|
||||
QuickSearchDao dao = db.quickSearchDao();
|
||||
dao.delete(quickSearch);
|
||||
}
|
||||
|
||||
public static synchronized void moveQuickSearch(int fromPosition, int toPosition) {
|
||||
if (fromPosition == toPosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean reverse = fromPosition > toPosition;
|
||||
int offset = reverse ? toPosition : fromPosition;
|
||||
int limit = reverse ? fromPosition - toPosition + 1 : toPosition - fromPosition + 1;
|
||||
|
||||
QuickSearchDao dao = db.quickSearchDao();
|
||||
List<QuickSearch> list = dao.list(offset, limit);
|
||||
|
||||
int step = reverse ? 1 : -1;
|
||||
int start = reverse ? limit - 1 : 0;
|
||||
int end = reverse ? 0 : limit - 1;
|
||||
long toTime = list.get(end).getTime();
|
||||
for (int i = end; reverse ? i < start : i > start; i += step) {
|
||||
list.get(i).setTime(list.get(i + step).getTime());
|
||||
}
|
||||
list.get(start).setTime(toTime);
|
||||
|
||||
dao.update(list);
|
||||
}
|
||||
|
||||
public static synchronized PagingSource<Integer, HistoryInfo> getHistoryLazyList() {
|
||||
return db.historyDao().listLazy();
|
||||
}
|
||||
|
||||
public static synchronized void putHistoryInfo(GalleryInfo galleryInfo) {
|
||||
HistoryDao dao = db.historyDao();
|
||||
HistoryInfo info;
|
||||
if (galleryInfo instanceof HistoryInfo) {
|
||||
info = (HistoryInfo) galleryInfo;
|
||||
} else {
|
||||
info = new HistoryInfo(galleryInfo);
|
||||
}
|
||||
info.time = System.currentTimeMillis();
|
||||
if (null != dao.load(info.gid)) {
|
||||
dao.update(info);
|
||||
} else {
|
||||
dao.insert(info);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void putHistoryInfo(List<HistoryInfo> historyInfoList) {
|
||||
HistoryDao dao = db.historyDao();
|
||||
for (HistoryInfo info : historyInfoList) {
|
||||
if (null == dao.load(info.gid)) {
|
||||
dao.insert(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void deleteHistoryInfo(HistoryInfo info) {
|
||||
HistoryDao dao = db.historyDao();
|
||||
dao.delete(info);
|
||||
}
|
||||
|
||||
public static synchronized void clearHistoryInfo() {
|
||||
HistoryDao dao = db.historyDao();
|
||||
dao.deleteAll();
|
||||
}
|
||||
|
||||
public static synchronized List<Filter> getAllFilter() {
|
||||
return db.filterDao().list();
|
||||
}
|
||||
|
||||
public static synchronized boolean addFilter(Filter filter) {
|
||||
Filter existFilter;
|
||||
try {
|
||||
existFilter = db.filterDao().load(filter.text, filter.mode);
|
||||
} catch (Exception e) {
|
||||
existFilter = null;
|
||||
}
|
||||
if (existFilter == null) {
|
||||
filter.setId(null);
|
||||
filter.setId(db.filterDao().insert(filter));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void deleteFilter(Filter filter) {
|
||||
db.filterDao().delete(filter);
|
||||
}
|
||||
|
||||
public static synchronized void triggerFilter(Filter filter) {
|
||||
filter.setEnable(!filter.enable);
|
||||
db.filterDao().update(filter);
|
||||
}
|
||||
|
||||
private static <T> void copyDao(BasicDao<T> from, BasicDao<T> to) {
|
||||
List<T> list = from.list();
|
||||
for (T item : list)
|
||||
to.insert(item);
|
||||
}
|
||||
|
||||
public static synchronized boolean exportDB(Context context, Uri uri) {
|
||||
final String ehExportName = "eh.export.db";
|
||||
|
||||
// Delete old export db
|
||||
context.deleteDatabase(ehExportName);
|
||||
EhDatabase newDb = Room.databaseBuilder(context, EhDatabase.class, ehExportName).allowMainThreadQueries().build();
|
||||
|
||||
try {
|
||||
// Copy data to a export db
|
||||
copyDao(db.downloadsDao(), newDb.downloadsDao());
|
||||
copyDao(db.downloadLabelDao(), newDb.downloadLabelDao());
|
||||
copyDao(db.downloadDirnameDao(), newDb.downloadDirnameDao());
|
||||
copyDao(db.historyDao(), newDb.historyDao());
|
||||
copyDao(db.quickSearchDao(), newDb.quickSearchDao());
|
||||
copyDao(db.localFavoritesDao(), newDb.localFavoritesDao());
|
||||
copyDao(db.filterDao(), newDb.filterDao());
|
||||
|
||||
// Close export db so we can copy it
|
||||
if (newDb.isOpen()) {
|
||||
newDb.close();
|
||||
}
|
||||
|
||||
// Copy export db to data dir
|
||||
File dbFile = context.getDatabasePath(ehExportName);
|
||||
if (dbFile == null || !dbFile.isFile()) {
|
||||
return false;
|
||||
}
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
is = new FileInputStream(dbFile);
|
||||
os = context.getContentResolver().openOutputStream(uri);
|
||||
IOUtils.copy(is, os);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
IOUtils.closeQuietly(os);
|
||||
}
|
||||
|
||||
// Delete failed file
|
||||
return false;
|
||||
} finally {
|
||||
context.deleteDatabase(ehExportName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return error string, null for no error
|
||||
*/
|
||||
public static synchronized String importDB(Context context, Uri uri) {
|
||||
try {
|
||||
InputStream inputStream = context.getContentResolver().openInputStream(uri);
|
||||
|
||||
// Copy file to cache dir
|
||||
File file = File.createTempFile("importDatabase", "");
|
||||
FileOutputStream outputStream = new FileOutputStream(file);
|
||||
byte[] buff = new byte[1024];
|
||||
int read;
|
||||
if (inputStream != null) {
|
||||
while ((read = inputStream.read(buff, 0, buff.length)) > 0) {
|
||||
outputStream.write(buff, 0, read);
|
||||
}
|
||||
} else {
|
||||
return context.getString(R.string.cant_read_the_file);
|
||||
}
|
||||
inputStream.close();
|
||||
outputStream.close();
|
||||
|
||||
// Check database version
|
||||
SQLiteDatabase oldDB = SQLiteDatabase.openDatabase(
|
||||
file.getPath(), null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
|
||||
int newVersion = CUR_DB_VER;
|
||||
int oldVersion = oldDB.getVersion();
|
||||
if (oldVersion < newVersion) {
|
||||
upgradeDB(oldDB, oldVersion);
|
||||
oldDB.setVersion(newVersion);
|
||||
} else if (oldVersion > newVersion) {
|
||||
return context.getString(R.string.db_version_too_high);
|
||||
}
|
||||
|
||||
// Crete temp room database from cache file
|
||||
String tmpDBName = "tmp.db";
|
||||
context.deleteDatabase(tmpDBName);
|
||||
EhDatabase oldRoomDatabase = Room.databaseBuilder(context, EhDatabase.class, tmpDBName)
|
||||
.createFromFile(file).allowMainThreadQueries().build();
|
||||
|
||||
// Download label
|
||||
DownloadManager manager = EhApplication.getDownloadManager();
|
||||
try {
|
||||
List<DownloadLabel> downloadLabelList = oldRoomDatabase.downloadLabelDao().list();
|
||||
manager.addDownloadLabel(downloadLabelList);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// Downloads
|
||||
try {
|
||||
List<DownloadInfo> downloadInfoList = oldRoomDatabase.downloadsDao().list();
|
||||
manager.addDownload(downloadInfoList, false);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// Download dirname
|
||||
try {
|
||||
List<DownloadDirname> downloadDirnameList = oldRoomDatabase.downloadDirnameDao().list();
|
||||
for (DownloadDirname dirname : downloadDirnameList) {
|
||||
putDownloadDirname(dirname.getGid(), dirname.getDirname());
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// History
|
||||
try {
|
||||
List<HistoryInfo> historyInfoList = oldRoomDatabase.historyDao().list();
|
||||
putHistoryInfo(historyInfoList);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// QuickSearch
|
||||
try {
|
||||
List<QuickSearch> quickSearchList = oldRoomDatabase.quickSearchDao().list();
|
||||
List<QuickSearch> currentQuickSearchList = db.quickSearchDao().list();
|
||||
List<QuickSearch> importList = new ArrayList<>();
|
||||
for (QuickSearch quickSearch : quickSearchList) {
|
||||
String name = quickSearch.name;
|
||||
for (QuickSearch q : currentQuickSearchList) {
|
||||
if (ObjectUtils.equal(q.name, name)) {
|
||||
// The same name
|
||||
name = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (null == name) {
|
||||
continue;
|
||||
}
|
||||
importList.add(quickSearch);
|
||||
}
|
||||
importQuickSearch(importList);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// LocalFavorites
|
||||
try {
|
||||
List<LocalFavoriteInfo> localFavoriteInfoList = oldRoomDatabase.localFavoritesDao().list();
|
||||
for (LocalFavoriteInfo info : localFavoriteInfoList) {
|
||||
putLocalFavorites(info);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// Filter
|
||||
try {
|
||||
List<Filter> filterList = oldRoomDatabase.filterDao().list();
|
||||
List<Filter> currentFilterList = db.filterDao().list();
|
||||
for (Filter filter : filterList) {
|
||||
if (!currentFilterList.contains(filter)) {
|
||||
addFilter(filter);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// Delete temp database
|
||||
if (oldRoomDatabase.isOpen()) {
|
||||
oldRoomDatabase.close();
|
||||
}
|
||||
context.deleteDatabase(tmpDBName);
|
||||
|
||||
return null;
|
||||
} catch (Throwable e) {
|
||||
ExceptionUtils.throwIfFatal(e);
|
||||
// Ignore
|
||||
return context.getString(R.string.cant_read_the_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.hippo.network.InetValidator;
|
||||
import com.hippo.util.ExceptionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class EhProxySelector extends ProxySelector {
|
||||
|
||||
public static final int TYPE_DIRECT = 0;
|
||||
public static final int TYPE_SYSTEM = 1;
|
||||
public static final int TYPE_HTTP = 2;
|
||||
public static final int TYPE_SOCKS = 3;
|
||||
|
||||
private ProxySelector delegation;
|
||||
private ProxySelector alternative;
|
||||
|
||||
EhProxySelector() {
|
||||
alternative = ProxySelector.getDefault();
|
||||
if (alternative == null) {
|
||||
alternative = new NullProxySelector();
|
||||
}
|
||||
|
||||
updateProxy();
|
||||
}
|
||||
|
||||
public void updateProxy() {
|
||||
switch (Settings.getProxyType()) {
|
||||
case TYPE_DIRECT:
|
||||
delegation = new NullProxySelector();
|
||||
break;
|
||||
default:
|
||||
case TYPE_SYSTEM:
|
||||
delegation = alternative;
|
||||
break;
|
||||
case TYPE_HTTP:
|
||||
case TYPE_SOCKS:
|
||||
delegation = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Proxy> select(URI uri) {
|
||||
int type = Settings.getProxyType();
|
||||
if (type == TYPE_HTTP || type == TYPE_SOCKS) {
|
||||
try {
|
||||
String ip = Settings.getProxyIp();
|
||||
int port = Settings.getProxyPort();
|
||||
if (!TextUtils.isEmpty(ip) && InetValidator.isValidInetPort(port)) {
|
||||
InetAddress inetAddress = InetAddress.getByName(ip);
|
||||
SocketAddress socketAddress = new InetSocketAddress(inetAddress, port);
|
||||
return Collections.singletonList(new Proxy(type == TYPE_HTTP ? Proxy.Type.HTTP : Proxy.Type.SOCKS, socketAddress));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
ExceptionUtils.throwIfFatal(t);
|
||||
}
|
||||
}
|
||||
|
||||
if (delegation != null) {
|
||||
return delegation.select(uri);
|
||||
}
|
||||
|
||||
return alternative.select(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
if (delegation != null) {
|
||||
delegation.select(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NullProxySelector extends ProxySelector {
|
||||
@Override
|
||||
public List<Proxy> select(URI uri) {
|
||||
return Collections.singletonList(Proxy.NO_PROXY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo;
|
||||
import com.hippo.yorozuya.IntIdGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class FavouriteStatusRouter {
|
||||
|
||||
private static final String KEY_DATA_MAP_NEXT_ID = "data_map_next_id";
|
||||
|
||||
private final IntIdGenerator idGenerator = new IntIdGenerator(Settings.getInt(KEY_DATA_MAP_NEXT_ID, 0));
|
||||
@SuppressLint("UseSparseArrays")
|
||||
private final HashMap<Integer, Map<Long, GalleryInfo>> maps = new HashMap<>();
|
||||
|
||||
private final List<Listener> listeners = new ArrayList<>();
|
||||
|
||||
public int saveDataMap(Map<Long, GalleryInfo> map) {
|
||||
int id = idGenerator.nextId();
|
||||
maps.put(id, map);
|
||||
Settings.putInt(KEY_DATA_MAP_NEXT_ID, idGenerator.nextId());
|
||||
return id;
|
||||
}
|
||||
|
||||
public Map<Long, GalleryInfo> restoreDataMap(int id) {
|
||||
return maps.remove(id);
|
||||
}
|
||||
|
||||
public void modifyFavourites(long gid, int slot) {
|
||||
for (Map<Long, GalleryInfo> map : maps.values()) {
|
||||
GalleryInfo info = map.get(gid);
|
||||
if (info != null) {
|
||||
info.favoriteSlot = slot;
|
||||
}
|
||||
}
|
||||
|
||||
for (Listener listener : listeners) {
|
||||
listener.onModifyFavourites(gid, slot);
|
||||
}
|
||||
}
|
||||
|
||||
public void addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(Listener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void onModifyFavourites(long gid, int slot);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
public class GetText {
|
||||
|
||||
private static Resources sResources;
|
||||
|
||||
public static void initialize(Context context) {
|
||||
sResources = context.getApplicationContext().getResources();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getString(@StringRes int id) {
|
||||
return sResources.getString(id);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getString(@StringRes int id, Object... formatArgs) {
|
||||
return sResources.getString(id, formatArgs);
|
||||
}
|
||||
}
|
||||
@@ -1,343 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
/*
|
||||
* Created by Hippo on 2018/3/21.
|
||||
*/
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.hippo.database.MSQLiteBuilder;
|
||||
import com.hippo.util.SqlUtils;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Hosts {
|
||||
|
||||
private static final int VERSION_1 = 1;
|
||||
private static final String TABLE_HOSTS = "HOSTS";
|
||||
private static final String COLUMN_HOST = "HOST";
|
||||
private static final String COLUMN_IP = "IP";
|
||||
|
||||
private static final int DB_VERSION = VERSION_1;
|
||||
|
||||
private final SQLiteDatabase db;
|
||||
|
||||
public Hosts(Context context, String name) {
|
||||
SQLiteOpenHelper helper = new MSQLiteBuilder()
|
||||
.version(VERSION_1)
|
||||
.createTable(TABLE_HOSTS)
|
||||
.insertColumn(TABLE_HOSTS, COLUMN_HOST, String.class)
|
||||
.insertColumn(TABLE_HOSTS, COLUMN_IP, String.class)
|
||||
.build(context, name, DB_VERSION);
|
||||
db = helper.getWritableDatabase();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static InetAddress toInetAddress(String host, String ip) {
|
||||
if (!isValidHost(host)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ip == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] bytes = parseV4(ip);
|
||||
if (bytes == null) {
|
||||
bytes = parseV6(ip);
|
||||
}
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return InetAddress.getByAddress(host, bytes);
|
||||
} catch (UnknownHostException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the host is valid.
|
||||
*/
|
||||
public static boolean isValidHost(String host) {
|
||||
if (host == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (host.length() > 253) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int labelLength = 0;
|
||||
for (int i = 0, n = host.length(); i < n; i++) {
|
||||
char ch = host.charAt(i);
|
||||
|
||||
if (ch == '.') {
|
||||
if (labelLength < 1 || labelLength > 63) {
|
||||
return false;
|
||||
}
|
||||
labelLength = 0;
|
||||
} else {
|
||||
labelLength++;
|
||||
}
|
||||
|
||||
if ((ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '-' && ch != '.') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return labelLength >= 1 && labelLength <= 63;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if ips are valid.
|
||||
*/
|
||||
public static boolean isValidIp(String ips) {
|
||||
if (ips == null) {
|
||||
return false;
|
||||
}
|
||||
String[] list = ips.split("\\+");
|
||||
for (String ip : list) {
|
||||
if (parseV4(ip) == null && parseV6(ip) == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// org.xbill.DNS.Address.parseV4
|
||||
@Nullable
|
||||
private static byte[] parseV4(String s) {
|
||||
int numDigits;
|
||||
int currentOctet;
|
||||
byte[] values = new byte[4];
|
||||
int currentValue;
|
||||
int length = s.length();
|
||||
|
||||
currentOctet = 0;
|
||||
currentValue = 0;
|
||||
numDigits = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c >= '0' && c <= '9') {
|
||||
/* Can't have more than 3 digits per octet. */
|
||||
if (numDigits == 3)
|
||||
return null;
|
||||
/* Octets shouldn't start with 0, unless they are 0. */
|
||||
if (numDigits > 0 && currentValue == 0)
|
||||
return null;
|
||||
numDigits++;
|
||||
currentValue *= 10;
|
||||
currentValue += (c - '0');
|
||||
/* 255 is the maximum value for an octet. */
|
||||
if (currentValue > 255)
|
||||
return null;
|
||||
} else if (c == '.') {
|
||||
/* Can't have more than 3 dots. */
|
||||
if (currentOctet == 3)
|
||||
return null;
|
||||
/* Two consecutive dots are bad. */
|
||||
if (numDigits == 0)
|
||||
return null;
|
||||
values[currentOctet++] = (byte) currentValue;
|
||||
currentValue = 0;
|
||||
numDigits = 0;
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
/* Must have 4 octets. */
|
||||
if (currentOctet != 3)
|
||||
return null;
|
||||
/* The fourth octet can't be empty. */
|
||||
if (numDigits == 0)
|
||||
return null;
|
||||
values[currentOctet] = (byte) currentValue;
|
||||
return values;
|
||||
}
|
||||
|
||||
// org.xbill.DNS.Address.parseV6
|
||||
@Nullable
|
||||
private static byte[] parseV6(String s) {
|
||||
int range = -1;
|
||||
byte[] data = new byte[16];
|
||||
|
||||
String[] tokens = s.split(":", -1);
|
||||
|
||||
int first = 0;
|
||||
int last = tokens.length - 1;
|
||||
|
||||
if (tokens[0].length() == 0) {
|
||||
// If the first two tokens are empty, it means the string
|
||||
// started with ::, which is fine. If only the first is
|
||||
// empty, the string started with :, which is bad.
|
||||
if (last - first > 0 && tokens[1].length() == 0)
|
||||
first++;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
if (tokens[last].length() == 0) {
|
||||
// If the last two tokens are empty, it means the string
|
||||
// ended with ::, which is fine. If only the last is
|
||||
// empty, the string ended with :, which is bad.
|
||||
if (last - first > 0 && tokens[last - 1].length() == 0)
|
||||
last--;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
if (last - first + 1 > 8)
|
||||
return null;
|
||||
|
||||
int i, j;
|
||||
for (i = first, j = 0; i <= last; i++) {
|
||||
if (tokens[i].length() == 0) {
|
||||
if (range >= 0)
|
||||
return null;
|
||||
range = j;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tokens[i].indexOf('.') >= 0) {
|
||||
// An IPv4 address must be the last component
|
||||
if (i < last)
|
||||
return null;
|
||||
// There can't have been more than 6 components.
|
||||
if (i > 6)
|
||||
return null;
|
||||
byte[] v4addr = parseV4(tokens[i]);
|
||||
if (v4addr == null)
|
||||
return null;
|
||||
for (int k = 0; k < 4; k++)
|
||||
data[j++] = v4addr[k];
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
for (int k = 0; k < tokens[i].length(); k++) {
|
||||
char c = tokens[i].charAt(k);
|
||||
if (Character.digit(c, 16) < 0)
|
||||
return null;
|
||||
}
|
||||
int x = Integer.parseInt(tokens[i], 16);
|
||||
if (x > 0xFFFF || x < 0)
|
||||
return null;
|
||||
data[j++] = (byte) (x >>> 8);
|
||||
data[j++] = (byte) (x & 0xFF);
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (j < 16 && range < 0)
|
||||
return null;
|
||||
|
||||
if (range >= 0) {
|
||||
int empty = 16 - j;
|
||||
System.arraycopy(data, range, data, range + empty, j - range);
|
||||
for (i = range; i < range + empty; i++)
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a InetAddress with the host.
|
||||
*/
|
||||
@Nullable
|
||||
public List<InetAddress> get(String host) {
|
||||
if (!isValidHost(host)) {
|
||||
return null;
|
||||
}
|
||||
try (Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_HOSTS + " WHERE " + COLUMN_HOST + " = ?;", new String[]{host})) {
|
||||
if (cursor.moveToNext()) {
|
||||
String[] ips = SqlUtils.getString(cursor, COLUMN_IP, null).split("\\+");
|
||||
List<InetAddress> addresses = new ArrayList<>();
|
||||
for (String ip : ips) {
|
||||
addresses.add(toInetAddress(host, ip));
|
||||
}
|
||||
return addresses;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean contains(String host) {
|
||||
try (Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_HOSTS + " WHERE " + COLUMN_HOST + " = ?;", new String[]{host})) {
|
||||
return cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the host-ip pair into this hosts.
|
||||
*/
|
||||
public boolean put(String host, String ip) {
|
||||
if (!isValidHost(host) || !isValidIp(ip)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(COLUMN_HOST, host);
|
||||
values.put(COLUMN_IP, ip);
|
||||
|
||||
if (contains(host)) {
|
||||
db.update(TABLE_HOSTS, values, COLUMN_HOST + " = ?", new String[]{host});
|
||||
} else {
|
||||
db.insert(TABLE_HOSTS, null, values);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts delete the entry with the host.
|
||||
*/
|
||||
public void delete(String host) {
|
||||
db.delete(TABLE_HOSTS, COLUMN_HOST + " = ?", new String[]{host});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from this host.
|
||||
*/
|
||||
public List<Pair<String, String>> getAll() {
|
||||
List<Pair<String, String>> result = new ArrayList<>();
|
||||
|
||||
try (Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_HOSTS + ";", null)) {
|
||||
while (cursor.moveToNext()) {
|
||||
String host = SqlUtils.getString(cursor, COLUMN_HOST, null);
|
||||
String ip = SqlUtils.getString(cursor, COLUMN_IP, null);
|
||||
result.add(new Pair<>(host, ip));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,895 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.DimenRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.hippo.ehviewer.client.EhConfig;
|
||||
import com.hippo.ehviewer.client.data.FavListUrlBuilder;
|
||||
import com.hippo.ehviewer.ui.CommonOperations;
|
||||
import com.hippo.ehviewer.ui.scene.GalleryListScene;
|
||||
import com.hippo.unifile.UniFile;
|
||||
import com.hippo.yorozuya.AssertUtils;
|
||||
import com.hippo.yorozuya.NumberUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
public class Settings {
|
||||
|
||||
/********************
|
||||
****** Eh
|
||||
********************/
|
||||
|
||||
public static final String KEY_THEME = "theme";
|
||||
|
||||
public static final String KEY_ACCOUNT = "account";
|
||||
public static final String KEY_BLACK_DARK_THEME = "black_dark_theme";
|
||||
public static final int THEME_SYSTEM = -1;
|
||||
public static final String KEY_GALLERY_SITE = "gallery_site";
|
||||
public static final String KEY_LIST_MODE = "list_mode";
|
||||
public static final String KEY_DETAIL_SIZE = "detail_size";
|
||||
public static final String KEY_THUMB_SIZE = "thumb_size_";
|
||||
public static final String KEY_THUMB_RESOLUTION = "thumb_resolution";
|
||||
public static final String KEY_SHOW_TAG_TRANSLATIONS = "show_tag_translations";
|
||||
public static final String KEY_DEFAULT_CATEGORIES = "default_categories";
|
||||
public static final int DEFAULT_DEFAULT_CATEGORIES = EhConfig.ALL_CATEGORY;
|
||||
public static final String KEY_EXCLUDED_TAG_NAMESPACES = "excluded_tag_namespaces";
|
||||
public static final String KEY_EXCLUDED_LANGUAGES = "excluded_languages";
|
||||
/********************
|
||||
****** Privacy and Security
|
||||
********************/
|
||||
public static final String KEY_SEC_SECURITY = "enable_secure";
|
||||
public static final boolean VALUE_SEC_SECURITY = false;
|
||||
/********************
|
||||
****** Download
|
||||
********************/
|
||||
public static final String KEY_DOWNLOAD_SAVE_SCHEME = "image_scheme";
|
||||
public static final String KEY_DOWNLOAD_SAVE_AUTHORITY = "image_authority";
|
||||
public static final String KEY_DOWNLOAD_SAVE_PATH = "image_path";
|
||||
public static final String KEY_NOTIFICATION_REQUIRED = "notification_required";
|
||||
public static final String KEY_DOWNLOAD_SAVE_QUERY = "image_query";
|
||||
public static final String KEY_DOWNLOAD_SAVE_FRAGMENT = "image_fragment";
|
||||
public static final String KEY_MEDIA_SCAN = "media_scan";
|
||||
public static final String KEY_IMAGE_RESOLUTION = "image_size";
|
||||
public static final String DEFAULT_IMAGE_RESOLUTION = EhConfig.IMAGE_SIZE_AUTO;
|
||||
public static final int INVALID_DEFAULT_FAV_SLOT = -2;
|
||||
/********************
|
||||
****** Advanced
|
||||
********************/
|
||||
public static final String KEY_SAVE_PARSE_ERROR_BODY = "save_parse_error_body";
|
||||
public static final String KEY_SECURITY = "require_unlock";
|
||||
public static final String KEY_SECURITY_DELAY = "require_unlock_delay";
|
||||
public static final String KEY_READ_CACHE_SIZE = "read_cache_size";
|
||||
public static final int DEFAULT_READ_CACHE_SIZE = 320;
|
||||
public static final String KEY_BUILT_IN_HOSTS = "built_in_hosts_2";
|
||||
public static final String KEY_DOMAIN_FRONTING = "domain_fronting";
|
||||
public static final String KEY_APP_LANGUAGE = "app_language";
|
||||
public static final String KEY_LIST_THUMB_SIZE = "list_tile_size";
|
||||
private static final String KEY_HIDE_HV_EVENTS = "hide_hv_events";
|
||||
private static final boolean DEFAULT_HIDE_HV_EVENTS = true;
|
||||
private static final String KEY_SHOW_COMMENTS = "show_gallery_comments";
|
||||
private static final boolean DEFAULT_SHOW_COMMENTS = true;
|
||||
private static final String KEY_PREVIEW_NUM = "preview_num";
|
||||
private static final int DEFAULT_PREVIEW_NUM = 60;
|
||||
private static final String TAG = Settings.class.getSimpleName();
|
||||
private static final String KEY_DISPLAY_NAME = "display_name";
|
||||
private static final String DEFAULT_DISPLAY_NAME = null;
|
||||
private static final int DEFAULT_LIST_THUMB_SIZE = 40;
|
||||
private static final String KEY_AVATAR = "avatar";
|
||||
private static final String KEY_REMOVE_IMAGE_FILES = "include_pic";
|
||||
private static final boolean DEFAULT_REMOVE_IMAGE_FILES = true;
|
||||
private static final String KEY_NEED_SIGN_IN = "need_sign_in";
|
||||
private static final boolean DEFAULT_NEED_SIGN_IN = true;
|
||||
private static final String KEY_SELECT_SITE = "select_site";
|
||||
private static final boolean DEFAULT_SELECT_SITE = true;
|
||||
private static final int DEFAULT_THEME = THEME_SYSTEM;
|
||||
private static final int DEFAULT_GALLERY_SITE = 1;
|
||||
private static final String KEY_LAUNCH_PAGE = "launch_page";
|
||||
private static final int DEFAULT_LAUNCH_PAGE = 0;
|
||||
private static final int DEFAULT_LIST_MODE = 0;
|
||||
private static final int DEFAULT_DETAIL_SIZE = 0;
|
||||
private static final int DEFAULT_THUMB_SIZE = 120;
|
||||
private static final int DEFAULT_THUMB_RESOLUTION = 0;
|
||||
private static final String KEY_SHOW_JPN_TITLE = "show_jpn_title";
|
||||
private static final boolean DEFAULT_SHOW_JPN_TITLE = false;
|
||||
private static final String KEY_SHOW_GALLERY_PAGES = "show_gallery_pages";
|
||||
private static final boolean DEFAULT_SHOW_GALLERY_PAGES = false;
|
||||
private static final boolean DEFAULT_SHOW_TAG_TRANSLATIONS = false;
|
||||
private static final int DEFAULT_EXCLUDED_TAG_NAMESPACES = 0;
|
||||
private static final String DEFAULT_EXCLUDED_LANGUAGES = null;
|
||||
private static final String KEY_METERED_NETWORK_WARNING = "cellular_network_warning";
|
||||
private static final boolean DEFAULT_METERED_NETWORK_WARNING = false;
|
||||
private static final String KEY_APP_LINK_VERIFY_TIP = "app_link_verify_tip";
|
||||
private static final boolean DEFAULT_APP_LINK_VERIFY_TIP = false;
|
||||
/********************
|
||||
****** Read
|
||||
********************/
|
||||
private static final String KEY_SCREEN_ROTATION = "screen_rotation";
|
||||
private static final int DEFAULT_SCREEN_ROTATION = 0;
|
||||
private static final String KEY_READING_DIRECTION = "reading_direction";
|
||||
private static final String KEY_PAGE_SCALING = "page_scaling";
|
||||
private static final String KEY_START_POSITION = "start_position";
|
||||
private static final String KEY_KEEP_SCREEN_ON = "keep_screen_on";
|
||||
private static final boolean DEFAULT_KEEP_SCREEN_ON = false;
|
||||
private static final String KEY_SHOW_CLOCK = "gallery_show_clock";
|
||||
private static final boolean DEFAULT_SHOW_CLOCK = true;
|
||||
private static final String KEY_SHOW_PROGRESS = "gallery_show_progress";
|
||||
private static final boolean DEFAULT_SHOW_PROGRESS = true;
|
||||
private static final String KEY_SHOW_BATTERY = "gallery_show_battery";
|
||||
private static final boolean DEFAULT_SHOW_BATTERY = true;
|
||||
private static final String KEY_SHOW_PAGE_INTERVAL = "gallery_show_page_interval";
|
||||
private static final boolean DEFAULT_SHOW_PAGE_INTERVAL = true;
|
||||
private static final String KEY_VOLUME_PAGE = "volume_page";
|
||||
private static final boolean DEFAULT_VOLUME_PAGE = false;
|
||||
private static final String KEY_REVERSE_VOLUME_PAGE = "reserve_volume_page";
|
||||
private static final boolean DEFAULT_REVERSE_VOLUME_PAGE = false;
|
||||
private static final String KEY_READING_FULLSCREEN = "reading_fullscreen";
|
||||
private static final boolean VALUE_READING_FULLSCREEN = true;
|
||||
private static final String KEY_CUSTOM_SCREEN_LIGHTNESS = "custom_screen_lightness";
|
||||
private static final boolean DEFAULT_CUSTOM_SCREEN_LIGHTNESS = false;
|
||||
private static final String KEY_SCREEN_LIGHTNESS = "screen_lightness";
|
||||
private static final int DEFAULT_SCREEN_LIGHTNESS = 50;
|
||||
private static final boolean DEFAULT_MEDIA_SCAN = false;
|
||||
private static final String KEY_RECENT_DOWNLOAD_LABEL = "recent_download_label";
|
||||
private static final String DEFAULT_RECENT_DOWNLOAD_LABEL = null;
|
||||
private static final String KEY_HAS_DEFAULT_DOWNLOAD_LABEL = "has_default_download_label";
|
||||
private static final boolean DEFAULT_HAS_DOWNLOAD_LABEL = false;
|
||||
private static final String KEY_DEFAULT_DOWNLOAD_LABEL = "default_download_label";
|
||||
private static final String DEFAULT_DOWNLOAD_LABEL = null;
|
||||
private static final String KEY_MULTI_THREAD_DOWNLOAD = "download_thread";
|
||||
private static final int DEFAULT_MULTI_THREAD_DOWNLOAD = 3;
|
||||
private static final String KEY_PRELOAD_IMAGE = "preload_image";
|
||||
private static final int DEFAULT_PRELOAD_IMAGE = 5;
|
||||
private static final String KEY_DOWNLOAD_ORIGIN_IMAGE = "download_origin_image";
|
||||
private static final boolean DEFAULT_DOWNLOAD_ORIGIN_IMAGE = false;
|
||||
private static final String KEY_READ_THEME = "read_theme";
|
||||
private static final int DEFAULT_READ_THEME = 1;
|
||||
/********************
|
||||
****** Favorites
|
||||
********************/
|
||||
private static final String KEY_FAV_CAT_0 = "fav_cat_0";
|
||||
private static final String KEY_FAV_CAT_1 = "fav_cat_1";
|
||||
private static final String KEY_FAV_CAT_2 = "fav_cat_2";
|
||||
private static final String KEY_FAV_CAT_3 = "fav_cat_3";
|
||||
private static final String KEY_FAV_CAT_4 = "fav_cat_4";
|
||||
private static final String KEY_FAV_CAT_5 = "fav_cat_5";
|
||||
private static final String KEY_FAV_CAT_6 = "fav_cat_6";
|
||||
private static final String KEY_FAV_CAT_7 = "fav_cat_7";
|
||||
private static final String KEY_FAV_CAT_8 = "fav_cat_8";
|
||||
private static final String KEY_FAV_CAT_9 = "fav_cat_9";
|
||||
private static final String DEFAULT_FAV_CAT_0 = "Favorites 0";
|
||||
private static final String DEFAULT_FAV_CAT_1 = "Favorites 1";
|
||||
private static final String DEFAULT_FAV_CAT_2 = "Favorites 2";
|
||||
private static final String DEFAULT_FAV_CAT_3 = "Favorites 3";
|
||||
private static final String DEFAULT_FAV_CAT_4 = "Favorites 4";
|
||||
private static final String DEFAULT_FAV_CAT_5 = "Favorites 5";
|
||||
private static final String DEFAULT_FAV_CAT_6 = "Favorites 6";
|
||||
private static final String DEFAULT_FAV_CAT_7 = "Favorites 7";
|
||||
private static final String DEFAULT_FAV_CAT_8 = "Favorites 8";
|
||||
private static final String DEFAULT_FAV_CAT_9 = "Favorites 9";
|
||||
private static final String KEY_FAV_COUNT_0 = "fav_count_0";
|
||||
private static final String KEY_FAV_COUNT_1 = "fav_count_1";
|
||||
private static final String KEY_FAV_COUNT_2 = "fav_count_2";
|
||||
private static final String KEY_FAV_COUNT_3 = "fav_count_3";
|
||||
private static final String KEY_FAV_COUNT_4 = "fav_count_4";
|
||||
private static final String KEY_FAV_COUNT_5 = "fav_count_5";
|
||||
private static final String KEY_FAV_COUNT_6 = "fav_count_6";
|
||||
private static final String KEY_FAV_COUNT_7 = "fav_count_7";
|
||||
private static final String KEY_FAV_COUNT_8 = "fav_count_8";
|
||||
private static final String KEY_FAV_COUNT_9 = "fav_count_9";
|
||||
private static final String KEY_FAV_LOCAL = "fav_local";
|
||||
private static final String KEY_FAV_CLOUD = "fav_cloud";
|
||||
private static final int DEFAULT_FAV_COUNT = 0;
|
||||
private static final String KEY_RECENT_FAV_CAT = "recent_fav_cat";
|
||||
private static final int DEFAULT_RECENT_FAV_CAT = FavListUrlBuilder.FAV_CAT_ALL;
|
||||
// -1 for local, 0 - 9 for cloud favorite, other for no default fav slot
|
||||
private static final String KEY_DEFAULT_FAV_SLOT = "default_favorite_2";
|
||||
private static final int DEFAULT_DEFAULT_FAV_SLOT = INVALID_DEFAULT_FAV_SLOT;
|
||||
private static final boolean DEFAULT_SAVE_PARSE_ERROR_BODY = true;
|
||||
private static final String KEY_SAVE_CRASH_LOG = "save_crash_log";
|
||||
private static final boolean DEFAULT_SAVE_CRASH_LOG = true;
|
||||
private static final boolean DEFAULT_BUILT_IN_HOSTS = false;
|
||||
private static final boolean DEFAULT_FRONTING = false;
|
||||
private static final String DEFAULT_APP_LANGUAGE = "system";
|
||||
private static final String KEY_PROXY_TYPE = "proxy_type";
|
||||
private static final int DEFAULT_PROXY_TYPE = EhProxySelector.TYPE_SYSTEM;
|
||||
private static final String KEY_PROXY_IP = "proxy_ip";
|
||||
private static final String DEFAULT_PROXY_IP = null;
|
||||
private static final String KEY_PROXY_PORT = "proxy_port";
|
||||
private static final int DEFAULT_PROXY_PORT = -1;
|
||||
private static final String KEY_GUIDE_GALLERY = "guide_gallery";
|
||||
private static final boolean DEFAULT_GUIDE_GALLERY = true;
|
||||
private static final String KEY_CLIPBOARD_TEXT_HASH_CODE = "clipboard_text_hash_code";
|
||||
private static final int DEFAULT_CLIPBOARD_TEXT_HASH_CODE = 0;
|
||||
private static final String KEY_DOWNLOAD_DELAY = "download_delay";
|
||||
private static final int DEFAULT_DOWNLOAD_DELAY = 0;
|
||||
private static final String KEY_REQUEST_NEWS = "request_news";
|
||||
private static final boolean DEFAULT_REQUEST_NEWS = true;
|
||||
private static final String KEY_ARCHIVE_PASSWDS = "archive_passwds";
|
||||
public static boolean LIST_THUMB_SIZE_INITED = false;
|
||||
public static SharedPreferences sSettingsPre;
|
||||
private static int LIST_THUMB_SIZE = 40;
|
||||
private static Context sContext;
|
||||
private static EhConfig sEhConfig;
|
||||
|
||||
public static void initialize(Context context) {
|
||||
sContext = context.getApplicationContext();
|
||||
sSettingsPre = PreferenceManager.getDefaultSharedPreferences(sContext);
|
||||
sEhConfig = loadEhConfig();
|
||||
fixDefaultValue();
|
||||
}
|
||||
|
||||
private static void fixDefaultValue() {
|
||||
if ("CN".equals(Locale.getDefault().getCountry())) {
|
||||
// Enable domain fronting if the country is CN
|
||||
if (!sSettingsPre.contains(KEY_BUILT_IN_HOSTS)) {
|
||||
putBuiltInHosts(true);
|
||||
}
|
||||
if (!sSettingsPre.contains(KEY_DOMAIN_FRONTING)) {
|
||||
putDF(true);
|
||||
}
|
||||
// Enable show tag translations if the country is CN
|
||||
if (!sSettingsPre.contains(KEY_SHOW_TAG_TRANSLATIONS)) {
|
||||
putShowTagTranslations(true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Locale getLocale() {
|
||||
String language = Settings.getAppLanguage();
|
||||
if (language != null && !language.equals("system")) {
|
||||
return Locale.forLanguageTag(language);
|
||||
} else {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private static EhConfig loadEhConfig() {
|
||||
EhConfig ehConfig = new EhConfig();
|
||||
ehConfig.imageSize = getImageResolution();
|
||||
ehConfig.excludedLanguages = getExcludedLanguages();
|
||||
ehConfig.defaultCategories = getDefaultCategories();
|
||||
ehConfig.excludedNamespaces = getExcludedTagNamespaces();
|
||||
ehConfig.setDirty();
|
||||
return ehConfig;
|
||||
}
|
||||
|
||||
public static boolean getBoolean(String key, boolean defValue) {
|
||||
try {
|
||||
return sSettingsPre.getBoolean(key, defValue);
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "Get ClassCastException when get " + key + " value", e);
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static void putBoolean(String key, boolean value) {
|
||||
sSettingsPre.edit().putBoolean(key, value).apply();
|
||||
}
|
||||
|
||||
public static int getInt(String key, int defValue) {
|
||||
try {
|
||||
return sSettingsPre.getInt(key, defValue);
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "Get ClassCastException when get " + key + " value", e);
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static void putInt(String key, int value) {
|
||||
sSettingsPre.edit().putInt(key, value).apply();
|
||||
}
|
||||
|
||||
public static String getString(String key, String defValue) {
|
||||
try {
|
||||
return sSettingsPre.getString(key, defValue);
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "Get ClassCastException when get " + key + " value", e);
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static void putString(String key, String value) {
|
||||
sSettingsPre.edit().putString(key, value).apply();
|
||||
}
|
||||
|
||||
public static Set<String> getStringSet(String key) {
|
||||
return sSettingsPre.getStringSet(key, null);
|
||||
}
|
||||
|
||||
public static void putStringToStringSet(String key, String value) {
|
||||
Set<String> set = getStringSet(key);
|
||||
if (set == null)
|
||||
set = Set.of(value);
|
||||
else if (set.contains(value))
|
||||
return;
|
||||
else
|
||||
set.add(value);
|
||||
sSettingsPre.edit().putStringSet(key, set).apply();
|
||||
}
|
||||
|
||||
public static int getIntFromStr(String key, int defValue) {
|
||||
try {
|
||||
return NumberUtils.parseIntSafely(sSettingsPre.getString(key, Integer.toString(defValue)), defValue);
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "Get ClassCastException when get " + key + " value", e);
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static void putIntToStr(String key, int value) {
|
||||
sSettingsPre.edit().putString(key, Integer.toString(value)).apply();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getDisplayName() {
|
||||
return getString(KEY_DISPLAY_NAME, DEFAULT_DISPLAY_NAME);
|
||||
}
|
||||
|
||||
public static void putDisplayName(String value) {
|
||||
putString(KEY_DISPLAY_NAME, value);
|
||||
}
|
||||
|
||||
public static void putAvatar(String value) {
|
||||
putString(KEY_AVATAR, value);
|
||||
}
|
||||
|
||||
public static boolean getRemoveImageFiles() {
|
||||
return getBoolean(KEY_REMOVE_IMAGE_FILES, DEFAULT_REMOVE_IMAGE_FILES);
|
||||
}
|
||||
|
||||
public static void putRemoveImageFiles(boolean value) {
|
||||
putBoolean(KEY_REMOVE_IMAGE_FILES, value);
|
||||
}
|
||||
|
||||
public static EhConfig getEhConfig() {
|
||||
return sEhConfig;
|
||||
}
|
||||
|
||||
public static boolean getNeedSignIn() {
|
||||
return getBoolean(KEY_NEED_SIGN_IN, DEFAULT_NEED_SIGN_IN);
|
||||
}
|
||||
|
||||
public static void putNeedSignIn(boolean value) {
|
||||
putBoolean(KEY_NEED_SIGN_IN, value);
|
||||
}
|
||||
|
||||
public static boolean getSelectSite() {
|
||||
return getBoolean(KEY_SELECT_SITE, DEFAULT_SELECT_SITE);
|
||||
}
|
||||
|
||||
public static void putSelectSite(boolean value) {
|
||||
putBoolean(KEY_SELECT_SITE, value);
|
||||
}
|
||||
|
||||
public static int getTheme() {
|
||||
return getIntFromStr(KEY_THEME, DEFAULT_THEME);
|
||||
}
|
||||
|
||||
public static int getGallerySite() {
|
||||
return getIntFromStr(KEY_GALLERY_SITE, DEFAULT_GALLERY_SITE);
|
||||
}
|
||||
|
||||
public static void putGallerySite(int value) {
|
||||
putIntToStr(KEY_GALLERY_SITE, value);
|
||||
}
|
||||
|
||||
public static String getLaunchPageGalleryListSceneAction() {
|
||||
int value = getIntFromStr(KEY_LAUNCH_PAGE, DEFAULT_LAUNCH_PAGE);
|
||||
return switch (value) {
|
||||
case 0 -> GalleryListScene.ACTION_HOMEPAGE;
|
||||
case 1 -> GalleryListScene.ACTION_SUBSCRIPTION;
|
||||
case 2 -> GalleryListScene.ACTION_WHATS_HOT;
|
||||
case 3 -> GalleryListScene.ACTION_TOP_LIST;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + value);
|
||||
};
|
||||
}
|
||||
|
||||
public static int getListMode() {
|
||||
return getIntFromStr(KEY_LIST_MODE, DEFAULT_LIST_MODE);
|
||||
}
|
||||
|
||||
public static int getDetailSize() {
|
||||
return getIntFromStr(KEY_DETAIL_SIZE, DEFAULT_DETAIL_SIZE);
|
||||
}
|
||||
|
||||
@DimenRes
|
||||
public static int getDetailSizeResId() {
|
||||
return switch (getDetailSize()) {
|
||||
case 0 -> R.dimen.gallery_list_column_width_long;
|
||||
case 1 -> R.dimen.gallery_list_column_width_short;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + getDetailSize());
|
||||
};
|
||||
}
|
||||
|
||||
public static int getThumbSize() {
|
||||
return dip2px(getInt(KEY_THUMB_SIZE, DEFAULT_THUMB_SIZE));
|
||||
}
|
||||
|
||||
public static int dip2px(int dpValue) {
|
||||
final float scale = sContext.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
public static int getThumbResolution() {
|
||||
return getIntFromStr(KEY_THUMB_RESOLUTION, DEFAULT_THUMB_RESOLUTION);
|
||||
}
|
||||
|
||||
public static boolean getShowComments() {
|
||||
return getBoolean(KEY_SHOW_COMMENTS, DEFAULT_SHOW_COMMENTS);
|
||||
}
|
||||
|
||||
public static boolean getRequestNews() {
|
||||
return getBoolean(KEY_REQUEST_NEWS, DEFAULT_REQUEST_NEWS);
|
||||
}
|
||||
|
||||
public static boolean getHideHvEvents() {
|
||||
return getBoolean(KEY_HIDE_HV_EVENTS, DEFAULT_HIDE_HV_EVENTS);
|
||||
}
|
||||
|
||||
public static boolean getShowJpnTitle() {
|
||||
return getBoolean(KEY_SHOW_JPN_TITLE, DEFAULT_SHOW_JPN_TITLE);
|
||||
}
|
||||
|
||||
public static boolean getShowGalleryPages() {
|
||||
return getBoolean(KEY_SHOW_GALLERY_PAGES, DEFAULT_SHOW_GALLERY_PAGES);
|
||||
}
|
||||
|
||||
public static boolean getShowTagTranslations() {
|
||||
return getBoolean(KEY_SHOW_TAG_TRANSLATIONS, DEFAULT_SHOW_TAG_TRANSLATIONS);
|
||||
}
|
||||
|
||||
public static void putShowTagTranslations(boolean value) {
|
||||
putBoolean(KEY_SHOW_TAG_TRANSLATIONS, value);
|
||||
}
|
||||
|
||||
public static int getPreviewNum() {
|
||||
return getInt(KEY_PREVIEW_NUM, DEFAULT_PREVIEW_NUM);
|
||||
}
|
||||
|
||||
public static int getDefaultCategories() {
|
||||
return getInt(KEY_DEFAULT_CATEGORIES, DEFAULT_DEFAULT_CATEGORIES);
|
||||
}
|
||||
|
||||
public static int getExcludedTagNamespaces() {
|
||||
return getInt(KEY_EXCLUDED_TAG_NAMESPACES, DEFAULT_EXCLUDED_TAG_NAMESPACES);
|
||||
}
|
||||
|
||||
public static String getExcludedLanguages() {
|
||||
return getString(KEY_EXCLUDED_LANGUAGES, DEFAULT_EXCLUDED_LANGUAGES);
|
||||
}
|
||||
|
||||
public static boolean getMeteredNetworkWarning() {
|
||||
return getBoolean(KEY_METERED_NETWORK_WARNING, DEFAULT_METERED_NETWORK_WARNING);
|
||||
}
|
||||
|
||||
public static boolean getAppLinkVerifyTip() {
|
||||
return getBoolean(KEY_APP_LINK_VERIFY_TIP, DEFAULT_APP_LINK_VERIFY_TIP);
|
||||
}
|
||||
|
||||
public static void putAppLinkVerifyTip(boolean value) {
|
||||
putBoolean(KEY_APP_LINK_VERIFY_TIP, value);
|
||||
}
|
||||
|
||||
public static int getScreenRotation() {
|
||||
return getIntFromStr(KEY_SCREEN_ROTATION, DEFAULT_SCREEN_ROTATION);
|
||||
}
|
||||
|
||||
public static void putScreenRotation(int value) {
|
||||
putIntToStr(KEY_SCREEN_ROTATION, value);
|
||||
}
|
||||
|
||||
public static void putReadingDirection(int value) {
|
||||
putIntToStr(KEY_READING_DIRECTION, value);
|
||||
}
|
||||
|
||||
public static void putPageScaling(int value) {
|
||||
putIntToStr(KEY_PAGE_SCALING, value);
|
||||
}
|
||||
|
||||
public static void putStartPosition(int value) {
|
||||
putIntToStr(KEY_START_POSITION, value);
|
||||
}
|
||||
|
||||
public static boolean getKeepScreenOn() {
|
||||
return getBoolean(KEY_KEEP_SCREEN_ON, DEFAULT_KEEP_SCREEN_ON);
|
||||
}
|
||||
|
||||
public static void putKeepScreenOn(boolean value) {
|
||||
putBoolean(KEY_KEEP_SCREEN_ON, value);
|
||||
}
|
||||
|
||||
public static boolean getShowClock() {
|
||||
return getBoolean(KEY_SHOW_CLOCK, DEFAULT_SHOW_CLOCK);
|
||||
}
|
||||
|
||||
public static void putShowClock(boolean value) {
|
||||
putBoolean(KEY_SHOW_CLOCK, value);
|
||||
}
|
||||
|
||||
public static boolean getShowProgress() {
|
||||
return getBoolean(KEY_SHOW_PROGRESS, DEFAULT_SHOW_PROGRESS);
|
||||
}
|
||||
|
||||
public static void putShowProgress(boolean value) {
|
||||
putBoolean(KEY_SHOW_PROGRESS, value);
|
||||
}
|
||||
|
||||
public static boolean getShowBattery() {
|
||||
return getBoolean(KEY_SHOW_BATTERY, DEFAULT_SHOW_BATTERY);
|
||||
}
|
||||
|
||||
public static void putShowBattery(boolean value) {
|
||||
putBoolean(KEY_SHOW_BATTERY, value);
|
||||
}
|
||||
|
||||
public static boolean getShowPageInterval() {
|
||||
return getBoolean(KEY_SHOW_PAGE_INTERVAL, DEFAULT_SHOW_PAGE_INTERVAL);
|
||||
}
|
||||
|
||||
public static void putShowPageInterval(boolean value) {
|
||||
putBoolean(KEY_SHOW_PAGE_INTERVAL, value);
|
||||
}
|
||||
|
||||
public static boolean getVolumePage() {
|
||||
return getBoolean(KEY_VOLUME_PAGE, DEFAULT_VOLUME_PAGE);
|
||||
}
|
||||
|
||||
public static void putVolumePage(boolean value) {
|
||||
putBoolean(KEY_VOLUME_PAGE, value);
|
||||
}
|
||||
|
||||
public static boolean getReverseVolumePage() {
|
||||
return getBoolean(KEY_REVERSE_VOLUME_PAGE, DEFAULT_REVERSE_VOLUME_PAGE);
|
||||
}
|
||||
|
||||
public static void putReverseVolumePage(boolean value) {
|
||||
putBoolean(KEY_REVERSE_VOLUME_PAGE, value);
|
||||
}
|
||||
|
||||
public static boolean getReadingFullscreen() {
|
||||
return getBoolean(KEY_READING_FULLSCREEN, VALUE_READING_FULLSCREEN);
|
||||
}
|
||||
|
||||
public static void putReadingFullscreen(boolean value) {
|
||||
putBoolean(KEY_READING_FULLSCREEN, value);
|
||||
}
|
||||
|
||||
public static boolean getCustomScreenLightness() {
|
||||
return getBoolean(KEY_CUSTOM_SCREEN_LIGHTNESS, DEFAULT_CUSTOM_SCREEN_LIGHTNESS);
|
||||
}
|
||||
|
||||
public static void putCustomScreenLightness(boolean value) {
|
||||
putBoolean(KEY_CUSTOM_SCREEN_LIGHTNESS, value);
|
||||
}
|
||||
|
||||
public static int getScreenLightness() {
|
||||
return getInt(KEY_SCREEN_LIGHTNESS, DEFAULT_SCREEN_LIGHTNESS);
|
||||
}
|
||||
|
||||
public static void putScreenLightness(int value) {
|
||||
putInt(KEY_SCREEN_LIGHTNESS, value);
|
||||
}
|
||||
|
||||
public static int getReadTheme() {
|
||||
return getIntFromStr(KEY_READ_THEME, DEFAULT_READ_THEME);
|
||||
}
|
||||
|
||||
public static void putReadTheme(int value) {
|
||||
putIntToStr(KEY_READ_THEME, value);
|
||||
}
|
||||
|
||||
public static boolean getEnabledSecurity() {
|
||||
return getBoolean(KEY_SEC_SECURITY, VALUE_SEC_SECURITY);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static UniFile getDownloadLocation() {
|
||||
UniFile dir;
|
||||
Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(getString(KEY_DOWNLOAD_SAVE_SCHEME, null));
|
||||
builder.encodedAuthority(getString(KEY_DOWNLOAD_SAVE_AUTHORITY, null));
|
||||
builder.encodedPath(getString(KEY_DOWNLOAD_SAVE_PATH, null));
|
||||
builder.encodedQuery(getString(KEY_DOWNLOAD_SAVE_QUERY, null));
|
||||
builder.encodedFragment(getString(KEY_DOWNLOAD_SAVE_FRAGMENT, null));
|
||||
dir = UniFile.fromUri(sContext, builder.build());
|
||||
return dir != null ? dir : UniFile.fromFile(AppConfig.getDefaultDownloadDir());
|
||||
}
|
||||
|
||||
public static void putDownloadLocation(@NonNull UniFile location) {
|
||||
Uri uri = location.getUri();
|
||||
putString(KEY_DOWNLOAD_SAVE_SCHEME, uri.getScheme());
|
||||
putString(KEY_DOWNLOAD_SAVE_AUTHORITY, uri.getEncodedAuthority());
|
||||
putString(KEY_DOWNLOAD_SAVE_PATH, uri.getEncodedPath());
|
||||
putString(KEY_DOWNLOAD_SAVE_QUERY, uri.getEncodedQuery());
|
||||
putString(KEY_DOWNLOAD_SAVE_FRAGMENT, uri.getEncodedFragment());
|
||||
|
||||
if (getMediaScan()) {
|
||||
CommonOperations.removeNoMediaFile(location);
|
||||
} else {
|
||||
CommonOperations.ensureNoMediaFile(location);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean getMediaScan() {
|
||||
return getBoolean(KEY_MEDIA_SCAN, DEFAULT_MEDIA_SCAN);
|
||||
}
|
||||
|
||||
public static String getRecentDownloadLabel() {
|
||||
return getString(KEY_RECENT_DOWNLOAD_LABEL, DEFAULT_RECENT_DOWNLOAD_LABEL);
|
||||
}
|
||||
|
||||
public static void putRecentDownloadLabel(String value) {
|
||||
putString(KEY_RECENT_DOWNLOAD_LABEL, value);
|
||||
}
|
||||
|
||||
public static boolean getHasDefaultDownloadLabel() {
|
||||
return getBoolean(KEY_HAS_DEFAULT_DOWNLOAD_LABEL, DEFAULT_HAS_DOWNLOAD_LABEL);
|
||||
}
|
||||
|
||||
public static void putHasDefaultDownloadLabel(boolean hasDefaultDownloadLabel) {
|
||||
putBoolean(KEY_HAS_DEFAULT_DOWNLOAD_LABEL, hasDefaultDownloadLabel);
|
||||
}
|
||||
|
||||
public static String getDefaultDownloadLabel() {
|
||||
return getString(KEY_DEFAULT_DOWNLOAD_LABEL, DEFAULT_DOWNLOAD_LABEL);
|
||||
}
|
||||
|
||||
public static void putDefaultDownloadLabel(String value) {
|
||||
putString(KEY_DEFAULT_DOWNLOAD_LABEL, value);
|
||||
}
|
||||
|
||||
public static int getMultiThreadDownload() {
|
||||
return getIntFromStr(KEY_MULTI_THREAD_DOWNLOAD, DEFAULT_MULTI_THREAD_DOWNLOAD);
|
||||
}
|
||||
|
||||
public static int getDownloadDelay() {
|
||||
return getIntFromStr(KEY_DOWNLOAD_DELAY, DEFAULT_DOWNLOAD_DELAY);
|
||||
}
|
||||
|
||||
public static int getPreloadImage() {
|
||||
return getIntFromStr(KEY_PRELOAD_IMAGE, DEFAULT_PRELOAD_IMAGE);
|
||||
}
|
||||
|
||||
public static String getImageResolution() {
|
||||
return getString(KEY_IMAGE_RESOLUTION, DEFAULT_IMAGE_RESOLUTION);
|
||||
}
|
||||
|
||||
public static void putImageResolution(String value) {
|
||||
sEhConfig.imageSize = value;
|
||||
sEhConfig.setDirty();
|
||||
putString(KEY_IMAGE_RESOLUTION, value);
|
||||
}
|
||||
|
||||
public static boolean getDownloadOriginImage() {
|
||||
return getBoolean(KEY_DOWNLOAD_ORIGIN_IMAGE, DEFAULT_DOWNLOAD_ORIGIN_IMAGE);
|
||||
}
|
||||
|
||||
public static String[] getFavCat() {
|
||||
String[] favCat = new String[10];
|
||||
favCat[0] = sSettingsPre.getString(KEY_FAV_CAT_0, DEFAULT_FAV_CAT_0);
|
||||
favCat[1] = sSettingsPre.getString(KEY_FAV_CAT_1, DEFAULT_FAV_CAT_1);
|
||||
favCat[2] = sSettingsPre.getString(KEY_FAV_CAT_2, DEFAULT_FAV_CAT_2);
|
||||
favCat[3] = sSettingsPre.getString(KEY_FAV_CAT_3, DEFAULT_FAV_CAT_3);
|
||||
favCat[4] = sSettingsPre.getString(KEY_FAV_CAT_4, DEFAULT_FAV_CAT_4);
|
||||
favCat[5] = sSettingsPre.getString(KEY_FAV_CAT_5, DEFAULT_FAV_CAT_5);
|
||||
favCat[6] = sSettingsPre.getString(KEY_FAV_CAT_6, DEFAULT_FAV_CAT_6);
|
||||
favCat[7] = sSettingsPre.getString(KEY_FAV_CAT_7, DEFAULT_FAV_CAT_7);
|
||||
favCat[8] = sSettingsPre.getString(KEY_FAV_CAT_8, DEFAULT_FAV_CAT_8);
|
||||
favCat[9] = sSettingsPre.getString(KEY_FAV_CAT_9, DEFAULT_FAV_CAT_9);
|
||||
return favCat;
|
||||
}
|
||||
|
||||
public static void putFavCat(String[] value) {
|
||||
AssertUtils.assertEquals(10, value.length);
|
||||
sSettingsPre.edit()
|
||||
.putString(KEY_FAV_CAT_0, value[0])
|
||||
.putString(KEY_FAV_CAT_1, value[1])
|
||||
.putString(KEY_FAV_CAT_2, value[2])
|
||||
.putString(KEY_FAV_CAT_3, value[3])
|
||||
.putString(KEY_FAV_CAT_4, value[4])
|
||||
.putString(KEY_FAV_CAT_5, value[5])
|
||||
.putString(KEY_FAV_CAT_6, value[6])
|
||||
.putString(KEY_FAV_CAT_7, value[7])
|
||||
.putString(KEY_FAV_CAT_8, value[8])
|
||||
.putString(KEY_FAV_CAT_9, value[9])
|
||||
.apply();
|
||||
}
|
||||
|
||||
public static int[] getFavCount() {
|
||||
int[] favCount = new int[10];
|
||||
favCount[0] = sSettingsPre.getInt(KEY_FAV_COUNT_0, DEFAULT_FAV_COUNT);
|
||||
favCount[1] = sSettingsPre.getInt(KEY_FAV_COUNT_1, DEFAULT_FAV_COUNT);
|
||||
favCount[2] = sSettingsPre.getInt(KEY_FAV_COUNT_2, DEFAULT_FAV_COUNT);
|
||||
favCount[3] = sSettingsPre.getInt(KEY_FAV_COUNT_3, DEFAULT_FAV_COUNT);
|
||||
favCount[4] = sSettingsPre.getInt(KEY_FAV_COUNT_4, DEFAULT_FAV_COUNT);
|
||||
favCount[5] = sSettingsPre.getInt(KEY_FAV_COUNT_5, DEFAULT_FAV_COUNT);
|
||||
favCount[6] = sSettingsPre.getInt(KEY_FAV_COUNT_6, DEFAULT_FAV_COUNT);
|
||||
favCount[7] = sSettingsPre.getInt(KEY_FAV_COUNT_7, DEFAULT_FAV_COUNT);
|
||||
favCount[8] = sSettingsPre.getInt(KEY_FAV_COUNT_8, DEFAULT_FAV_COUNT);
|
||||
favCount[9] = sSettingsPre.getInt(KEY_FAV_COUNT_9, DEFAULT_FAV_COUNT);
|
||||
return favCount;
|
||||
}
|
||||
|
||||
public static void putFavCount(int[] count) {
|
||||
AssertUtils.assertEquals(10, count.length);
|
||||
sSettingsPre.edit()
|
||||
.putInt(KEY_FAV_COUNT_0, count[0])
|
||||
.putInt(KEY_FAV_COUNT_1, count[1])
|
||||
.putInt(KEY_FAV_COUNT_2, count[2])
|
||||
.putInt(KEY_FAV_COUNT_3, count[3])
|
||||
.putInt(KEY_FAV_COUNT_4, count[4])
|
||||
.putInt(KEY_FAV_COUNT_5, count[5])
|
||||
.putInt(KEY_FAV_COUNT_6, count[6])
|
||||
.putInt(KEY_FAV_COUNT_7, count[7])
|
||||
.putInt(KEY_FAV_COUNT_8, count[8])
|
||||
.putInt(KEY_FAV_COUNT_9, count[9])
|
||||
.apply();
|
||||
}
|
||||
|
||||
public static int getFavLocalCount() {
|
||||
return sSettingsPre.getInt(KEY_FAV_LOCAL, DEFAULT_FAV_COUNT);
|
||||
}
|
||||
|
||||
public static void putFavLocalCount(int count) {
|
||||
sSettingsPre.edit().putInt(KEY_FAV_LOCAL, count).apply();
|
||||
}
|
||||
|
||||
public static int getFavCloudCount() {
|
||||
return sSettingsPre.getInt(KEY_FAV_CLOUD, DEFAULT_FAV_COUNT);
|
||||
}
|
||||
|
||||
public static void putFavCloudCount(int count) {
|
||||
sSettingsPre.edit().putInt(KEY_FAV_CLOUD, count).apply();
|
||||
}
|
||||
|
||||
public static int getRecentFavCat() {
|
||||
return getInt(KEY_RECENT_FAV_CAT, DEFAULT_RECENT_FAV_CAT);
|
||||
}
|
||||
|
||||
public static void putRecentFavCat(int value) {
|
||||
putInt(KEY_RECENT_FAV_CAT, value);
|
||||
}
|
||||
|
||||
public static int getDefaultFavSlot() {
|
||||
return getInt(KEY_DEFAULT_FAV_SLOT, DEFAULT_DEFAULT_FAV_SLOT);
|
||||
}
|
||||
|
||||
public static void putDefaultFavSlot(int value) {
|
||||
putInt(KEY_DEFAULT_FAV_SLOT, value);
|
||||
}
|
||||
|
||||
public static boolean getSaveParseErrorBody() {
|
||||
return getBoolean(KEY_SAVE_PARSE_ERROR_BODY, DEFAULT_SAVE_PARSE_ERROR_BODY);
|
||||
}
|
||||
|
||||
public static boolean getSaveCrashLog() {
|
||||
return getBoolean(KEY_SAVE_CRASH_LOG, DEFAULT_SAVE_CRASH_LOG);
|
||||
}
|
||||
|
||||
public static boolean getSecurity() {
|
||||
return getBoolean(KEY_SECURITY, false);
|
||||
}
|
||||
|
||||
public static void putSecurity(boolean value) {
|
||||
putBoolean(KEY_SECURITY, value);
|
||||
}
|
||||
|
||||
public static int getSecurityDelay() {
|
||||
return getInt(KEY_SECURITY_DELAY, 0);
|
||||
}
|
||||
|
||||
public static int getReadCacheSize() {
|
||||
return getIntFromStr(KEY_READ_CACHE_SIZE, DEFAULT_READ_CACHE_SIZE);
|
||||
}
|
||||
|
||||
public static boolean getBuiltInHosts() {
|
||||
return getBoolean(KEY_BUILT_IN_HOSTS, DEFAULT_BUILT_IN_HOSTS);
|
||||
}
|
||||
|
||||
public static void putBuiltInHosts(boolean value) {
|
||||
putBoolean(KEY_BUILT_IN_HOSTS, value);
|
||||
}
|
||||
|
||||
public static boolean getDF() {
|
||||
return getBoolean(KEY_DOMAIN_FRONTING, DEFAULT_FRONTING);
|
||||
}
|
||||
|
||||
public static void putDF(boolean value) {
|
||||
putBoolean(KEY_DOMAIN_FRONTING, value);
|
||||
}
|
||||
|
||||
public static String getAppLanguage() {
|
||||
return getString(KEY_APP_LANGUAGE, DEFAULT_APP_LANGUAGE);
|
||||
}
|
||||
|
||||
public static int getProxyType() {
|
||||
return getInt(KEY_PROXY_TYPE, DEFAULT_PROXY_TYPE);
|
||||
}
|
||||
|
||||
public static void putProxyType(int value) {
|
||||
putInt(KEY_PROXY_TYPE, value);
|
||||
}
|
||||
|
||||
public static String getProxyIp() {
|
||||
return getString(KEY_PROXY_IP, DEFAULT_PROXY_IP);
|
||||
}
|
||||
|
||||
public static void putProxyIp(String value) {
|
||||
putString(KEY_PROXY_IP, value);
|
||||
}
|
||||
|
||||
public static int getProxyPort() {
|
||||
return getInt(KEY_PROXY_PORT, DEFAULT_PROXY_PORT);
|
||||
}
|
||||
|
||||
public static void putProxyPort(int value) {
|
||||
putInt(KEY_PROXY_PORT, value);
|
||||
}
|
||||
|
||||
public static boolean getGuideGallery() {
|
||||
return getBoolean(KEY_GUIDE_GALLERY, DEFAULT_GUIDE_GALLERY);
|
||||
}
|
||||
|
||||
public static void putGuideGallery(boolean value) {
|
||||
putBoolean(KEY_GUIDE_GALLERY, value);
|
||||
}
|
||||
|
||||
public static int getClipboardTextHashCode() {
|
||||
return getInt(KEY_CLIPBOARD_TEXT_HASH_CODE, DEFAULT_CLIPBOARD_TEXT_HASH_CODE);
|
||||
}
|
||||
|
||||
public static void putClipboardTextHashCode(int value) {
|
||||
putInt(KEY_CLIPBOARD_TEXT_HASH_CODE, value);
|
||||
}
|
||||
|
||||
public static Set<String> getArchivePasswds() {
|
||||
return getStringSet(KEY_ARCHIVE_PASSWDS);
|
||||
}
|
||||
|
||||
public static void putPasswdToArchivePasswds(String value) {
|
||||
putStringToStringSet(KEY_ARCHIVE_PASSWDS, value);
|
||||
}
|
||||
|
||||
public static int getListThumbSize() {
|
||||
if (LIST_THUMB_SIZE_INITED) {
|
||||
return LIST_THUMB_SIZE;
|
||||
}
|
||||
int size = 3 * getInt(KEY_LIST_THUMB_SIZE, DEFAULT_LIST_THUMB_SIZE);
|
||||
LIST_THUMB_SIZE = size;
|
||||
LIST_THUMB_SIZE_INITED = true;
|
||||
return size;
|
||||
}
|
||||
|
||||
public static boolean getNotificationRequired() {
|
||||
return getBoolean(KEY_NOTIFICATION_REQUIRED, false);
|
||||
}
|
||||
|
||||
public static void putNotificationRequired() {
|
||||
putBoolean(KEY_NOTIFICATION_REQUIRED, true);
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.browser.customtabs.CustomTabsIntent;
|
||||
|
||||
import com.hippo.ehviewer.client.EhUrlOpener;
|
||||
import com.hippo.ehviewer.client.data.GalleryDetail;
|
||||
import com.hippo.ehviewer.client.parser.GalleryPageUrlParser;
|
||||
import com.hippo.ehviewer.ui.MainActivity;
|
||||
import com.hippo.scene.Announcer;
|
||||
import com.hippo.scene.StageActivity;
|
||||
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
|
||||
|
||||
public final class UrlOpener {
|
||||
|
||||
private UrlOpener() {
|
||||
}
|
||||
|
||||
public static void openUrl(@NonNull Context context, String url, boolean ehUrl) {
|
||||
openUrl(context, url, ehUrl, null);
|
||||
}
|
||||
|
||||
public static void openUrl(@NonNull Context context, String url, boolean ehUrl, GalleryDetail galleryDetail) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent;
|
||||
Uri uri = Uri.parse(url);
|
||||
|
||||
if (ehUrl) {
|
||||
if (galleryDetail != null) {
|
||||
GalleryPageUrlParser.Result result = GalleryPageUrlParser.parse(url);
|
||||
if (result != null) {
|
||||
if (result.gid == galleryDetail.gid) {
|
||||
intent = new Intent(context, ReaderActivity.class);
|
||||
intent.setAction(ReaderActivity.ACTION_EH);
|
||||
intent.putExtra(ReaderActivity.KEY_GALLERY_INFO, galleryDetail);
|
||||
intent.putExtra(ReaderActivity.KEY_PAGE, result.page);
|
||||
context.startActivity(intent);
|
||||
return;
|
||||
}
|
||||
} else if (url.startsWith("#c")) {
|
||||
try {
|
||||
intent = new Intent(context, ReaderActivity.class);
|
||||
intent.setAction(ReaderActivity.ACTION_EH);
|
||||
intent.putExtra(ReaderActivity.KEY_GALLERY_INFO, galleryDetail);
|
||||
intent.putExtra(ReaderActivity.KEY_PAGE, Integer.parseInt(url.replace("#c", "")) - 1);
|
||||
context.startActivity(intent);
|
||||
return;
|
||||
} catch (NumberFormatException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
Announcer announcer = EhUrlOpener.parseUrl(url);
|
||||
if (null != announcer) {
|
||||
intent = new Intent(context, MainActivity.class);
|
||||
intent.setAction(StageActivity.ACTION_START_SCENE);
|
||||
intent.putExtra(StageActivity.KEY_SCENE_NAME, announcer.getClazz().getName());
|
||||
intent.putExtra(StageActivity.KEY_SCENE_ARGS, announcer.getArgs());
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CustomTabsIntent.Builder customTabsIntent = new CustomTabsIntent.Builder();
|
||||
customTabsIntent.setShowTitle(true);
|
||||
try {
|
||||
customTabsIntent.build().launchUrl(context, uri);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(context, R.string.no_browser_installed, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Tarsin Norbin
|
||||
*
|
||||
* This file is part of EhViewer
|
||||
*
|
||||
* EhViewer is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* EhViewer is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with EhViewer.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.view.WindowInsetsAnimationCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class WindowInsetsAnimationHelper extends WindowInsetsAnimationCompat.Callback {
|
||||
private final View[] views;
|
||||
private final HashMap<View, Integer> startPaddings = new HashMap<>();
|
||||
private final HashMap<View, Integer> endPaddings = new HashMap<>();
|
||||
WindowInsetsAnimationCompat animation;
|
||||
|
||||
public WindowInsetsAnimationHelper(int dispatchMode, View... views) {
|
||||
super(dispatchMode);
|
||||
this.views = views;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepare(@NonNull WindowInsetsAnimationCompat animation) {
|
||||
super.onPrepare(animation);
|
||||
this.animation = animation;
|
||||
for (View view : views) {
|
||||
if (view == null) {
|
||||
continue;
|
||||
}
|
||||
startPaddings.put(view, view.getPaddingBottom());
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public WindowInsetsAnimationCompat.BoundsCompat onStart(@NonNull WindowInsetsAnimationCompat animation, @NonNull WindowInsetsAnimationCompat.BoundsCompat bounds) {
|
||||
this.animation = animation;
|
||||
for (View view : views) {
|
||||
if (view == null) {
|
||||
continue;
|
||||
}
|
||||
endPaddings.put(view, view.getPaddingBottom());
|
||||
int startPadding = startPaddings.containsKey(view) ? startPaddings.get(view) : 0;
|
||||
view.setTranslationY(-(startPadding - view.getPaddingBottom()));
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public WindowInsetsCompat onProgress(@NonNull WindowInsetsCompat insets, @NonNull List<WindowInsetsAnimationCompat> runningAnimations) {
|
||||
if (animation == null) {
|
||||
return insets;
|
||||
}
|
||||
WindowInsetsAnimationCompat imeAnimation = null;
|
||||
for (WindowInsetsAnimationCompat animation : runningAnimations) {
|
||||
if ((animation.getTypeMask() & WindowInsetsCompat.Type.ime()) != 0) {
|
||||
imeAnimation = animation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (imeAnimation != null) {
|
||||
for (View view : views) {
|
||||
if (view == null) {
|
||||
continue;
|
||||
}
|
||||
int startPadding = startPaddings.containsKey(view) ? startPaddings.get(view) : 0;
|
||||
int endPadding = endPaddings.containsKey(view) ? endPaddings.get(view) : 0;
|
||||
view.setTranslationY(MathUtils.lerp(endPadding - startPadding, 0, animation.getInterpolatedFraction()));
|
||||
}
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(@NonNull WindowInsetsAnimationCompat animation) {
|
||||
super.onEnd(animation);
|
||||
startPaddings.clear();
|
||||
endPaddings.clear();
|
||||
this.animation = null;
|
||||
for (View view : views) {
|
||||
if (view == null) {
|
||||
continue;
|
||||
}
|
||||
view.setTranslationY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 972 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user