Compare commits
11267 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a105cc339 | ||
|
|
6859053727 | ||
|
|
8c207cf1eb | ||
|
|
bce8c2ee5a | ||
|
|
e1922bd555 | ||
|
|
fc9a901c4c | ||
|
|
6f93d9848c | ||
|
|
bde429cff6 | ||
|
|
4c8d33d1eb | ||
|
|
fac7826efa | ||
|
|
3e133bbfa3 | ||
|
|
6c8d1bdffe | ||
|
|
59fc495593 | ||
|
|
60827bdcc4 | ||
|
|
f992feb71c | ||
|
|
cf66e66db8 | ||
|
|
63aa3948e5 | ||
|
|
7899ed6f69 | ||
|
|
5e44239657 | ||
|
|
17cd452fff | ||
|
|
004861fbb7 | ||
|
|
8727f12b18 | ||
|
|
05604e4bd2 | ||
|
|
fd7d497cd1 | ||
|
|
a974d0d52d | ||
|
|
c850a61a89 | ||
|
|
3a2fdec241 | ||
|
|
08b804cd2d | ||
|
|
de7891771d | ||
|
|
602768209b | ||
|
|
73b1f8fcdd | ||
|
|
e1b923ab7d | ||
|
|
bed9876d68 | ||
|
|
d184e2708f | ||
|
|
580c3f4ffe | ||
|
|
158b8aea38 | ||
|
|
d22766f458 | ||
|
|
70391243dc | ||
|
|
61eef68ff3 | ||
|
|
41cc2854c5 | ||
|
|
478014f02a | ||
|
|
aff7c2d771 | ||
|
|
00dd52317a | ||
|
|
17522b31e9 | ||
|
|
163b1ee9f8 | ||
|
|
7b9a992f83 | ||
|
|
4efb258671 | ||
|
|
7532358806 | ||
|
|
13c05e7937 | ||
|
|
c6e9bca76c | ||
|
|
3706afbd01 | ||
|
|
bcd0802ea4 | ||
|
|
9360148829 | ||
|
|
a6165c00ce | ||
|
|
a5826fec25 | ||
|
|
839c6668cf | ||
|
|
e9a9fc5050 | ||
|
|
426668cd2e | ||
|
|
926d7c56a6 | ||
|
|
9934dbfe69 | ||
|
|
b6314c109d | ||
|
|
f8955f90b8 | ||
|
|
9248fc96b3 | ||
|
|
2875ee2423 | ||
|
|
36f707b25e | ||
|
|
2a05bd9ed6 | ||
|
|
b7db9944ec | ||
|
|
86f7d08483 | ||
|
|
1358a81c32 | ||
|
|
09ad48c12b | ||
|
|
aa137fb2d2 | ||
|
|
09284d512d | ||
|
|
02fd7e51ff | ||
|
|
b359b89aa1 | ||
|
|
873b20677e | ||
|
|
a049664219 | ||
|
|
64c6e25896 | ||
|
|
9f9122ab8e | ||
|
|
d0661cd4a3 | ||
|
|
707b19dc35 | ||
|
|
6fd15d66a7 | ||
|
|
8c9a814e18 | ||
|
|
74ef5f38e9 | ||
|
|
624a3ee1a7 | ||
|
|
fc658a25d7 | ||
|
|
308619a726 | ||
|
|
e87d8d9856 | ||
|
|
7594264725 | ||
|
|
69533ce8f5 | ||
|
|
9fac43a3a3 | ||
|
|
972270ff3e | ||
|
|
b00db39739 | ||
|
|
6f2a584279 | ||
|
|
de717268f7 | ||
|
|
e27b19c756 | ||
|
|
045cb461f1 | ||
|
|
088c0eedc6 | ||
|
|
e5137b03fc | ||
|
|
76d34a4d74 | ||
|
|
a3f7121a3a | ||
|
|
ae4f0e5728 | ||
|
|
5df59027ad | ||
|
|
c888e33f04 | ||
|
|
1a56ecaa39 | ||
|
|
d778c3cf19 | ||
|
|
8bf57c6226 | ||
|
|
3c762b8809 | ||
|
|
3561fd7c43 | ||
|
|
66bfc0ec64 | ||
|
|
7d0e576e3b | ||
|
|
a65453676f | ||
|
|
aa330bc8c7 | ||
|
|
b4de492e0d | ||
|
|
5bf3114e6f | ||
|
|
1fc82c5daf | ||
|
|
d2b1a2e5a3 | ||
|
|
4b01f6359b | ||
|
|
bcfa62f45a | ||
|
|
e7e8a2ca5f | ||
|
|
5edeb0250b | ||
|
|
0c2657df78 | ||
|
|
e4c57e8031 | ||
|
|
6a25548097 | ||
|
|
db7cbdfc44 | ||
|
|
2f26badb84 | ||
|
|
f7e665c42f | ||
|
|
3bc44ee451 | ||
|
|
125de855ef | ||
|
|
3881ebcce0 | ||
|
|
ca50e9e6d6 | ||
|
|
bef5324fea | ||
|
|
c2655370e0 | ||
|
|
d017e34795 | ||
|
|
aa44da35ba | ||
|
|
5c4c6e68f6 | ||
|
|
a435363b94 | ||
|
|
d6634eb14e | ||
|
|
afee2cf71a | ||
|
|
79b0a6ba9c | ||
|
|
0c2438b36a | ||
|
|
d6da46f94b | ||
|
|
562e39c9c5 | ||
|
|
2d08e0955a | ||
|
|
baffa969d3 | ||
|
|
1fbc8739b9 | ||
|
|
b9dec84489 | ||
|
|
6feb864c38 | ||
|
|
b6db1898b1 | ||
|
|
de902d179e | ||
|
|
58b77e3427 | ||
|
|
cdcac86256 | ||
|
|
79b05e48e8 | ||
|
|
541146e8ce | ||
|
|
97b161c536 | ||
|
|
ba3a6ecb52 | ||
|
|
cf27b7440d | ||
|
|
407b9c9cd7 | ||
|
|
d0055310ba | ||
|
|
02f5fa32af | ||
|
|
b6590e95b5 | ||
|
|
4f9f5ac3e6 | ||
|
|
ec65211d54 | ||
|
|
8dfa08f146 | ||
|
|
daef2d0546 | ||
|
|
15eaa80301 | ||
|
|
1e924a8530 | ||
|
|
23995ccb07 | ||
|
|
a4f2603454 | ||
|
|
cc860b4a76 | ||
|
|
0be82602ce | ||
|
|
b42c42692e | ||
|
|
7fcbff3ceb | ||
|
|
efec0af394 | ||
|
|
aafecd9d1e | ||
|
|
e37c43ea06 | ||
|
|
3fac7b5bb7 | ||
|
|
9b90114d03 | ||
|
|
7c5cfe6697 | ||
|
|
d1fd69337f | ||
|
|
3fc218111a | ||
|
|
c63fb0fc6b | ||
|
|
6fe4ac241d | ||
|
|
c385b80807 | ||
|
|
97f36fa46f | ||
|
|
856d4b39d1 | ||
|
|
01abd73a2a | ||
|
|
375c2a87c7 | ||
|
|
6ca507f8dd | ||
|
|
86b4a53858 | ||
|
|
9a61b7682b | ||
|
|
8959ba9b82 | ||
|
|
a62a230d3d | ||
|
|
cc45129e9f | ||
|
|
bffc9d5aba | ||
|
|
f2b121cd58 | ||
|
|
c1e22f9e86 | ||
|
|
e6e49ae3f7 | ||
|
|
fd30be7644 | ||
|
|
4b191b9cc7 | ||
|
|
efbe737439 | ||
|
|
172fe3d7ff | ||
|
|
5dc70562bf | ||
|
|
a598e1fc2c | ||
|
|
d9052c7e3c | ||
|
|
dcfe10b691 | ||
|
|
914a096b42 | ||
|
|
5fa9dcbc7e | ||
|
|
93ec01e0a1 | ||
|
|
bbc98db6b4 | ||
|
|
1f8d29a221 | ||
|
|
d267dd2515 | ||
|
|
51954c7f3d | ||
|
|
df842a8e8d | ||
|
|
60919488f1 | ||
|
|
4dbaaa63bb | ||
|
|
8cc4003837 | ||
|
|
35790c584b | ||
|
|
09d7cf2cc1 | ||
|
|
58d7c7f6ae | ||
|
|
cab24836d8 | ||
|
|
cf9ef615c9 | ||
|
|
8c96032b2b | ||
|
|
d256551907 | ||
|
|
e800e2db2b | ||
|
|
ae09281bb8 | ||
|
|
9a776b3cdf | ||
|
|
63d7bfde81 | ||
|
|
cc9f41df5f | ||
|
|
bb3784d8dd | ||
|
|
e5539c0d01 | ||
|
|
c997360b4a | ||
|
|
ea8621d6ec | ||
|
|
88fa18204f | ||
|
|
ac05a2ede7 | ||
|
|
808baf203d | ||
|
|
beeafc6bc5 | ||
|
|
6f8c977e73 | ||
|
|
9a2fbdde20 | ||
|
|
b325b2c003 | ||
|
|
feda23587c | ||
|
|
e8f3b7f853 | ||
|
|
e28341ca4b | ||
|
|
6c11a020ee | ||
|
|
7200c2ac0c | ||
|
|
732ca49b02 | ||
|
|
ee976ed460 | ||
|
|
06ac3e896a | ||
|
|
6ce0f6e806 | ||
|
|
e006586275 | ||
|
|
e9d6b17a00 | ||
|
|
bf2f199f37 | ||
|
|
718ca548be | ||
|
|
51c0dc070a | ||
|
|
d5e0d52bc4 | ||
|
|
f6b99db738 | ||
|
|
ef69294072 | ||
|
|
c56d395c90 | ||
|
|
778e9141d8 | ||
|
|
c70a4662b4 | ||
|
|
e441a31051 | ||
|
|
9f5ec5cc50 | ||
|
|
825ded2e08 | ||
|
|
a7c3776557 | ||
|
|
1e7cfc2644 | ||
|
|
c6fd32ffde | ||
|
|
5f551a8b47 | ||
|
|
f73ff57148 | ||
|
|
c538d7372e | ||
|
|
4e7804ca75 | ||
|
|
8fe715983a | ||
|
|
4a3fb07d5f | ||
|
|
f5062c0507 | ||
|
|
f0d7a17b72 | ||
|
|
b89d2d7580 | ||
|
|
7a7f57fa45 | ||
|
|
047dd31724 | ||
|
|
0ce1a200f7 | ||
|
|
0e0024218f | ||
|
|
4886d088e9 | ||
|
|
6eec6e2d65 | ||
|
|
6c12880f5b | ||
|
|
eb472111a8 | ||
|
|
8d8b7ed567 | ||
|
|
681dc70205 | ||
|
|
130cfbf231 | ||
|
|
940e4a6152 | ||
|
|
38f7d9ad37 | ||
|
|
e896d316f2 | ||
|
|
af690b64d6 | ||
|
|
699aad8626 | ||
|
|
4382e53acb | ||
|
|
832adf92a6 | ||
|
|
33e2582918 | ||
|
|
1c2f413211 | ||
|
|
2300581c93 | ||
|
|
03c4fba730 | ||
|
|
75a8b209f5 | ||
|
|
d554b41fea | ||
|
|
b0db1f827e | ||
|
|
3070baf04e | ||
|
|
72629ca511 | ||
|
|
1c39fc71d9 | ||
|
|
0bb59b66be | ||
|
|
31b177f8ad | ||
|
|
8ee5ced08d | ||
|
|
c96a1632f5 | ||
|
|
b3b2649814 | ||
|
|
95805d2e7c | ||
|
|
d4b92141fd | ||
|
|
829e915c90 | ||
|
|
aaffc7485d | ||
|
|
9ea1d6e8af | ||
|
|
17661b4b5f | ||
|
|
32874b89ca | ||
|
|
d4a038c437 | ||
|
|
59fed33797 | ||
|
|
feea137dbf | ||
|
|
70e4a2c4fa | ||
|
|
696359daba | ||
|
|
5695350e98 | ||
|
|
4e3a0720c3 | ||
|
|
dc56d8560d | ||
|
|
81ecea29c8 | ||
|
|
ad58697521 | ||
|
|
6ca7527ec9 | ||
|
|
8ced3699c2 | ||
|
|
c4de5b45df | ||
|
|
71056e1db1 | ||
|
|
f94faeeace | ||
|
|
80f56a1315 | ||
|
|
485f5a07ed | ||
|
|
821af482f0 | ||
|
|
b2d1fadf66 | ||
|
|
3b73e5223e | ||
|
|
6a964e7caf | ||
|
|
a6f06c2d94 | ||
|
|
a85f0a93c6 | ||
|
|
250387c7e5 | ||
|
|
dde7144f5a | ||
|
|
68733a2bc0 | ||
|
|
b2d3a11de8 | ||
|
|
a024e4c10a | ||
|
|
db6e4d1c32 | ||
|
|
8393c382c3 | ||
|
|
5c0e3688fe | ||
|
|
1e6c07246e | ||
|
|
e5370971d6 | ||
|
|
090d921006 | ||
|
|
39c0a7525b | ||
|
|
407b02bde8 | ||
|
|
da7912b879 | ||
|
|
02c08aed12 | ||
|
|
87668f7fa8 | ||
|
|
001734a725 | ||
|
|
276ab3eae3 | ||
|
|
1b976f30f3 | ||
|
|
019afe2a1a | ||
|
|
37ebcd3b4f | ||
|
|
5ad6eeccdf | ||
|
|
65cd33cb15 | ||
|
|
4aa59226d7 | ||
|
|
d53c98860d | ||
|
|
d022e1acce | ||
|
|
98100520eb | ||
|
|
42526fc2dc | ||
|
|
9c76afa2a3 | ||
|
|
943db4496b | ||
|
|
4a77b6673b | ||
|
|
62b31b1e4a | ||
|
|
ddde4e1965 | ||
|
|
96a99935ef | ||
|
|
60c003733e | ||
|
|
9def9a5cb7 | ||
|
|
145295302d | ||
|
|
302d2dbd51 | ||
|
|
49ba3ffee6 | ||
|
|
d83ce0863a | ||
|
|
cf844cb27c | ||
|
|
5ccef18d4e | ||
|
|
40bbdfdf6a | ||
|
|
ad8ad0ccd7 | ||
|
|
1cf012650b | ||
|
|
4f280b5497 | ||
|
|
5ee7009271 | ||
|
|
07f850ed15 | ||
|
|
dde0c41c84 | ||
|
|
1b6fbe3a2e | ||
|
|
b1b415ec5b | ||
|
|
8730bbac2f | ||
|
|
e8918ca149 | ||
|
|
82478eef09 | ||
|
|
892e9cd835 | ||
|
|
3dd6499ac4 | ||
|
|
037da34e5d | ||
|
|
ad30d35663 | ||
|
|
8d70b3b79e | ||
|
|
109c66aea3 | ||
|
|
24b0f8e27e | ||
|
|
1a76e83fa4 | ||
|
|
2fa788b01b | ||
|
|
028cbdcffa | ||
|
|
8aefbd911b | ||
|
|
f37387de80 | ||
|
|
4f705fc3f8 | ||
|
|
5b727065cf | ||
|
|
952e466d91 | ||
|
|
c1cc76119c | ||
|
|
9d156141b1 | ||
|
|
8c92b0cd3a | ||
|
|
dd515da889 | ||
|
|
2862b69d56 | ||
|
|
db8e46184b | ||
|
|
99a7cd3cfb | ||
|
|
75746d714a | ||
|
|
983d6d3b42 | ||
|
|
060dd8b020 | ||
|
|
b5be0a2e3e | ||
|
|
46a687b0a6 | ||
|
|
4ff7aa4352 | ||
|
|
750d1f820d | ||
|
|
f046a34d34 | ||
|
|
0d165920bb | ||
|
|
9e3a4402e0 | ||
|
|
34d7aea1be | ||
|
|
e2abc0b727 | ||
|
|
a677a68ab7 | ||
|
|
df228237de | ||
|
|
fc2a038ee1 | ||
|
|
619b39f955 | ||
|
|
becaa3b920 | ||
|
|
c0b9ab930d | ||
|
|
f106b1db15 | ||
|
|
958217dd55 | ||
|
|
2f80fdae97 | ||
|
|
9507f191b0 | ||
|
|
92f5d8c8be | ||
|
|
8535eb7bf5 | ||
|
|
c9604eaabf | ||
|
|
3bc214e544 | ||
|
|
43cec4398d | ||
|
|
335394aaa1 | ||
|
|
c9615cc19c | ||
|
|
5315d8fe3f | ||
|
|
75dedb3345 | ||
|
|
134dfb8804 | ||
|
|
86f4a8d33a | ||
|
|
abeb924554 | ||
|
|
4da3933f24 | ||
|
|
c5703306ef | ||
|
|
a26774b99e | ||
|
|
9258593776 | ||
|
|
48604041e8 | ||
|
|
110af3b524 | ||
|
|
57ed9ec8e2 | ||
|
|
5434b53a99 | ||
|
|
f4361818e0 | ||
|
|
801ab611ed | ||
|
|
bc34167c84 | ||
|
|
decd0dc035 | ||
|
|
9ac9c693ad | ||
|
|
9b2cd69c0f | ||
|
|
b3f1a19db6 | ||
|
|
f3b6708a92 | ||
|
|
99cdc7af32 | ||
|
|
8848885d9a | ||
|
|
c1cab6789e | ||
|
|
907777eeb0 | ||
|
|
7889612edc | ||
|
|
e81e264988 | ||
|
|
eacc29ded0 | ||
|
|
ea04c93bfd | ||
|
|
8692977585 | ||
|
|
6a40f3ed60 | ||
|
|
dd1f631d9d | ||
|
|
15874ac45c | ||
|
|
761fc74a67 | ||
|
|
0e2239e50b | ||
|
|
e9a17517d3 | ||
|
|
94254e61c1 | ||
|
|
32eb81d4ae | ||
|
|
6f7e38b94c | ||
|
|
87f271af29 | ||
|
|
ff74310e32 | ||
|
|
a181fa2992 | ||
|
|
76e879e5de | ||
|
|
c01ab3ed39 | ||
|
|
9f403a4d6b | ||
|
|
55792d5528 | ||
|
|
a3f726baa8 | ||
|
|
ebc2b23c3a | ||
|
|
e4ca3609d9 | ||
|
|
bc092d8d78 | ||
|
|
dd5933b048 | ||
|
|
5d6128b25c | ||
|
|
24cb04c346 | ||
|
|
f1b54cf0a4 | ||
|
|
e64a7b87a8 | ||
|
|
2b452ea3e8 | ||
|
|
66c6c6c7d1 | ||
|
|
5b4aa1afc2 | ||
|
|
89205276ab | ||
|
|
6d2ab6a7d6 | ||
|
|
e6da910ee2 | ||
|
|
2100ac3cfc | ||
|
|
c7476a1d96 | ||
|
|
d8c3033941 | ||
|
|
7e26ee5a73 | ||
|
|
a8e25ccfe6 | ||
|
|
b6267ec7c2 | ||
|
|
b6bd2884d5 | ||
|
|
767a235611 | ||
|
|
620fc06b6c | ||
|
|
0fa4c89a1b | ||
|
|
1bf046c142 | ||
|
|
52f8429218 | ||
|
|
932b414063 | ||
|
|
097b2390db | ||
|
|
ca8d252ad7 | ||
|
|
23a0dbe3cc | ||
|
|
545ece82b3 | ||
|
|
eaea947b74 | ||
|
|
f1b61d5882 | ||
|
|
e466d72058 | ||
|
|
385be35ed5 | ||
|
|
528b9b6a60 | ||
|
|
dd374eaebf | ||
|
|
9ea483d1dc | ||
|
|
d8a396bf24 | ||
|
|
b1813df61a | ||
|
|
8715f74d29 | ||
|
|
152224944b | ||
|
|
f86d12c8f4 | ||
|
|
94d4bc4bac | ||
|
|
c95488549d | ||
|
|
39613aa2d9 | ||
|
|
7c2aafd4ee | ||
|
|
e834c7fe3e | ||
|
|
f96958adf8 | ||
|
|
776074b24f | ||
|
|
c9d64d75f3 | ||
|
|
9651689bb8 | ||
|
|
75be0475ba | ||
|
|
e130b58b20 | ||
|
|
e44f0c497f | ||
|
|
2d0f96d28b | ||
|
|
34d1f79777 | ||
|
|
2185ccd4ea | ||
|
|
125634759d | ||
|
|
350e636e3d | ||
|
|
429140df97 | ||
|
|
a921deafd1 | ||
|
|
071fba2f71 | ||
|
|
9de729e3e7 | ||
|
|
7cf5bd30f2 | ||
|
|
e6cee2965a | ||
|
|
af2b263bc7 | ||
|
|
aa120e0478 | ||
|
|
b07c55a0d9 | ||
|
|
e7f1f496c5 | ||
|
|
823c0434eb | ||
|
|
22162635e7 | ||
|
|
8be0031602 | ||
|
|
29c5e74d31 | ||
|
|
3c8867a1e8 | ||
|
|
c439fe0437 | ||
|
|
b21db670b4 | ||
|
|
1f84aa9809 | ||
|
|
4ac249c26c | ||
|
|
85a29fce94 | ||
|
|
71ecb470b6 | ||
|
|
15a000bb45 | ||
|
|
18e4a7ac6e | ||
|
|
d0322f5fbd | ||
|
|
c1f01b7e35 | ||
|
|
71064f481b | ||
|
|
436293713b | ||
|
|
fc726bfb4b | ||
|
|
b0c3780667 | ||
|
|
3e431c65be | ||
|
|
5b0b90d1f5 | ||
|
|
d16714e84b | ||
|
|
1d5fff9f58 | ||
|
|
fbe8d6144a | ||
|
|
d5f59a57bf | ||
|
|
7465c79884 | ||
|
|
769195fcff | ||
|
|
dc786bd1cc | ||
|
|
960f4ed649 | ||
|
|
91ad3bf1b6 | ||
|
|
91b495d526 | ||
|
|
973d91d120 | ||
|
|
bf5deace8e | ||
|
|
0e4acf6299 | ||
|
|
a5cd0061c5 | ||
|
|
630e3903fa | ||
|
|
0b6a5fad70 | ||
|
|
67ca1b82cc | ||
|
|
9866053f0c | ||
|
|
89a2c1a09c | ||
|
|
70220d8b9c | ||
|
|
274f69526f | ||
|
|
d7026fe36b | ||
|
|
b9b65d7dfb | ||
|
|
1545c78d05 | ||
|
|
f0c292e77b | ||
|
|
62336127e3 | ||
|
|
5beaf8ac98 | ||
|
|
9efd484e27 | ||
|
|
44d5cf980a | ||
|
|
e53650d6c6 | ||
|
|
5bf9a9828c | ||
|
|
24f3bc9f0c | ||
|
|
c200e55f95 | ||
|
|
ea19d59fca | ||
|
|
d34d14c1f4 | ||
|
|
7b17306dbd | ||
|
|
6731564c2d | ||
|
|
194ba0cf8d | ||
|
|
6fc2429540 | ||
|
|
bdcbe61273 | ||
|
|
de5d7bfbd3 | ||
|
|
242878c45c | ||
|
|
c0911da887 | ||
|
|
6e0bf04276 | ||
|
|
56c460d932 | ||
|
|
f0933b66a9 | ||
|
|
422d633f89 | ||
|
|
0537be129c | ||
|
|
9b947c8370 | ||
|
|
14eb4326e7 | ||
|
|
89a3e8fcc7 | ||
|
|
6fd5133bed | ||
|
|
e010877490 | ||
|
|
f56371c79b | ||
|
|
c98f3c5d29 | ||
|
|
5c8de9d82f | ||
|
|
b9c8b6ba23 | ||
|
|
6cd968b53b | ||
|
|
2aa76d257c | ||
|
|
32c0be8bde | ||
|
|
88d283a89d | ||
|
|
66b370c421 | ||
|
|
20bf139b3f | ||
|
|
1da4602567 | ||
|
|
e7ef69e6e7 | ||
|
|
d55904d4db | ||
|
|
740dc59255 | ||
|
|
98b6362c07 | ||
|
|
cd829c096b | ||
|
|
f127c55802 | ||
|
|
13247a0e00 | ||
|
|
609752d331 | ||
|
|
413410d02d | ||
|
|
3528610a51 | ||
|
|
59ee045c24 | ||
|
|
b1dec12893 | ||
|
|
319b0acdd8 | ||
|
|
c605c46f83 | ||
|
|
9ef692b48c | ||
|
|
6da4dfe605 | ||
|
|
7b4cb31a10 | ||
|
|
03ce4d7e2b | ||
|
|
f55f5fa92a | ||
|
|
76757ad1f2 | ||
|
|
347e88dc65 | ||
|
|
746d032e58 | ||
|
|
b6d598a001 | ||
|
|
b35961c53c | ||
|
|
47fba5827b | ||
|
|
47f75ad8bf | ||
|
|
516167c0f8 | ||
|
|
238b3a97a8 | ||
|
|
d4ab8a5a5d | ||
|
|
6672299f8a | ||
|
|
ea5f515f18 | ||
|
|
ea6293544d | ||
|
|
cbe35281b9 | ||
|
|
51a0fc45e2 | ||
|
|
1e7e2bd34f | ||
|
|
fa2f3d136f | ||
|
|
92b6026695 | ||
|
|
c9a5f21344 | ||
|
|
0174bf3722 | ||
|
|
0d003e7450 | ||
|
|
8847838c43 | ||
|
|
9594ce9a8a | ||
|
|
4a91d09c86 | ||
|
|
06837bd32b | ||
|
|
b8d8887d5a | ||
|
|
256f8dd41b | ||
|
|
e0fdafc7e5 | ||
|
|
9a55df245f | ||
|
|
9800d95c50 | ||
|
|
c340416c94 | ||
|
|
9af8a1d30c | ||
|
|
4da96ee980 | ||
|
|
21637e033c | ||
|
|
9ebf2dc97b | ||
|
|
a04689b784 | ||
|
|
5066945adc | ||
|
|
e945c12856 | ||
|
|
0b062d0b8a | ||
|
|
9cc1eff15c | ||
|
|
327e5d06e1 | ||
|
|
a2dd0aea92 | ||
|
|
39da3459c7 | ||
|
|
c0be4c36e1 | ||
|
|
31e04378cd | ||
|
|
e80c99ad74 | ||
|
|
d9be443e53 | ||
|
|
6db323b15e | ||
|
|
5abbfd3f19 | ||
|
|
674215e9e6 | ||
|
|
dce6a5763d | ||
|
|
d89d6e8a01 | ||
|
|
6230dbed2d | ||
|
|
9641254443 | ||
|
|
95871fe13c | ||
|
|
0cecfceb14 | ||
|
|
b9f1cb2021 | ||
|
|
3f208d806c | ||
|
|
ba9ea3f02a | ||
|
|
13970280d9 | ||
|
|
55ce80aabe | ||
|
|
9536a490b3 | ||
|
|
405e07f0a2 | ||
|
|
d3ce91bd89 | ||
|
|
eb44201c5f | ||
|
|
73248aadd5 | ||
|
|
f6a4084f81 | ||
|
|
d5f89c165a | ||
|
|
a518471a27 | ||
|
|
dce5080e53 | ||
|
|
2221d4d612 | ||
|
|
5f73a46c05 | ||
|
|
b782c6bd16 | ||
|
|
ab8d8aa552 | ||
|
|
f955276694 | ||
|
|
77cc60faf2 | ||
|
|
a6f50b8c85 | ||
|
|
e2dfa1d72f | ||
|
|
9a61c0a6fc | ||
|
|
e10b25a12c | ||
|
|
0c1e803208 | ||
|
|
b57dcc74d1 | ||
|
|
f8c583636c | ||
|
|
e6521d1cf3 | ||
|
|
96785e8df1 | ||
|
|
d689778465 | ||
|
|
3c8f8b76aa | ||
|
|
c123fa5422 | ||
|
|
0ade8be7f7 | ||
|
|
a60c2f38c6 | ||
|
|
f1c0797780 | ||
|
|
701167bc12 | ||
|
|
a39e63e324 | ||
|
|
8401e9c2b4 | ||
|
|
c5fca0a1e7 | ||
|
|
e779335d06 | ||
|
|
26039adf5b | ||
|
|
c88286556a | ||
|
|
831b9d4433 | ||
|
|
e937e8fff9 | ||
|
|
f616b2d49a | ||
|
|
fe84dae313 | ||
|
|
9104933b18 | ||
|
|
79654635d3 | ||
|
|
f0edfca75c | ||
|
|
e845da2edc | ||
|
|
7a3050f2c0 | ||
|
|
9a6531e2a2 | ||
|
|
a6a17a85f3 | ||
|
|
9275fd16c2 | ||
|
|
904ae05810 | ||
|
|
54f95389a8 | ||
|
|
a8fc70a5b9 | ||
|
|
c374072822 | ||
|
|
0212de68a4 | ||
|
|
2ea9b6d409 | ||
|
|
823d71df28 | ||
|
|
7560918b32 | ||
|
|
fd87faa7a6 | ||
|
|
cb2d706fa1 | ||
|
|
6b638ac896 | ||
|
|
2bd5ae3617 | ||
|
|
39a5311315 | ||
|
|
9b6e46dc6b | ||
|
|
7311d1182d | ||
|
|
ea1d8b8104 | ||
|
|
fb03e3f00e | ||
|
|
c9c35255e7 | ||
|
|
99a578dbad | ||
|
|
e56c0a6251 | ||
|
|
66479e2aa7 | ||
|
|
6feddcbced | ||
|
|
db020ca1a3 | ||
|
|
6c93518ef7 | ||
|
|
eb02d01eed | ||
|
|
7a9093f634 | ||
|
|
d55f691ec0 | ||
|
|
f222030edb | ||
|
|
5f691fb05c | ||
|
|
1732b2dfe3 | ||
|
|
a62f891a60 | ||
|
|
a22ecd42ed | ||
|
|
b7cb2a2951 | ||
|
|
c490970324 | ||
|
|
5a9c8a9343 | ||
|
|
5ba7e5d7d7 | ||
|
|
f7b281a65f | ||
|
|
df5a1c59e6 | ||
|
|
0615709a7a | ||
|
|
d85a0130b7 | ||
|
|
71f17a233e | ||
|
|
25c35cbbe4 | ||
|
|
257ba570ee | ||
|
|
91e96b2314 | ||
|
|
c2ee7cbff5 | ||
|
|
27f813e043 | ||
|
|
00ed91f12e | ||
|
|
4cb5efc277 | ||
|
|
65a453d21b | ||
|
|
9c8cb4dea3 | ||
|
|
ed902fdb70 | ||
|
|
509067391b | ||
|
|
04b261057d | ||
|
|
852343f254 | ||
|
|
26e35344d0 | ||
|
|
d3a619659f | ||
|
|
979f2415fb | ||
|
|
28c1d219f6 | ||
|
|
5792f4bf07 | ||
|
|
3a0fa5cb29 | ||
|
|
074ee656f0 | ||
|
|
064f93185c | ||
|
|
4b5922f652 | ||
|
|
85be906b68 | ||
|
|
775285cdf8 | ||
|
|
42f96dc7a6 | ||
|
|
e96fa64625 | ||
|
|
8dc495c9bc | ||
|
|
5d70d889e9 | ||
|
|
999ae6eb49 | ||
|
|
ae1450bbcf | ||
|
|
dcd8a05809 | ||
|
|
62e466f774 | ||
|
|
70777a047d | ||
|
|
47fd95db9d | ||
|
|
7602d9e54b | ||
|
|
1ed0079882 | ||
|
|
b026be410c | ||
|
|
767a1711ff | ||
|
|
a93bd8d944 | ||
|
|
4e12f86e90 | ||
|
|
3007009fab | ||
|
|
2d886b65ce | ||
|
|
8700b87030 | ||
|
|
5a46f1229d | ||
|
|
9d5f8883a7 | ||
|
|
8e0b9b82e9 | ||
|
|
ea4b4ddce4 | ||
|
|
bd95c7b82a | ||
|
|
e20c5cf9cf | ||
|
|
6adb489cb3 | ||
|
|
0c2db1cea5 | ||
|
|
e33604887b | ||
|
|
410f37df1b | ||
|
|
c9f3883c8c | ||
|
|
4346d7605d | ||
|
|
a0a2c27973 | ||
|
|
3fb87ee76e | ||
|
|
242aeea24c | ||
|
|
c305dc8d22 | ||
|
|
f61b898633 | ||
|
|
2bdcd436bb | ||
|
|
a1bea7d7cc | ||
|
|
b2bdc73164 | ||
|
|
cbaf0a3864 | ||
|
|
103563b375 | ||
|
|
595429fdde | ||
|
|
b384b27546 | ||
|
|
0b996245d5 | ||
|
|
1ee91dd690 | ||
|
|
f9e602c44c | ||
|
|
4fa827ddfd | ||
|
|
1b3c73618c | ||
|
|
7b08f1cc8c | ||
|
|
7d392e5adb | ||
|
|
f44cc2b60c | ||
|
|
31680898e3 | ||
|
|
318fd7c9e3 | ||
|
|
b10b8ca3f4 | ||
|
|
b0c33308be | ||
|
|
1421c4e9d3 | ||
|
|
f55dfc9025 | ||
|
|
c218970890 | ||
|
|
bd27ce2520 | ||
|
|
44795b65f9 | ||
|
|
af84c4e6bd | ||
|
|
0a28207200 | ||
|
|
8ca2a5832c | ||
|
|
333534dfe7 | ||
|
|
d8ce0d0df0 | ||
|
|
28c3259449 | ||
|
|
0d0ede7b14 | ||
|
|
9ebf6bcc92 | ||
|
|
9d186e9ba3 | ||
|
|
3c3a4526bf | ||
|
|
3094c2ce17 | ||
|
|
393494a728 | ||
|
|
d2725c3f49 | ||
|
|
4d4425a5bf | ||
|
|
c11fbe0868 | ||
|
|
c676689df0 | ||
|
|
0f5625d721 | ||
|
|
6f5e6bd0f1 | ||
|
|
a0af092ecb | ||
|
|
3a07a194ab | ||
|
|
682ffa7cf5 | ||
|
|
dc4a4ca9d3 | ||
|
|
3c2b6ce112 | ||
|
|
f8b3a395fb | ||
|
|
087b45ab90 | ||
|
|
33ac85f637 | ||
|
|
efd9421dc9 | ||
|
|
9b696a872b | ||
|
|
aab515b16c | ||
|
|
f220628354 | ||
|
|
322bc5dc87 | ||
|
|
75c3bda866 | ||
|
|
b2b776169b | ||
|
|
8e8d7ae614 | ||
|
|
fa1af5a2cb | ||
|
|
a27e4072b4 | ||
|
|
fad26a49be | ||
|
|
1742159345 | ||
|
|
ed8d2cb482 | ||
|
|
8e1f022810 | ||
|
|
4c25072c18 | ||
|
|
564ec32520 | ||
|
|
a743feb040 | ||
|
|
b028667de1 | ||
|
|
41888f84bc | ||
|
|
6a918dbde9 | ||
|
|
578230e32c | ||
|
|
d486b03089 | ||
|
|
8559334339 | ||
|
|
968c6ed8be | ||
|
|
8893d9edc4 | ||
|
|
43753ec113 | ||
|
|
2ec3e4a912 | ||
|
|
a086745ec0 | ||
|
|
51156d0582 | ||
|
|
ea9925f489 | ||
|
|
026b96b8f2 | ||
|
|
136b2ae37f | ||
|
|
97009a2748 | ||
|
|
e123f7c743 | ||
|
|
e28bde6ccd | ||
|
|
a976f418e3 | ||
|
|
3c701e780c | ||
|
|
769dd174bd | ||
|
|
e92514ee63 | ||
|
|
8ebc517b41 | ||
|
|
91b03e52f1 | ||
|
|
a22406c9f8 | ||
|
|
ebc3666c6f | ||
|
|
f1fee1239b | ||
|
|
8769fa0156 | ||
|
|
f4d7338687 | ||
|
|
6a8c3f82ef | ||
|
|
05bcbfa28c | ||
|
|
6a55500c1b | ||
|
|
a5a5ac60ba | ||
|
|
6ed7f47b3f | ||
|
|
a3e94855f9 | ||
|
|
503da97a79 | ||
|
|
088a93e023 | ||
|
|
30f71ad632 | ||
|
|
0026849821 | ||
|
|
cf5a310286 | ||
|
|
72384ff2cb | ||
|
|
c33ef01af8 | ||
|
|
11116bdcb7 | ||
|
|
09a5cf4e68 | ||
|
|
a9172129d2 | ||
|
|
3ec06705ca | ||
|
|
5fb0d38ad8 | ||
|
|
9ed5cddb89 | ||
|
|
4e97fb0e58 | ||
|
|
1688e373bc | ||
|
|
cada0b6df1 | ||
|
|
91358010a0 | ||
|
|
51024d3821 | ||
|
|
b329d998ca | ||
|
|
482f1dba27 | ||
|
|
23fc7e65d4 | ||
|
|
8f594ad6d9 | ||
|
|
d8d46039a2 | ||
|
|
19e1325604 | ||
|
|
220d6ed494 | ||
|
|
b5ed3edc8f | ||
|
|
9772726065 | ||
|
|
8ecdde6cb5 | ||
|
|
73c96f35c1 | ||
|
|
5b3824917d | ||
|
|
ca4f10dc5e | ||
|
|
853fb33913 | ||
|
|
e352cfc861 | ||
|
|
b8d79d9132 | ||
|
|
507c71f64c | ||
|
|
ce0067d8eb | ||
|
|
c0b238b19a | ||
|
|
d961cf21fb | ||
|
|
1f7622e4c4 | ||
|
|
b019ca0746 | ||
|
|
04fe7e61de | ||
|
|
beb4e00afb | ||
|
|
3e6607585f | ||
|
|
0b2213dd41 | ||
|
|
9450305568 | ||
|
|
08725c44c6 | ||
|
|
e18c64c9d9 | ||
|
|
7b018c60cb | ||
|
|
a81286c795 | ||
|
|
75a66b716e | ||
|
|
0c05e6593e | ||
|
|
571e9bf26a | ||
|
|
c4714e95b6 | ||
|
|
c43ab50d66 | ||
|
|
0d283b2666 | ||
|
|
26e7da0b96 | ||
|
|
98b1c7a38c | ||
|
|
d407e5556e | ||
|
|
6a3cfe54af | ||
|
|
a0bffe4a78 | ||
|
|
336c716a44 | ||
|
|
ccdbec619c | ||
|
|
47001c3303 | ||
|
|
8e50fecccc | ||
|
|
938fcdd1a6 | ||
|
|
9ede57b228 | ||
|
|
8810658858 | ||
|
|
e074d02714 | ||
|
|
e26de9c1d1 | ||
|
|
7dc3835a54 | ||
|
|
117a8cafca | ||
|
|
337dfd5ee4 | ||
|
|
e37c9ed0a1 | ||
|
|
aa6a31eba5 | ||
|
|
8a0a0aef5c | ||
|
|
4750e15c20 | ||
|
|
747ce9b1f1 | ||
|
|
7fa874d9ef | ||
|
|
5febc3e07d | ||
|
|
2244bf2ba2 | ||
|
|
29cb62af3d | ||
|
|
027847a663 | ||
|
|
8134ba1faf | ||
|
|
d30748f1de | ||
|
|
6aa041b193 | ||
|
|
0fdc0a01d0 | ||
|
|
de7f2eef47 | ||
|
|
a449ffe49d | ||
|
|
08cacc4943 | ||
|
|
04b9216758 | ||
|
|
1ff97754af | ||
|
|
20e43311db | ||
|
|
89bcb1de42 | ||
|
|
7a1a44f802 | ||
|
|
e9edec0875 | ||
|
|
06aa32db22 | ||
|
|
6f8593cf47 | ||
|
|
3b2efb1000 | ||
|
|
87482e3746 | ||
|
|
ef6a280019 | ||
|
|
326ae05b06 | ||
|
|
3f13c85b64 | ||
|
|
1ae7bd6477 | ||
|
|
c91641aa83 | ||
|
|
f92d2e3f7c | ||
|
|
3e2489465f | ||
|
|
a5bf32a97d | ||
|
|
8bb2d29a8d | ||
|
|
a9b75d059b | ||
|
|
938e8110ca | ||
|
|
93039081d5 | ||
|
|
3d253309b7 | ||
|
|
301c1861f3 | ||
|
|
a3a90ea09b | ||
|
|
e6f289deb6 | ||
|
|
0e22618d93 | ||
|
|
a0ad110cff | ||
|
|
89ee28f858 | ||
|
|
5917786296 | ||
|
|
7f1e0313a0 | ||
|
|
c89be96209 | ||
|
|
fcd6c3065e | ||
|
|
a700ef5e24 | ||
|
|
3a6ea57d2c | ||
|
|
e960bcfd1c | ||
|
|
65e8ed6871 | ||
|
|
a77d7b8442 | ||
|
|
51e9f302b0 | ||
|
|
72fd1cc5a6 | ||
|
|
1a77bdd1d0 | ||
|
|
1ea9002fe8 | ||
|
|
7d1c3920fd | ||
|
|
c5bb074573 | ||
|
|
cead10b9af | ||
|
|
382e94e282 | ||
|
|
7e8434404f | ||
|
|
cfcbaf33af | ||
|
|
175f78fa84 | ||
|
|
c8ab2bec5e | ||
|
|
136d50a7c5 | ||
|
|
0fa653d580 | ||
|
|
48f2c85791 | ||
|
|
13ca56d380 | ||
|
|
b5109d2a1a | ||
|
|
8ab532efb5 | ||
|
|
f11c17063c | ||
|
|
72eb44aebc | ||
|
|
b070503e77 | ||
|
|
f48e1ee0ac | ||
|
|
a5b7590d3a | ||
|
|
f0955f1620 | ||
|
|
6dda2713cf | ||
|
|
4769254978 | ||
|
|
ca917f7b9a | ||
|
|
b9df4c99cf | ||
|
|
e6dadb215e | ||
|
|
d70bba2806 | ||
|
|
3217452b02 | ||
|
|
ff0494b180 | ||
|
|
8be15c1b5b | ||
|
|
0207b5ba8b | ||
|
|
5ab917f606 | ||
|
|
ea541ca21b | ||
|
|
fc223f5924 | ||
|
|
7b8eb84cb8 | ||
|
|
38443c72c3 | ||
|
|
0cef3e67ce | ||
|
|
b98d4875da | ||
|
|
ae52db41de | ||
|
|
c3e2b463e4 | ||
|
|
5b3ea012ab | ||
|
|
07df43aa2a | ||
|
|
6e3bc77369 | ||
|
|
24ddefe3ad | ||
|
|
7db645587b | ||
|
|
cbf6d53e84 | ||
|
|
5f012c5dc9 | ||
|
|
5e0ce96e49 | ||
|
|
4a2228a372 | ||
|
|
d9a0382539 | ||
|
|
f52a532771 | ||
|
|
efc4c53b44 | ||
|
|
4837f9cdad | ||
|
|
317c53acf6 | ||
|
|
f02af5fe6e | ||
|
|
92e6c21210 | ||
|
|
beb26e84f3 | ||
|
|
2b7a605223 | ||
|
|
d70f0092f7 | ||
|
|
7f6e4a9744 | ||
|
|
96a4fc7ca2 | ||
|
|
29c1797493 | ||
|
|
860dead985 | ||
|
|
518ceb53a8 | ||
|
|
4bcddca1f0 | ||
|
|
cf80f03084 | ||
|
|
47f31eed37 | ||
|
|
8ff9a9ff08 | ||
|
|
8dcf27ba29 | ||
|
|
d97043725d | ||
|
|
90fd323ac5 | ||
|
|
b6c384a0f7 | ||
|
|
cda8a7be38 | ||
|
|
c657d766cf | ||
|
|
4706ff6938 | ||
|
|
c444af007f | ||
|
|
6e80bb49fb | ||
|
|
bf3d0c1274 | ||
|
|
0ded1d326c | ||
|
|
708d288121 | ||
|
|
6462c83f69 | ||
|
|
f30bb452cc | ||
|
|
ad4dd2def5 | ||
|
|
76582a60b5 | ||
|
|
004246163d | ||
|
|
a2cae45f00 | ||
|
|
c1159337da | ||
|
|
71adbd7c39 | ||
|
|
ded949052c | ||
|
|
40fd6eb358 | ||
|
|
48b65bf9d8 | ||
|
|
a761f9eb55 | ||
|
|
d1bf0da144 | ||
|
|
de15a1e7c8 | ||
|
|
a56bc0e1e0 | ||
|
|
519db2aace | ||
|
|
e64c5661da | ||
|
|
b15421826d | ||
|
|
3b31dbaa16 | ||
|
|
318957cb81 | ||
|
|
4b516fdb09 | ||
|
|
913b620c66 | ||
|
|
cd4d90c647 | ||
|
|
456207b4e7 | ||
|
|
39604d2fdc | ||
|
|
27e415e664 | ||
|
|
c57a4cf926 | ||
|
|
0a868b5c27 | ||
|
|
753f137575 | ||
|
|
728788e3b9 | ||
|
|
ec6e130eb3 | ||
|
|
8972ca8134 | ||
|
|
671b6d2eda | ||
|
|
043f7bf2ab | ||
|
|
625cdde9a4 | ||
|
|
e3d39fbf3f | ||
|
|
94cbc8bd31 | ||
|
|
e262de9b2d | ||
|
|
17d9e30be5 | ||
|
|
37b7dc8e7c | ||
|
|
5c2f7a744a | ||
|
|
535f0f45c9 | ||
|
|
b9cef2f38f | ||
|
|
793d78fba6 | ||
|
|
5ad055efb4 | ||
|
|
3277595366 | ||
|
|
b11be32063 | ||
|
|
725652006d | ||
|
|
10587e3a84 | ||
|
|
073115e7ab | ||
|
|
45dcd987c5 | ||
|
|
960246fbb9 | ||
|
|
2fa274de1e | ||
|
|
4cc98874a0 | ||
|
|
fafd05afb2 | ||
|
|
7a3ad30bfa | ||
|
|
32acf9cb72 | ||
|
|
ddbc35181c | ||
|
|
0946ac2ff9 | ||
|
|
1d314834a4 | ||
|
|
875aecf9c6 | ||
|
|
13e0151cd2 | ||
|
|
51a7be29f5 | ||
|
|
ef46738384 | ||
|
|
54806f6ee8 | ||
|
|
ae538a2259 | ||
|
|
66f443fd00 | ||
|
|
ca9c29e2b6 | ||
|
|
273beb016b | ||
|
|
cd8a0f33b5 | ||
|
|
b1e05b4832 | ||
|
|
4c0378eeae | ||
|
|
ea14398929 | ||
|
|
1b5dd8bbd7 | ||
|
|
c85acf8044 | ||
|
|
78a587791f | ||
|
|
f4a3ebcb41 | ||
|
|
4e8fc6d198 | ||
|
|
086dab902c | ||
|
|
722c03b6c6 | ||
|
|
39128c34cc | ||
|
|
542d21c4e1 | ||
|
|
90a62405ca | ||
|
|
bba20c27fe | ||
|
|
d355e57fa6 | ||
|
|
f2d7c4091a | ||
|
|
bf879ce742 | ||
|
|
e89a3b05ec | ||
|
|
52305ca91b | ||
|
|
d6167636fa | ||
|
|
cc1e1a525f | ||
|
|
96deae43fa | ||
|
|
5aa0267936 | ||
|
|
b1b1e0eba4 | ||
|
|
07f6465872 | ||
|
|
eda7c5369c | ||
|
|
e9f709301c | ||
|
|
7e29bd10b6 | ||
|
|
20eea2184b | ||
|
|
eaa375936f | ||
|
|
de8582ec07 | ||
|
|
e6ccdc2378 | ||
|
|
4450a01014 | ||
|
|
bb962b90cc | ||
|
|
a1ac507a94 | ||
|
|
ad6eb15eac | ||
|
|
2e94e4cd67 | ||
|
|
44f75d94e1 | ||
|
|
ad89310c45 | ||
|
|
c26e112bee | ||
|
|
7daf18b077 | ||
|
|
a8a5d2fc4e | ||
|
|
90f6abfa7c | ||
|
|
65f2d7fd66 | ||
|
|
f3554804bf | ||
|
|
f5e571ba40 | ||
|
|
e43331b7a2 | ||
|
|
e78fd09e07 | ||
|
|
b4c1ca88f3 | ||
|
|
dba9c2fbb0 | ||
|
|
ab074f52fe | ||
|
|
121fa834d5 | ||
|
|
598cbf2210 | ||
|
|
f481ba1c1c | ||
|
|
9e42dfd094 | ||
|
|
8aa117e4ae | ||
|
|
f6f4e40a64 | ||
|
|
caf2c0a6c4 | ||
|
|
57dde3e980 | ||
|
|
dc8da4717f | ||
|
|
7b30fc4b82 | ||
|
|
6791b05a40 | ||
|
|
b54ddccd7b | ||
|
|
d32360cb3e | ||
|
|
3eba0c2297 | ||
|
|
01f4ce96f1 | ||
|
|
90b6afe06b | ||
|
|
b22caef65f | ||
|
|
db4281164c | ||
|
|
217c2cacaf | ||
|
|
df4b6f0376 | ||
|
|
6ec1bfebec | ||
|
|
5d88326915 | ||
|
|
24354b9dcc | ||
|
|
39de8e28da | ||
|
|
06beb59628 | ||
|
|
2dbe567e3b | ||
|
|
563a5088be | ||
|
|
c10c59db4b | ||
|
|
463f084b3e | ||
|
|
312e0dcbc8 | ||
|
|
6f93001658 | ||
|
|
48821a6da5 | ||
|
|
b93bc142d3 | ||
|
|
ab9b8b8b0a | ||
|
|
1c4a90626a | ||
|
|
3bf1866f4a | ||
|
|
1a652b555f | ||
|
|
3f61d24d0a | ||
|
|
16064d5614 | ||
|
|
d9f21db623 | ||
|
|
8ac541e634 | ||
|
|
da2688403e | ||
|
|
dbd230da74 | ||
|
|
f660530ef5 | ||
|
|
a19563e139 | ||
|
|
c4400cf72a | ||
|
|
aae4943e64 | ||
|
|
b0339b848f | ||
|
|
f3f106c21f | ||
|
|
7fbff885dd | ||
|
|
60b0e652df | ||
|
|
bb3405ef60 | ||
|
|
9ef0883011 | ||
|
|
a50433dd95 | ||
|
|
37d7d18bb7 | ||
|
|
fa0176c1e6 | ||
|
|
695c60c3fe | ||
|
|
ffadb70d81 | ||
|
|
414b7e28d3 | ||
|
|
fca464071f | ||
|
|
cdb85f1309 | ||
|
|
4f08f4b84c | ||
|
|
1b5175d018 | ||
|
|
6d7fba6758 | ||
|
|
0bfda6d4c8 | ||
|
|
880b22604b | ||
|
|
04a2dc075f | ||
|
|
01448c152c | ||
|
|
a09beb3833 | ||
|
|
feda1e6d84 | ||
|
|
4256bea418 | ||
|
|
4d47b098e5 | ||
|
|
163754a46c | ||
|
|
66b56416b6 | ||
|
|
c855346358 | ||
|
|
0e32c86c3d | ||
|
|
fac3579fb0 | ||
|
|
19952264c8 | ||
|
|
5ec1e97cae | ||
|
|
5f5746a2f6 | ||
|
|
458b023204 | ||
|
|
4bad4ec632 | ||
|
|
e34853e19e | ||
|
|
6cbdb1b4c3 | ||
|
|
60f890ce0d | ||
|
|
c82c0a9812 | ||
|
|
123b1d4002 | ||
|
|
e4958d5bb9 | ||
|
|
89e734dcca | ||
|
|
090fe394e4 | ||
|
|
389b4beba4 | ||
|
|
d0ee6d1ad2 | ||
|
|
ec769bc9f9 | ||
|
|
6b259070f0 | ||
|
|
651ea8cc2f | ||
|
|
3f0e948981 | ||
|
|
24ed7fbf3f | ||
|
|
b13c3979c2 | ||
|
|
7a55dd512a | ||
|
|
fdd0dbd973 | ||
|
|
774dd6d5e3 | ||
|
|
4cbaddf4c4 | ||
|
|
10f1da2736 | ||
|
|
0e5d76e735 | ||
|
|
339c9cceec | ||
|
|
2354bb5427 | ||
|
|
fe80f8179c | ||
|
|
b97143e9db | ||
|
|
aaab905e72 | ||
|
|
bc6d384ca9 | ||
|
|
6fc8c174f9 | ||
|
|
63b205c601 | ||
|
|
f0a834f7e8 | ||
|
|
fdb2cf09c7 | ||
|
|
a67738380c | ||
|
|
15ce8bc79b | ||
|
|
8d70b91955 | ||
|
|
a33ed05bec | ||
|
|
aace8a14ce | ||
|
|
d80b8ff30f | ||
|
|
3a66255576 | ||
|
|
1541f67eab | ||
|
|
a2959c6e9e | ||
|
|
06c71eec65 | ||
|
|
70a7661711 | ||
|
|
d190b1995b | ||
|
|
a6f8230063 | ||
|
|
aabc6c2825 | ||
|
|
8323458da9 | ||
|
|
e4c60d70b0 | ||
|
|
4d8a815932 | ||
|
|
b0e5f5973a | ||
|
|
05cb4fd897 | ||
|
|
72dc6ea77c | ||
|
|
1b0a6fe9eb | ||
|
|
363ad01bce | ||
|
|
04a45a407e | ||
|
|
14735e0a48 | ||
|
|
1c07428f89 | ||
|
|
e0d68664c4 | ||
|
|
6c72c3d4a5 | ||
|
|
9df8dbee08 | ||
|
|
140af45bb0 | ||
|
|
2bf2f2518c | ||
|
|
5bcc379530 | ||
|
|
c854ec0686 | ||
|
|
6a825cc504 | ||
|
|
3ed6763da9 | ||
|
|
dbeabb8ff0 | ||
|
|
cc66e1d966 | ||
|
|
d7c7ff1c12 | ||
|
|
919ea9f750 | ||
|
|
5816ee9f9a | ||
|
|
bcb258bcbb | ||
|
|
e02c09d361 | ||
|
|
09b2cdd618 | ||
|
|
1e526e68ab | ||
|
|
d77c7d51e3 | ||
|
|
4ff3c57976 | ||
|
|
d51d0160d3 | ||
|
|
c2ad9d4996 | ||
|
|
3416190e4b | ||
|
|
de7cb6d6ad | ||
|
|
eb297104de | ||
|
|
dfa6463e5b | ||
|
|
9cd9776b7d | ||
|
|
097afab9f4 | ||
|
|
03a214c8b9 | ||
|
|
3f06a857c2 | ||
|
|
79f828125d | ||
|
|
ad4b18cbbe | ||
|
|
1bd49671b7 | ||
|
|
9896057549 | ||
|
|
44832bbacb | ||
|
|
f20a923dd7 | ||
|
|
30403da326 | ||
|
|
f81a3ba45d | ||
|
|
018fa052f2 | ||
|
|
c771d2809f | ||
|
|
fc78206049 | ||
|
|
618d673947 | ||
|
|
6464099364 | ||
|
|
7c19f0cca7 | ||
|
|
c2181c23ef | ||
|
|
3cf145aa6a | ||
|
|
6bea3d6bfc | ||
|
|
993db01400 | ||
|
|
f2d078e3cd | ||
|
|
4cb4f17500 | ||
|
|
15a689c6f5 | ||
|
|
7894fed741 | ||
|
|
61f7c1e7d7 | ||
|
|
30efeb5bec | ||
|
|
18caf0273f | ||
|
|
214b81e491 | ||
|
|
e60fb17524 | ||
|
|
4f1fdf85c8 | ||
|
|
33865993db | ||
|
|
5a27aaef24 | ||
|
|
7f65d82a74 | ||
|
|
8ab1f31058 | ||
|
|
4cd5529027 | ||
|
|
770036c5a8 | ||
|
|
d38b75900a | ||
|
|
e8acf7e87a | ||
|
|
2a4aea67b8 | ||
|
|
d12744011a | ||
|
|
c0e4c92d47 | ||
|
|
cc3e910194 | ||
|
|
5d9f993352 | ||
|
|
eaa52c19a8 | ||
|
|
42aeb19562 | ||
|
|
ffc3dba682 | ||
|
|
1acc5ceb5f | ||
|
|
7d694dca07 | ||
|
|
7a693500c4 | ||
|
|
1c44912aff | ||
|
|
5e14da67e1 | ||
|
|
6b68a76bbe | ||
|
|
b586fcebab | ||
|
|
244c0d828a | ||
|
|
57ebd7e170 | ||
|
|
8f10b58cb1 | ||
|
|
f8bc408abc | ||
|
|
f581f6163a | ||
|
|
5776471547 | ||
|
|
88486a1278 | ||
|
|
9fcadc2d7c | ||
|
|
c50e3a702a | ||
|
|
2173ef5fb6 | ||
|
|
9ef6c57ca5 | ||
|
|
443d7684db | ||
|
|
1f6da1c653 | ||
|
|
c165894ce9 | ||
|
|
19903ea3c1 | ||
|
|
0b38ab259c | ||
|
|
5d82037ffb | ||
|
|
a41713febb | ||
|
|
5002d8e1fa | ||
|
|
237c6eed50 | ||
|
|
a3ba7f0788 | ||
|
|
f13b1e8604 | ||
|
|
f083c0cba1 | ||
|
|
defa2d9df1 | ||
|
|
05c422ef23 | ||
|
|
51d274961b | ||
|
|
4b4cc04897 | ||
|
|
4bf3d4d87a | ||
|
|
71cc980e96 | ||
|
|
58c0b81908 | ||
|
|
3b42bd43ab | ||
|
|
a151532ffa | ||
|
|
a0d1ce77dc | ||
|
|
863cae1bab | ||
|
|
4010ea814a | ||
|
|
8e25c091f4 | ||
|
|
2a57e00cb4 | ||
|
|
52424b0f9c | ||
|
|
132547a9d9 | ||
|
|
fdb0459288 | ||
|
|
df84352385 | ||
|
|
8d4f6a7865 | ||
|
|
d72276df94 | ||
|
|
450bb1c2cb | ||
|
|
6f22e47feb | ||
|
|
c6acb6191c | ||
|
|
6cade7d935 | ||
|
|
c857ecab46 | ||
|
|
53d9cbc69c | ||
|
|
0ee403eab3 | ||
|
|
6f2d09eb20 | ||
|
|
d6442ec991 | ||
|
|
f3831fa77f | ||
|
|
3265c2e543 | ||
|
|
1a9ea64523 | ||
|
|
9de650e175 | ||
|
|
d8b5f383f5 | ||
|
|
658c0734e2 | ||
|
|
5c7f01140a | ||
|
|
12767746ca | ||
|
|
ffa86b25db | ||
|
|
2763c0f40e | ||
|
|
6aa99a903f | ||
|
|
d9faf6c4bb | ||
|
|
48cd5855fe | ||
|
|
bd0fc8a2d7 | ||
|
|
476bd7400d | ||
|
|
bd10d48338 | ||
|
|
bb91064416 | ||
|
|
72d2fe2fd4 | ||
|
|
92a5b9ac41 | ||
|
|
cded6b1136 | ||
|
|
19f0ce7e37 | ||
|
|
a88a515fa0 | ||
|
|
a4b2eac0f0 | ||
|
|
0bd38290e6 | ||
|
|
19e4f3c2f0 | ||
|
|
e6edac1589 | ||
|
|
781d0c0fe0 | ||
|
|
b48cb47f41 | ||
|
|
1ece7caa57 | ||
|
|
0c1a3b1a61 | ||
|
|
2b5d4ef346 | ||
|
|
2dbd990017 | ||
|
|
34961b39fe | ||
|
|
088a54dacb | ||
|
|
bc9d4a7643 | ||
|
|
e0ee14d5b0 | ||
|
|
e88db3d609 | ||
|
|
f7d3550122 | ||
|
|
896681b671 | ||
|
|
fbdbd440d2 | ||
|
|
c0af854cb6 | ||
|
|
92889397e6 | ||
|
|
7c10b53209 | ||
|
|
a154fedbfb | ||
|
|
7c43f5b554 | ||
|
|
d19769115c | ||
|
|
561ffce031 | ||
|
|
61e2190f98 | ||
|
|
c56abbf7df | ||
|
|
1cd2f7e0f4 | ||
|
|
516ad23aa5 | ||
|
|
0599d27463 | ||
|
|
f56107c84d | ||
|
|
dd61824df5 | ||
|
|
531b4d955c | ||
|
|
8bede7b81f | ||
|
|
37d563c30e | ||
|
|
3775be4ce9 | ||
|
|
5ac08ec3aa | ||
|
|
87e2aa42b8 | ||
|
|
d9560ad124 | ||
|
|
b93397e415 | ||
|
|
44d89c7209 | ||
|
|
5bb9890660 | ||
|
|
f22d589c49 | ||
|
|
17f873db70 | ||
|
|
1647c39bf2 | ||
|
|
026d6d4a70 | ||
|
|
93113e0f00 | ||
|
|
236692908a | ||
|
|
6eea7c7e50 | ||
|
|
31516acec2 | ||
|
|
c9728961bf | ||
|
|
7bd89a9ab1 | ||
|
|
39b553529d | ||
|
|
e5883dd605 | ||
|
|
6b02c664fb | ||
|
|
c7ae3fdc9a | ||
|
|
c667572d3e | ||
|
|
9bbd6ff67d | ||
|
|
ca98a566ee | ||
|
|
f865d6e5da | ||
|
|
bc9f2922e0 | ||
|
|
c5a9b00eae | ||
|
|
f408ff982c | ||
|
|
9a8d1200ec | ||
|
|
16c7aa2813 | ||
|
|
85f52d2aed | ||
|
|
8e71324514 | ||
|
|
ea235c0c67 | ||
|
|
ea995d017b | ||
|
|
1aecbbece5 | ||
|
|
e30be643c9 | ||
|
|
0bba9482df | ||
|
|
07fd2dbc99 | ||
|
|
f8a8559523 | ||
|
|
6481c9dca1 | ||
|
|
7aaa1973f4 | ||
|
|
a12abaac9d | ||
|
|
4dea1b5a0d | ||
|
|
da44ab0529 | ||
|
|
1a1e8463cc | ||
|
|
343fccd7fd | ||
|
|
577102c4ec | ||
|
|
73b836c73d | ||
|
|
af0c2f59cc | ||
|
|
f5faa053bf | ||
|
|
1044e8e91a | ||
|
|
dffc0a4ed8 | ||
|
|
ba4b1cb5af | ||
|
|
5cb4cdaa5e | ||
|
|
0525eb2d29 | ||
|
|
7be1d9e45a | ||
|
|
f34af496ec | ||
|
|
ae97649948 | ||
|
|
3787c490d4 | ||
|
|
c3f1aae570 | ||
|
|
0c94747ab1 | ||
|
|
783cca1e13 | ||
|
|
f15e32d063 | ||
|
|
238a616292 | ||
|
|
6010b5c619 | ||
|
|
4812c5486d | ||
|
|
afc75af62f | ||
|
|
23b30fdd10 | ||
|
|
2778a7220f | ||
|
|
c69556f2ff | ||
|
|
b0689614bf | ||
|
|
e42a401987 | ||
|
|
5162459e4a | ||
|
|
39d914c9df | ||
|
|
8d2f4d9dfd | ||
|
|
a7d2f9b530 | ||
|
|
26f593afaa | ||
|
|
ca4e7f9b4f | ||
|
|
b11858bcac | ||
|
|
034f23b47e | ||
|
|
9c25f300cf | ||
|
|
db4ff56f0b | ||
|
|
830c2472cb | ||
|
|
079e2af0c0 | ||
|
|
5f166158c3 | ||
|
|
4a06378d67 | ||
|
|
d0f0a74df8 | ||
|
|
65a8965e85 | ||
|
|
ab2376f8d8 | ||
|
|
48717dff00 | ||
|
|
b64dd7ab57 | ||
|
|
bf013ecf00 | ||
|
|
22b744fa23 | ||
|
|
f560fe3b37 | ||
|
|
839a29a2a6 | ||
|
|
81bc44b30f | ||
|
|
58083ccb0c | ||
|
|
71cc2d7d5d | ||
|
|
976a4da0a1 | ||
|
|
74c48e5906 | ||
|
|
d7f0b130ce | ||
|
|
1d0ad72800 | ||
|
|
23b65c8e6e | ||
|
|
62b367fa81 | ||
|
|
beac45b075 | ||
|
|
dfc5159aa3 | ||
|
|
886cdb440b | ||
|
|
6ed9443972 | ||
|
|
08e0f172de | ||
|
|
cfc43f6dea | ||
|
|
f1d168f781 | ||
|
|
302d9796c4 | ||
|
|
ee85784be1 | ||
|
|
1260887fa7 | ||
|
|
ce8073d25e | ||
|
|
31f4d9066b | ||
|
|
35e66770be | ||
|
|
cf2f7f2132 | ||
|
|
a145559662 | ||
|
|
d029e3dc16 | ||
|
|
286326a98e | ||
|
|
2f59d78737 | ||
|
|
adf4782076 | ||
|
|
b38ffef2be | ||
|
|
6375f2d73a | ||
|
|
1a2df9c51c | ||
|
|
770fdb2b7d | ||
|
|
a7d3a49171 | ||
|
|
920e7db709 | ||
|
|
4a6b45cf04 | ||
|
|
7bd60adfbe | ||
|
|
171ff54ea4 | ||
|
|
da452decf6 | ||
|
|
c335719e8f | ||
|
|
d57cdf645e | ||
|
|
e47a96bf24 | ||
|
|
daad607c7c | ||
|
|
29f1f9c872 | ||
|
|
a49cfa8142 | ||
|
|
b57d296adc | ||
|
|
01d8bd445e | ||
|
|
04e220cc4b | ||
|
|
cb70c48b36 | ||
|
|
750d6f4be9 | ||
|
|
c6e14a696e | ||
|
|
d34423fce9 | ||
|
|
4999547f87 | ||
|
|
fc5dc9717a | ||
|
|
d20759c141 | ||
|
|
f7b00c62a4 | ||
|
|
32873ce70d | ||
|
|
dc59561a95 | ||
|
|
4bf3fdd898 | ||
|
|
d87eece1d2 | ||
|
|
4fe4eacc00 | ||
|
|
108a892a11 | ||
|
|
2c4bd9a3fe | ||
|
|
c80ac58eff | ||
|
|
d56e1f6285 | ||
|
|
22b3ddab66 | ||
|
|
3fe2491b73 | ||
|
|
4e6758e31d | ||
|
|
098ec1abb4 | ||
|
|
17cf824545 | ||
|
|
e35f5d3c93 | ||
|
|
f4f98e5856 | ||
|
|
dc0335d1d5 | ||
|
|
6013814cf4 | ||
|
|
e0a0570cc4 | ||
|
|
61deb4fcfd | ||
|
|
7c4c60425b | ||
|
|
302f49baf2 | ||
|
|
3f6cd5a663 | ||
|
|
1b232041c9 | ||
|
|
eaf117cce1 | ||
|
|
88d49c7c3e | ||
|
|
db8bd30dcd | ||
|
|
9e3ec63637 | ||
|
|
d2aa2c080f | ||
|
|
7148311953 | ||
|
|
c23dfa0d23 | ||
|
|
b08de33b0b | ||
|
|
fc1d8c0138 | ||
|
|
a5a77d1e7c | ||
|
|
f57fcefe6b | ||
|
|
a5483a03c9 | ||
|
|
bb8b3b9291 | ||
|
|
6c6dca05e7 | ||
|
|
97b4a31b16 | ||
|
|
40d9277ef3 | ||
|
|
009044b71e | ||
|
|
4760a3f3e8 | ||
|
|
3302012c02 | ||
|
|
812c5a314f | ||
|
|
c2da8c3fd4 | ||
|
|
aa78640491 | ||
|
|
7c49688e1b | ||
|
|
dbe10c7965 | ||
|
|
f1f5107282 | ||
|
|
cc06250bf8 | ||
|
|
af1ea7f495 | ||
|
|
3491c488d3 | ||
|
|
1828b6daab | ||
|
|
c26f45b7c2 | ||
|
|
e116b90116 | ||
|
|
fff14fca50 | ||
|
|
1c0290df2d | ||
|
|
c72b7a8830 | ||
|
|
a31ea72ced | ||
|
|
487e415de5 | ||
|
|
825709870d | ||
|
|
970ef5e51c | ||
|
|
04aa58d920 | ||
|
|
e7f1d350c9 | ||
|
|
cb4a1d51c1 | ||
|
|
352d110622 | ||
|
|
3b9aedec5f | ||
|
|
fabcf841c9 | ||
|
|
43a5f928ba | ||
|
|
873fa16517 | ||
|
|
f7ce374a28 | ||
|
|
2dd124d09e | ||
|
|
bd6c1b06c1 | ||
|
|
116915890d | ||
|
|
0e9347efa5 | ||
|
|
d3bd55e628 | ||
|
|
6901a37cd2 | ||
|
|
c52a5a2974 | ||
|
|
d6523c67a6 | ||
|
|
a9fd3608ea | ||
|
|
b25cace3ea | ||
|
|
4320f047db | ||
|
|
b4b3e7b9a4 | ||
|
|
b6938da552 | ||
|
|
4830a1559d | ||
|
|
92ea3ef720 | ||
|
|
73d2719330 | ||
|
|
af82aab3a6 | ||
|
|
51b4b6216f | ||
|
|
3eb6748578 | ||
|
|
de32b0bba5 | ||
|
|
de0fab78ed | ||
|
|
71425c3b23 | ||
|
|
75f7b1e261 | ||
|
|
9af35d998f | ||
|
|
34e3f3907a | ||
|
|
46b0510b99 | ||
|
|
a7624ea48b | ||
|
|
2f3b4a7aaf | ||
|
|
a9bbe0b128 | ||
|
|
0d9d0a4b70 | ||
|
|
8235d0bd50 | ||
|
|
c2e01bedc5 | ||
|
|
32c4614a32 | ||
|
|
24ae6c91ea | ||
|
|
346a4f5933 | ||
|
|
c6551336c8 | ||
|
|
a240e1de75 | ||
|
|
a776210aa7 | ||
|
|
88a6a2d1de | ||
|
|
e022a7edee | ||
|
|
5d912efb32 | ||
|
|
5243af975c | ||
|
|
43486e7137 | ||
|
|
b2430495f5 | ||
|
|
1b1a6e357a | ||
|
|
626b5f36ad | ||
|
|
746ceebcdc | ||
|
|
2a40051475 | ||
|
|
2406574041 | ||
|
|
23c40b9618 | ||
|
|
95e4dca38a | ||
|
|
66e562af72 | ||
|
|
1f70331a12 | ||
|
|
38e3369566 | ||
|
|
7303cdbe08 | ||
|
|
4677e34ea6 | ||
|
|
a48dc3ddf6 | ||
|
|
c548969877 | ||
|
|
68150edbb9 | ||
|
|
8e347e1b2e | ||
|
|
b26989f594 | ||
|
|
0a3259d77c | ||
|
|
d95492c5d0 | ||
|
|
3555c7f0c5 | ||
|
|
272e2d5654 | ||
|
|
3dab0d365d | ||
|
|
3abd110d45 | ||
|
|
cebb406277 | ||
|
|
71e4f1c8a7 | ||
|
|
403e42b662 | ||
|
|
a5598c33f3 | ||
|
|
0c1cc32017 | ||
|
|
994fb6c043 | ||
|
|
0252bac4ba | ||
|
|
b468069875 | ||
|
|
a1842491ad | ||
|
|
241e449564 | ||
|
|
ad8848f96a | ||
|
|
7f3c1a89c3 | ||
|
|
7e1f431eca | ||
|
|
70c55da1df | ||
|
|
f9ab7647dd | ||
|
|
623aa7ea48 | ||
|
|
046d264688 | ||
|
|
944e168120 | ||
|
|
9594105e57 | ||
|
|
675343f575 | ||
|
|
fc6ff45c49 | ||
|
|
b4bac88c39 | ||
|
|
c622ba84b9 | ||
|
|
339f95c647 | ||
|
|
ec67e0ab22 | ||
|
|
0b371c8103 | ||
|
|
2192ea6fdf | ||
|
|
0060f88c45 | ||
|
|
1eac4db491 | ||
|
|
0d2c3be367 | ||
|
|
d12c6ccb72 | ||
|
|
1eb63fd8b9 | ||
|
|
2cf2171ac2 | ||
|
|
c8dd516d6c | ||
|
|
0f19627407 | ||
|
|
3eb71fe7b5 | ||
|
|
0035584d91 | ||
|
|
8cbd2e3e9e | ||
|
|
b0f5c7f36f | ||
|
|
412eb0a90b | ||
|
|
f8e816629d | ||
|
|
3d0138569d | ||
|
|
7bb7d736a2 | ||
|
|
7910f39613 | ||
|
|
bf6ef2a588 | ||
|
|
a11d89daa3 | ||
|
|
b8a4a6b959 | ||
|
|
dd6045d9f8 | ||
|
|
e1c3a19420 | ||
|
|
cc586685e6 | ||
|
|
31883f603c | ||
|
|
f377c81c8a | ||
|
|
32384eaf07 | ||
|
|
7c2efa697c | ||
|
|
e1df69dfcb | ||
|
|
6dd84fde33 | ||
|
|
60eaedc67f | ||
|
|
ce908b31c1 | ||
|
|
f687739cfe | ||
|
|
56d1e3792a | ||
|
|
ce8215ec6c | ||
|
|
db5b86dbac | ||
|
|
ecab83264c | ||
|
|
81194b2caa | ||
|
|
ce185c14d3 | ||
|
|
ff1db9a055 | ||
|
|
f928f17bb5 | ||
|
|
1241e778f9 | ||
|
|
3ab0ef1902 | ||
|
|
c7c35b8b5a | ||
|
|
3d9b1fd343 | ||
|
|
96bed3a623 | ||
|
|
e72b0edce2 | ||
|
|
ae4aeb4b1e | ||
|
|
302abc2a60 | ||
|
|
2b3cbc638b | ||
|
|
3de055bf65 | ||
|
|
df449e7bfe | ||
|
|
6326a50d20 | ||
|
|
aef212ada9 | ||
|
|
802a7ff3a8 | ||
|
|
9cedc864c2 | ||
|
|
ee804cd6b1 | ||
|
|
25c7e64ded | ||
|
|
5c4fbbebe1 | ||
|
|
615402ea83 | ||
|
|
a0a72a9f6d | ||
|
|
8b9acf750b | ||
|
|
24d68a7f09 | ||
|
|
781eeff021 | ||
|
|
3e6c2c6024 | ||
|
|
f180558041 | ||
|
|
506ea71302 | ||
|
|
01e11e9043 | ||
|
|
7ed197f46b | ||
|
|
5c36eef039 | ||
|
|
26e20f9999 | ||
|
|
71195895ba | ||
|
|
c7ebb4b009 | ||
|
|
c0cef8dd12 | ||
|
|
ea850e58d2 | ||
|
|
dcdd97a985 | ||
|
|
a61ce45a32 | ||
|
|
1326c4e71e | ||
|
|
ad5f3877f1 | ||
|
|
9cbbc80f7a | ||
|
|
8a02e967d3 | ||
|
|
7c49f22702 | ||
|
|
fdb7c115a7 | ||
|
|
fa9e9510e5 | ||
|
|
06b3ad1071 | ||
|
|
d96a731e93 | ||
|
|
847ff77a81 | ||
|
|
df746c7911 | ||
|
|
2583270774 | ||
|
|
5393d674f9 | ||
|
|
4aed866d69 | ||
|
|
d775a7ee21 | ||
|
|
c044ff3444 | ||
|
|
6e75842354 | ||
|
|
ac2b6bcc33 | ||
|
|
c440b758a3 | ||
|
|
e9471124c0 | ||
|
|
442d1cb48f | ||
|
|
5030c55b1e | ||
|
|
fa91e2a60c | ||
|
|
32de123db0 | ||
|
|
90e9c37d35 | ||
|
|
84d4036117 | ||
|
|
e38e85572e | ||
|
|
f50d6208c8 | ||
|
|
34d189c02e | ||
|
|
ba9b49bc83 | ||
|
|
ed08eb07c6 | ||
|
|
ae875734e2 | ||
|
|
d2d6f8c970 | ||
|
|
04edb741a6 | ||
|
|
34b4b65865 | ||
|
|
25a74f3664 | ||
|
|
fa5537bfc0 | ||
|
|
3588c4ab99 | ||
|
|
5a9b1f769d | ||
|
|
782ec06f2b | ||
|
|
5b43db7171 | ||
|
|
df62037c4a | ||
|
|
ad1cc82b38 | ||
|
|
05b8c53ff7 | ||
|
|
7268426248 | ||
|
|
c39de966df | ||
|
|
eb133ef9a7 | ||
|
|
721461dd3e | ||
|
|
337e25ad43 | ||
|
|
7042528d26 | ||
|
|
ce52c27a8a | ||
|
|
f9c3b80780 | ||
|
|
ab0e2f5236 | ||
|
|
b7280a442e | ||
|
|
8af91b0209 | ||
|
|
ee4a262953 | ||
|
|
d584293cde | ||
|
|
c60c9b323b | ||
|
|
eaee27c9e4 | ||
|
|
a2575059e2 | ||
|
|
54bdf59dde | ||
|
|
e96e3dc6e6 | ||
|
|
3ac4337aec | ||
|
|
f68674b35a | ||
|
|
729d0d5368 | ||
|
|
5c0d31873a | ||
|
|
5310f4e310 | ||
|
|
2c961328f1 | ||
|
|
c36773674e | ||
|
|
54c615dbc2 | ||
|
|
483ef09890 | ||
|
|
81a741e760 | ||
|
|
278f2a6cac | ||
|
|
cf277261dc | ||
|
|
451ee5a593 | ||
|
|
ba3811a284 | ||
|
|
e2241b9365 | ||
|
|
fe2bb84403 | ||
|
|
6f1067a889 | ||
|
|
f0cdbd0f52 | ||
|
|
9632cafa95 | ||
|
|
321b2b9b49 | ||
|
|
fb3dd5eee6 | ||
|
|
e518445853 | ||
|
|
8ce240b95c | ||
|
|
0db047e572 | ||
|
|
22275f3077 | ||
|
|
b77acb3e53 | ||
|
|
6ae9ef571e | ||
|
|
8e5189464e | ||
|
|
0de713ff36 | ||
|
|
137bee9d27 | ||
|
|
3641ab8c7d | ||
|
|
16b6b76507 | ||
|
|
5cd9540d5f | ||
|
|
ae7873260e | ||
|
|
3dfe604ba0 | ||
|
|
3e19c4ddae | ||
|
|
de59300aaf | ||
|
|
8cb05a91ab | ||
|
|
5f2c3f607e | ||
|
|
8ebcc4439b | ||
|
|
b65ee01aef | ||
|
|
2b311bd860 | ||
|
|
a841b75b98 | ||
|
|
9b3b7dc098 | ||
|
|
f783454774 | ||
|
|
81d9258e80 | ||
|
|
c6bfd5e7be | ||
|
|
3c5cfd465b | ||
|
|
f61f9bdc5f | ||
|
|
2ab6e0843d | ||
|
|
d21bf41b6c | ||
|
|
c54ba1fb86 | ||
|
|
4d86a199f0 | ||
|
|
4756826054 | ||
|
|
ea309aa19e | ||
|
|
bad4ea6e65 | ||
|
|
cf4288767a | ||
|
|
802ccdff4a | ||
|
|
ba50de15ea | ||
|
|
73e30e8085 | ||
|
|
a53912cc19 | ||
|
|
f105f70ded | ||
|
|
f0cd084738 | ||
|
|
ae5158b676 | ||
|
|
bfd45a0017 | ||
|
|
78be0c66da | ||
|
|
562cde37f4 | ||
|
|
263dea0e36 | ||
|
|
de743e35d0 | ||
|
|
09a46d0c74 | ||
|
|
ca5a1d0853 | ||
|
|
97fcc495f2 | ||
|
|
4e69467b14 | ||
|
|
d2e366a46f | ||
|
|
94905a71ac | ||
|
|
c7644ad29d | ||
|
|
0daa462207 | ||
|
|
d8f79f48e9 | ||
|
|
bf878dc446 | ||
|
|
c06b37b798 | ||
|
|
30e3580856 | ||
|
|
d29caa099a | ||
|
|
d1270aab4d | ||
|
|
cd55298616 | ||
|
|
c6f3298f78 | ||
|
|
350db4ed9f | ||
|
|
1ccca9863c | ||
|
|
a7b03c1cea | ||
|
|
2cb52f8875 | ||
|
|
2c797807cd | ||
|
|
37b94bf5fa | ||
|
|
cbbe4b33a3 | ||
|
|
a00a849952 | ||
|
|
e877a001ab | ||
|
|
709665846e | ||
|
|
93a310582f | ||
|
|
9f4219773e | ||
|
|
f0b7a7e5d3 | ||
|
|
97502f4c04 | ||
|
|
737f660011 | ||
|
|
e0568f33e8 | ||
|
|
2ba95758eb | ||
|
|
fc3d0233af | ||
|
|
13c08f9660 | ||
|
|
82528e2f38 | ||
|
|
90a983a7e5 | ||
|
|
58a9cde61d | ||
|
|
a00aae702d | ||
|
|
69584f541d | ||
|
|
855f4b869a | ||
|
|
60d5443f00 | ||
|
|
527b0a7065 | ||
|
|
22a7c21886 | ||
|
|
484d240e7e | ||
|
|
108855aca2 | ||
|
|
8ca321df7c | ||
|
|
ed97800c80 | ||
|
|
78c6f40093 | ||
|
|
5acd166d18 | ||
|
|
3efeeecace | ||
|
|
259db3778c | ||
|
|
52be5c1660 | ||
|
|
f85cce714f | ||
|
|
2eb93387c2 | ||
|
|
2d9fe72215 | ||
|
|
dd3ec468f6 | ||
|
|
88d28cd6fe | ||
|
|
b4035c2d19 | ||
|
|
65dcb39bac | ||
|
|
b92bb0bd28 | ||
|
|
0a840c02f7 | ||
|
|
62433b5f05 | ||
|
|
6ffdf3880f | ||
|
|
9bfa5c82d1 | ||
|
|
66cf085272 | ||
|
|
567448e2fd | ||
|
|
d174531931 | ||
|
|
a38ded702f | ||
|
|
cd5f255966 | ||
|
|
d1a3561585 | ||
|
|
da8b276699 | ||
|
|
5aa0304149 | ||
|
|
7877e2467e | ||
|
|
96277372d5 | ||
|
|
98ee99071c | ||
|
|
b8991750c5 | ||
|
|
97acfd23fb | ||
|
|
18726737d0 | ||
|
|
af05fa3e85 | ||
|
|
6a297a8f3d | ||
|
|
309904b15a | ||
|
|
453ce4df3b | ||
|
|
02537b80b2 | ||
|
|
62730366ee | ||
|
|
0558a25141 | ||
|
|
3f57609b75 | ||
|
|
9850d18420 | ||
|
|
05ae18d74e | ||
|
|
778086ce19 | ||
|
|
63ba72331f | ||
|
|
3e231e7c13 | ||
|
|
a522a66715 | ||
|
|
c2c891723f | ||
|
|
c087aaf5be | ||
|
|
4cb46c124a | ||
|
|
2e4772ac0e | ||
|
|
4f70fd3e71 | ||
|
|
ebb4811a75 | ||
|
|
835e222af0 | ||
|
|
a5e63aa90a | ||
|
|
1922a2139d | ||
|
|
f5acbccb79 | ||
|
|
d39ebebc9d | ||
|
|
b5ed1de31e | ||
|
|
5cf156f698 | ||
|
|
dcd99c2d30 | ||
|
|
a29e5521cc | ||
|
|
59bd90b967 | ||
|
|
ff53da5b0a | ||
|
|
9520123f6d | ||
|
|
d9efb037e3 | ||
|
|
c403c9aece | ||
|
|
df5115e7b8 | ||
|
|
22fbb512d5 | ||
|
|
2acfa7e525 | ||
|
|
69659e9bd5 | ||
|
|
6c066f6107 | ||
|
|
b96a05494b | ||
|
|
0d42b4cf8a | ||
|
|
df0c77ccd3 | ||
|
|
3a0a611f15 | ||
|
|
1eaf6df842 | ||
|
|
9fe9137c96 | ||
|
|
363fc5c72b | ||
|
|
d4af745fc8 | ||
|
|
6e03104e3e | ||
|
|
e89a84608f | ||
|
|
1dbd83a582 | ||
|
|
c1002557cf | ||
|
|
cccea911fa | ||
|
|
eb10120607 | ||
|
|
c00dc6120d | ||
|
|
d0605e8d5f | ||
|
|
d33c331abd | ||
|
|
05b6c33a2c | ||
|
|
3064f2ced5 | ||
|
|
5e7c9b9d4a | ||
|
|
009e03c3ba | ||
|
|
af3b0146a8 | ||
|
|
883e2ccc91 | ||
|
|
7c1e99884c | ||
|
|
29e1302f3f | ||
|
|
798f2466e4 | ||
|
|
67f19745fd | ||
|
|
72abe5f3d3 | ||
|
|
08a287dea1 | ||
|
|
7dadf387e5 | ||
|
|
8febcc2705 | ||
|
|
ff20370d0b | ||
|
|
cc9ca8bbff | ||
|
|
5906d6cce3 | ||
|
|
8265dac9c0 | ||
|
|
6eeac03a0e | ||
|
|
7ca8f7b5cc | ||
|
|
d7ed5518d1 | ||
|
|
6f036bc778 | ||
|
|
ba4a8aa762 | ||
|
|
5f992ffe15 | ||
|
|
2904e58a9f | ||
|
|
c45a9504e7 | ||
|
|
403ead44f9 | ||
|
|
9b0d123217 | ||
|
|
8e673a6cdf | ||
|
|
6d3c1fb7fc | ||
|
|
01043fa790 | ||
|
|
23d5e15f0f | ||
|
|
5500473387 | ||
|
|
c8399e8104 | ||
|
|
423e1422ef | ||
|
|
c34c0c6718 | ||
|
|
e3e96e59d2 | ||
|
|
accb211280 | ||
|
|
f07a4667b6 | ||
|
|
cb768ea23f | ||
|
|
b3249c10c2 | ||
|
|
c6fce5de24 | ||
|
|
5c8e1169cd | ||
|
|
c0a485083d | ||
|
|
5f7d83bd4d | ||
|
|
52916bfcec | ||
|
|
cb2646154a | ||
|
|
61a7c4fb33 | ||
|
|
3a3abc8087 | ||
|
|
e9b60cfb26 | ||
|
|
eea9e2c1d0 | ||
|
|
171d129ad1 | ||
|
|
0154c5d74e | ||
|
|
9032a656fa | ||
|
|
fda57a93a5 | ||
|
|
4ad208668a | ||
|
|
23edb51ba4 | ||
|
|
adf10296f1 | ||
|
|
d3e6d6b6a6 | ||
|
|
82de0862a1 | ||
|
|
1969537fd7 | ||
|
|
973afe042a | ||
|
|
99ceb1691b | ||
|
|
4a904fa3a8 | ||
|
|
c13d7e29ef | ||
|
|
58d9ca1bfd | ||
|
|
e2115e8ea5 | ||
|
|
ba417894ed | ||
|
|
a237248388 | ||
|
|
7fd332f8cf | ||
|
|
2811d6ae53 | ||
|
|
d8c6d93c6e | ||
|
|
134529a09d | ||
|
|
24c7bb600e | ||
|
|
90e9948dbe | ||
|
|
db006b911a | ||
|
|
eb2c2b9400 | ||
|
|
86fc5b5ed8 | ||
|
|
f7e9454697 | ||
|
|
02a16050d9 | ||
|
|
598fe91464 | ||
|
|
21272735ae | ||
|
|
52fea09c53 | ||
|
|
d9ccd24b02 | ||
|
|
27fef98a39 | ||
|
|
c6db644c42 | ||
|
|
41108fc4d3 | ||
|
|
d7a20821c3 | ||
|
|
20285d076b | ||
|
|
44bb070203 | ||
|
|
9e87219aea | ||
|
|
1b7e220de7 | ||
|
|
fe8b723622 | ||
|
|
1e85c40c42 | ||
|
|
f72464a240 | ||
|
|
65785ead69 | ||
|
|
c550100a55 | ||
|
|
2836bce8fe | ||
|
|
7f95d47721 | ||
|
|
51c0045be4 | ||
|
|
abfbfd9e9b | ||
|
|
5d6c8fd807 | ||
|
|
f4799b2ddb | ||
|
|
9afa6cc245 | ||
|
|
25e8d70786 | ||
|
|
978e45911f | ||
|
|
da7bce3470 | ||
|
|
4efa5cfa75 | ||
|
|
444ae51a3e | ||
|
|
07f82e4a14 | ||
|
|
3379f6f793 | ||
|
|
80b47734a7 | ||
|
|
69d46538ce | ||
|
|
208d38207e | ||
|
|
ffe80c66d7 | ||
|
|
bfa672f42c | ||
|
|
9f89f3190a | ||
|
|
71931b423c | ||
|
|
b54aabc958 | ||
|
|
a45fe72eb9 | ||
|
|
62d64631b5 | ||
|
|
11945ce7bc | ||
|
|
bb3d908bcf | ||
|
|
98b3946fca | ||
|
|
c15de3b68b | ||
|
|
78ed1ae446 | ||
|
|
56fdc4f3fe | ||
|
|
f17261020d | ||
|
|
6f98ca68af | ||
|
|
269538fdc7 | ||
|
|
6b23c3e179 | ||
|
|
5cc19ce053 | ||
|
|
bdf6289b32 | ||
|
|
e3c04b1fd0 | ||
|
|
a7948d7bfe | ||
|
|
505782f224 | ||
|
|
1353c291e9 | ||
|
|
9af1b62bee | ||
|
|
d7ec36e3da | ||
|
|
aab97adb23 | ||
|
|
91502b4104 | ||
|
|
9bc76b4259 | ||
|
|
9948bb3f2a | ||
|
|
0722775038 | ||
|
|
65423b1768 | ||
|
|
9bb0f1d18e | ||
|
|
39866b7463 | ||
|
|
4c58a5cef2 | ||
|
|
c748230b35 | ||
|
|
c3aa15cc16 | ||
|
|
b45bd901e0 | ||
|
|
317fd06357 | ||
|
|
4a7c678213 | ||
|
|
85e06a77af | ||
|
|
7cadc30914 | ||
|
|
995fc63f2c | ||
|
|
e735220691 | ||
|
|
9b7c6e96f7 | ||
|
|
d83fe9d417 | ||
|
|
a1d1d5dba7 | ||
|
|
781fdaafcd | ||
|
|
1f1d5b9181 | ||
|
|
9e22ec267c | ||
|
|
b296a73330 | ||
|
|
65be3de200 | ||
|
|
45078dda82 | ||
|
|
822bbd9ad5 | ||
|
|
c873f7e702 | ||
|
|
0a5ac62b59 | ||
|
|
1e5405ccaf | ||
|
|
12d2270935 | ||
|
|
ed00d1b2e3 | ||
|
|
2b452ffbd3 | ||
|
|
3b4a23c4a1 | ||
|
|
4484985c2d | ||
|
|
6f99ca1d31 | ||
|
|
8efa103041 | ||
|
|
9638bf2b1e | ||
|
|
6f43468724 | ||
|
|
18a9ebdb1e | ||
|
|
604142af93 | ||
|
|
2d83868ed9 | ||
|
|
73195a0215 | ||
|
|
13d05549f8 | ||
|
|
0143bc734c | ||
|
|
ff860a3310 | ||
|
|
ed0044aeab | ||
|
|
1a6d290d71 | ||
|
|
dbb7245e22 | ||
|
|
437aa4082c | ||
|
|
0f9802a47c | ||
|
|
46d6d1c329 | ||
|
|
4dd1521677 | ||
|
|
32fba39915 | ||
|
|
c1697ce96b | ||
|
|
ba49e6a588 | ||
|
|
5525f082e6 | ||
|
|
a4d987b45a | ||
|
|
3cc66b6816 | ||
|
|
21ff570c4d | ||
|
|
f2e4cf3a92 | ||
|
|
7123de66f9 | ||
|
|
e4fe202fc6 | ||
|
|
bde6caf167 | ||
|
|
96f45b5fbe | ||
|
|
4352afeeb0 | ||
|
|
369f34b2d1 | ||
|
|
1ca558f011 | ||
|
|
a6db822a69 | ||
|
|
ad8226d549 | ||
|
|
1b27327057 | ||
|
|
3d713cee62 | ||
|
|
afd4da8f11 | ||
|
|
3ee632514c | ||
|
|
456fe71ca9 | ||
|
|
f2c59b3881 | ||
|
|
2c1560e027 | ||
|
|
34fec995f7 | ||
|
|
ec7cbe272a | ||
|
|
98bc1ed600 | ||
|
|
7756773683 | ||
|
|
dfdf11d461 | ||
|
|
cc5ef57843 | ||
|
|
71c599f50e | ||
|
|
a1f3a5d9b6 | ||
|
|
a9e89d2fcc | ||
|
|
fdc89d1b89 | ||
|
|
c4c1b1f5a2 | ||
|
|
12b9106fc7 | ||
|
|
faaffdd618 | ||
|
|
774729b221 | ||
|
|
1455fa6bc3 | ||
|
|
a9853e6033 | ||
|
|
eefa47776b | ||
|
|
0b12a7e66f | ||
|
|
3019d8341d | ||
|
|
dcacfc1124 | ||
|
|
2f6cb764a4 | ||
|
|
a0cf2b53e0 | ||
|
|
593a5072d9 | ||
|
|
27617efbfb | ||
|
|
6ab12597f5 | ||
|
|
07cd1d1272 | ||
|
|
abe35817cd | ||
|
|
585bdf562a | ||
|
|
034441bd13 | ||
|
|
1819704620 | ||
|
|
18801a6c60 | ||
|
|
f83c2d5cd1 | ||
|
|
724dc48fe8 | ||
|
|
791ff25d52 | ||
|
|
299eb469f8 | ||
|
|
0f9a8a43e4 | ||
|
|
7856f5882b | ||
|
|
284e5dd2e8 | ||
|
|
3d3f4f50fb | ||
|
|
8d89c4bbce | ||
|
|
85d8225cc0 | ||
|
|
8ad24ca3e8 | ||
|
|
6360dee125 | ||
|
|
e931616011 | ||
|
|
ab611e9ef3 | ||
|
|
240d4704aa | ||
|
|
f9d43479f2 | ||
|
|
c2f6f87cae | ||
|
|
869534fafa | ||
|
|
56f88f2e30 | ||
|
|
a1d5ce3716 | ||
|
|
78dc679a72 | ||
|
|
57e3ee47ee | ||
|
|
184928204a | ||
|
|
2651eae663 | ||
|
|
28e4977c33 | ||
|
|
adc164b825 | ||
|
|
66bf55710e | ||
|
|
c6abe87ec2 | ||
|
|
4bb16b18ed | ||
|
|
4cc413cdaf | ||
|
|
be3b630474 | ||
|
|
677ad71b96 | ||
|
|
9607bb29fd | ||
|
|
d29415a6e2 | ||
|
|
54fa28441c | ||
|
|
bb42ec2bfc | ||
|
|
d31251c54e | ||
|
|
6a338e28b2 | ||
|
|
f3ce5e73fe | ||
|
|
c53d3a4b3a | ||
|
|
5135f236c2 | ||
|
|
78c847ef7d | ||
|
|
673a2f67f1 | ||
|
|
c5bc4fe245 | ||
|
|
bc4a92b702 | ||
|
|
ea381d9180 | ||
|
|
4f82428a20 | ||
|
|
e494a76b33 | ||
|
|
1753e40466 | ||
|
|
6667ba4172 | ||
|
|
75e8aa8aee | ||
|
|
a81a1bd5f1 | ||
|
|
5d1539df75 | ||
|
|
a821682c8c | ||
|
|
9446e0348e | ||
|
|
41ccb61c2e | ||
|
|
1b7781a159 | ||
|
|
d66f58a550 | ||
|
|
e2824f9259 | ||
|
|
4376f8f030 | ||
|
|
d377660b5a | ||
|
|
c5ce9b0699 | ||
|
|
c74a7ce4fc | ||
|
|
d98ed68749 | ||
|
|
70d6d2f2db | ||
|
|
da441c59f6 | ||
|
|
42093aedcf | ||
|
|
74d80473df | ||
|
|
7ecb337405 | ||
|
|
07792adc56 | ||
|
|
c0c827d3ad | ||
|
|
6a2bbed73d | ||
|
|
4c1944a08d | ||
|
|
95f870f1b4 | ||
|
|
c250de7dae | ||
|
|
e4b6a143c7 | ||
|
|
9367e9fe5a | ||
|
|
a0c2bbac9d | ||
|
|
f5f6ec3d71 | ||
|
|
c57c1c8b2e | ||
|
|
44f639f371 | ||
|
|
4435717168 | ||
|
|
6767ff5434 | ||
|
|
ff1a0d217f | ||
|
|
42c5e98670 | ||
|
|
c9b80a3612 | ||
|
|
e78a4d61d8 | ||
|
|
88ebcb56e7 | ||
|
|
308dda1587 | ||
|
|
67a9dd8497 | ||
|
|
732ce25d7f | ||
|
|
c16fda1cb6 | ||
|
|
f036c25dca | ||
|
|
7fc4292ed8 | ||
|
|
b50e8a5cf9 | ||
|
|
7018da3f12 | ||
|
|
a66c43166a | ||
|
|
2893f7d481 | ||
|
|
398e42acb5 | ||
|
|
6ecd31a715 | ||
|
|
456bc2ef86 | ||
|
|
e071cd4635 | ||
|
|
cc03e1ceef | ||
|
|
e4d08fc5d7 | ||
|
|
b25192332b | ||
|
|
0eeaf8713f | ||
|
|
42c4a0da51 | ||
|
|
79eb6d3942 | ||
|
|
db853134e3 | ||
|
|
218029ee57 | ||
|
|
4295fbf6c6 | ||
|
|
0985adb770 | ||
|
|
5d2ac10073 | ||
|
|
85aa495741 | ||
|
|
8bf1e3a944 | ||
|
|
066febdf40 | ||
|
|
9b620b2a35 | ||
|
|
a9bbfe9c4f | ||
|
|
d95735deaf | ||
|
|
af31bbeba1 | ||
|
|
1d7d604016 | ||
|
|
df26fec1b3 | ||
|
|
6086a70e06 | ||
|
|
e5529938ea | ||
|
|
e25db4d1b5 | ||
|
|
32acb0ff01 | ||
|
|
f230c07ba5 | ||
|
|
2becc3273a | ||
|
|
f4f610f1a3 | ||
|
|
10c5b46e3b | ||
|
|
b503ef8761 | ||
|
|
94393d27c8 | ||
|
|
12f4787b67 | ||
|
|
f15c1c4e54 | ||
|
|
62925c4c3f | ||
|
|
4fdf5d28ca | ||
|
|
b78c9a2251 | ||
|
|
b436c4a94c | ||
|
|
db1a546aba | ||
|
|
9402f537b6 | ||
|
|
2d29095348 | ||
|
|
ac03b4ccd7 | ||
|
|
759a18685b | ||
|
|
e07ab65d73 | ||
|
|
26f51ece90 | ||
|
|
99066ae939 | ||
|
|
5ff0f09a45 | ||
|
|
5afe779ffc | ||
|
|
af042ccf07 | ||
|
|
e587fe5ce8 | ||
|
|
0b31c677f2 | ||
|
|
d3362dfa0c | ||
|
|
7890157f52 | ||
|
|
b3d1ea4cd5 | ||
|
|
7c842f3170 | ||
|
|
054c5da294 | ||
|
|
5c5a808290 | ||
|
|
5c30b2f271 | ||
|
|
ce2216f544 | ||
|
|
1d13cc1601 | ||
|
|
166879b8b0 | ||
|
|
aeb9d5cd90 | ||
|
|
8e9d076216 | ||
|
|
0d48cb959f | ||
|
|
d908f53607 | ||
|
|
238551b024 | ||
|
|
4e6539efec | ||
|
|
c806279fa9 | ||
|
|
ee1fde4262 | ||
|
|
4d0611b7d4 | ||
|
|
1358303e42 | ||
|
|
c17f0fb44f | ||
|
|
569cd6c57c | ||
|
|
0cfaf34a22 | ||
|
|
e8aeecc4c9 | ||
|
|
edf834188d | ||
|
|
4e402dca7d | ||
|
|
7f6bf7170a | ||
|
|
0ed9d3c62c | ||
|
|
149071bf0c | ||
|
|
720e691f33 | ||
|
|
32614e4074 | ||
|
|
9dc5a3bfc9 | ||
|
|
8db006d9a1 | ||
|
|
cb4afd39bd | ||
|
|
e078caffd8 | ||
|
|
90a9febb6c | ||
|
|
d00761628f | ||
|
|
e4a1286aae | ||
|
|
08a8011456 | ||
|
|
6c10af29ee | ||
|
|
ae62d6fb86 | ||
|
|
d2e0ecd6a3 | ||
|
|
13386ddbd7 | ||
|
|
643b6f0aa3 | ||
|
|
45d262d6c0 | ||
|
|
5dbd11c6ed | ||
|
|
3fcb6df0f1 | ||
|
|
9701516228 | ||
|
|
77dfe63d90 | ||
|
|
2367d94a42 | ||
|
|
d85c849668 | ||
|
|
cbd8c07265 | ||
|
|
3a6d3cb396 | ||
|
|
6e52f552cf | ||
|
|
973114caf6 | ||
|
|
17291e04df | ||
|
|
e27e0ca198 | ||
|
|
27329e39e4 | ||
|
|
38c2070aab | ||
|
|
a0f28708ab | ||
|
|
e25d205a7f | ||
|
|
e28dab17d6 | ||
|
|
05b3237bae | ||
|
|
4fd9d1ee5f | ||
|
|
0fe7004d38 | ||
|
|
06b0dbdfba | ||
|
|
48fb3d3653 | ||
|
|
baa5fd9739 | ||
|
|
e01c277c56 | ||
|
|
7062a7ce66 | ||
|
|
ec3a066e4e | ||
|
|
b0c8e75c6e | ||
|
|
52ad5b7df5 | ||
|
|
1b1d11dcf1 | ||
|
|
35200e5f1b | ||
|
|
d39942902c | ||
|
|
87fc4e6588 | ||
|
|
091ef33f18 | ||
|
|
84e57d040b | ||
|
|
a4f64c02d0 | ||
|
|
278eeb5ee9 | ||
|
|
3342fc2244 | ||
|
|
87857fe5d9 | ||
|
|
64efd07f6b | ||
|
|
aa01c2f4db | ||
|
|
6be66d6df9 | ||
|
|
740015339d | ||
|
|
b7778ca1f9 | ||
|
|
ddd77ee6ee | ||
|
|
b625b5f645 | ||
|
|
c9e272a78d | ||
|
|
9bfb63fd98 | ||
|
|
21ecf54b73 | ||
|
|
429e3ce30a | ||
|
|
26e20d35c2 | ||
|
|
f40406514c | ||
|
|
a68934f498 | ||
|
|
95ef78ab23 | ||
|
|
5be0743751 | ||
|
|
8fc7f2aca1 | ||
|
|
4db4ab9798 | ||
|
|
b6c2c8117e | ||
|
|
86a42aad16 | ||
|
|
8e2e09bb16 | ||
|
|
3713aa210f | ||
|
|
a65c23546b | ||
|
|
ed79bef51b | ||
|
|
f6de91bf0f | ||
|
|
062633d312 | ||
|
|
0cde7f9897 | ||
|
|
4a54699c1f | ||
|
|
c72f6e6ea8 | ||
|
|
790a9155d4 | ||
|
|
f141b845fd | ||
|
|
a274c87cb3 | ||
|
|
85e21ce617 | ||
|
|
157a9e895c | ||
|
|
a94c9d2709 | ||
|
|
f9b18aa62f | ||
|
|
0866cea72c | ||
|
|
6adbb93f0a | ||
|
|
7e2635adfe | ||
|
|
b655d04b34 | ||
|
|
7f84933cab | ||
|
|
36220fdde8 | ||
|
|
67848c03ed | ||
|
|
685d05f98b | ||
|
|
931afe98b1 | ||
|
|
fe0e00f8f8 | ||
|
|
13d19d42cb | ||
|
|
ec852b0c8d | ||
|
|
a05c8ff66b | ||
|
|
5ce50d0a2e | ||
|
|
dfbdeafa39 | ||
|
|
4a6f775334 | ||
|
|
5fa3e10701 | ||
|
|
eb322e8312 | ||
|
|
c2e819771f | ||
|
|
896d29d0c0 | ||
|
|
4c633a9fb8 | ||
|
|
5fd1674d50 | ||
|
|
67cbeaa3d4 | ||
|
|
23f3d554b8 | ||
|
|
95355ddec0 | ||
|
|
cbab7d2150 | ||
|
|
4284088611 | ||
|
|
744d548380 | ||
|
|
82a4bbd571 | ||
|
|
c187461985 | ||
|
|
cc91db55b7 | ||
|
|
bb70223509 | ||
|
|
98fb2ec639 | ||
|
|
a8cef79b1a | ||
|
|
5076e38c1c | ||
|
|
e000d98cc5 | ||
|
|
38cc88c861 | ||
|
|
d71e70bedf | ||
|
|
48e74035f2 | ||
|
|
38bccecc04 | ||
|
|
3ebe35f7f7 | ||
|
|
b81f1111d1 | ||
|
|
ac8db6479e | ||
|
|
d903772831 | ||
|
|
cc71e507cb | ||
|
|
fe44ebee93 | ||
|
|
c80e009cf3 | ||
|
|
f6e8ce5516 | ||
|
|
f808a2b5a1 | ||
|
|
51a2e64a89 | ||
|
|
bf24a106ce | ||
|
|
1387b88ba4 | ||
|
|
d9ece80fda | ||
|
|
b88a9c2627 | ||
|
|
18dbc490fe | ||
|
|
d753492382 | ||
|
|
8c26db63dd | ||
|
|
5d7d30f789 | ||
|
|
63a3f5149a | ||
|
|
c28e27357a | ||
|
|
fa6e5e4d75 | ||
|
|
cae0a26ac0 | ||
|
|
156010050c | ||
|
|
524551a05c | ||
|
|
b89387d608 | ||
|
|
cef1c09db6 | ||
|
|
712759ea4b | ||
|
|
66fc12c928 | ||
|
|
f66fb8e2a8 | ||
|
|
bb786b1f61 | ||
|
|
62610b5ec0 | ||
|
|
2594178158 | ||
|
|
4866ed5283 | ||
|
|
86e93664d0 | ||
|
|
07f0043428 | ||
|
|
e4f15c078a | ||
|
|
35f29b5d8a | ||
|
|
3716f4e809 | ||
|
|
6cf040d3ee | ||
|
|
48a25b1b85 | ||
|
|
d448742ae5 | ||
|
|
f801f52274 | ||
|
|
eabbad176d | ||
|
|
e6d7f22ba9 | ||
|
|
36d73b3da9 | ||
|
|
dcd8fb289e | ||
|
|
0dc266153d | ||
|
|
7850ecbd95 | ||
|
|
1cb60c7f5e | ||
|
|
e4ed0f8acd | ||
|
|
28043726e6 | ||
|
|
9c5df51141 | ||
|
|
eedfb7de32 | ||
|
|
3fc955abfd | ||
|
|
615fa1119f | ||
|
|
7e736c5359 | ||
|
|
2f3c3db020 | ||
|
|
967d4da30a | ||
|
|
7a144b90fb | ||
|
|
4a028b6015 | ||
|
|
8da0f9d356 | ||
|
|
fc396f16ff | ||
|
|
b5e4a5f51c | ||
|
|
77ba647778 | ||
|
|
10491294d8 | ||
|
|
65cbc7c2bb | ||
|
|
1a75e3c24a | ||
|
|
b0b67fbcc4 | ||
|
|
254a6be277 | ||
|
|
fdf920b374 | ||
|
|
dffd82cb24 | ||
|
|
633693c94b | ||
|
|
9840d1ce73 | ||
|
|
6a45bd4372 | ||
|
|
b361fb4f89 | ||
|
|
530bc996ca | ||
|
|
2f2bd03b15 | ||
|
|
a8f179145b | ||
|
|
912ccb31a1 | ||
|
|
6959c9e423 | ||
|
|
53363d6808 | ||
|
|
1b9a350469 | ||
|
|
d0f7b1d9b7 | ||
|
|
86c0abe67e | ||
|
|
46cc64f2d8 | ||
|
|
9e29c13678 | ||
|
|
438ce44af9 | ||
|
|
e37ccb7a63 | ||
|
|
afaa8012c8 | ||
|
|
c4778e5e24 | ||
|
|
d5ee8d80ab | ||
|
|
1fbc131469 | ||
|
|
468af29e3e | ||
|
|
b05e7943c2 | ||
|
|
dbf0c1893c | ||
|
|
950006a4de | ||
|
|
2f7dfb0286 | ||
|
|
7c98aea524 | ||
|
|
688c5bdd20 | ||
|
|
4feff1cf89 | ||
|
|
df2d181602 | ||
|
|
752a9d904c | ||
|
|
a5b9fbaf00 | ||
|
|
7bf1c5f27b | ||
|
|
d841303c04 | ||
|
|
5e5b9895df | ||
|
|
ac8f798e56 | ||
|
|
5c8ec5cce4 | ||
|
|
19e509d997 | ||
|
|
38b230a128 | ||
|
|
b47fdd748f | ||
|
|
c69c7db4f7 | ||
|
|
de20d8f73a | ||
|
|
5deecfea28 | ||
|
|
dfa48ba17c | ||
|
|
b3928f3d2a | ||
|
|
009ecb0ff4 | ||
|
|
68ffddafb1 | ||
|
|
d3bc50e18d | ||
|
|
d3f741a8b6 | ||
|
|
ad4e8fd7f5 | ||
|
|
2c7597066c | ||
|
|
c06c2650e5 | ||
|
|
9d664df993 | ||
|
|
89ecc07eb0 | ||
|
|
9ffb10c0e6 | ||
|
|
dd4b8529c2 | ||
|
|
5d1d6299cd | ||
|
|
4e1c32e610 | ||
|
|
d6f98ab88e | ||
|
|
7188e719ef | ||
|
|
2328dfc851 | ||
|
|
30c00df4f3 | ||
|
|
e1b85a361c | ||
|
|
915328d92a | ||
|
|
6019a34da2 | ||
|
|
5a9e6c8a69 | ||
|
|
57231a8807 | ||
|
|
dd9f7ef6e9 | ||
|
|
8b76b5a0a6 | ||
|
|
3d3e7bafd5 | ||
|
|
a42ff1e6d4 | ||
|
|
ea8ff7037a | ||
|
|
2438af1cb5 | ||
|
|
a32626e489 | ||
|
|
3a9f149c80 | ||
|
|
a0e4f7ddb1 | ||
|
|
8189408190 | ||
|
|
db0a3a7534 | ||
|
|
5f612521da | ||
|
|
53efd4e470 | ||
|
|
22a9e4c9a9 | ||
|
|
56f0244360 | ||
|
|
60a7e68b1b | ||
|
|
ec6d4f8ac3 | ||
|
|
a6ab3dd36a | ||
|
|
6bf0f4225c | ||
|
|
4df5d44ef9 | ||
|
|
dd962027cc | ||
|
|
7c05500392 | ||
|
|
5d83469621 | ||
|
|
d03c27d18c | ||
|
|
7e8c7f86f0 | ||
|
|
b438ffead4 | ||
|
|
cbaaa1c57f | ||
|
|
f0690aadcc | ||
|
|
fc31ecdab0 | ||
|
|
6bfc5aa96c | ||
|
|
5505f5fa02 | ||
|
|
6349a7417f | ||
|
|
e1a55ba471 | ||
|
|
881406f82b | ||
|
|
293e405f5b | ||
|
|
8d6441704b | ||
|
|
9fcb3bf2e8 | ||
|
|
7d088c8d56 | ||
|
|
ed3d3b6f27 | ||
|
|
dcd5f00077 | ||
|
|
4aa9549828 | ||
|
|
bca3113fba | ||
|
|
a8a2c806f2 | ||
|
|
e00c5c6bf1 | ||
|
|
7e8c895ccd | ||
|
|
139c39c2ce | ||
|
|
6bae91dd7e | ||
|
|
c115e8ee60 | ||
|
|
ddebbcc0a0 | ||
|
|
4f3be92a0d | ||
|
|
9655b27f81 | ||
|
|
5a475453ab | ||
|
|
eb04dbc5ce | ||
|
|
2bf76928cc | ||
|
|
89d97c556a | ||
|
|
4ff2b8ed1b | ||
|
|
ed17e8a649 | ||
|
|
33700e9cf4 | ||
|
|
13b3594ff3 | ||
|
|
eebeb450c3 | ||
|
|
0fe449ba33 | ||
|
|
cd4454100b | ||
|
|
fb060c27ef | ||
|
|
fcd9e115c2 | ||
|
|
cf00a9dbfc | ||
|
|
bace238e9f | ||
|
|
7586bc9dcf | ||
|
|
7a294c3843 | ||
|
|
2599d78d0c | ||
|
|
fc6b337bbb | ||
|
|
ea17b46e94 | ||
|
|
9cf8931136 | ||
|
|
afb29176a4 | ||
|
|
1da0042ee5 | ||
|
|
76d8e59e9b | ||
|
|
1061027071 | ||
|
|
a403611ac9 | ||
|
|
2b3f931c85 | ||
|
|
9bf26cee6d | ||
|
|
d9066ef26b | ||
|
|
4610fa2774 | ||
|
|
fff720c00d | ||
|
|
7e26200510 | ||
|
|
1dbf89362f | ||
|
|
cc1453a8de | ||
|
|
a8def37dcf | ||
|
|
355a9ac7ee | ||
|
|
a8274bbfb3 | ||
|
|
7dadbbbac7 | ||
|
|
49f7d63290 | ||
|
|
0044906fab | ||
|
|
ac8706e919 | ||
|
|
5b48eb3657 | ||
|
|
43f04e4bc0 | ||
|
|
649260ce44 | ||
|
|
f091a3c9fc | ||
|
|
18338495af | ||
|
|
a3f9cf7e97 | ||
|
|
ef0f195fe8 | ||
|
|
469809183d | ||
|
|
8611e7f8a6 | ||
|
|
55e1026c98 | ||
|
|
9e1af2492f | ||
|
|
4eb40528a9 | ||
|
|
6ba77ce0e2 | ||
|
|
a256195767 | ||
|
|
23b53cd1ce | ||
|
|
26d69796d0 | ||
|
|
71307d3a2e | ||
|
|
acb114d0d1 | ||
|
|
1781df006f | ||
|
|
63f84ece6e | ||
|
|
d0d14579d1 | ||
|
|
b11db26edf | ||
|
|
6d7e364a0d | ||
|
|
7e99931733 | ||
|
|
8733d9f2a6 | ||
|
|
29da06c298 | ||
|
|
7a1afc315d | ||
|
|
244e813bfa | ||
|
|
0bc2a4f603 | ||
|
|
6abbadf6c8 | ||
|
|
8b4af7cf0b | ||
|
|
1ca6ef0f60 | ||
|
|
dae89ce91c | ||
|
|
056f3d352c | ||
|
|
620e8f2f0b | ||
|
|
7f7e049397 | ||
|
|
40d99c1716 | ||
|
|
2dd66df8eb | ||
|
|
eabf804dc9 | ||
|
|
b955c2d2c5 | ||
|
|
5a6141faa2 | ||
|
|
da460ff32f | ||
|
|
12c571a187 | ||
|
|
179eeb10a6 | ||
|
|
aac5fd96cc | ||
|
|
16930c1c54 | ||
|
|
76a2a5c432 | ||
|
|
de63e40a70 | ||
|
|
803e85caeb | ||
|
|
062dea8e13 | ||
|
|
959667c009 | ||
|
|
46152cc56b | ||
|
|
c8fc3ad7cd | ||
|
|
301e405769 | ||
|
|
229d82c4c7 | ||
|
|
d9759ba63c | ||
|
|
2d1dbc8f40 | ||
|
|
1b160c0a2d | ||
|
|
356c7003f2 | ||
|
|
83f8a03964 | ||
|
|
7ed32a764c | ||
|
|
4f69bcfc38 | ||
|
|
9a82b8414b | ||
|
|
0b05203cf4 | ||
|
|
4135a10211 | ||
|
|
7991db14be | ||
|
|
1509c9682b | ||
|
|
e7287152a2 | ||
|
|
082bd58805 | ||
|
|
e288f46967 | ||
|
|
efb0ac5996 | ||
|
|
984de8f46f | ||
|
|
2c819c8619 | ||
|
|
10ce6cc154 | ||
|
|
7c1d1f8bd3 | ||
|
|
bcaa0dacdf | ||
|
|
5dae0ef4f9 | ||
|
|
62bc5e8051 | ||
|
|
ef6e067a45 | ||
|
|
721496f922 | ||
|
|
be225164eb | ||
|
|
1650ac2edd | ||
|
|
bb1aa04689 | ||
|
|
67bb167cf8 | ||
|
|
b4be1da91e | ||
|
|
d41556a1ea | ||
|
|
50796079fa | ||
|
|
9acf007687 | ||
|
|
dafe0afa65 | ||
|
|
30d0f9888c | ||
|
|
2bd7d30a5b | ||
|
|
cab22f228a | ||
|
|
0545baaf56 | ||
|
|
fbd26e8d9d | ||
|
|
6ad4ed87a3 | ||
|
|
3c8de7b59d | ||
|
|
611e22d676 | ||
|
|
0c43a9bb5d | ||
|
|
eb85d381fd | ||
|
|
aab16123b5 | ||
|
|
1f8b4b14a4 | ||
|
|
4640253614 | ||
|
|
e646684493 | ||
|
|
257dcaaf8b | ||
|
|
a30934c563 | ||
|
|
5e6f6e2c3e | ||
|
|
620082c16b | ||
|
|
83c18f4d4a | ||
|
|
b2218574ee | ||
|
|
1b959a4731 | ||
|
|
8ee4a54c10 | ||
|
|
acb0604a71 | ||
|
|
26a7c88ddf | ||
|
|
70a0a83363 | ||
|
|
894f5bc79a | ||
|
|
b47b917eb0 | ||
|
|
c41c04cf11 | ||
|
|
0895756658 | ||
|
|
c6e65ec6da | ||
|
|
192b69b11a | ||
|
|
733a5ccb08 | ||
|
|
b0ca73c1ba | ||
|
|
367937e479 | ||
|
|
6e91d85bcb | ||
|
|
f995ef0124 | ||
|
|
4a26f0d2d4 | ||
|
|
90cf238019 | ||
|
|
97cb108937 | ||
|
|
34f6d9f714 | ||
|
|
76e644e18a | ||
|
|
a0cefe7fdb | ||
|
|
be4c9a9598 | ||
|
|
be852ba857 | ||
|
|
3370e8516f | ||
|
|
998dd58206 | ||
|
|
108cc7b270 | ||
|
|
ace8252569 | ||
|
|
56113b0bde | ||
|
|
b52e9731e3 | ||
|
|
61a8a16139 | ||
|
|
eff72aeb47 | ||
|
|
94316da63e | ||
|
|
ae35ac0cec | ||
|
|
2f9a044559 | ||
|
|
1f429a0033 | ||
|
|
a3ed0b94cd | ||
|
|
204838bd10 | ||
|
|
dd806bd031 | ||
|
|
8442693d7a | ||
|
|
cd526139fb | ||
|
|
75c8f656c9 | ||
|
|
459ec78a5e | ||
|
|
6bf5eea646 | ||
|
|
e9f49d9d9c | ||
|
|
9713436f49 | ||
|
|
406ea67bbc | ||
|
|
a24d254404 | ||
|
|
285781b887 | ||
|
|
40db68886d | ||
|
|
d5088549f8 | ||
|
|
03851ee7cc | ||
|
|
2d460117fc | ||
|
|
73cabbf822 | ||
|
|
411b7964ab | ||
|
|
bc45c5368e | ||
|
|
7a65b6cfe4 | ||
|
|
ee464c6589 | ||
|
|
d83f12e883 | ||
|
|
76770c69bf | ||
|
|
e9225b15d2 | ||
|
|
3056b96bb0 | ||
|
|
856945d838 | ||
|
|
be1c05a03f | ||
|
|
34717cc83c | ||
|
|
e73cde1612 | ||
|
|
a9b71f5b4a | ||
|
|
c99fb4b7f1 | ||
|
|
b28279241b | ||
|
|
5c5ae2969e | ||
|
|
3af691043d | ||
|
|
9615d02b35 | ||
|
|
7a55ead97d | ||
|
|
cd200ee706 | ||
|
|
db930b794d | ||
|
|
08bcd29eee | ||
|
|
3f75dd1083 | ||
|
|
eb2d6fca3a | ||
|
|
32423a7706 | ||
|
|
57cb4ccb74 | ||
|
|
12c9e64463 | ||
|
|
d872a0ca86 | ||
|
|
9c5ddf079a | ||
|
|
f094ac19d1 | ||
|
|
7f244a8039 | ||
|
|
14953fa5c9 | ||
|
|
75f73fffe1 | ||
|
|
897dd7f380 | ||
|
|
95f1366f0c | ||
|
|
feb5d3af89 | ||
|
|
875597cde1 | ||
|
|
f15c12376a | ||
|
|
b223e364c6 | ||
|
|
e1738e8021 | ||
|
|
a33dfff188 | ||
|
|
0c27fdd944 | ||
|
|
f897cd6bc8 | ||
|
|
1bc9672ec8 | ||
|
|
dfce7c6ca4 | ||
|
|
6e61e2a45b | ||
|
|
eabed9d0e5 | ||
|
|
2af61605f2 | ||
|
|
0992822ce5 | ||
|
|
f08777c9ac | ||
|
|
472ed909cd | ||
|
|
3ed19f5b00 | ||
|
|
a60b91b21e | ||
|
|
40dd8aa3d4 | ||
|
|
02459ebde0 | ||
|
|
774dc871cc | ||
|
|
7bb69e20f5 | ||
|
|
6e0be570dd | ||
|
|
5dd291fc60 | ||
|
|
630ccf3810 | ||
|
|
8d16092171 | ||
|
|
05c137c1ab | ||
|
|
83e0442b66 | ||
|
|
98cfad5f2d | ||
|
|
a48e795f8a | ||
|
|
f620274c6a | ||
|
|
ae5b3a83f1 | ||
|
|
5e23640563 | ||
|
|
7d3dfc3ed8 | ||
|
|
5b0991fabc | ||
|
|
0fa638399f | ||
|
|
d59c6aa887 | ||
|
|
b6ec8bf687 | ||
|
|
f28d6ad59e | ||
|
|
e841e48258 | ||
|
|
c0141a7d5e | ||
|
|
aa15867c95 | ||
|
|
8d87b529f5 | ||
|
|
900663b85f | ||
|
|
1e79107d0e | ||
|
|
52803a30b6 | ||
|
|
eb30658c68 | ||
|
|
f77aaf1def | ||
|
|
8c7bf6d2f3 | ||
|
|
94df121e0a | ||
|
|
873670594b | ||
|
|
09ef1b1bb6 | ||
|
|
31e9efdae0 | ||
|
|
bb2103ac45 | ||
|
|
e98c74bce7 | ||
|
|
feb03dc194 | ||
|
|
bb8f73b58a | ||
|
|
02da3adb5a | ||
|
|
28d1913d84 | ||
|
|
051ab698ed | ||
|
|
9014524477 | ||
|
|
316f68c12d | ||
|
|
9387be1aa7 | ||
|
|
c3ca257f18 | ||
|
|
d0ba2cf6d4 | ||
|
|
e33d8c288b | ||
|
|
34fbcfdfaa | ||
|
|
2e9738e204 | ||
|
|
9a7e8f4d68 | ||
|
|
7b445a5b39 | ||
|
|
ce13fef6aa | ||
|
|
38e99c8354 | ||
|
|
a85b1efa4f | ||
|
|
00a95f4b91 | ||
|
|
433951ab55 | ||
|
|
baa46e105c | ||
|
|
4e389b474a | ||
|
|
63c76eae0c | ||
|
|
9431785466 | ||
|
|
953391cca9 | ||
|
|
8e0fc9e762 | ||
|
|
fe4defe752 | ||
|
|
f32ba06564 | ||
|
|
a5a6488757 | ||
|
|
b8aabde6c3 | ||
|
|
44d4f0a484 | ||
|
|
09666ae8e9 | ||
|
|
4a60f45220 | ||
|
|
7b9946079f | ||
|
|
fe724acc3b | ||
|
|
4409b2b40a | ||
|
|
33f446fcd0 | ||
|
|
953d02e4b7 | ||
|
|
a124c120f4 | ||
|
|
5f8b093d79 | ||
|
|
f923d21df3 | ||
|
|
5a9e9284c2 | ||
|
|
c7c04aba3d | ||
|
|
33503349ec | ||
|
|
ef3994da30 | ||
|
|
2e758f11e7 | ||
|
|
7283e2e279 | ||
|
|
352dd364d2 | ||
|
|
d5c3363909 | ||
|
|
2ede8e3675 | ||
|
|
fe318d4eb8 | ||
|
|
c0bf3c8af1 | ||
|
|
175a3c4008 | ||
|
|
e9f3095f41 | ||
|
|
ebf540ffbc | ||
|
|
4f1031f92b | ||
|
|
ddb9db188b | ||
|
|
63e8f1f36b | ||
|
|
a3f77409a4 | ||
|
|
705ff97892 | ||
|
|
1bb2d0b954 | ||
|
|
0773b9bf92 | ||
|
|
da775d182a | ||
|
|
0f836c9d5e | ||
|
|
e77914fe3f | ||
|
|
ed785fbb1b | ||
|
|
25f34d8ad3 | ||
|
|
0a51ea1bfa | ||
|
|
9ffad65b65 | ||
|
|
8face5a66c | ||
|
|
edd91a7ed1 | ||
|
|
c5b32032a7 | ||
|
|
4bb93c4327 | ||
|
|
e11e99b2d1 | ||
|
|
2dce7c212f | ||
|
|
2ea87b65ca | ||
|
|
a6c42e8756 | ||
|
|
b688dc3995 | ||
|
|
59ac3d04eb | ||
|
|
97308ad2fb | ||
|
|
2dff10564c | ||
|
|
d401e5e7c4 | ||
|
|
67ce5f4c9c | ||
|
|
5bd1ea0b95 | ||
|
|
9ac67b44e4 | ||
|
|
bc4a1ee500 | ||
|
|
78816f2f74 | ||
|
|
fedb5fbcf5 | ||
|
|
bb61e672b0 | ||
|
|
de6f07ec89 | ||
|
|
d0dc8c1e4c | ||
|
|
5ec2e28802 | ||
|
|
391020fd1b | ||
|
|
e46874149d | ||
|
|
7f49f6a45c | ||
|
|
901b0ac146 | ||
|
|
28bc4089d0 | ||
|
|
2bca612a92 | ||
|
|
66d72d9870 | ||
|
|
11624cd83e | ||
|
|
55b7182136 | ||
|
|
55dc6fbc1c | ||
|
|
c446ffb814 | ||
|
|
689ced2ac0 | ||
|
|
51c533536f | ||
|
|
2431631b46 | ||
|
|
e189f5f887 | ||
|
|
5a736d338b | ||
|
|
95059f2bfd | ||
|
|
1bb67f63e3 | ||
|
|
b12d254427 | ||
|
|
af909f66a7 | ||
|
|
e05f41630b | ||
|
|
ba8f8c3403 | ||
|
|
84e2bdcf76 | ||
|
|
a211c16b73 | ||
|
|
f325c29b48 | ||
|
|
d5c451c4a8 | ||
|
|
8d0cbeab38 | ||
|
|
636fb95e24 | ||
|
|
2f1ad15645 | ||
|
|
b1ed79f239 | ||
|
|
aea61bf034 | ||
|
|
2254262cf0 | ||
|
|
872e4a0513 | ||
|
|
0e1ea54c32 | ||
|
|
ff69413729 | ||
|
|
a8c2b75b9b | ||
|
|
c8ff773b96 | ||
|
|
fa78dc79f3 | ||
|
|
1ef31d27c7 | ||
|
|
f634d15768 | ||
|
|
9bc9aa123f | ||
|
|
92b08f1f07 | ||
|
|
a81011333f | ||
|
|
a2e0706d55 | ||
|
|
85ccfb4bbc | ||
|
|
2ec28a5993 | ||
|
|
8ff8a3eab9 | ||
|
|
f5573deb60 | ||
|
|
16dcbc1e67 | ||
|
|
19782655e6 | ||
|
|
c53f788cc8 | ||
|
|
440ccf19d1 | ||
|
|
fc7d9c235c | ||
|
|
0f5ae5cac8 | ||
|
|
6903dbcc0d | ||
|
|
a806c68713 | ||
|
|
393cd46a82 | ||
|
|
0576046d02 | ||
|
|
c0794a83b4 | ||
|
|
dcd636f7be | ||
|
|
83e7d89f7e | ||
|
|
02763811b3 | ||
|
|
8b9952e770 | ||
|
|
43e55eb9a6 | ||
|
|
120e578a67 | ||
|
|
411b8e48a3 | ||
|
|
d38b5ed2f5 | ||
|
|
04abfdd5a6 | ||
|
|
1662f76f03 | ||
|
|
283e5d3a5c | ||
|
|
bef5be827d | ||
|
|
a8b78dc1f5 | ||
|
|
19888b95cc | ||
|
|
3e6a55a295 | ||
|
|
bbe58dd550 | ||
|
|
a422063c7d | ||
|
|
518db97962 | ||
|
|
fdf5799857 | ||
|
|
99dc161483 | ||
|
|
f16dc7afc8 | ||
|
|
32cd0cc984 | ||
|
|
169d75d2d1 | ||
|
|
6d234daa88 | ||
|
|
f8f64e853d | ||
|
|
823b873e50 | ||
|
|
5c97280359 | ||
|
|
7e62c3fa29 | ||
|
|
c18b6cbd68 | ||
|
|
29b3950e32 | ||
|
|
17bc11bbd4 | ||
|
|
3e937266b2 | ||
|
|
a02f22aab7 | ||
|
|
b31616e5bf | ||
|
|
b1057e8cd1 | ||
|
|
7543e27eae | ||
|
|
8a43bead74 | ||
|
|
2867cd2043 | ||
|
|
88ca6fc12e | ||
|
|
e04d3c45a4 | ||
|
|
db586e0c27 | ||
|
|
4aaea422bc | ||
|
|
7fd882a088 | ||
|
|
b0396cd646 | ||
|
|
d5117a62b8 | ||
|
|
b13328140f | ||
|
|
3be0b0925c | ||
|
|
7c47b9d75c | ||
|
|
09a8b4b379 | ||
|
|
ea36ebd0df | ||
|
|
549f7a53b1 | ||
|
|
739a612824 | ||
|
|
953a2fd9b2 | ||
|
|
2fa9645dfc | ||
|
|
3bd6450333 | ||
|
|
fee258edbe | ||
|
|
e294dfa760 | ||
|
|
669013f7e6 | ||
|
|
dde482082e | ||
|
|
868e9aa058 | ||
|
|
a815e2e30b | ||
|
|
89b76530da | ||
|
|
e909c2bbce | ||
|
|
ab1e1e9114 | ||
|
|
13b0fdadb1 | ||
|
|
90580a860b | ||
|
|
6d7fdb14f0 | ||
|
|
a2cb7b9ca4 | ||
|
|
91aeb25523 | ||
|
|
bb86ee7cc4 | ||
|
|
887a59066b | ||
|
|
e060135304 | ||
|
|
6bf2c64aa2 | ||
|
|
1aba495a1c | ||
|
|
482e26ae26 | ||
|
|
c50105b8c1 | ||
|
|
530a378aa1 | ||
|
|
04935f139d | ||
|
|
5228462363 | ||
|
|
9dc831f1ef | ||
|
|
6844d7c752 | ||
|
|
cda3d23508 | ||
|
|
e4ee165e29 | ||
|
|
e0255c0dc4 | ||
|
|
6ce3ca1ce0 | ||
|
|
c3cd613f42 | ||
|
|
f2078b25ad | ||
|
|
f9ec3c66ff | ||
|
|
4760dc9bcb | ||
|
|
808f362921 | ||
|
|
43cafcc761 | ||
|
|
b00c22b69b | ||
|
|
73248fd227 | ||
|
|
7205ffb5c0 | ||
|
|
ff77f14f2f | ||
|
|
a0cba6564f | ||
|
|
35b4f0a863 | ||
|
|
0fba1a777e | ||
|
|
d47ea20aa8 | ||
|
|
be6dcb5d0a | ||
|
|
bddf8cfde4 | ||
|
|
9369150db7 | ||
|
|
0fd7634339 | ||
|
|
969a91c432 | ||
|
|
4d08fcf1a7 | ||
|
|
8048b7addc | ||
|
|
4499ee178f | ||
|
|
b17f741050 | ||
|
|
4a45c35c4e | ||
|
|
f4c94ab121 | ||
|
|
64bb1ca2bb | ||
|
|
b7386a0e88 | ||
|
|
a7ff2cc5ea | ||
|
|
dcacdd23c8 | ||
|
|
8e46b07268 | ||
|
|
2f4c441074 | ||
|
|
61f85bcb14 | ||
|
|
699ff644ad | ||
|
|
0877e5b578 | ||
|
|
46114bb24d | ||
|
|
6208ee3809 | ||
|
|
17e341d245 | ||
|
|
f22c7afc59 | ||
|
|
d7aa24fd2d | ||
|
|
255c5ae94f | ||
|
|
ab2ff4a520 | ||
|
|
1a53a4bc53 | ||
|
|
4423f4c930 | ||
|
|
9c512bb645 | ||
|
|
bd0959b5a4 | ||
|
|
fe401203bd | ||
|
|
c86032d4dc | ||
|
|
e864679942 | ||
|
|
cadef5924f | ||
|
|
1a25b0bda7 | ||
|
|
f748139606 | ||
|
|
a5aff7d0c9 | ||
|
|
2afe28785c | ||
|
|
aca719ac74 | ||
|
|
8871f8d0f4 | ||
|
|
29b377d4c5 | ||
|
|
4915a4efbb | ||
|
|
245142cc07 | ||
|
|
5ac0f371c7 | ||
|
|
cf6d51bee8 | ||
|
|
d68ce0f345 | ||
|
|
4e21c14ff6 | ||
|
|
753e1e4616 | ||
|
|
9a1f051068 | ||
|
|
bcffb6cf55 | ||
|
|
0e09dca952 | ||
|
|
3bd3686acf | ||
|
|
4493304fa7 | ||
|
|
6decffb00c | ||
|
|
54e941724f | ||
|
|
e155e7d9ce | ||
|
|
6433ce70a1 | ||
|
|
1e086a4ac8 | ||
|
|
1c3e669761 | ||
|
|
af125fbe4f | ||
|
|
43249bd4be | ||
|
|
f54aa4f21e | ||
|
|
6822415ee2 | ||
|
|
6d0e1b0e07 | ||
|
|
238303d819 | ||
|
|
998f39868f | ||
|
|
20ac91703d | ||
|
|
33bb89729c | ||
|
|
e06e64823f | ||
|
|
cd485b0fdf | ||
|
|
1cf0de568d | ||
|
|
662316e687 | ||
|
|
14383a4c4a | ||
|
|
1dc795722a | ||
|
|
08274ffab7 | ||
|
|
5ea11d1222 | ||
|
|
35b6c2baad | ||
|
|
a92f22a4a4 | ||
|
|
2fc3f381ac | ||
|
|
2a2a21a736 | ||
|
|
5a739ddc47 | ||
|
|
4ef2493e95 | ||
|
|
c98776923a | ||
|
|
bb4f9eecbe | ||
|
|
d4e91d5d9b | ||
|
|
558e3f8042 | ||
|
|
9f9b9dfd82 | ||
|
|
a8d81a68d6 | ||
|
|
abe6ab4775 | ||
|
|
9a155cf5a5 | ||
|
|
ae9e64cedf | ||
|
|
e6d62f6e05 | ||
|
|
09567da292 | ||
|
|
a1ce5df74f | ||
|
|
dede5fabeb | ||
|
|
4a4c18b8b3 | ||
|
|
06026c1c27 | ||
|
|
e2b9162a30 | ||
|
|
eec4d9b5ad | ||
|
|
376091010f | ||
|
|
ac967db4e8 | ||
|
|
af8cbf000f | ||
|
|
034032c7c2 | ||
|
|
05e11844e5 | ||
|
|
4ba91cf4e3 | ||
|
|
9a52b90f22 | ||
|
|
8ea8700eef | ||
|
|
1f128e84fb | ||
|
|
1514b0f4e5 | ||
|
|
dc066d4c9b | ||
|
|
3d6b606792 | ||
|
|
c80837a9e6 | ||
|
|
a732b2bca1 | ||
|
|
0009f7f051 | ||
|
|
7b04c7e7df | ||
|
|
b5cc26fe76 | ||
|
|
b3cb78a598 | ||
|
|
60b38a3a52 | ||
|
|
c0a896ff5e | ||
|
|
63bbde2368 | ||
|
|
91b710b07d | ||
|
|
34fee2a790 | ||
|
|
6c709551ce | ||
|
|
aa4f8b2901 | ||
|
|
3003f85a3e | ||
|
|
33573edafa | ||
|
|
95c53c7e0b | ||
|
|
a94a28bb7e | ||
|
|
7b56fdebac | ||
|
|
0905018d3b | ||
|
|
9d230b1f4c | ||
|
|
9f4064e03b | ||
|
|
461e86423a | ||
|
|
f70413a031 | ||
|
|
26b7a3aca0 | ||
|
|
75721b7e82 | ||
|
|
fa3e7a574f | ||
|
|
d4fa33dddd | ||
|
|
a0cbed80f3 | ||
|
|
128d1f7aa8 | ||
|
|
09a841f3be | ||
|
|
074bf009d8 | ||
|
|
268b96effa | ||
|
|
5a3c2b19c9 | ||
|
|
b120394b49 | ||
|
|
46c67e7f2f | ||
|
|
790660e612 | ||
|
|
2bcfa0c126 | ||
|
|
e02029ecc6 | ||
|
|
09e143dc1f | ||
|
|
53c1d3775c | ||
|
|
62ad32cf2e | ||
|
|
150e238b02 | ||
|
|
ab1d47b36f | ||
|
|
dcd658f12e | ||
|
|
34399b8b47 | ||
|
|
092c1c8c4c | ||
|
|
b265a55b81 | ||
|
|
717ae54868 | ||
|
|
ade11568f9 | ||
|
|
98541beee3 | ||
|
|
ec12b78ddf | ||
|
|
08d2adddf5 | ||
|
|
a417389934 | ||
|
|
aa6f7481a0 | ||
|
|
ff2935e70c | ||
|
|
cd21519de3 | ||
|
|
a4de63ca92 | ||
|
|
4baf5eab16 | ||
|
|
7361af85b5 | ||
|
|
8ce644af28 | ||
|
|
78040330b6 | ||
|
|
3f88a7619f | ||
|
|
056ec81a71 | ||
|
|
bc40651bc2 | ||
|
|
442b510b23 | ||
|
|
4db112e28e | ||
|
|
4fdad3b8af | ||
|
|
9c02c66ed3 | ||
|
|
d82bf2b921 | ||
|
|
3ee35b83c2 | ||
|
|
500b141341 | ||
|
|
f9cca2422a | ||
|
|
76a8006003 | ||
|
|
7ac70e1f23 | ||
|
|
a0a1246efb | ||
|
|
8705882e6e | ||
|
|
2105cfd433 | ||
|
|
16f9e7bd40 | ||
|
|
f3a753bda6 | ||
|
|
1700aedbed | ||
|
|
48b1042347 | ||
|
|
a454aad124 | ||
|
|
c8afde6f87 | ||
|
|
726576363c | ||
|
|
d2ffe29343 | ||
|
|
ce81de1409 | ||
|
|
89bbf6cd67 | ||
|
|
17c102ebe1 | ||
|
|
d6812cf75e | ||
|
|
04f7f99fc3 | ||
|
|
46a4208b3d | ||
|
|
f0f58dade8 | ||
|
|
b282e45a02 | ||
|
|
0a876e1518 | ||
|
|
1d3d713c1c | ||
|
|
da9fe27db1 | ||
|
|
f91db3ee8e | ||
|
|
c7351c0922 | ||
|
|
99247d0c59 | ||
|
|
9b13db1c48 | ||
|
|
ed79621c76 | ||
|
|
afdde44061 | ||
|
|
c462d2f15e | ||
|
|
c304361c9b | ||
|
|
bae2af09a0 | ||
|
|
12ca4caa4a | ||
|
|
a0e0b82067 | ||
|
|
9fb65e10bd | ||
|
|
f02314dfd8 | ||
|
|
af46c192bf | ||
|
|
77a8a2b9ac | ||
|
|
a0e390c6c8 | ||
|
|
09b6888526 | ||
|
|
fd7d3f9286 | ||
|
|
59a2057fa0 | ||
|
|
be6619d9c0 | ||
|
|
bb7457f43c | ||
|
|
14f701f7fc | ||
|
|
058f7277b5 | ||
|
|
5d18996362 | ||
|
|
ad3f61a215 | ||
|
|
1eab488754 | ||
|
|
471c3c4d06 | ||
|
|
ca1022675c | ||
|
|
c3920116f2 | ||
|
|
26e0fd624a | ||
|
|
4c69c56797 | ||
|
|
df03805579 | ||
|
|
b38ce967f3 | ||
|
|
dbe73cdcbe | ||
|
|
2f0ebdeade | ||
|
|
98e3e7ff9b | ||
|
|
226aad357d | ||
|
|
7c5f1e814b | ||
|
|
49a236345f | ||
|
|
840cea680c | ||
|
|
83365840af | ||
|
|
5c46e66694 | ||
|
|
b44e46f8be | ||
|
|
bca05dc89f | ||
|
|
6ee6285670 | ||
|
|
dcfe9bc64f | ||
|
|
8fd619da71 | ||
|
|
1620691cbe | ||
|
|
49bd859136 | ||
|
|
93a11ade04 | ||
|
|
343982a2f9 | ||
|
|
3da9107354 | ||
|
|
f5169bdbbb | ||
|
|
d32f583fda | ||
|
|
bab00731a8 | ||
|
|
8cd539e125 | ||
|
|
3b8a0d4773 | ||
|
|
b60098ec68 | ||
|
|
321611f865 | ||
|
|
de02fddf89 | ||
|
|
2e058c9abc | ||
|
|
a7b48b9650 | ||
|
|
844bef5070 | ||
|
|
6210b7727f | ||
|
|
01015bc0d5 | ||
|
|
2b910eb5aa | ||
|
|
9672d35d8c | ||
|
|
14e14c6c92 | ||
|
|
1c07880c01 | ||
|
|
39fe80a196 | ||
|
|
7c28a40c3e | ||
|
|
029d155a07 | ||
|
|
97e329906e | ||
|
|
c92bc60cec | ||
|
|
551eea05ed | ||
|
|
6593dff9f5 | ||
|
|
90c82e4394 | ||
|
|
924c8db712 | ||
|
|
6c60be9e8d | ||
|
|
be5187718c | ||
|
|
14183b8fb5 | ||
|
|
f34e6d8977 | ||
|
|
58ee2a49fa | ||
|
|
68c6d7a099 | ||
|
|
6c37a38980 | ||
|
|
5277e79fa2 | ||
|
|
1035c453ea | ||
|
|
afe2ba3690 | ||
|
|
01776e767d | ||
|
|
87079e8071 | ||
|
|
f83b7c2d52 | ||
|
|
45e0fc6802 | ||
|
|
cbcf389f50 | ||
|
|
fe7fba4789 | ||
|
|
3bd2288ea9 | ||
|
|
f8f69767b7 | ||
|
|
ee5fd8a0bd | ||
|
|
032cbca651 | ||
|
|
be3e0ca9a1 | ||
|
|
a5f843ba9b | ||
|
|
4781a8cb6b | ||
|
|
a38c8cc75c | ||
|
|
51c0e5a988 | ||
|
|
d2ed3a9abb | ||
|
|
1b1550fb31 | ||
|
|
04ec35d9cc | ||
|
|
e3095ce6b2 | ||
|
|
70b8f3240f | ||
|
|
673cf8d35e | ||
|
|
fed61c082c | ||
|
|
d406e2aae2 | ||
|
|
3153129e2e | ||
|
|
c618bfc607 | ||
|
|
497ebca54f | ||
|
|
64ee42fc3d | ||
|
|
f6d024cb3f | ||
|
|
e6f9f284bf | ||
|
|
7ddf51722c | ||
|
|
59dafb610d | ||
|
|
2d91aed183 | ||
|
|
3dd64e7916 | ||
|
|
048a636315 | ||
|
|
1c750dac41 | ||
|
|
5e53f36f34 | ||
|
|
8f95b8a824 | ||
|
|
5456ee7f65 | ||
|
|
277da43631 | ||
|
|
70719c67d3 | ||
|
|
43fca182e3 | ||
|
|
80ce2def46 | ||
|
|
a1f9d40d08 | ||
|
|
bdcee4fc30 | ||
|
|
bb2ec5d8dc | ||
|
|
56d1c08317 | ||
|
|
2d69b419ff | ||
|
|
fef3155e6a | ||
|
|
1a2f722cdb | ||
|
|
8fc48f2d43 | ||
|
|
2d17e1c677 | ||
|
|
a829256bc4 | ||
|
|
b6d34bffcc | ||
|
|
8e5c1135c3 | ||
|
|
89a825cd03 | ||
|
|
ce8349662d | ||
|
|
02575f46a6 | ||
|
|
441cdeff3f | ||
|
|
85a6dd6031 | ||
|
|
b4dad81767 | ||
|
|
6d0b88e242 | ||
|
|
dbeee4707b | ||
|
|
ae8623e3af | ||
|
|
41da5af721 | ||
|
|
93d4a16017 | ||
|
|
6ef0116f09 | ||
|
|
76b5c68646 | ||
|
|
b6b4827680 | ||
|
|
a310cb2fbb | ||
|
|
67069beddc | ||
|
|
331fe92b9e | ||
|
|
f0d68a1a25 | ||
|
|
66309a3fea | ||
|
|
04185b05ab | ||
|
|
2047801b85 | ||
|
|
43992dc463 | ||
|
|
fac5d81790 | ||
|
|
b56633e1d6 | ||
|
|
1732ffed7a | ||
|
|
7d0c1bb737 | ||
|
|
c444e40c01 | ||
|
|
46cb45d94b | ||
|
|
4a5d1076ed | ||
|
|
4e6072fb29 | ||
|
|
f492f808f4 | ||
|
|
547ef772ab | ||
|
|
27cd26ec1e | ||
|
|
2216c3dd32 | ||
|
|
9e251a1abc | ||
|
|
45b42cbc1c | ||
|
|
c11ebd12d5 | ||
|
|
465d89129c | ||
|
|
0336082920 | ||
|
|
24da5d82db | ||
|
|
64809dd277 | ||
|
|
6ca3442ba3 | ||
|
|
27baf46eb5 | ||
|
|
d2dcb93866 | ||
|
|
d826515ba8 | ||
|
|
b221c68e4b | ||
|
|
fd81a4bdc4 | ||
|
|
b7fb78245a | ||
|
|
571a9642a5 | ||
|
|
9e2424ee76 | ||
|
|
6d2661a8f7 | ||
|
|
0f8d2d4e58 | ||
|
|
63107f5b2f | ||
|
|
a31331bfd9 | ||
|
|
07d33a1183 | ||
|
|
0dbb024c99 | ||
|
|
ba954b8cfe | ||
|
|
3fa809ae79 | ||
|
|
1a9c1ecfb1 | ||
|
|
c6b2652c01 | ||
|
|
5a9ea29614 | ||
|
|
6cc3294395 | ||
|
|
5f229d81e9 | ||
|
|
cb70192f36 | ||
|
|
2227de5f65 | ||
|
|
3dfafb710c | ||
|
|
9f5d44fa32 | ||
|
|
cd1e5d4171 | ||
|
|
beec49847f | ||
|
|
e4503f743e | ||
|
|
635c5e532b | ||
|
|
384cb215be | ||
|
|
9e64ce7da7 | ||
|
|
661c20e452 | ||
|
|
4c27fa5c37 | ||
|
|
6cf2e9945a | ||
|
|
b21a5c3ce9 | ||
|
|
5057a4bd4c | ||
|
|
3a0db39fa0 | ||
|
|
1d8d2c6e55 | ||
|
|
dc88ccdc0b | ||
|
|
b512780e37 | ||
|
|
91dda86a74 | ||
|
|
4171854e2f | ||
|
|
24a650d7ec | ||
|
|
cb042e32bc | ||
|
|
5e94187d03 | ||
|
|
cadd958339 | ||
|
|
b06c52553d | ||
|
|
b41c5f3497 | ||
|
|
930e1fdbdc | ||
|
|
f15fd93f90 | ||
|
|
6ad14f4ca0 | ||
|
|
9d55a254dc | ||
|
|
f9aecf5d4c | ||
|
|
c57b2d25b2 | ||
|
|
3cc756f302 | ||
|
|
3e7dffb676 | ||
|
|
d7ecaa8b23 | ||
|
|
512f3a7643 | ||
|
|
c1eb796cbd | ||
|
|
dd35cad62a | ||
|
|
5f972e00fe | ||
|
|
cc0cd0b292 | ||
|
|
c92bb6176a | ||
|
|
fffb95299e | ||
|
|
40cdb70b2f | ||
|
|
feae454481 | ||
|
|
71c2cc79e5 | ||
|
|
7ac4b47702 | ||
|
|
d24cf0b85b | ||
|
|
0e2c539d93 | ||
|
|
4f24cc7377 | ||
|
|
9bf83a57bd | ||
|
|
668f56807a | ||
|
|
8d479aa1c7 | ||
|
|
296117124c | ||
|
|
0d21c6f863 | ||
|
|
b787865fbb | ||
|
|
210c91398d | ||
|
|
7a377e72e7 | ||
|
|
c2abbe2c23 | ||
|
|
5f6f87a7cd | ||
|
|
e4eff6a32b | ||
|
|
c1e44c0f54 | ||
|
|
5cf2bf6b29 | ||
|
|
56d1614ea6 | ||
|
|
c3e365ef47 | ||
|
|
4bf0c9e36a | ||
|
|
509844fd7e | ||
|
|
fb111e6d95 | ||
|
|
e177462c90 | ||
|
|
82f19e6278 | ||
|
|
edf6ad9eda | ||
|
|
a86b260f73 | ||
|
|
21f464a557 | ||
|
|
423274b923 | ||
|
|
6c4054c20b | ||
|
|
69099a2732 | ||
|
|
4bd6cf5652 | ||
|
|
d99a51e5b7 | ||
|
|
843d631111 | ||
|
|
2e4e56f7cc | ||
|
|
bd0f63980b | ||
|
|
4eead1c688 | ||
|
|
d70c42b495 | ||
|
|
660079bd2a | ||
|
|
7c600b0380 | ||
|
|
e982698de1 | ||
|
|
4b7967b938 | ||
|
|
e3c7200b6f | ||
|
|
4656856dfb | ||
|
|
019dcefeca | ||
|
|
f7309b926b | ||
|
|
217c324a98 | ||
|
|
a0cfa769bd | ||
|
|
7df62589ac | ||
|
|
93259e4e92 | ||
|
|
f560a3c98f | ||
|
|
add9890754 | ||
|
|
503b2225f0 | ||
|
|
e3a6b0012e | ||
|
|
304085606f | ||
|
|
5d4110375a | ||
|
|
5902528bae | ||
|
|
1e8dcaffc9 | ||
|
|
4b7947d98c | ||
|
|
c034fab4da | ||
|
|
4cfd7b65fb | ||
|
|
5967360991 | ||
|
|
deede8e2dd | ||
|
|
f85c6d76de | ||
|
|
131baa9f45 | ||
|
|
629c915f36 | ||
|
|
c994f26dbd | ||
|
|
886a1a5381 | ||
|
|
d4c81d8e0e | ||
|
|
a4588af0f8 | ||
|
|
1709dbd376 | ||
|
|
9937fea2e7 | ||
|
|
d6fc85f460 | ||
|
|
db25f2024e | ||
|
|
395cf86607 | ||
|
|
4fb9989b4f | ||
|
|
40a8e50471 | ||
|
|
66e1e5b1b6 | ||
|
|
ecd161d678 | ||
|
|
e9f32ef94e | ||
|
|
2cf4381e19 | ||
|
|
0844fb8d8a | ||
|
|
764d6e3407 | ||
|
|
b2ab906483 | ||
|
|
6943960f99 | ||
|
|
858a6270d5 | ||
|
|
8a60bb4619 | ||
|
|
03d3cbdbf8 | ||
|
|
89aa882c95 | ||
|
|
0fba1bb868 | ||
|
|
fad381586c | ||
|
|
a0e1a8e0a2 | ||
|
|
a486c90686 | ||
|
|
53e353abf2 | ||
|
|
dd45d0a8b2 | ||
|
|
577da0eb9e | ||
|
|
eee037f7c2 | ||
|
|
23a20ba6a5 | ||
|
|
299b9e9014 | ||
|
|
21d081e175 | ||
|
|
8e475810a7 | ||
|
|
eb86ffefbf | ||
|
|
f1afb0ddfe | ||
|
|
561372e203 | ||
|
|
66f48847c9 | ||
|
|
62e3083f23 | ||
|
|
c331e585b8 | ||
|
|
05de59d4ad | ||
|
|
2de1285121 | ||
|
|
647a9b2740 | ||
|
|
e81949bb09 | ||
|
|
42878c40fc | ||
|
|
9aadcb0bd4 | ||
|
|
82306682c6 | ||
|
|
05f9f0a393 | ||
|
|
03f692f24f | ||
|
|
014a1f0158 | ||
|
|
746ea5a369 | ||
|
|
d868ebe4ba | ||
|
|
b49e09939a | ||
|
|
91db66b32d | ||
|
|
f0faa7f9b0 | ||
|
|
ef11b3eb2b | ||
|
|
3ab92ba9d9 | ||
|
|
949cce094e | ||
|
|
09abba3dd0 | ||
|
|
84105c3b05 | ||
|
|
a70db805b7 | ||
|
|
750e0a8d11 | ||
|
|
8970d30c93 | ||
|
|
75285fd452 | ||
|
|
76c8bbf7b8 | ||
|
|
eb3e43feec | ||
|
|
08bea83c03 | ||
|
|
8892568652 | ||
|
|
ce10a44e72 | ||
|
|
0f5bc00586 | ||
|
|
50ec3b300b | ||
|
|
2c5b6cf8dc | ||
|
|
f2ec84fb13 | ||
|
|
51d791d824 | ||
|
|
db08e2cea0 | ||
|
|
619f8f752b | ||
|
|
e8958b1fb8 | ||
|
|
07b67963f1 | ||
|
|
b0a491eaa8 | ||
|
|
be3bfa3806 | ||
|
|
47c14d3ca1 | ||
|
|
6a8c583220 | ||
|
|
468e976a88 | ||
|
|
25a63dc413 | ||
|
|
61e019e176 | ||
|
|
894b3706e7 | ||
|
|
e59237e680 | ||
|
|
b05c1c391c | ||
|
|
c09bab466a | ||
|
|
46cc360e4e | ||
|
|
d6ff8dc9b6 | ||
|
|
d0d72c7fd2 | ||
|
|
f0798f7833 | ||
|
|
3ce79dd6e1 | ||
|
|
ef7225b4f6 | ||
|
|
4f4d0e416e | ||
|
|
8fde0f01b8 | ||
|
|
757489beb7 | ||
|
|
906cbbe45d | ||
|
|
dfb75840b8 | ||
|
|
75804d7ce5 | ||
|
|
62f0266f46 | ||
|
|
7773ef0ff4 | ||
|
|
0600817ef7 | ||
|
|
2f5990962c | ||
|
|
214fa81ec6 | ||
|
|
81ae0fa252 | ||
|
|
fefc78a849 | ||
|
|
98fd311891 | ||
|
|
0d415fb3c9 | ||
|
|
ffe058d48f | ||
|
|
8d0cdf5c9a | ||
|
|
aa63c23839 | ||
|
|
57214fd659 | ||
|
|
5a2b17a1da | ||
|
|
0bb5f38ba5 | ||
|
|
6f21b3dc34 | ||
|
|
ae3067200b | ||
|
|
e13d7beac4 | ||
|
|
4562e1cc1c | ||
|
|
568cf2a9e4 | ||
|
|
67dd9c2930 | ||
|
|
e9c91a3ef3 | ||
|
|
4cde513523 | ||
|
|
c2ad28a000 | ||
|
|
f7ad5bbaad | ||
|
|
2a8c4bfbae | ||
|
|
c0f7b8879d | ||
|
|
3a347d7a56 | ||
|
|
c735503f7e | ||
|
|
b0f4929d41 | ||
|
|
10a1569c9a | ||
|
|
301e5383c7 | ||
|
|
66d0b4d0d5 | ||
|
|
94212766cc | ||
|
|
5b436d8fc3 | ||
|
|
cd2d1ff02a | ||
|
|
4ab4224277 | ||
|
|
b5b2e34da5 | ||
|
|
34d28e7ba9 | ||
|
|
ada578e7e3 | ||
|
|
f826c09abc | ||
|
|
3bd7133ba3 | ||
|
|
ce38350e00 | ||
|
|
45923f408f | ||
|
|
94e92bb4bf | ||
|
|
3fadedcc54 | ||
|
|
e095cb8113 | ||
|
|
1fcf59ff94 | ||
|
|
5cfb63da50 | ||
|
|
38646fe0e1 | ||
|
|
259f425050 | ||
|
|
e418a6b3d4 | ||
|
|
340d437ab2 | ||
|
|
34f576f540 | ||
|
|
64a97d42ff | ||
|
|
beb51040c2 | ||
|
|
8fc9d87b1b | ||
|
|
ab1dec813b | ||
|
|
4a71fb0831 | ||
|
|
5a8efc10d8 | ||
|
|
1aa9ce8fe5 | ||
|
|
32dfa4e868 | ||
|
|
b507ac1f98 | ||
|
|
601706b7b5 | ||
|
|
ef952a41b3 | ||
|
|
e7f6cd2cfa | ||
|
|
8e626a0142 | ||
|
|
9845272522 | ||
|
|
d4af870bb6 | ||
|
|
7b77e05f3a | ||
|
|
a284e1f9d8 | ||
|
|
89fbb86c7b | ||
|
|
8e4dea2334 | ||
|
|
8340d152e1 | ||
|
|
ec11ebbd54 | ||
|
|
f825e27f1a | ||
|
|
e7143a265a | ||
|
|
c087d1e18b | ||
|
|
51d9c37f6b | ||
|
|
057da80f2f | ||
|
|
edf804ea67 | ||
|
|
6f586ae11a | ||
|
|
22c89b6c66 | ||
|
|
cfae618c60 | ||
|
|
7766db40f5 | ||
|
|
9c72963d7c | ||
|
|
64fe15b6f5 | ||
|
|
18349efccc | ||
|
|
73766caa81 | ||
|
|
1c5630ef5a | ||
|
|
03d95ec089 | ||
|
|
09d84b5b68 | ||
|
|
d92ceed737 | ||
|
|
9d16666484 | ||
|
|
4ff533769a | ||
|
|
e3ce0496f5 | ||
|
|
8ef422a79b | ||
|
|
4a6e6ba1b2 | ||
|
|
bb4dcbe89e | ||
|
|
8a8c757327 | ||
|
|
8c75ace6ec | ||
|
|
8b3535bd0f | ||
|
|
28b2db93dc | ||
|
|
439d41b194 | ||
|
|
08a8f195e7 | ||
|
|
eb5dfcc9df | ||
|
|
a29c84b522 | ||
|
|
ab3b126ff6 | ||
|
|
fe960d7c28 | ||
|
|
07b628b667 | ||
|
|
fcb3674ce4 | ||
|
|
ad487ec9f7 | ||
|
|
7cfe4c0f01 | ||
|
|
77ffc385ab | ||
|
|
6a17da9b08 | ||
|
|
fca405741a | ||
|
|
715847bf74 | ||
|
|
78146d6417 | ||
|
|
59779f2a0e | ||
|
|
b1e191ce21 | ||
|
|
01289048a9 | ||
|
|
dc90f103d4 | ||
|
|
7181cf9012 | ||
|
|
d304821977 | ||
|
|
2f026b66a2 | ||
|
|
55f3198c9c | ||
|
|
48db3a189f | ||
|
|
08820fd655 | ||
|
|
a3d39b223d | ||
|
|
5c5fc0a62f | ||
|
|
66991a0778 | ||
|
|
26b92c8564 | ||
|
|
f965d9dc9e | ||
|
|
538845cbf5 | ||
|
|
684b572aa8 | ||
|
|
869126259b | ||
|
|
814dfcd4ac | ||
|
|
a61c72b3b2 | ||
|
|
48be6ad5c4 | ||
|
|
a07b5ba4dd | ||
|
|
412f177c56 | ||
|
|
fbc2bb02b4 | ||
|
|
861bd15c72 | ||
|
|
b8fcfc7698 | ||
|
|
494ce9b872 | ||
|
|
a984cd2b27 | ||
|
|
215d615fc3 | ||
|
|
7a7bfd9de7 | ||
|
|
d0956eb39d | ||
|
|
4d7acdd44d | ||
|
|
5b1ef760a0 | ||
|
|
4859e6e11a | ||
|
|
c2990964f0 | ||
|
|
d4bb6c17d1 | ||
|
|
fca1a7506e | ||
|
|
27bc5fa4b0 | ||
|
|
ad6cb63e07 | ||
|
|
adec67d5fa | ||
|
|
85b7c90637 | ||
|
|
e9ae51cfbc | ||
|
|
979c05b24d | ||
|
|
3dac1a8d4a | ||
|
|
d326e7a75c | ||
|
|
4c08d7c480 | ||
|
|
e5653945d3 | ||
|
|
ffaab27e77 | ||
|
|
9ba72a06b3 | ||
|
|
a604236d89 | ||
|
|
5024fe3e2d | ||
|
|
44cb68a356 | ||
|
|
157966eb11 | ||
|
|
b7ca2b41cc | ||
|
|
8451ee20c9 | ||
|
|
d4acf41192 | ||
|
|
24d256e253 | ||
|
|
cb39d9435d | ||
|
|
0a55d6d511 | ||
|
|
0305983360 | ||
|
|
11c703cb4b | ||
|
|
657ec75c3d | ||
|
|
a79b268438 | ||
|
|
5c12b56e87 | ||
|
|
11b03ca4d2 | ||
|
|
91e3c5c34e | ||
|
|
1c821640ce | ||
|
|
7ed80bf443 | ||
|
|
1c32c5fd2a | ||
|
|
ba547c2257 | ||
|
|
dae0107dd0 | ||
|
|
d5763ba476 | ||
|
|
95311ad07e | ||
|
|
8a8689c191 | ||
|
|
dd2c4c37ff | ||
|
|
0afdb3ed4d | ||
|
|
9a04b49585 | ||
|
|
dcad9ce26a | ||
|
|
3b6d7e3066 | ||
|
|
3d8de8cf0a | ||
|
|
19ec8488e0 | ||
|
|
0e8e0b48b3 | ||
|
|
cc0d53e695 | ||
|
|
cce2b08e6b | ||
|
|
ef4a0e5af5 | ||
|
|
a68e2999f1 | ||
|
|
fc5b688716 | ||
|
|
6b327f9f4c | ||
|
|
d59c1bb6bf | ||
|
|
6a4050cc93 | ||
|
|
5abcb8c978 | ||
|
|
aa7f6111a6 | ||
|
|
b1f82257e8 | ||
|
|
bc0f4b4fa5 | ||
|
|
e6a59ad36f | ||
|
|
e375224dfe | ||
|
|
f55ef7e728 | ||
|
|
bf1ec44186 | ||
|
|
e47c08ed72 | ||
|
|
e1a209a3da | ||
|
|
76703dee84 | ||
|
|
df45c13f62 | ||
|
|
3acc5b0508 | ||
|
|
455720ae93 | ||
|
|
8073be87da | ||
|
|
8d3bf59b7b | ||
|
|
d5c56c0f5d | ||
|
|
981631752a | ||
|
|
f3c0e212bf | ||
|
|
7092458945 | ||
|
|
56772e4807 | ||
|
|
3e7ab8e113 | ||
|
|
53fca8a248 | ||
|
|
1c712ce93e | ||
|
|
dc53573975 | ||
|
|
1ad1b74512 | ||
|
|
0e91810ed6 | ||
|
|
4471f580d7 | ||
|
|
063654373d | ||
|
|
ee929752e3 | ||
|
|
88ebfe6edb | ||
|
|
e1fdac3278 | ||
|
|
d65740311b | ||
|
|
55868ad02d | ||
|
|
014b629928 | ||
|
|
4bffa49add | ||
|
|
fe37b03757 | ||
|
|
4b2bd871b7 | ||
|
|
2108173e74 | ||
|
|
08900b730b | ||
|
|
9dd545f420 | ||
|
|
fda5231a71 | ||
|
|
b03545f899 | ||
|
|
e327b8cb9a | ||
|
|
64c81ed174 | ||
|
|
87eaa6d8e5 | ||
|
|
874cff1a87 | ||
|
|
3bb0efd2cb | ||
|
|
a99ebd42ec | ||
|
|
0cfe2ecd7b | ||
|
|
e5141dd91b | ||
|
|
14f1292743 | ||
|
|
c96f1dbbe2 | ||
|
|
8fcf16ee63 | ||
|
|
9936670f44 | ||
|
|
4fc8416c3c | ||
|
|
6c178d4485 | ||
|
|
8bd8af7d16 | ||
|
|
b4f8f4df7b | ||
|
|
98e2b2a60b | ||
|
|
eb69f6c346 | ||
|
|
2cb3ccbf14 | ||
|
|
6ac3fc4e07 | ||
|
|
fb1e3cba8b | ||
|
|
94d6461568 | ||
|
|
09f1e4bdfb | ||
|
|
8dceb8e3a7 | ||
|
|
d942818bd9 | ||
|
|
1acef2e242 | ||
|
|
e2814f5d80 | ||
|
|
542d9130b5 | ||
|
|
159d6469fd | ||
|
|
53445ba6bd | ||
|
|
1810edae93 | ||
|
|
7f9ab491f2 | ||
|
|
77190cca92 | ||
|
|
babe14410c | ||
|
|
d2e3e3003a | ||
|
|
56d981c8ef | ||
|
|
250d758d74 | ||
|
|
e32f9e0354 | ||
|
|
0325efeb35 | ||
|
|
9ab33f1e13 | ||
|
|
66c0ac591c | ||
|
|
6241967112 | ||
|
|
250d947667 | ||
|
|
6a49e3124e | ||
|
|
4cd0b745cb | ||
|
|
16f584608f | ||
|
|
88d0bf94d8 | ||
|
|
241a0829dc | ||
|
|
66a0b4790e | ||
|
|
46ab7ca786 | ||
|
|
3efe144fa0 | ||
|
|
744960d36d | ||
|
|
727b49c8ab | ||
|
|
0aa01740d1 | ||
|
|
1c75e71eb3 | ||
|
|
fbc57fa8e3 | ||
|
|
60fcb5f4f2 | ||
|
|
eb1e9edd33 | ||
|
|
6b6c2ccfa3 | ||
|
|
8a4ee0506c | ||
|
|
ee2ba21246 | ||
|
|
8e6ebd4f7b | ||
|
|
76af8fa754 | ||
|
|
601ebee969 | ||
|
|
becd5f1446 | ||
|
|
ab363e3132 | ||
|
|
7c655c8d61 | ||
|
|
7386fa57c8 | ||
|
|
3f2b7d756c | ||
|
|
cba602bf64 | ||
|
|
78c9f752af | ||
|
|
d13a6180be | ||
|
|
d479ed00e4 | ||
|
|
cf4588f16f | ||
|
|
67b6d41d57 | ||
|
|
601f1eb624 | ||
|
|
301b41eaa4 | ||
|
|
ed0d7890ab | ||
|
|
f50ae07560 | ||
|
|
8e53491867 | ||
|
|
d43542dd7a | ||
|
|
3c3c0ed342 | ||
|
|
8d9c47acdf | ||
|
|
9d69792e08 | ||
|
|
5b4aa71878 | ||
|
|
240db7b602 | ||
|
|
aff476d0d4 | ||
|
|
d5ff82bbe4 | ||
|
|
c8dbcf8a2a | ||
|
|
d893eb67b8 | ||
|
|
5dad444026 | ||
|
|
217a684e5f | ||
|
|
1ef558d7e6 | ||
|
|
7b6ddeb859 | ||
|
|
b12dc89bb1 | ||
|
|
a387868540 | ||
|
|
59caf141d1 | ||
|
|
1ac35dd047 | ||
|
|
458f2e748d | ||
|
|
b62dee4c90 | ||
|
|
6ea7ef43e0 | ||
|
|
3838472a8e | ||
|
|
064464a553 | ||
|
|
9bf366b7d4 | ||
|
|
4668f36ddd | ||
|
|
a68308b164 | ||
|
|
f7e3d0dbf6 | ||
|
|
bd3bc503ed | ||
|
|
e2eb36ded6 | ||
|
|
4ac3cec66e | ||
|
|
823729d2c1 | ||
|
|
34b38f06e0 | ||
|
|
0fef599341 | ||
|
|
124e08efde | ||
|
|
66338a5757 | ||
|
|
ebee3e208c | ||
|
|
f8cf68ab53 | ||
|
|
28c85cf3ae | ||
|
|
cf4e2b2953 | ||
|
|
f3d3ec5744 | ||
|
|
29829eb011 | ||
|
|
129e6bddde | ||
|
|
8260817cf7 | ||
|
|
47d15f3bf4 | ||
|
|
96d439bcee | ||
|
|
47fab97210 | ||
|
|
5dec3ff18e | ||
|
|
bd3e5156c4 | ||
|
|
fccc1da666 | ||
|
|
55995b0494 | ||
|
|
eb17598254 | ||
|
|
0d512dffc3 | ||
|
|
988028577b | ||
|
|
6cf3ebb7db | ||
|
|
c571ca40d7 | ||
|
|
3a17225546 | ||
|
|
5e541ff53b | ||
|
|
9b19e40a74 | ||
|
|
71a30cd9a5 | ||
|
|
766a7fb1b4 | ||
|
|
40a7446e3e | ||
|
|
fc96cd3710 | ||
|
|
40c625158f | ||
|
|
7dad842f35 | ||
|
|
909f67fb3a | ||
|
|
ef27a1ce6c | ||
|
|
75471ba10f | ||
|
|
e7d20efb1b | ||
|
|
a8d527f1cd | ||
|
|
e5f3296c6b | ||
|
|
9d584fc720 | ||
|
|
92e0c502f7 | ||
|
|
b5d4acf10a | ||
|
|
47fbdda409 | ||
|
|
1bb6dfc9a0 | ||
|
|
549866c090 | ||
|
|
7b69dc574b | ||
|
|
5e47b767ea | ||
|
|
5376a734d4 | ||
|
|
3f1a4b6559 | ||
|
|
11a7a08b9d | ||
|
|
d16bbfb224 | ||
|
|
48959d5606 | ||
|
|
94e548b07a | ||
|
|
4be48b8d8b | ||
|
|
9cd715bbbf | ||
|
|
04d66ba7f4 | ||
|
|
7efcb3c75f | ||
|
|
359bfb76f6 | ||
|
|
0e1c628066 | ||
|
|
65bc146afa | ||
|
|
7ef641e256 | ||
|
|
9630d2ef2c | ||
|
|
6e9d5a03c2 | ||
|
|
839c154869 | ||
|
|
6995d54a3c | ||
|
|
d31df715fb | ||
|
|
26fa091aa2 | ||
|
|
cfbeb1655d | ||
|
|
39c194c5c3 | ||
|
|
9dfb471c0b | ||
|
|
f51a7225c8 | ||
|
|
1d903655af | ||
|
|
9abb061e71 | ||
|
|
6e48c36519 | ||
|
|
d450fc61c4 | ||
|
|
a899ce1c22 | ||
|
|
1a737be2b4 | ||
|
|
fae9c23637 | ||
|
|
1159dd59ed | ||
|
|
0ce7358f0f | ||
|
|
41749f5eda | ||
|
|
1567b7b383 | ||
|
|
e70bd0054c | ||
|
|
b450b6a435 | ||
|
|
0403738981 | ||
|
|
0d7062ffdf | ||
|
|
8f59b2d3e0 | ||
|
|
1b290f573a | ||
|
|
b77169f1d8 | ||
|
|
00d8783e45 | ||
|
|
cf5beafcfd | ||
|
|
cdaf5f3fc0 | ||
|
|
bdf50a824e | ||
|
|
f23c8e7597 | ||
|
|
52657b6215 | ||
|
|
28cd2759d7 | ||
|
|
12f33d2cd4 | ||
|
|
11cdc36bcc | ||
|
|
22d45a8d1e | ||
|
|
7d9d1e0cdb | ||
|
|
98b53801e0 | ||
|
|
bff1e215cc | ||
|
|
6efef3922b | ||
|
|
caec565de5 | ||
|
|
16a2bfa95b | ||
|
|
60da235efb | ||
|
|
71e0e55b0b | ||
|
|
b28ff509b1 | ||
|
|
8467ecb1d7 | ||
|
|
1f47f4ff96 | ||
|
|
4fef29e61c | ||
|
|
56c3d5dbcb | ||
|
|
ceed0f7a1b | ||
|
|
906d91d4d1 | ||
|
|
e539a9e7bd | ||
|
|
1be98d7b7f | ||
|
|
66832c41e9 | ||
|
|
8e4c5db766 | ||
|
|
1dc3253d4a | ||
|
|
feebe7d4c6 | ||
|
|
9a8071e014 | ||
|
|
9ce817bb6e | ||
|
|
fe2a937cf2 | ||
|
|
1cf90dd14d | ||
|
|
6823f0aa52 | ||
|
|
f2efa8c753 | ||
|
|
e5cfb8a0cd | ||
|
|
4a3149d1ba | ||
|
|
dafe0a5547 | ||
|
|
fe5f1e4d67 | ||
|
|
5cf06a679c | ||
|
|
859195d07a | ||
|
|
344aa13c64 | ||
|
|
69b22e3f79 | ||
|
|
a782c9944c | ||
|
|
39055c919c | ||
|
|
bc890d3038 | ||
|
|
e424ae0473 | ||
|
|
780abe7dd4 | ||
|
|
a3fc9e3742 | ||
|
|
325cbfcdb3 | ||
|
|
69e7a7594a | ||
|
|
c489f734db | ||
|
|
60a54e9aac | ||
|
|
280baf7c82 | ||
|
|
a23f8b6231 | ||
|
|
ccc8ff107e | ||
|
|
59a9f6bf02 | ||
|
|
2aff3a1a05 | ||
|
|
25988ddefa | ||
|
|
c99962106d | ||
|
|
52c1f79f2e | ||
|
|
2c07a92ad7 | ||
|
|
e67ff5c122 | ||
|
|
37b7b2f1a8 | ||
|
|
fd5764e166 | ||
|
|
c49eec71f0 | ||
|
|
812d904c98 | ||
|
|
a4fdf3fbbb | ||
|
|
9090bfd1c3 | ||
|
|
8c57ed64d0 | ||
|
|
b58bf75f21 | ||
|
|
189a15fe37 | ||
|
|
c7d9a5ac91 | ||
|
|
d0bc81f8d2 | ||
|
|
0dc777bc45 | ||
|
|
4f39119e37 | ||
|
|
8aa4af372d | ||
|
|
d5e90d678a | ||
|
|
0061ac8584 | ||
|
|
f648809856 | ||
|
|
687114b407 | ||
|
|
40f805c94a | ||
|
|
9751d03a4d | ||
|
|
36678d1b90 | ||
|
|
8f465e3097 | ||
|
|
c80f4feb62 | ||
|
|
2d06e86b5b | ||
|
|
400441d56b | ||
|
|
7d92e9026e | ||
|
|
42416aad22 | ||
|
|
9d51318c53 | ||
|
|
cdb1bc9be6 | ||
|
|
52183f8bf8 | ||
|
|
00dc7c916d | ||
|
|
5fd6e36be7 | ||
|
|
c2714262b3 | ||
|
|
a58f386831 | ||
|
|
e61b44ddbb | ||
|
|
f3c374b6ff | ||
|
|
21b2c0afa3 | ||
|
|
ca4c725d57 | ||
|
|
fe1aa90304 | ||
|
|
656ec585b2 | ||
|
|
64a49eb54a | ||
|
|
b106b53d05 | ||
|
|
a791809a84 | ||
|
|
71c3a0a197 | ||
|
|
9497c6c0f7 | ||
|
|
18279234fd | ||
|
|
4dd05dc4e8 | ||
|
|
cf7481da53 | ||
|
|
b8a9390f49 | ||
|
|
61c86212b9 | ||
|
|
a33562144b | ||
|
|
9b94ad2ffe | ||
|
|
70b39e829b | ||
|
|
29a29f277e | ||
|
|
e5f1bcacc8 | ||
|
|
ccbc532c1a | ||
|
|
e6c166a182 | ||
|
|
26bd532bc5 | ||
|
|
c89b2ac3b7 | ||
|
|
6acd96fd33 | ||
|
|
a652e546cc | ||
|
|
ee307729fc | ||
|
|
48d2b3afa8 | ||
|
|
491856fa79 | ||
|
|
56a675f713 | ||
|
|
05c8d4819d | ||
|
|
c8d5390512 | ||
|
|
f3cf708c85 | ||
|
|
24d1d752fe | ||
|
|
ba55400f14 | ||
|
|
0c5918f290 | ||
|
|
0216dc733d | ||
|
|
ff8ee6fb22 | ||
|
|
1a7ccc462b | ||
|
|
769da564e2 | ||
|
|
09b4660c7d | ||
|
|
69394c1680 | ||
|
|
4203d43c58 | ||
|
|
f273815d8f | ||
|
|
6a2c5e0731 | ||
|
|
07ae431950 | ||
|
|
0c4a1fb9be | ||
|
|
e6f1fb3d95 | ||
|
|
030d703a05 | ||
|
|
edc262f5af | ||
|
|
41cf846ee3 | ||
|
|
335536bbbf | ||
|
|
89aa9a80c4 | ||
|
|
d636ff586d | ||
|
|
8797049144 | ||
|
|
623dfa1384 | ||
|
|
cc1ffff7cd | ||
|
|
5698462588 | ||
|
|
f99c007187 | ||
|
|
54a0690323 | ||
|
|
23812e5b48 | ||
|
|
c37908f344 | ||
|
|
4011dd18f0 | ||
|
|
52b1ea10a1 | ||
|
|
09009d4b32 | ||
|
|
ec173e7eb2 | ||
|
|
bcf4cb519a | ||
|
|
27bc8294ae | ||
|
|
5cc6c6c1e9 | ||
|
|
991db280be | ||
|
|
6f709a6f57 | ||
|
|
71c206fdb9 | ||
|
|
4c0e8a61ae | ||
|
|
dc2c6d00fe | ||
|
|
e7c8012794 | ||
|
|
9bd30eb8bf | ||
|
|
b883b9c983 | ||
|
|
5468ebbb43 | ||
|
|
27f8320353 | ||
|
|
e15307747f | ||
|
|
f427b4a325 | ||
|
|
a6835f4e71 | ||
|
|
052ed1f88b | ||
|
|
34a0ec4089 | ||
|
|
2ed77b5986 | ||
|
|
d70e6f273b | ||
|
|
d2e22d8c2f | ||
|
|
7c501ef60f | ||
|
|
a0eb628526 | ||
|
|
0ddc3e4af2 | ||
|
|
5be9477f21 | ||
|
|
4ab21edba8 | ||
|
|
2862baeee1 | ||
|
|
15b9a67c01 | ||
|
|
80ca99fe5b | ||
|
|
6f88d5e92b | ||
|
|
295ed07d40 | ||
|
|
d6b1eff70e | ||
|
|
7fb02752de | ||
|
|
d88d4b3c3a | ||
|
|
58155864cb | ||
|
|
9cf9217686 | ||
|
|
fa93114804 | ||
|
|
66511d8f07 | ||
|
|
f52e5d90b0 | ||
|
|
f571b753b6 | ||
|
|
40e747ecde | ||
|
|
9e24b28376 | ||
|
|
5abdee73ee | ||
|
|
2feb6795b0 | ||
|
|
c200808fbb | ||
|
|
1f8b705a6a | ||
|
|
a3c2ef4084 | ||
|
|
9dcbef4cb1 | ||
|
|
8bd4e004ff | ||
|
|
47b2959486 | ||
|
|
f70d27b793 | ||
|
|
7c845aafa2 | ||
|
|
16b57a2b28 | ||
|
|
89457c8390 | ||
|
|
ea4d1b5101 | ||
|
|
dd38fad9ee | ||
|
|
c61853ff0b | ||
|
|
bdecb61bfa | ||
|
|
c9231785ab | ||
|
|
f79d5ec18e | ||
|
|
98e0534984 | ||
|
|
617f2863c4 | ||
|
|
0f36916fb4 | ||
|
|
1fd2b6f5b6 | ||
|
|
7d386c2777 | ||
|
|
fb60eeaa9a | ||
|
|
9625d940a5 | ||
|
|
b8a0bc0b0b | ||
|
|
cee41bb1e5 | ||
|
|
4a270d10d1 | ||
|
|
ea5262a0df | ||
|
|
86e888e5eb | ||
|
|
9d7a88b40d | ||
|
|
be8061b64b | ||
|
|
d91a82430a | ||
|
|
b9664f6980 | ||
|
|
66334374af | ||
|
|
741af8c164 | ||
|
|
137f5b3dbc | ||
|
|
e1cd51d8d9 | ||
|
|
237aca32e3 | ||
|
|
906a810735 | ||
|
|
808605cd65 | ||
|
|
06a674775e | ||
|
|
b195407028 | ||
|
|
1650d79862 | ||
|
|
e8a888caab | ||
|
|
3648f9952c | ||
|
|
8b7ab90836 | ||
|
|
866dc9a9b3 | ||
|
|
0e76cec28f | ||
|
|
2988e33b57 | ||
|
|
aef239f421 | ||
|
|
3456c192fe | ||
|
|
ae5a1362a7 | ||
|
|
fefc2290a1 | ||
|
|
6bd35ef740 | ||
|
|
b772a5f564 | ||
|
|
234e9476fb | ||
|
|
a7d339be5a | ||
|
|
b745a143c3 | ||
|
|
6e9e267b27 | ||
|
|
2e9336beb5 | ||
|
|
5951fa56ae | ||
|
|
4372e1fcda | ||
|
|
24a9c3ba79 | ||
|
|
c4261b9c4b | ||
|
|
7b060dff68 | ||
|
|
90f759412b | ||
|
|
15691d3ced | ||
|
|
6f2dd5d325 | ||
|
|
9e46472ca2 | ||
|
|
61d9b34929 | ||
|
|
00fe4e747f | ||
|
|
b0cdec0c35 | ||
|
|
373af6d4f4 | ||
|
|
4ae503bef7 | ||
|
|
72a19a14af | ||
|
|
a7d0c45606 | ||
|
|
dbc0cc8c92 | ||
|
|
a1be6f11ed | ||
|
|
143e389695 | ||
|
|
962a3f7945 | ||
|
|
bced63e823 | ||
|
|
51e40add66 | ||
|
|
4500faf463 | ||
|
|
66fb0fdcd7 | ||
|
|
105e7626fc | ||
|
|
c6bcea0f82 | ||
|
|
4fbebe7b2d | ||
|
|
e812836a60 | ||
|
|
d11d36040d | ||
|
|
c3b3f41a21 | ||
|
|
46daaa11fd | ||
|
|
cca2b1621f | ||
|
|
807776cb15 | ||
|
|
9914e171b1 | ||
|
|
b3c805d7d0 | ||
|
|
d31c91c9d3 | ||
|
|
bf252d2388 | ||
|
|
5c379b4d35 | ||
|
|
4d3b0577c9 | ||
|
|
d37e6b9271 | ||
|
|
654139933f | ||
|
|
1d9e0f17a6 | ||
|
|
9120a82ab4 | ||
|
|
ca24bfdc46 | ||
|
|
aaa83ae5d2 | ||
|
|
8123a62302 | ||
|
|
e84281b620 | ||
|
|
6239a27288 | ||
|
|
0b272264ea | ||
|
|
d5ffa5508d | ||
|
|
991db80646 | ||
|
|
cb3fb0049f | ||
|
|
eef1fcbb07 | ||
|
|
186dd9dee0 | ||
|
|
373651c3db | ||
|
|
663802e699 | ||
|
|
4c5722c766 | ||
|
|
6734854776 | ||
|
|
1c0ece8411 | ||
|
|
cf120b2351 | ||
|
|
6481722fd9 | ||
|
|
b1876ac14f | ||
|
|
d7ec6865b4 | ||
|
|
46b6415f5f | ||
|
|
5aa0fe2bf0 | ||
|
|
f43f38c054 | ||
|
|
235ba81f25 | ||
|
|
55aaabc2f1 | ||
|
|
5be132f877 | ||
|
|
b5966041be | ||
|
|
62d6bada4c | ||
|
|
e8e61c83d5 | ||
|
|
13788af908 | ||
|
|
d5bd5cda97 | ||
|
|
29b0ed87d6 | ||
|
|
0e6d84e207 | ||
|
|
796228b7ad | ||
|
|
7489a4442e | ||
|
|
5e99295bf6 | ||
|
|
4ff89a5862 | ||
|
|
87ca60b0b1 | ||
|
|
525d554a35 | ||
|
|
4c121aff30 | ||
|
|
d77872de50 | ||
|
|
91ed3b357d | ||
|
|
d4e53bb86f | ||
|
|
471449f539 | ||
|
|
187fc9a51b | ||
|
|
abbf245d14 | ||
|
|
20ae69ab7b | ||
|
|
67024c023a | ||
|
|
2f76d63835 | ||
|
|
754329097f | ||
|
|
c5950c0370 | ||
|
|
e2e7bee3cc | ||
|
|
edada2b786 | ||
|
|
ccc9cc8202 | ||
|
|
84c86f01c8 | ||
|
|
9b542c5bcf | ||
|
|
108bb7649b | ||
|
|
1104e2652f | ||
|
|
f2dc55244c | ||
|
|
048a8c5f44 | ||
|
|
1fbb1e6c2a | ||
|
|
7e9162ef06 | ||
|
|
f09fe8da78 | ||
|
|
4d794103be | ||
|
|
61f339a874 | ||
|
|
7b3aa92b5a | ||
|
|
27e9b5618b | ||
|
|
4d1f5c1752 | ||
|
|
23e774db8e | ||
|
|
4190a40de8 | ||
|
|
6143f49042 | ||
|
|
607c414634 | ||
|
|
d65007b230 | ||
|
|
41e0d5f664 | ||
|
|
fa7a6203fb | ||
|
|
5877e28d72 | ||
|
|
318643cf9a | ||
|
|
ab9b82e778 | ||
|
|
fee65f0c69 | ||
|
|
643f515eaf | ||
|
|
1305584d77 | ||
|
|
0a7364d494 | ||
|
|
2cce599fd7 | ||
|
|
7dc99cb4a4 | ||
|
|
45eb61bcf0 | ||
|
|
80400d7191 | ||
|
|
9ca7cc565b | ||
|
|
6147f819ce | ||
|
|
842a041a88 | ||
|
|
68a91ec3ea | ||
|
|
d58f965b9a | ||
|
|
83d0e48ebe | ||
|
|
ca58ef80ae | ||
|
|
0956dcadd3 | ||
|
|
304c393f38 | ||
|
|
05654e4980 | ||
|
|
c8000fca1f | ||
|
|
48547f5f9e | ||
|
|
b4f8136315 | ||
|
|
06f1910ac0 | ||
|
|
03b31932d1 | ||
|
|
e4b0e31a28 | ||
|
|
ba4f75ba19 | ||
|
|
fc62f07a08 | ||
|
|
3d0a7f4fc5 | ||
|
|
47ef41695a | ||
|
|
4adf2caaa6 | ||
|
|
db82d303e2 | ||
|
|
0fac35686b | ||
|
|
5ae2d15dc0 | ||
|
|
dc18440c18 | ||
|
|
499b7de0d2 | ||
|
|
1a0cf2666a | ||
|
|
7bff60edac | ||
|
|
e935473c5c | ||
|
|
3af3b36db3 | ||
|
|
9333503600 | ||
|
|
7a42aed1f6 | ||
|
|
5bffae6219 | ||
|
|
ae8cdc3b42 | ||
|
|
b413beeb36 | ||
|
|
0cf5536e90 | ||
|
|
5e767144c9 | ||
|
|
6d87311394 | ||
|
|
0ee2378cec | ||
|
|
28d6b9ce16 | ||
|
|
f3c0db0f39 | ||
|
|
3a52af6327 | ||
|
|
aec92e0e17 | ||
|
|
c364bff0c1 | ||
|
|
74f55d1504 | ||
|
|
f436ec6f21 | ||
|
|
be097bf415 | ||
|
|
f1b014b7eb | ||
|
|
ad637b5b50 | ||
|
|
5abc9ef10b | ||
|
|
d47df8663f | ||
|
|
77267e049a | ||
|
|
e2b6464f83 | ||
|
|
973f15438a | ||
|
|
1f42d23332 | ||
|
|
b80f0b8960 | ||
|
|
06be21af05 | ||
|
|
ab5e7ad7a2 | ||
|
|
0d3c378e10 | ||
|
|
471031390c | ||
|
|
8517e7e798 | ||
|
|
e70bf97508 | ||
|
|
6385d11b54 | ||
|
|
d0d0a2df3a | ||
|
|
99ca2a7cc6 | ||
|
|
acacea5efe | ||
|
|
187f19b170 | ||
|
|
49b38bd71b | ||
|
|
75f3e9202e | ||
|
|
0098dce597 | ||
|
|
cff5e360fd | ||
|
|
45c033b9aa | ||
|
|
5c92337821 | ||
|
|
341386a95b | ||
|
|
bd84a3ee08 | ||
|
|
383b7928cf | ||
|
|
9cb856d5fd | ||
|
|
2d5768b71c | ||
|
|
90ec3340e4 | ||
|
|
cf2609530f | ||
|
|
cdccf60132 | ||
|
|
df2725a360 | ||
|
|
592cf893c0 | ||
|
|
85f24c292f | ||
|
|
1c4629f5e1 | ||
|
|
af8ed605f8 | ||
|
|
186f85483f | ||
|
|
e157e3bec8 | ||
|
|
4450170790 | ||
|
|
66b032823b | ||
|
|
c9745a4129 | ||
|
|
bf7b0b11ef | ||
|
|
e778815605 | ||
|
|
f2e802229a | ||
|
|
64cf36a2b5 | ||
|
|
8873fbfee9 | ||
|
|
89df4551aa | ||
|
|
ecfc7b8f4c | ||
|
|
3b68df1be6 | ||
|
|
9518dc0e4e | ||
|
|
e084b776ee | ||
|
|
6c38857502 | ||
|
|
41ff8fdd37 | ||
|
|
182f94a9ac | ||
|
|
92077725c3 | ||
|
|
9f37dbc6dc | ||
|
|
33528c616a | ||
|
|
894f0156af | ||
|
|
9d5b6858ea | ||
|
|
7a405da3b7 | ||
|
|
49cc952825 | ||
|
|
31e62bd19e | ||
|
|
52c6ea5115 | ||
|
|
f15d96bebe | ||
|
|
18c57eeaa0 | ||
|
|
2b898537d7 | ||
|
|
081bff605a | ||
|
|
8a5c23fd50 | ||
|
|
830f1bcd50 | ||
|
|
17e81095b3 | ||
|
|
ed71afa6c7 | ||
|
|
4cafa6280d | ||
|
|
b488034352 | ||
|
|
944cd883bb | ||
|
|
f9dd4188b4 | ||
|
|
557aa18526 | ||
|
|
b18f3f4f7a | ||
|
|
4111ba8dee | ||
|
|
035449e4a3 | ||
|
|
2a2abf14bb | ||
|
|
b553ecbb18 | ||
|
|
d87a270e2c | ||
|
|
3443416540 | ||
|
|
f2589cc820 | ||
|
|
691fadc93d | ||
|
|
65a320c509 | ||
|
|
b0f2c22000 | ||
|
|
ef8a251115 | ||
|
|
4a7384bc0c | ||
|
|
90bc21f2d5 | ||
|
|
1c5629263b | ||
|
|
6adfbabbb7 | ||
|
|
2a48222393 | ||
|
|
4addde782e | ||
|
|
9b87940ed2 | ||
|
|
8000d6b5d4 | ||
|
|
e9679d251c | ||
|
|
68f6043d44 | ||
|
|
f560a88ff3 | ||
|
|
4b0d0df781 | ||
|
|
05453ce493 | ||
|
|
af7ea07b43 | ||
|
|
289161aad1 | ||
|
|
6a3919587f | ||
|
|
80e7337984 | ||
|
|
6cea5ddfad | ||
|
|
ba08555efc | ||
|
|
f99b62b516 | ||
|
|
2f45182b48 | ||
|
|
9da1439a4d | ||
|
|
57602647ef | ||
|
|
4848dc5ec8 | ||
|
|
8b5a190d71 | ||
|
|
a4804ff977 | ||
|
|
998bd585bb | ||
|
|
0123a28186 | ||
|
|
ff1d900ccb | ||
|
|
1808ffcdf2 | ||
|
|
86c4743ed9 | ||
|
|
1408e3da3b | ||
|
|
5f6eedcc1a | ||
|
|
7cec3f4dbf | ||
|
|
80ff7fa353 | ||
|
|
7892ed9e77 | ||
|
|
0e3b5536e2 | ||
|
|
6c55e44f4c | ||
|
|
5b88e9574f | ||
|
|
ecfb608518 | ||
|
|
9411732c1b | ||
|
|
acb8eeb853 | ||
|
|
d1c7e78990 | ||
|
|
0a96cdd950 | ||
|
|
5686901869 | ||
|
|
6531cbd1d2 | ||
|
|
09da109eba | ||
|
|
fa2de77abe | ||
|
|
8ab3a4ebd7 | ||
|
|
8eb6dafe31 | ||
|
|
ca11d7b9a7 | ||
|
|
a7a73a5150 | ||
|
|
83b5bbfeea | ||
|
|
59108b18ae | ||
|
|
037e1edb1f | ||
|
|
c00796d553 | ||
|
|
23f9f8bc3b | ||
|
|
88a4889780 | ||
|
|
bac297cf31 | ||
|
|
3c73228d80 | ||
|
|
0085b64b2b | ||
|
|
1c0c01ccfe | ||
|
|
b0d1fa09c1 | ||
|
|
68b32cd8f4 | ||
|
|
d5dcaacf2c | ||
|
|
03ca0bfa69 | ||
|
|
3aa22c29fd | ||
|
|
06a211704f | ||
|
|
913046aa28 | ||
|
|
b4707705f1 | ||
|
|
a618f70f56 | ||
|
|
05444f92f9 | ||
|
|
9566eab934 | ||
|
|
d704832ff6 | ||
|
|
3c1dff3039 | ||
|
|
4edf580ebf | ||
|
|
7b177be271 | ||
|
|
d183e47dc9 | ||
|
|
dc7c3f70eb | ||
|
|
d06ce6294d | ||
|
|
21ee29e46d | ||
|
|
bee09a6d8b | ||
|
|
a100c47f11 | ||
|
|
ba62f14482 | ||
|
|
2a34a497d5 | ||
|
|
4ea4a036ef | ||
|
|
2dbf8a5e00 | ||
|
|
9359f9fe4d | ||
|
|
01526a9a79 | ||
|
|
01fc590938 | ||
|
|
6e9fb9b9fd | ||
|
|
a97b09210e | ||
|
|
acddf5aa8d | ||
|
|
6614d465d6 | ||
|
|
2ba2187c2e | ||
|
|
2ea482d163 | ||
|
|
599b395e24 | ||
|
|
1416b81877 | ||
|
|
aa766b53d6 | ||
|
|
4e2a050afb | ||
|
|
cf437c6a33 | ||
|
|
8b6a24c67d | ||
|
|
a72b549aa7 | ||
|
|
46d8cf3f94 | ||
|
|
91d19a3326 | ||
|
|
a510c91d48 | ||
|
|
2f8c5cf7d0 | ||
|
|
1f2482f6ab | ||
|
|
9476c631b0 | ||
|
|
10e459140b | ||
|
|
b66cd8363e | ||
|
|
376b05bcc9 | ||
|
|
a4a99d2d46 | ||
|
|
2fcbbfe3d4 | ||
|
|
2095937c60 | ||
|
|
d33974cec4 | ||
|
|
9ec995dbf0 | ||
|
|
79a806f328 | ||
|
|
445fa6825a | ||
|
|
e3c8e4f483 | ||
|
|
8f3a99ad1f | ||
|
|
a3fef34a3f | ||
|
|
17618be14d | ||
|
|
3faca10efc | ||
|
|
280f52f007 | ||
|
|
126e06b32a | ||
|
|
988371be0b | ||
|
|
b4efe8ad8d | ||
|
|
964a02d684 | ||
|
|
40effa4417 | ||
|
|
35c05a3180 | ||
|
|
4a071b9a1c | ||
|
|
ead80481b9 | ||
|
|
297057d2bd | ||
|
|
11cdd0033d | ||
|
|
06bd540cfa | ||
|
|
3451fe2d40 | ||
|
|
2ee0f769d9 | ||
|
|
8161ec88e5 | ||
|
|
7b992decd4 | ||
|
|
9b9fe39839 | ||
|
|
1f57a59618 | ||
|
|
5a1b850dd6 | ||
|
|
c4e0e20eb3 | ||
|
|
eedee6d0a1 | ||
|
|
e316494e06 | ||
|
|
4585e35b3e | ||
|
|
9717d4502f | ||
|
|
f9b342c87d | ||
|
|
222113ee57 | ||
|
|
5f7b2e7c17 | ||
|
|
179478a940 | ||
|
|
53570de5a3 | ||
|
|
41a6300d3c | ||
|
|
1376e59d00 | ||
|
|
d623228cf6 | ||
|
|
75d63684b8 | ||
|
|
d3d184192d | ||
|
|
9be4c4d6d1 | ||
|
|
d3a5911932 | ||
|
|
dbbae4bac8 | ||
|
|
9132b9c026 | ||
|
|
769f697ae3 | ||
|
|
7d891a54e7 | ||
|
|
e71cdf02a8 | ||
|
|
7d82b5f28d | ||
|
|
eec2871680 | ||
|
|
029cf6395d | ||
|
|
08f15a6fc6 | ||
|
|
c24cfbc62a | ||
|
|
caf077cbf8 | ||
|
|
5cc8837fb6 | ||
|
|
ddecbf052e | ||
|
|
6a7fa6bf54 | ||
|
|
5ed4ed2246 | ||
|
|
72ed290ccd | ||
|
|
16067db718 | ||
|
|
363d872326 | ||
|
|
f4a4d70149 | ||
|
|
4335e49381 | ||
|
|
992f8272d3 | ||
|
|
27678a523c | ||
|
|
1bdcfe5219 | ||
|
|
89d21c0873 | ||
|
|
23e2b3be09 | ||
|
|
a346399fe6 | ||
|
|
8e5c56dcc2 | ||
|
|
77b58ec02f | ||
|
|
ceeb9836b9 | ||
|
|
df7f0eb9a4 | ||
|
|
6103c30184 | ||
|
|
b52a968c74 | ||
|
|
82aa87c190 | ||
|
|
1af844e474 | ||
|
|
c664a4bdcd | ||
|
|
229f95d555 | ||
|
|
ac6ebeee47 | ||
|
|
8896ebf7cb | ||
|
|
9bd11afc62 | ||
|
|
08c0d78296 | ||
|
|
9daa3b85c8 | ||
|
|
d8c93c0d13 | ||
|
|
42abc2201c | ||
|
|
27257de995 | ||
|
|
15e836b7dd | ||
|
|
0d062251b6 | ||
|
|
ecb1515e5d | ||
|
|
4728e72d18 | ||
|
|
c352047228 | ||
|
|
1aedf22228 | ||
|
|
5408264559 | ||
|
|
b7d92d3a09 | ||
|
|
bd17dc52f2 | ||
|
|
e6315d252a | ||
|
|
ce3be598bb | ||
|
|
e891199a23 | ||
|
|
b1d4e97699 | ||
|
|
16dcaaa3a8 | ||
|
|
fd5c92822c | ||
|
|
77f71303f2 | ||
|
|
266dab1b59 | ||
|
|
2d119c81a4 | ||
|
|
88bb61018d | ||
|
|
c940d8d7ca | ||
|
|
aa70cbbf21 | ||
|
|
6db717a1a0 | ||
|
|
ad9990e100 | ||
|
|
403e90861c | ||
|
|
2d63bbb91e | ||
|
|
271ed82d0d | ||
|
|
c47439fca4 | ||
|
|
e3734328eb | ||
|
|
ddc454bd82 | ||
|
|
799d4ad549 | ||
|
|
8dcdcd55e5 | ||
|
|
1fca442828 | ||
|
|
d077f15270 | ||
|
|
31d1a72854 | ||
|
|
f9a989fe1b | ||
|
|
46e079beea | ||
|
|
4048cb67d2 | ||
|
|
b16e4c558f | ||
|
|
2d6e87fb17 | ||
|
|
024d2737d0 | ||
|
|
b2e5b6c977 | ||
|
|
75f058e15e | ||
|
|
7fb849ab87 | ||
|
|
fca8e0aa6a | ||
|
|
8dd9ab05a9 | ||
|
|
c3b93de099 | ||
|
|
27c8c74988 | ||
|
|
80352dab5f | ||
|
|
00a49b42e4 | ||
|
|
f5735fb67b | ||
|
|
fb5b588349 | ||
|
|
9e497cde40 | ||
|
|
f3816836e5 | ||
|
|
038c928b9b | ||
|
|
c596248f40 | ||
|
|
6ae3a92f53 | ||
|
|
fbf868e976 | ||
|
|
5e0bb6ecd5 | ||
|
|
a34d8773f1 | ||
|
|
4bc94c0ee9 | ||
|
|
bf1a21e46f | ||
|
|
d18427a522 | ||
|
|
76850a7340 | ||
|
|
d096106824 | ||
|
|
562124c29f | ||
|
|
48063fa5ef | ||
|
|
41111bcdad | ||
|
|
133292e241 | ||
|
|
64cad0a041 | ||
|
|
b73c844d1a | ||
|
|
da1b10b741 | ||
|
|
c7b4a53af2 | ||
|
|
024809f970 | ||
|
|
126af3a24a | ||
|
|
b91d95d241 | ||
|
|
8ca5a65dcf | ||
|
|
798a03c2ab | ||
|
|
34c4775916 | ||
|
|
c5cff7d637 | ||
|
|
c2af370282 | ||
|
|
118fed29b5 | ||
|
|
4c50bfebc2 | ||
|
|
dab00a98e0 | ||
|
|
2b2ea40bce | ||
|
|
1273ac67f4 | ||
|
|
676481de58 | ||
|
|
54c5e03b4f | ||
|
|
a8374b25f1 | ||
|
|
4d81c498e2 | ||
|
|
b0dd824dbc | ||
|
|
5dc638c5b3 | ||
|
|
7f982a0778 | ||
|
|
28a1be4d36 | ||
|
|
c456e01219 | ||
|
|
ef53db0b91 | ||
|
|
21542d1f9e | ||
|
|
07d6472eea | ||
|
|
6c771f84ce | ||
|
|
02b7bc0803 | ||
|
|
681d6ca1dd | ||
|
|
3b4f70ae83 | ||
|
|
0e100a864b | ||
|
|
dc14f8bf2c | ||
|
|
37b9a809a6 | ||
|
|
5f1a1db30f | ||
|
|
99ff808b8a | ||
|
|
08c0729f5f | ||
|
|
7e4e2f28db | ||
|
|
08d9316d76 | ||
|
|
0233e9ad2a | ||
|
|
31e0812711 | ||
|
|
76e9809169 | ||
|
|
07a8151ae6 | ||
|
|
075ced80a6 | ||
|
|
4c96b9778e | ||
|
|
1b31c9f8a8 | ||
|
|
b858eec644 | ||
|
|
5af9923e29 | ||
|
|
e122901e49 | ||
|
|
aed1373b70 | ||
|
|
3b5e1c05b7 | ||
|
|
1472f85b16 | ||
|
|
3d6255ae24 | ||
|
|
f25e0c3829 | ||
|
|
b0a6a5a91e | ||
|
|
b917cf1ecc | ||
|
|
4d5469f27e | ||
|
|
1848a22118 | ||
|
|
b429576349 | ||
|
|
bb9557a9ae | ||
|
|
0d7e7ac657 | ||
|
|
b8c77bbcfc | ||
|
|
327b22d24e | ||
|
|
8b3d2c02e1 | ||
|
|
1ac799f629 | ||
|
|
234c64574b | ||
|
|
7b948bdd29 | ||
|
|
1f075d92bc | ||
|
|
fe02665f54 | ||
|
|
ec74b57000 | ||
|
|
3f488e9842 | ||
|
|
54e07389fa | ||
|
|
28906bf50a | ||
|
|
70e912736f | ||
|
|
ec1156d37a | ||
|
|
dcbc65a796 | ||
|
|
8eccd7d47d | ||
|
|
5530833bf8 | ||
|
|
2f8fb2b663 | ||
|
|
5d2035b729 | ||
|
|
7c36331042 | ||
|
|
36cfdd529b | ||
|
|
3e13568f91 | ||
|
|
e84ed1cb9a | ||
|
|
f1fd672d7b | ||
|
|
02b0472058 | ||
|
|
5854a226d7 | ||
|
|
bdf8940040 | ||
|
|
2b9a8fa1ac | ||
|
|
45137a55a4 | ||
|
|
d6dd2c5bd6 | ||
|
|
d4330ceacc | ||
|
|
364da7a57e | ||
|
|
05eeb8432e | ||
|
|
fce68f1a39 | ||
|
|
7f374fe69f | ||
|
|
836cb16455 | ||
|
|
dd8feac540 | ||
|
|
f526b9fcfb | ||
|
|
8bf9b1311d | ||
|
|
5b3e863323 | ||
|
|
6ce9eedb5f | ||
|
|
6f78183b74 | ||
|
|
1d96544c9d | ||
|
|
69f6a5c08c | ||
|
|
38b4f6a391 | ||
|
|
425e13843e | ||
|
|
f28fa0ab5a | ||
|
|
f162993001 | ||
|
|
af774a7269 | ||
|
|
d82cfdf581 | ||
|
|
b84818a334 | ||
|
|
9c26ee122e | ||
|
|
f27047dd2e | ||
|
|
643a62038e | ||
|
|
fbb83d831b | ||
|
|
2a4032d71a | ||
|
|
42c9f853a7 | ||
|
|
3389df77cc | ||
|
|
97732f7006 | ||
|
|
8f2457855c | ||
|
|
7e4c880e1e | ||
|
|
2a21285037 | ||
|
|
61bf77f668 | ||
|
|
cf583168dd | ||
|
|
236b528552 | ||
|
|
f730e476f0 | ||
|
|
3563568f6f | ||
|
|
912be5a792 | ||
|
|
30358100ab | ||
|
|
492665a8a1 | ||
|
|
005baea319 | ||
|
|
4f3b1edf9d | ||
|
|
2e692fca93 | ||
|
|
9dbd997141 | ||
|
|
416a82bf12 | ||
|
|
2e35dc648f | ||
|
|
55836e8ca6 | ||
|
|
a17acfb04f | ||
|
|
e9fe258b5e | ||
|
|
79e618415a | ||
|
|
bea0a491cf | ||
|
|
108b052e4e | ||
|
|
f5b593ff42 | ||
|
|
cdfd42053d | ||
|
|
36d4086673 | ||
|
|
01b541d8b0 | ||
|
|
928fce875e | ||
|
|
1d3c6e7420 | ||
|
|
c96fe2931a | ||
|
|
8a11dc0c90 | ||
|
|
324d427ac7 | ||
|
|
84c04cfe1c | ||
|
|
1925f2dec2 | ||
|
|
5235a72bca | ||
|
|
80c65ea8f3 | ||
|
|
3a2a7d0508 | ||
|
|
59002cb873 | ||
|
|
f49ce500a1 | ||
|
|
40b9130c63 | ||
|
|
e917b94929 | ||
|
|
abce12ccd9 | ||
|
|
83f8f8ebb8 | ||
|
|
4bd825e778 | ||
|
|
2fea5ff889 | ||
|
|
a94a42d609 | ||
|
|
4784f847c9 | ||
|
|
867d8510ca | ||
|
|
d53fb9d1b5 | ||
|
|
58b5c4cc16 | ||
|
|
10ecb6d368 | ||
|
|
e7c3ca9bd8 | ||
|
|
e8a4e9a31f | ||
|
|
43914852e5 | ||
|
|
c7f097ec84 | ||
|
|
7562f77bdf | ||
|
|
c4ed04fc82 | ||
|
|
f3061651d4 | ||
|
|
0b740826c5 | ||
|
|
e2d028fb97 | ||
|
|
e0913dc8e6 | ||
|
|
56f3b12171 | ||
|
|
927313968a | ||
|
|
2e54024b92 | ||
|
|
cdfcb1ed24 | ||
|
|
e6581aa09c | ||
|
|
8ebb000650 | ||
|
|
fc98bd1563 | ||
|
|
7ccf47f4c6 | ||
|
|
35debe46bc | ||
|
|
98c18f416a | ||
|
|
ea19971285 | ||
|
|
47d55694a4 | ||
|
|
f0e615dee5 | ||
|
|
5376b478b8 | ||
|
|
909e618f6c | ||
|
|
c492573429 | ||
|
|
8ae97b556e | ||
|
|
dfc0d4cf59 | ||
|
|
bfad624528 | ||
|
|
062b9ecbf3 | ||
|
|
d3cad5a651 | ||
|
|
a7ecf51915 | ||
|
|
893ae17b99 | ||
|
|
e48d5383ce | ||
|
|
9675acdf87 | ||
|
|
14229d0dd3 | ||
|
|
2b5d19924b | ||
|
|
3f658cc2ea | ||
|
|
6962bc5147 | ||
|
|
321957781e | ||
|
|
fd91513832 | ||
|
|
4fcfcc8117 | ||
|
|
11cecea597 | ||
|
|
e549833077 | ||
|
|
b15a5f03e6 | ||
|
|
7738083f3e | ||
|
|
98fe474276 | ||
|
|
03b8ecd0de | ||
|
|
bb669ccd2c | ||
|
|
e9d924b5d7 | ||
|
|
143601374c | ||
|
|
586c72fbe5 | ||
|
|
8bb832e23f | ||
|
|
184f522d5f | ||
|
|
0f0e23445a | ||
|
|
1b75e4de0d | ||
|
|
2deafa0dea | ||
|
|
938a621810 | ||
|
|
583a047e83 | ||
|
|
57edfa7ae8 | ||
|
|
b4da2d35bf | ||
|
|
fd357f87be | ||
|
|
df8c69f73b | ||
|
|
8ce98e38dc | ||
|
|
3a00140797 | ||
|
|
bf580fcc06 | ||
|
|
31d9208172 | ||
|
|
508ea9153c | ||
|
|
6ff16e2651 | ||
|
|
da682717ab | ||
|
|
647b5d098f | ||
|
|
3a9e5f0f98 | ||
|
|
50c9aec436 | ||
|
|
ec7ecc285e | ||
|
|
dea0d07b9a | ||
|
|
357e7af6ad | ||
|
|
53057830e0 | ||
|
|
7ae0317b6a | ||
|
|
547df2219a | ||
|
|
1c8c7479b8 | ||
|
|
36a960adec | ||
|
|
07ee4984cb | ||
|
|
e4448423fb | ||
|
|
50e9d02458 | ||
|
|
45233dd53c | ||
|
|
1a9fdc565c | ||
|
|
e32e616031 | ||
|
|
b14fb1759d | ||
|
|
abd757d356 | ||
|
|
28645b492e | ||
|
|
3919c8f79f | ||
|
|
803be11bbc | ||
|
|
335de94343 | ||
|
|
b62463107c | ||
|
|
93ce1661af | ||
|
|
f59ed38a38 | ||
|
|
3fad69e5ca | ||
|
|
005db13c45 | ||
|
|
d7ddafb39f | ||
|
|
3fe7bf27de | ||
|
|
4b718929df | ||
|
|
a44c908147 | ||
|
|
1bf37305a8 | ||
|
|
ed4d589077 | ||
|
|
47a080d79c | ||
|
|
66a8e5ddbb | ||
|
|
8c39ed61a9 | ||
|
|
a12d403981 | ||
|
|
ccf0274d13 | ||
|
|
21103f8bc4 | ||
|
|
a1ba44db72 | ||
|
|
3c22a7b482 | ||
|
|
d056b13e14 | ||
|
|
7a39ccf7bb | ||
|
|
3be90c2e45 | ||
|
|
60caecffdd | ||
|
|
df3eb562f0 | ||
|
|
c4b247e75e | ||
|
|
d9fdd0ce36 | ||
|
|
226fcac72e | ||
|
|
5c8a911c93 | ||
|
|
2cc1844d97 | ||
|
|
3916d5c567 | ||
|
|
ef51c1c2b2 | ||
|
|
f637faf0d2 | ||
|
|
d010f4fcae | ||
|
|
d5e436d15b | ||
|
|
18ee1ba589 | ||
|
|
795b39250f | ||
|
|
ae89f1b3b3 | ||
|
|
cbe600369c | ||
|
|
1de1b58a08 | ||
|
|
4f577cbdeb | ||
|
|
c2bd7d1e56 | ||
|
|
e501289a55 | ||
|
|
1ebc9de1e6 | ||
|
|
f34b060e23 | ||
|
|
84064b90a6 | ||
|
|
08e21fd0b8 | ||
|
|
1077686bda | ||
|
|
582d075c45 | ||
|
|
b60f1085db | ||
|
|
a3bdfc1580 | ||
|
|
76a8711570 | ||
|
|
87b424123b | ||
|
|
9a66d47d54 | ||
|
|
5a0712f766 | ||
|
|
660ea89521 | ||
|
|
60204becf4 | ||
|
|
032216153f | ||
|
|
dac4447e33 | ||
|
|
fa94c0a65b | ||
|
|
76d78571d6 | ||
|
|
556407408f | ||
|
|
a862bf488c | ||
|
|
f629dc51aa | ||
|
|
96cc6a916d | ||
|
|
6c0e0b3eae | ||
|
|
8a129610da | ||
|
|
8688753522 | ||
|
|
9a0400c93a | ||
|
|
13b5eb0ad8 | ||
|
|
e059efb4c4 | ||
|
|
0be74c6551 | ||
|
|
6fe6e1596f | ||
|
|
0e7c3951a6 | ||
|
|
40c8549cf5 | ||
|
|
a7ea370ec3 | ||
|
|
b6c6f06537 | ||
|
|
2e531c103f | ||
|
|
1a05939e0b | ||
|
|
acb8e85b61 | ||
|
|
8c38841a4d | ||
|
|
2c2ee706ac | ||
|
|
b7df4de4b7 | ||
|
|
b237425c94 | ||
|
|
bd3708870d | ||
|
|
2aa699d03e | ||
|
|
1d20b2603a | ||
|
|
6576f9c0c3 | ||
|
|
f840082aae | ||
|
|
f162508ad1 | ||
|
|
3ccefa20e8 | ||
|
|
00b19ccee0 | ||
|
|
54d55fb62f | ||
|
|
dcc8a94d07 | ||
|
|
5dd501e0ea | ||
|
|
af7a3fc2ea | ||
|
|
4b4b06bec5 | ||
|
|
54259593ea | ||
|
|
73cb270b14 | ||
|
|
3d1df8337e | ||
|
|
f08001a5a6 | ||
|
|
ecbba93784 | ||
|
|
47ebddf99f | ||
|
|
c70ac572fa | ||
|
|
f0a2747d80 | ||
|
|
67918033f9 | ||
|
|
93335cdb0e | ||
|
|
e308c3d34a | ||
|
|
977677d005 | ||
|
|
faf9814788 | ||
|
|
eeb9103e26 | ||
|
|
1f6386bd60 | ||
|
|
5c7acf4807 | ||
|
|
a92b9b7adb | ||
|
|
b4529229d2 | ||
|
|
bc776a9534 | ||
|
|
45c64c2d2e | ||
|
|
73f41023f3 | ||
|
|
139c1a956f | ||
|
|
b08af13872 | ||
|
|
1e59d9ade5 | ||
|
|
519aef7ff5 | ||
|
|
05cbdc6915 | ||
|
|
8d5e028b5b | ||
|
|
153ffbe558 | ||
|
|
394352d882 | ||
|
|
c0edfee224 | ||
|
|
06d2d31777 | ||
|
|
535691a05c | ||
|
|
d2058ee151 | ||
|
|
263cfe2538 | ||
|
|
717190975f | ||
|
|
d6a3f7765a | ||
|
|
f9d40adb18 | ||
|
|
087f9784e3 | ||
|
|
3bd74aabaa | ||
|
|
4933aef543 | ||
|
|
0e5d824bff | ||
|
|
b2d2dcc7fe | ||
|
|
7acb068590 | ||
|
|
80ec92ce8d | ||
|
|
83c4dd6bda | ||
|
|
e332d1074f | ||
|
|
42ed73ed4a | ||
|
|
5ed5c76d3f | ||
|
|
fe2288a88f | ||
|
|
8f0a0add1e | ||
|
|
3645eb18f8 | ||
|
|
610e80a19b | ||
|
|
d8460f147b | ||
|
|
71e508c7cd | ||
|
|
d3fcef43f8 | ||
|
|
cbc906c438 | ||
|
|
d57169fcf6 | ||
|
|
fdf639e1fb | ||
|
|
25760e30f9 | ||
|
|
3cdcb121c5 | ||
|
|
968209471e | ||
|
|
d71a53f24e | ||
|
|
c845d20352 | ||
|
|
11e888fb7c | ||
|
|
230617208b | ||
|
|
e99be61d49 | ||
|
|
635b8ff73a | ||
|
|
c9daafc887 | ||
|
|
033cf61380 | ||
|
|
70e17f9194 | ||
|
|
89e7e5e4fb | ||
|
|
ab32372f8f | ||
|
|
2778e63d6c | ||
|
|
d16fbda0f8 | ||
|
|
e8ea8d203d | ||
|
|
ac670856f6 | ||
|
|
88149f56bb | ||
|
|
6fcfab3488 | ||
|
|
dab3e90353 | ||
|
|
1c304eb8ba | ||
|
|
d1c84ad9f0 | ||
|
|
c39a680096 | ||
|
|
e8ddee284c | ||
|
|
abd7cfdc97 | ||
|
|
c904bd3a62 | ||
|
|
d48bda88e6 | ||
|
|
4ca24f114b | ||
|
|
7667c630a4 | ||
|
|
97458b2885 | ||
|
|
803bff4043 | ||
|
|
17aa8da9f0 | ||
|
|
7d5ee81628 | ||
|
|
b88be137ca | ||
|
|
195eb71200 | ||
|
|
f36e384ed7 | ||
|
|
3a3bd582b1 | ||
|
|
a342a5f8e0 | ||
|
|
42d139ee82 | ||
|
|
f1c6fd08c4 | ||
|
|
8ad2b3e7a1 | ||
|
|
a84695bb86 | ||
|
|
c2ec3b0bf4 | ||
|
|
bda9a833ba | ||
|
|
ac12f923ea | ||
|
|
b6be0e1b99 | ||
|
|
01809b08c9 | ||
|
|
42f5291f69 | ||
|
|
1d271ee771 | ||
|
|
1d19ea4a33 | ||
|
|
0d9b6ebc36 | ||
|
|
d9a48092e6 | ||
|
|
02ea713d6a | ||
|
|
94f15e3551 | ||
|
|
2d90b831f0 | ||
|
|
35110b6327 | ||
|
|
f52c670c05 | ||
|
|
f3adc8d738 | ||
|
|
40f6280c48 | ||
|
|
1c6d2857cb | ||
|
|
09967598e1 | ||
|
|
d3feb93619 | ||
|
|
0bba5cdc30 | ||
|
|
a3b1eec548 | ||
|
|
f174c4fccb | ||
|
|
32eead1542 | ||
|
|
1701e100cf | ||
|
|
397fef519c | ||
|
|
53bd0146bb | ||
|
|
a037758245 | ||
|
|
ffce1fc177 | ||
|
|
368f88740a | ||
|
|
ab369ab91d | ||
|
|
ddddf29f82 | ||
|
|
fdc36fb140 | ||
|
|
9ce5e25507 | ||
|
|
0bc4de2f34 | ||
|
|
e3dc242a3c | ||
|
|
bff2ed3837 | ||
|
|
9c31e26cf1 | ||
|
|
7a31c039fb | ||
|
|
7cca2b7fb0 | ||
|
|
10e5cf01cc | ||
|
|
384c19e54e | ||
|
|
7d5e7bf6c8 | ||
|
|
b6459e6172 | ||
|
|
b4f65840d1 | ||
|
|
b266ade4fe | ||
|
|
0f0fba0e9e | ||
|
|
54f25609c9 | ||
|
|
c48e90a556 | ||
|
|
e0409386c2 | ||
|
|
2aa69257a4 | ||
|
|
60d4b4c4f6 | ||
|
|
4a6a06fdc0 | ||
|
|
c631da7b0d | ||
|
|
9d425b4727 | ||
|
|
07d62bc111 | ||
|
|
91d0f87181 | ||
|
|
1c32564536 | ||
|
|
da07108be9 | ||
|
|
d7f4526a00 | ||
|
|
63dd6ad01a | ||
|
|
7b173a75e4 | ||
|
|
cb5a047e5d | ||
|
|
ed5abe5981 | ||
|
|
940534e303 | ||
|
|
1609473e5d | ||
|
|
1f951e2bd3 | ||
|
|
ed8e4962b9 | ||
|
|
10f9f9cc80 | ||
|
|
56c8e00b84 | ||
|
|
063577c19e | ||
|
|
57f20c0c22 | ||
|
|
e682b93883 | ||
|
|
a32b097e3c | ||
|
|
2ebf76cd50 | ||
|
|
65e5894363 | ||
|
|
dbef80f7bd | ||
|
|
06b0c89aee | ||
|
|
113bfe8fa2 | ||
|
|
df4e193990 | ||
|
|
28207c3313 | ||
|
|
e685c580f2 | ||
|
|
e6139c9f49 | ||
|
|
fac654ec5d | ||
|
|
1352e334b1 | ||
|
|
69ab6639b2 | ||
|
|
d52ee7ae27 | ||
|
|
ebcfc7f2b2 | ||
|
|
b347e1d861 | ||
|
|
8cb4a29a51 | ||
|
|
9fb08fb502 | ||
|
|
6710a77c26 | ||
|
|
e442fe753e | ||
|
|
a4685e6df3 | ||
|
|
a4f6c24273 | ||
|
|
53853814ff | ||
|
|
fb31f629c6 | ||
|
|
50612565e9 | ||
|
|
a92256e1cb | ||
|
|
d6c23486d5 | ||
|
|
d2bafdb2bf | ||
|
|
f2f2b534e6 | ||
|
|
2d9ae8ff2c | ||
|
|
4e4d406d23 | ||
|
|
a9bda2b12e | ||
|
|
5fb7ea8dbd | ||
|
|
d35678b891 | ||
|
|
405e3fc214 | ||
|
|
fbba78411d | ||
|
|
75cd816e02 | ||
|
|
c8a886e399 | ||
|
|
19b2568133 | ||
|
|
ccc8a05eb0 | ||
|
|
26125bcf0b | ||
|
|
263efbfe39 | ||
|
|
9a5ce2354d | ||
|
|
f25f5aeaaa | ||
|
|
af14020e42 | ||
|
|
4a49643bcd | ||
|
|
29596d12e3 | ||
|
|
1a28fb2a0c | ||
|
|
d985db60cc | ||
|
|
a76ad1478f | ||
|
|
044067f055 | ||
|
|
810d9e21bc | ||
|
|
7256579c16 | ||
|
|
ecf30b2c71 | ||
|
|
95f4f14dca | ||
|
|
391854058e | ||
|
|
1bcee2f11c | ||
|
|
572a04b40a | ||
|
|
d9ee8b2c32 | ||
|
|
614366e499 | ||
|
|
89e3f3210f | ||
|
|
dc55c710da | ||
|
|
47817b8ae1 | ||
|
|
3e66549ea4 | ||
|
|
8b7d0f33c3 | ||
|
|
a20fd4d463 | ||
|
|
bfd506f184 | ||
|
|
c20aa6062c | ||
|
|
b2a51db14e | ||
|
|
33ff7bf968 | ||
|
|
57a8b3f857 | ||
|
|
6e5a06421f | ||
|
|
5f0004b416 | ||
|
|
e79f450af9 | ||
|
|
c4f5d17db6 | ||
|
|
d1a018f2e8 | ||
|
|
6118570118 | ||
|
|
a9cceea850 | ||
|
|
81736a0129 | ||
|
|
dea4879938 | ||
|
|
2e2f984c45 | ||
|
|
bb639b08f7 | ||
|
|
5167f70015 | ||
|
|
cca5349110 | ||
|
|
5abe7d2dfb | ||
|
|
181d9a0777 | ||
|
|
5219c4a09a | ||
|
|
4da65183e0 | ||
|
|
b51ca4c8d3 | ||
|
|
198d2ab607 | ||
|
|
f43428aacf | ||
|
|
2d4f84563b | ||
|
|
418d102663 | ||
|
|
3b6a0d8e5c | ||
|
|
29c9972b86 | ||
|
|
7033966bb8 | ||
|
|
e90e4e4a59 | ||
|
|
954176cfc3 | ||
|
|
a8a6d807ff | ||
|
|
fe5f109af5 | ||
|
|
f1da003020 | ||
|
|
ea5a7180c7 | ||
|
|
9d0e2cbd89 | ||
|
|
032b6f193d | ||
|
|
e49c59959b | ||
|
|
b03cd330e5 | ||
|
|
542fa4a08c | ||
|
|
515f1e76b0 | ||
|
|
d95f7efea7 | ||
|
|
e97dd48b4c | ||
|
|
5915f31950 | ||
|
|
8caa4d9e37 | ||
|
|
d5525a38f1 | ||
|
|
e9a5af6109 | ||
|
|
fd6b32758e | ||
|
|
4387fb715b | ||
|
|
d7aaca6947 | ||
|
|
fa5115b3ed | ||
|
|
ec5e1067bc | ||
|
|
ee46faff1a | ||
|
|
fa629841bd | ||
|
|
155b57c2de | ||
|
|
6ea32a8ba3 | ||
|
|
8d72cea2d1 | ||
|
|
3ee4dd0d52 | ||
|
|
0f7832dc30 | ||
|
|
107083e3e4 | ||
|
|
d7a9d22a15 | ||
|
|
ecfbb10326 | ||
|
|
6c92a240cc | ||
|
|
0bad26e116 | ||
|
|
cd57483ed9 | ||
|
|
0908da9529 | ||
|
|
6e101e4582 | ||
|
|
f60309efa1 | ||
|
|
47f4007951 | ||
|
|
74f58818d6 | ||
|
|
17977effe7 | ||
|
|
477ed97c2f | ||
|
|
242ef70a77 | ||
|
|
755b751614 | ||
|
|
ad3a327366 | ||
|
|
a54bb07753 | ||
|
|
323ab3dba4 | ||
|
|
6947194824 | ||
|
|
879350b658 | ||
|
|
046e5e239f | ||
|
|
c5828fecc1 | ||
|
|
d12b360e92 | ||
|
|
5564b47dbc | ||
|
|
28ad60f892 | ||
|
|
171b6a222d | ||
|
|
f05181322c | ||
|
|
33d23a4a61 | ||
|
|
3e6088c614 | ||
|
|
8292553a20 | ||
|
|
6375401e0a | ||
|
|
b6b62506c5 | ||
|
|
f66aa336ac | ||
|
|
779cab047a | ||
|
|
cd575e80dd | ||
|
|
060cc15f81 | ||
|
|
6ed5784491 | ||
|
|
eab9040ee7 | ||
|
|
099b30afbf | ||
|
|
5cbf603203 | ||
|
|
c327b00efa | ||
|
|
7634d4ce69 | ||
|
|
98c6548d64 | ||
|
|
d169ee658e | ||
|
|
f718e2b0db | ||
|
|
dc59817a9d | ||
|
|
66fcea0ad8 | ||
|
|
a572609dbd | ||
|
|
94e458018b | ||
|
|
e5e0a6b31f | ||
|
|
5c63f7dd58 | ||
|
|
b0b5db770d | ||
|
|
878614f97a | ||
|
|
49e77e0f71 | ||
|
|
2115eb26a7 | ||
|
|
4f4c9bf5d6 | ||
|
|
90ab050493 | ||
|
|
28e0911f29 | ||
|
|
fd23844c8d | ||
|
|
5dc457b16c | ||
|
|
aadfb97d5a | ||
|
|
83abceb8be | ||
|
|
727a2fe4ea | ||
|
|
cb6c21ce90 | ||
|
|
a2e1019978 | ||
|
|
1171e1dd9c | ||
|
|
fff7be2c0f | ||
|
|
a1ef698cf2 | ||
|
|
43a794a905 | ||
|
|
4d50fe0928 | ||
|
|
e98938d03d | ||
|
|
c3c1572683 | ||
|
|
708f738952 | ||
|
|
5f1da17406 | ||
|
|
0499deea69 | ||
|
|
0fb0241901 | ||
|
|
24b55bbc9b | ||
|
|
3a7db8ec60 | ||
|
|
bc3e1e99fe | ||
|
|
efdd95fe7f | ||
|
|
65ecc5ae15 | ||
|
|
83a78a949d | ||
|
|
a7bf4366ce | ||
|
|
066ab8c1fc | ||
|
|
bedc393425 | ||
|
|
c1cc7bfc94 | ||
|
|
caae956f6e | ||
|
|
30a3339653 | ||
|
|
ef73607288 | ||
|
|
e7c3ecd192 | ||
|
|
a7d184ba54 | ||
|
|
546867c102 | ||
|
|
42fbc28b11 | ||
|
|
82631c3413 | ||
|
|
b153c651b4 | ||
|
|
8821986d87 | ||
|
|
35fc7328de | ||
|
|
7a611c6d47 | ||
|
|
f252f3efc5 | ||
|
|
da823125b9 | ||
|
|
7de5717418 | ||
|
|
a6f232f2b0 | ||
|
|
cbcd195461 | ||
|
|
837efcf5e7 | ||
|
|
8b0bcdb2a5 | ||
|
|
ca14ab3d55 | ||
|
|
cfdf1def2a | ||
|
|
37d350c3f5 | ||
|
|
b10c519cc1 | ||
|
|
78aeb50ce5 | ||
|
|
a12a614e7e | ||
|
|
f746418fda | ||
|
|
1bdab6e633 | ||
|
|
1bf2a9d47b | ||
|
|
8b4b135036 | ||
|
|
be10bf2ceb | ||
|
|
d4bd4ca000 | ||
|
|
2f3f95d3a9 | ||
|
|
d958f1099b | ||
|
|
7b0f3d9e26 | ||
|
|
92d581a342 | ||
|
|
8e11b2d6f0 | ||
|
|
79bd2ddd9c | ||
|
|
949ca844c5 | ||
|
|
f31af3c7c0 | ||
|
|
a0245f3e93 | ||
|
|
99811c90b6 | ||
|
|
c85f1a208d | ||
|
|
774923be1c | ||
|
|
d78b64d5b3 | ||
|
|
0938db8f7b | ||
|
|
d2c971eda9 | ||
|
|
57584ea429 | ||
|
|
49d84a364d | ||
|
|
89b5507354 | ||
|
|
2a25ddff36 | ||
|
|
b0b96daec0 | ||
|
|
8764cdf16a | ||
|
|
a45dd09fc0 | ||
|
|
320c32fd0f | ||
|
|
4afeefb5ce | ||
|
|
b2ad4e8c2a | ||
|
|
2bdf63d069 | ||
|
|
b897fd8315 | ||
|
|
82b35e2762 | ||
|
|
56f32104d5 | ||
|
|
2556d05602 | ||
|
|
7b06cb6682 | ||
|
|
cbd401c3e8 | ||
|
|
9277806664 | ||
|
|
828028259c | ||
|
|
d10525a375 | ||
|
|
d903758940 | ||
|
|
cf11ba1147 | ||
|
|
446b5550a2 | ||
|
|
4c2bdc9dc0 | ||
|
|
051759580d | ||
|
|
fb3f63bf59 | ||
|
|
f6b643e84e | ||
|
|
16d750d1f6 | ||
|
|
dfd626548f | ||
|
|
92d7c32f61 | ||
|
|
0ee48f6a58 | ||
|
|
664c762b35 | ||
|
|
9cb9608209 | ||
|
|
b20062efa6 | ||
|
|
8d4744d115 | ||
|
|
14f16a7ef0 | ||
|
|
df6c07aaad | ||
|
|
c95e9b9ba5 | ||
|
|
472a824a1e | ||
|
|
16df1c1ad4 | ||
|
|
e1fe637dcd | ||
|
|
2dce86d38e | ||
|
|
bcd02edd80 | ||
|
|
a73ea134cd | ||
|
|
e7a5aa7b9c | ||
|
|
aa33cacb62 | ||
|
|
0c74c79b18 | ||
|
|
0c973cc9fa | ||
|
|
62c921815f | ||
|
|
211cda540d | ||
|
|
6078d02c3a | ||
|
|
fa89b8f66d | ||
|
|
e399de8ad4 | ||
|
|
32a9487ff9 | ||
|
|
e891380ed5 | ||
|
|
2c73b457ef | ||
|
|
2f5f1a4d64 | ||
|
|
5c080ca4e8 | ||
|
|
4a85726e55 | ||
|
|
cb2eee1d2e | ||
|
|
8e80500ee6 | ||
|
|
03db9833e8 | ||
|
|
33153b8f3a | ||
|
|
3b2398ed01 | ||
|
|
a0a376e95e | ||
|
|
7b9df1d401 | ||
|
|
1244b0e36a | ||
|
|
ab58c95d27 | ||
|
|
a153368814 | ||
|
|
41fd729209 | ||
|
|
58aa0f3e1a | ||
|
|
02b390d7b8 | ||
|
|
41c2f74772 | ||
|
|
6c641b1834 | ||
|
|
700c05a55b | ||
|
|
188782c461 | ||
|
|
bdfdd23b36 | ||
|
|
9f0c3b496b | ||
|
|
1ae715da21 | ||
|
|
d5feb5135d | ||
|
|
fc533107ed | ||
|
|
1ee76cb506 | ||
|
|
4bb90dffc1 | ||
|
|
f4cd4184f8 | ||
|
|
c39c925d8d | ||
|
|
b1fc29be11 | ||
|
|
2a1f6e3df2 | ||
|
|
6f3493bb3c | ||
|
|
61257094b7 | ||
|
|
8aabc6bc3d | ||
|
|
f68148b7e0 | ||
|
|
4c526c7d3d | ||
|
|
4a24a8de43 | ||
|
|
b8ad22f525 | ||
|
|
d9ecca8591 | ||
|
|
83d07b9551 | ||
|
|
ee03391293 | ||
|
|
30503d6533 | ||
|
|
bbb83bea38 | ||
|
|
0f9ddbf3b2 | ||
|
|
8c4b8e623f | ||
|
|
b1c97dfcfd | ||
|
|
1a49f0d164 | ||
|
|
a2371d56fd | ||
|
|
c93db2cd21 | ||
|
|
15d422db80 | ||
|
|
14d1912115 | ||
|
|
b6477cd38b | ||
|
|
c42cbda904 | ||
|
|
39d56fd08f | ||
|
|
403f4c1a6b | ||
|
|
15ab331b6b | ||
|
|
495da14e38 | ||
|
|
bc2b948f1f | ||
|
|
ff9442474d | ||
|
|
9ca53fdc5d | ||
|
|
8e3a026276 | ||
|
|
b5ddd08630 | ||
|
|
92996e550c | ||
|
|
a037590ce3 | ||
|
|
c3c4254882 | ||
|
|
a18e8e1ede | ||
|
|
751c4c3169 | ||
|
|
595cb13d8f | ||
|
|
f783d594cc | ||
|
|
6e32be7e43 | ||
|
|
9e44b07275 | ||
|
|
4471c45fb7 | ||
|
|
99e681c09f | ||
|
|
4f5e9d77b2 | ||
|
|
98ccdf65fb | ||
|
|
4c0c153b8f | ||
|
|
c533c62c64 | ||
|
|
384db9d10d | ||
|
|
5d8b0acc16 | ||
|
|
3d23f4ec77 | ||
|
|
215bd07f0b | ||
|
|
6c79e0c077 | ||
|
|
b2ea61ea3e | ||
|
|
47d2467e24 | ||
|
|
a165303602 | ||
|
|
8e1716065e | ||
|
|
7251ce6e17 | ||
|
|
eaefb36212 | ||
|
|
a2f6f48daf | ||
|
|
a894456550 | ||
|
|
608e679d33 | ||
|
|
155844f142 | ||
|
|
cee9a20e85 | ||
|
|
70ca4a7fea | ||
|
|
7445f1881e | ||
|
|
e58dc726c5 | ||
|
|
1eba847e99 | ||
|
|
6bf6462a37 | ||
|
|
729d52f10a | ||
|
|
79e8e4599e | ||
|
|
ba5cfd8b25 | ||
|
|
dd8a3d845e | ||
|
|
66fc1dcf33 | ||
|
|
816f4907e3 | ||
|
|
d7e24b2494 | ||
|
|
288905c361 | ||
|
|
d4a957ca16 | ||
|
|
3071f3b71c | ||
|
|
e08e6c182c | ||
|
|
1ca0b85196 | ||
|
|
df57e7ab93 | ||
|
|
fa02f3a108 | ||
|
|
07d443a159 | ||
|
|
360397b2ed | ||
|
|
fa944fc526 | ||
|
|
df6e75e1d6 | ||
|
|
c49935d91c | ||
|
|
85082ea509 | ||
|
|
47731c75fc | ||
|
|
b5481edfd7 | ||
|
|
1325a81e9a | ||
|
|
1acfe53f74 | ||
|
|
265eb2b440 | ||
|
|
18b22f5f8a | ||
|
|
d609d2d2ad | ||
|
|
503c368f9e | ||
|
|
2848d1caaf | ||
|
|
69e145a630 | ||
|
|
a6d13f290b | ||
|
|
1a28720c56 | ||
|
|
b6cad08273 | ||
|
|
805cae7b31 | ||
|
|
7f423016f0 | ||
|
|
1070f3ed6b | ||
|
|
a41603ed85 | ||
|
|
2467698045 | ||
|
|
f93431b43e | ||
|
|
f5a03102d8 | ||
|
|
b6c4e6a6d0 | ||
|
|
8e3e90ddd2 | ||
|
|
e0e30ead58 | ||
|
|
0f208fb36b | ||
|
|
94fdcabac9 | ||
|
|
8a69a5c3c7 | ||
|
|
4f07abe655 | ||
|
|
bc01b6b4ad | ||
|
|
8783ccfd72 | ||
|
|
e819727b09 | ||
|
|
92615247ac | ||
|
|
78ed01f3ef | ||
|
|
4b1f87050f | ||
|
|
919de44a71 | ||
|
|
232862ae08 | ||
|
|
d59095c2e6 | ||
|
|
285e04c77e | ||
|
|
70f8840fbd | ||
|
|
8d0d2015d7 | ||
|
|
cf11a89457 | ||
|
|
65e18f5b8f | ||
|
|
732dfa63c7 | ||
|
|
b1ff5367e7 | ||
|
|
96fdb88690 | ||
|
|
3e992604c7 | ||
|
|
e9243e9660 | ||
|
|
59645f51a9 | ||
|
|
c866c48252 | ||
|
|
7b4d0168c0 | ||
|
|
dd3e530a63 | ||
|
|
3e2e60fb86 | ||
|
|
9bab858fd1 | ||
|
|
0ef8c5bda8 | ||
|
|
d4be96cd03 | ||
|
|
3d0c6700db | ||
|
|
5012baba15 | ||
|
|
41c67fa345 | ||
|
|
c75852455b | ||
|
|
27fa15e95d | ||
|
|
175e222927 | ||
|
|
55924f5c5b | ||
|
|
956f0043fc | ||
|
|
70cdbe4816 | ||
|
|
6644dc4861 | ||
|
|
3e144baacd | ||
|
|
bbacfbdd6a | ||
|
|
cbc0e5b934 | ||
|
|
81d556d32e | ||
|
|
5ad5a0fa07 | ||
|
|
e54ba7ecbc | ||
|
|
1c1d1f1185 | ||
|
|
bc1812840a | ||
|
|
74def75ca3 | ||
|
|
924b353e5a | ||
|
|
31618a4310 | ||
|
|
21e3481810 | ||
|
|
d7ba2c7168 | ||
|
|
6f811fd7f9 | ||
|
|
573846707c | ||
|
|
02e487f306 | ||
|
|
73b28b5d94 | ||
|
|
2a7ec29cd1 | ||
|
|
d4f8a8dedd | ||
|
|
f23c380cae | ||
|
|
7151467db7 | ||
|
|
16a8416495 | ||
|
|
5db3b71c6a | ||
|
|
8897c5763a | ||
|
|
07d92796d2 | ||
|
|
1f39c16d99 | ||
|
|
c8aeb5b160 | ||
|
|
69b08a2062 | ||
|
|
05fd5eb8be | ||
|
|
8ed0913df6 | ||
|
|
d85bcb2e37 | ||
|
|
09e5732f8a | ||
|
|
d7fcf31be5 | ||
|
|
f63aaa5429 | ||
|
|
321241da02 | ||
|
|
7c72886b1b | ||
|
|
2a52592292 | ||
|
|
ccdfbc721f | ||
|
|
a3436aea02 | ||
|
|
f62b2fc114 | ||
|
|
baf612bd59 | ||
|
|
f3490440b4 | ||
|
|
5cc1c30d7f | ||
|
|
0017de46e4 | ||
|
|
1cd1328b0c | ||
|
|
8ff9ad7636 | ||
|
|
1ba1c5b44e | ||
|
|
7db55d8db2 | ||
|
|
e058b19f53 | ||
|
|
bc3605a502 | ||
|
|
ce4daad431 | ||
|
|
0360d42d30 | ||
|
|
1fb37f93cc | ||
|
|
fce33402e7 | ||
|
|
abadd0bd34 | ||
|
|
16f27d0004 | ||
|
|
242eede258 | ||
|
|
8dc349caac | ||
|
|
91819bfc2d | ||
|
|
6ee691e019 | ||
|
|
28f0833237 | ||
|
|
eb415fd869 | ||
|
|
ace0a1cb75 | ||
|
|
6ceaea8478 | ||
|
|
30659aef50 | ||
|
|
46d0e23e7b | ||
|
|
2d3e20d96e | ||
|
|
723b51c931 | ||
|
|
a6160e3026 | ||
|
|
ecca69442d | ||
|
|
b2bae867d0 | ||
|
|
cfe843b870 | ||
|
|
1cef3f15d5 | ||
|
|
1bb56309a6 | ||
|
|
6468b7a914 | ||
|
|
6a083e8452 | ||
|
|
27cac334e1 | ||
|
|
947478ca76 | ||
|
|
c75357faa3 | ||
|
|
e9a27393b8 | ||
|
|
5d12c56510 | ||
|
|
00cfc4be44 | ||
|
|
70edcabca1 | ||
|
|
dce5e8d0cc | ||
|
|
59baf34170 | ||
|
|
5aa1146fe9 | ||
|
|
8059260c18 | ||
|
|
91bc8d473f | ||
|
|
3d4f2d146e | ||
|
|
ce61a64bd2 | ||
|
|
e2a498c8ca | ||
|
|
758e7b92eb | ||
|
|
cf4cdffcc1 | ||
|
|
e70c87ed41 | ||
|
|
d8472cc9f5 | ||
|
|
56a08f0d17 | ||
|
|
eb3685f537 | ||
|
|
201a6b8742 | ||
|
|
e2ee4ae024 | ||
|
|
23e3e2c504 | ||
|
|
ab698305bf | ||
|
|
143ae2b788 | ||
|
|
baf50ea84a | ||
|
|
73845e01ed | ||
|
|
178e3d5bc8 | ||
|
|
a94254a375 | ||
|
|
fc4083346e | ||
|
|
f79a11cbf7 | ||
|
|
edc0a7ef91 | ||
|
|
dce9a70ff5 | ||
|
|
631a8278d3 | ||
|
|
bae37c8e6f | ||
|
|
a5c1685ea0 | ||
|
|
d0a0051d85 | ||
|
|
8e4960f31d | ||
|
|
dd2a5e6b28 | ||
|
|
7e1e9ac94a | ||
|
|
29daf1ecee | ||
|
|
c62df39ce3 | ||
|
|
a91e7cbe8d | ||
|
|
159f02ba07 | ||
|
|
2daafe80a5 | ||
|
|
028b2a655d | ||
|
|
fd52cefe09 | ||
|
|
0e0dee43ab | ||
|
|
e2ee565f05 | ||
|
|
63e06578c4 | ||
|
|
a1f03015ec | ||
|
|
8220a6584c | ||
|
|
d4b51c491f | ||
|
|
3f66d9f8cd | ||
|
|
852073fc68 | ||
|
|
17082cda3c | ||
|
|
7ffa98118f | ||
|
|
c3bada3c32 | ||
|
|
23303391e0 | ||
|
|
8ac8acc49c | ||
|
|
94290102b6 | ||
|
|
f94c244b9f | ||
|
|
ec823196e0 | ||
|
|
957647bf06 | ||
|
|
df5524979d | ||
|
|
0ae3e50bd4 | ||
|
|
db710cd2df | ||
|
|
61407ad6c8 | ||
|
|
2e0180ba55 | ||
|
|
d476b7477b | ||
|
|
ec037abf92 | ||
|
|
1a56045b42 | ||
|
|
bf820beb79 | ||
|
|
cde7a3f66c | ||
|
|
4f99d641c5 | ||
|
|
f4aca35a88 | ||
|
|
732065bf13 | ||
|
|
d3d540a28b | ||
|
|
a6cbebe03c | ||
|
|
e1b54b6843 | ||
|
|
aadbd5a92d | ||
|
|
7b065365e0 | ||
|
|
d0827dbb3c | ||
|
|
fab103524a | ||
|
|
15be542e56 | ||
|
|
eebea70019 | ||
|
|
b58d56826b | ||
|
|
e770768b79 | ||
|
|
17011a7637 | ||
|
|
f891860408 | ||
|
|
3424c7dc87 | ||
|
|
dbf7ff9791 | ||
|
|
9addcfe827 | ||
|
|
d5d67708ac | ||
|
|
5aa0017e91 | ||
|
|
f90d5f3dc8 | ||
|
|
8b5793e629 | ||
|
|
de668f5999 | ||
|
|
606463114b | ||
|
|
40242ff7dc | ||
|
|
e411c7e8b3 | ||
|
|
80e1130bb5 | ||
|
|
d9a5b11c9a | ||
|
|
22839e48d0 | ||
|
|
f7f39cf6c0 | ||
|
|
54826808cf | ||
|
|
b30e799847 | ||
|
|
b4aaa1953c | ||
|
|
d64dcd298e | ||
|
|
02e8058c50 | ||
|
|
93057fae8c | ||
|
|
5bc6941b57 | ||
|
|
45dbd31d28 | ||
|
|
45a9eca792 | ||
|
|
b43064ce6e | ||
|
|
660c658c85 | ||
|
|
7804ae6a78 | ||
|
|
c916906716 | ||
|
|
1db57c498d | ||
|
|
54f7cd5302 | ||
|
|
9e70d54300 | ||
|
|
7465ca269b | ||
|
|
508157f07f | ||
|
|
33aa373b3f | ||
|
|
d96a7bc1fa | ||
|
|
dad8397763 | ||
|
|
e26295b6fa | ||
|
|
c8239c739d | ||
|
|
6c4f7caba1 | ||
|
|
cb47354a4f | ||
|
|
61588a4b77 | ||
|
|
142dd0053a | ||
|
|
0d9e12737a | ||
|
|
dfafa81bfe | ||
|
|
cda284424f | ||
|
|
610699d3c4 | ||
|
|
17f1d39fcf | ||
|
|
85766126e3 | ||
|
|
3bafa05ad1 | ||
|
|
1627297143 | ||
|
|
951376852c | ||
|
|
4d3647066f | ||
|
|
9e509aa25b | ||
|
|
d2226c0e9b | ||
|
|
1d65bc6382 | ||
|
|
b513662b52 | ||
|
|
8794106e85 | ||
|
|
88caa14030 | ||
|
|
bb233a9872 | ||
|
|
9acd3ebd42 | ||
|
|
0368b6730f | ||
|
|
ece1dd1d7e | ||
|
|
f57926d9ec | ||
|
|
96f196febd | ||
|
|
4295b1945e | ||
|
|
5ce96b9b95 | ||
|
|
7dfadfea4a | ||
|
|
d4e58e94f6 | ||
|
|
6e504b7bc9 | ||
|
|
7f944515de | ||
|
|
b6595a44d1 | ||
|
|
335d9af8dc | ||
|
|
8478ecc675 | ||
|
|
e5662dc893 | ||
|
|
0ef2cd8719 | ||
|
|
c32bc9dda4 | ||
|
|
d7080defd3 | ||
|
|
b20cce1408 | ||
|
|
9682c48b5b | ||
|
|
6a242f0d08 | ||
|
|
b1f3ccc6ee | ||
|
|
a36d74dad5 | ||
|
|
128d47430d | ||
|
|
e843d27f8c | ||
|
|
4f1e4ffa70 | ||
|
|
7249eebc75 | ||
|
|
8ea0b2051a | ||
|
|
c8678ba5a9 | ||
|
|
2ace4c57d0 | ||
|
|
8ef84e2aa7 | ||
|
|
bb0f3afb71 | ||
|
|
9fb8661eef | ||
|
|
91b81d6a2c | ||
|
|
88ac326caf | ||
|
|
bdd420a08e | ||
|
|
76daa03df0 | ||
|
|
62ad4dd109 | ||
|
|
41dc40dd84 | ||
|
|
2fc47cc52b | ||
|
|
9ad44a2060 | ||
|
|
5092cb75f4 | ||
|
|
f2f6a05342 | ||
|
|
52441dd754 | ||
|
|
38dd1c342a | ||
|
|
0f89db3b46 | ||
|
|
120afb30c1 | ||
|
|
47bc573de5 | ||
|
|
a6272fcf76 | ||
|
|
b8f0e565f5 | ||
|
|
83c9753507 | ||
|
|
91e0733e8e | ||
|
|
dd97d84c19 | ||
|
|
b2a4075e12 | ||
|
|
96e668a5b9 | ||
|
|
c9f4184126 | ||
|
|
6f1209ea49 | ||
|
|
89f0ecf25d | ||
|
|
eca70d81c8 | ||
|
|
639966622f | ||
|
|
be7e249630 | ||
|
|
d1493e6b70 | ||
|
|
fb059bfdc3 | ||
|
|
a3c45d47e6 | ||
|
|
6db2561eda | ||
|
|
ba2d0fae0e | ||
|
|
7f9e91f1c7 | ||
|
|
2312302dea | ||
|
|
dfede52048 | ||
|
|
a87d12f167 | ||
|
|
ec18c3770b | ||
|
|
3e0ea9727f | ||
|
|
e64378f94f | ||
|
|
888a7aa6b2 | ||
|
|
9cf2f424ad | ||
|
|
a1b35fb7d1 | ||
|
|
982b596fa4 | ||
|
|
1ce8168d72 | ||
|
|
93ce2728b7 | ||
|
|
0364bf4913 | ||
|
|
48813c55d5 | ||
|
|
a9a35ccb6b | ||
|
|
4d5c20ce17 | ||
|
|
ced84a2b01 | ||
|
|
6a0055f69f | ||
|
|
07b299abd2 | ||
|
|
ae563e2b1c | ||
|
|
1ceca4ae19 | ||
|
|
fa611b3616 | ||
|
|
bc0d4f28ef | ||
|
|
369a29ac90 | ||
|
|
b88a735e54 | ||
|
|
dca4de80fd | ||
|
|
bead3e6095 | ||
|
|
1436b075bf | ||
|
|
9831b358f8 | ||
|
|
7b11e634aa | ||
|
|
dce5c7e249 | ||
|
|
7f60ab49b2 | ||
|
|
d1d3dcf1a0 | ||
|
|
ce87a0c1d3 | ||
|
|
75067524ae | ||
|
|
1cd779459b | ||
|
|
e2eb0b2eac | ||
|
|
709bcedbed | ||
|
|
444e938e2d | ||
|
|
9820baf82e | ||
|
|
7f2c7cacd3 | ||
|
|
62a911a57e | ||
|
|
fcd34e41ca | ||
|
|
ba8a5ac82b | ||
|
|
e5a6c0a94d | ||
|
|
a9c8d4a216 | ||
|
|
6c7da13cd3 | ||
|
|
2ba23ebb13 | ||
|
|
74d69bdedc | ||
|
|
8a074dedb6 | ||
|
|
3dd4bf9955 | ||
|
|
2e2254371a | ||
|
|
693f7366a2 | ||
|
|
b673c804be | ||
|
|
03a1086ba3 | ||
|
|
e8a2ad4315 | ||
|
|
c9cbd2f4f6 | ||
|
|
90a99fc221 | ||
|
|
a649c3b72e | ||
|
|
caec5d81eb | ||
|
|
e4ec976a1f | ||
|
|
13768fdb9b | ||
|
|
46e4bd5fe0 | ||
|
|
95683c6239 | ||
|
|
db9ea66069 | ||
|
|
ef02464e3c | ||
|
|
d29bd4b054 | ||
|
|
17b7042a25 | ||
|
|
75afb37987 | ||
|
|
528a66fc97 | ||
|
|
b245311a7e | ||
|
|
4b2ef39648 | ||
|
|
286c3eafe3 | ||
|
|
3bb6c667db | ||
|
|
b530d1d449 | ||
|
|
fdbb5b67a8 | ||
|
|
67f09fb1d6 | ||
|
|
1a5dd5c87c | ||
|
|
c2a189ab18 | ||
|
|
56219f9f61 | ||
|
|
c38e7ee3e3 | ||
|
|
5e490ed8b7 | ||
|
|
9f9b1d3ce6 | ||
|
|
35ed9b9b72 | ||
|
|
c2830c4a98 | ||
|
|
3b9b03cf86 | ||
|
|
ef39c1e94b | ||
|
|
4ab2d46113 | ||
|
|
1e53528363 | ||
|
|
b46a8344d3 | ||
|
|
5d8334d7f4 | ||
|
|
c9a6e0155b | ||
|
|
7a9fab8f57 | ||
|
|
4bcc1f5adb | ||
|
|
3629468d47 | ||
|
|
d7f65ca125 | ||
|
|
c5d6f58988 | ||
|
|
a7a3ce7245 | ||
|
|
6cb527a937 | ||
|
|
007ba2bee4 | ||
|
|
2ce6d47519 | ||
|
|
f2bfdfdedd | ||
|
|
9d49faca61 | ||
|
|
bb85e139f1 | ||
|
|
c87d025902 | ||
|
|
c37b8f7f9d | ||
|
|
1ee5dba9b3 | ||
|
|
e8be8139cb | ||
|
|
fcc92299eb | ||
|
|
0c23cd62db | ||
|
|
04472bd730 | ||
|
|
c1f1d4e2ce | ||
|
|
e91a4bebed | ||
|
|
3d811a17fe | ||
|
|
f3ec818a66 | ||
|
|
a270ca5101 | ||
|
|
493aa9f20d | ||
|
|
6ff462abf3 | ||
|
|
4103344e48 | ||
|
|
193705a08a | ||
|
|
b59230067f | ||
|
|
7b7fa5f77b | ||
|
|
27b4c17f06 | ||
|
|
6491e30a80 | ||
|
|
4d478a3306 | ||
|
|
90dfa2ccaf | ||
|
|
c968d11943 | ||
|
|
e0918816fb | ||
|
|
66e84b68fc | ||
|
|
3d18f1447e | ||
|
|
d4ab74b25e | ||
|
|
d2cc7df7db | ||
|
|
231b70b987 | ||
|
|
1798ebd395 | ||
|
|
b1f4ea6206 | ||
|
|
350627988e | ||
|
|
87248c9f47 | ||
|
|
3fe616b8fe | ||
|
|
a12b2c8d33 | ||
|
|
468fb3c77a | ||
|
|
3a4bd27333 | ||
|
|
ac9974fd64 | ||
|
|
1e1b51bc1c | ||
|
|
127772e1b4 | ||
|
|
3ad3d3037f | ||
|
|
9c5f2de4ec | ||
|
|
59772ef772 | ||
|
|
96260ba26d | ||
|
|
ca2e2f5f45 | ||
|
|
92f3d863fa | ||
|
|
5970df0606 | ||
|
|
e1819a874f | ||
|
|
0c665e11f1 | ||
|
|
827d4c5fb0 | ||
|
|
e46fcc2893 | ||
|
|
ae8129f1fd | ||
|
|
6eed7eb540 | ||
|
|
7c86f11167 | ||
|
|
dc34bf18bb | ||
|
|
6bde70d60a | ||
|
|
b8370cffb9 | ||
|
|
b863447c2b | ||
|
|
7403f9f870 | ||
|
|
5252211c92 | ||
|
|
1d63654662 | ||
|
|
f83fc2e35c | ||
|
|
6cf17c7bcc | ||
|
|
19d7cfd66b | ||
|
|
a89772652d | ||
|
|
95485a0da2 | ||
|
|
f67acc82cf | ||
|
|
e2f1ce7758 | ||
|
|
4744e50244 | ||
|
|
61f105da6f | ||
|
|
273ab304b9 | ||
|
|
1d3af68f29 | ||
|
|
2a2a4b96c7 | ||
|
|
b630a01131 | ||
|
|
e70dbec6b9 | ||
|
|
f25189fc74 | ||
|
|
00fc66d8e8 | ||
|
|
97f17374f2 | ||
|
|
f16b19faf3 | ||
|
|
4ce16e9e91 | ||
|
|
be4bbd7b9b | ||
|
|
bae28965ab | ||
|
|
9daa97f279 | ||
|
|
4094c47e29 | ||
|
|
63efbdffe6 | ||
|
|
a7af6d8a3c | ||
|
|
ee1fe95ee5 | ||
|
|
f79c619065 | ||
|
|
028935a318 | ||
|
|
62353191e8 | ||
|
|
cbffd32d8e | ||
|
|
0394a3e939 | ||
|
|
8e400e9e40 | ||
|
|
66a53c6d3c | ||
|
|
f111c5c325 | ||
|
|
c4a9b61da6 | ||
|
|
a65ebbb319 | ||
|
|
bc78cf8a87 | ||
|
|
23823811e9 | ||
|
|
2bcc41c851 | ||
|
|
dce03a36d0 | ||
|
|
b24b3d21e1 | ||
|
|
556e507f68 | ||
|
|
29bf6e5d32 | ||
|
|
0927af40c3 | ||
|
|
c434d98365 | ||
|
|
0979f11cc3 | ||
|
|
68bdd26426 | ||
|
|
342c4384e4 | ||
|
|
73a41b16be | ||
|
|
e00062ea8f | ||
|
|
ca44ce5f8c | ||
|
|
812ac259e2 | ||
|
|
b8da386e55 | ||
|
|
3c0358c9cf | ||
|
|
c9aca2a13d | ||
|
|
ed9362a98c | ||
|
|
6b86d834a9 | ||
|
|
a2c5e30011 | ||
|
|
e06647b54e | ||
|
|
0f7d36cfa0 | ||
|
|
9e27559bdb | ||
|
|
0a21ffbfec | ||
|
|
542e487b69 | ||
|
|
bfc6d95a7e | ||
|
|
65a26958f7 | ||
|
|
2dfb4d0c17 | ||
|
|
368ad332a0 | ||
|
|
bde32eb7df | ||
|
|
dc64556902 | ||
|
|
0315077daf | ||
|
|
7237bacec0 | ||
|
|
9bf8e89192 | ||
|
|
5fa6b07e1b | ||
|
|
6668fe02aa | ||
|
|
82d09c288d | ||
|
|
8029f56d1c | ||
|
|
0a6916e1b9 | ||
|
|
e419a034b7 | ||
|
|
cafa5217ed | ||
|
|
bc16a1bcc4 | ||
|
|
f5737a6354 | ||
|
|
2865ad5281 | ||
|
|
33d75ad7b0 | ||
|
|
1a3222d357 | ||
|
|
5a17f86f1a | ||
|
|
c989a94916 | ||
|
|
8b57add891 | ||
|
|
5833bb3bd4 | ||
|
|
d17abedc7d | ||
|
|
b407074281 | ||
|
|
c4d6189b55 | ||
|
|
07706b41f4 | ||
|
|
346a48d4c2 | ||
|
|
77db84b4c8 | ||
|
|
b90b9bb472 | ||
|
|
d019187895 | ||
|
|
b3963456c0 | ||
|
|
bccf371aa9 | ||
|
|
641e9ff508 | ||
|
|
abb045e1ff | ||
|
|
ae97afd806 | ||
|
|
c09ee7d714 | ||
|
|
4047e871e5 | ||
|
|
4c1701ca77 | ||
|
|
8ba5cbc2b9 | ||
|
|
fbf13dde21 | ||
|
|
bdd713413a | ||
|
|
e896592261 | ||
|
|
d9312dbefb | ||
|
|
5cb638bd41 | ||
|
|
df23ef36c7 | ||
|
|
e1ffacbe32 | ||
|
|
6d9fe04aa8 | ||
|
|
16e48a859c | ||
|
|
6346c00527 | ||
|
|
3f6fe4f2be | ||
|
|
bb7680dc51 | ||
|
|
161572b292 | ||
|
|
3b3da24823 | ||
|
|
1f91c2fe12 | ||
|
|
b98fbcce0c | ||
|
|
b12d4c03cb | ||
|
|
bd4bdab81c | ||
|
|
792527d456 | ||
|
|
1a103662e9 | ||
|
|
25ea754502 | ||
|
|
3152d039a5 | ||
|
|
a33a5771ed | ||
|
|
5bedf3618d | ||
|
|
153cd0a205 | ||
|
|
f5f1b9602a | ||
|
|
7347b72010 | ||
|
|
5aeb8305fc | ||
|
|
53c950b235 | ||
|
|
8e6ff32c97 | ||
|
|
23acd2738b | ||
|
|
6bcc039e01 | ||
|
|
e776e79c1e | ||
|
|
e2660eaad3 | ||
|
|
5b6e731f37 | ||
|
|
ce0ba8edbd | ||
|
|
ec97464007 | ||
|
|
1ff6e4db9d | ||
|
|
59aae20aea | ||
|
|
97f9dedaa6 | ||
|
|
7f730b81ff | ||
|
|
e793fc9973 | ||
|
|
73876e5774 | ||
|
|
97e70d62bf | ||
|
|
47a356ff52 | ||
|
|
4e6a9fb202 | ||
|
|
141b8495e2 | ||
|
|
de503bf5c4 | ||
|
|
c94fbe5eeb | ||
|
|
523f7652f2 | ||
|
|
6c5795b519 | ||
|
|
6552ccc477 | ||
|
|
adb9f31803 | ||
|
|
d7f655dfc5 | ||
|
|
83a4999dbe | ||
|
|
abf1d7da23 | ||
|
|
dfaf116449 | ||
|
|
41362e2b6e | ||
|
|
731b6ebfa7 | ||
|
|
3f838e1dbc | ||
|
|
c845eed114 | ||
|
|
5b09829959 | ||
|
|
2e5a993f88 | ||
|
|
1fe1194ef4 | ||
|
|
19d0919451 | ||
|
|
afffbb6487 | ||
|
|
4964a1519b | ||
|
|
53e4b55ea3 | ||
|
|
9b3c00e0b6 | ||
|
|
7b31e5918e | ||
|
|
50a8ba8c18 | ||
|
|
b32bce9be2 | ||
|
|
8c87f32b38 | ||
|
|
0cf6c6c132 | ||
|
|
d757dd4e17 | ||
|
|
175ae58563 | ||
|
|
f32f7d2308 | ||
|
|
36acd34874 | ||
|
|
3ed6d82367 | ||
|
|
793047919d | ||
|
|
6a786342f9 | ||
|
|
d184b3fa86 | ||
|
|
91e97468a0 | ||
|
|
4a9317db6e | ||
|
|
b66aeea384 | ||
|
|
90f3cc7328 | ||
|
|
f9b732482d | ||
|
|
924f796eb8 | ||
|
|
2528f35f00 | ||
|
|
683a09781a | ||
|
|
d8774cda8e | ||
|
|
1ce4eda0b9 | ||
|
|
5bcb373c00 | ||
|
|
678239424a | ||
|
|
369dc295b1 | ||
|
|
7470b1180e | ||
|
|
99a4bb63c7 | ||
|
|
713a34c68e | ||
|
|
165a6d34b2 | ||
|
|
d96ab7c867 | ||
|
|
7de4f1d96f | ||
|
|
68fd1c28b0 | ||
|
|
e7a4aeca6f | ||
|
|
86002a2f7b | ||
|
|
08a4bbb7d0 | ||
|
|
ae4cf98458 | ||
|
|
1596391a2e | ||
|
|
0ff24b6f21 | ||
|
|
6cf8ca5e43 | ||
|
|
4bb6b5a547 | ||
|
|
f14ef10e48 | ||
|
|
f76046b612 | ||
|
|
69e1f6e4ba | ||
|
|
2fce010f30 | ||
|
|
5ba8749a38 | ||
|
|
5c5d45f52b | ||
|
|
a6d47ca772 | ||
|
|
11b4d98f37 | ||
|
|
6e016c439c | ||
|
|
d1af4a5582 | ||
|
|
9b5e6a1f7a | ||
|
|
060982adb4 | ||
|
|
bc95b2fc77 | ||
|
|
f926915e56 | ||
|
|
69123590fb | ||
|
|
66a35e973c | ||
|
|
9d1443bbfe | ||
|
|
f4f3769225 | ||
|
|
38543ad202 | ||
|
|
dda2ea8fed | ||
|
|
2293f9dad6 | ||
|
|
abb3341030 | ||
|
|
81e51dcafd | ||
|
|
e84e2c7258 | ||
|
|
d9b46587fe | ||
|
|
36322acb6d | ||
|
|
12b39feba3 | ||
|
|
16281c626b | ||
|
|
d24e867603 | ||
|
|
d5c14a513d | ||
|
|
f9b836027d | ||
|
|
3147b7c62b | ||
|
|
0ceb75ea09 | ||
|
|
3cb138ea41 | ||
|
|
9016ba0d61 | ||
|
|
3b6248cb64 | ||
|
|
5a71984b38 | ||
|
|
1274889931 | ||
|
|
ed7e715812 | ||
|
|
4d12af8396 | ||
|
|
6f45fb6e14 | ||
|
|
9de15616a5 | ||
|
|
5c0ef950cc | ||
|
|
0b0e0f8f43 | ||
|
|
a444c860a4 | ||
|
|
20db8bbe2e | ||
|
|
154923ca7d | ||
|
|
a34d636366 | ||
|
|
89ad259050 | ||
|
|
db1ae80877 | ||
|
|
7aa712a481 | ||
|
|
748c894450 | ||
|
|
0e8b13841a | ||
|
|
d284b8e0a0 | ||
|
|
4ce1cccc4a | ||
|
|
91c803ff65 | ||
|
|
7a17ee9f8c | ||
|
|
1ad8f20bce | ||
|
|
de421d02ef | ||
|
|
da390ff573 | ||
|
|
14cfa90d63 | ||
|
|
90a97ae35f | ||
|
|
501bd814c3 | ||
|
|
0f5a166cce | ||
|
|
d59f450819 | ||
|
|
e0a702df76 | ||
|
|
e990a35a91 | ||
|
|
3e286f4f19 | ||
|
|
e0a83b4b94 | ||
|
|
b9728a96ce | ||
|
|
537510f081 | ||
|
|
dc411ca889 | ||
|
|
9055d0910c | ||
|
|
1985502894 | ||
|
|
c3e3c32bdc | ||
|
|
f5ad1dfbc5 | ||
|
|
9eab9512a3 | ||
|
|
078db2dd80 | ||
|
|
a3796f9baa | ||
|
|
bdc279a49b | ||
|
|
544330345b | ||
|
|
4bf1d0373d | ||
|
|
192df273cc | ||
|
|
cf5c803fe0 | ||
|
|
3c302bae5a | ||
|
|
103cd2b7a1 | ||
|
|
7763643f2e | ||
|
|
61d2bed019 | ||
|
|
52cbbed6a0 | ||
|
|
4b624ab5da | ||
|
|
640d15dba5 | ||
|
|
69509f2a2a | ||
|
|
da5b9d5c74 | ||
|
|
af11525338 | ||
|
|
98b71bc63a | ||
|
|
271244bb36 | ||
|
|
ebef7d6348 | ||
|
|
20497f1be3 | ||
|
|
74947d1c1c | ||
|
|
db3d230ad9 | ||
|
|
fabf278633 | ||
|
|
743cfa13fd | ||
|
|
127ed1b188 | ||
|
|
b80674bf2e | ||
|
|
f74f7d543e | ||
|
|
72caf2ef9d | ||
|
|
5ef05d3a63 | ||
|
|
26aaa62048 | ||
|
|
c427fe94da | ||
|
|
7cd7837e08 | ||
|
|
66f7437965 | ||
|
|
cb32640f70 | ||
|
|
66c07a8b33 | ||
|
|
b326ab78b3 | ||
|
|
8811ca9e9e | ||
|
|
471d88c1d2 | ||
|
|
4a738024cc | ||
|
|
8ac32cf4d6 | ||
|
|
b541351a0a | ||
|
|
92f5a2b6a6 | ||
|
|
ae092efb49 | ||
|
|
94065fde33 | ||
|
|
aab7bc5282 | ||
|
|
9e2ccbd2a7 | ||
|
|
6a6494d947 | ||
|
|
cb9e944de1 | ||
|
|
1f92c594c8 | ||
|
|
f91031bd65 | ||
|
|
5d3e04216d | ||
|
|
055d55b71b | ||
|
|
ca948d66a9 | ||
|
|
fa8cb40af0 | ||
|
|
b13fb1cca9 | ||
|
|
01b8ed97ed | ||
|
|
863ee9e6dd | ||
|
|
4ebd604ca9 | ||
|
|
581ef6e18d | ||
|
|
321a32050b | ||
|
|
db6a207afe | ||
|
|
9b42bc860d | ||
|
|
6174aa01e0 | ||
|
|
fb7692cf9c | ||
|
|
9279840860 | ||
|
|
9c05f37c0f | ||
|
|
b5c72611b4 | ||
|
|
2b3b5d2c8a | ||
|
|
d46fe20986 | ||
|
|
9e46409517 | ||
|
|
d42da529ec | ||
|
|
c1c96e01fa | ||
|
|
aee2742951 | ||
|
|
c3af36d33b | ||
|
|
3885aa1e8c | ||
|
|
33b1c57092 | ||
|
|
441d3bf1ed | ||
|
|
bd83936e5d | ||
|
|
88a68b941f | ||
|
|
084b41fc2c | ||
|
|
7b713e2576 | ||
|
|
25982f0475 | ||
|
|
2d2ac98b3d | ||
|
|
f1fc201862 | ||
|
|
681f45943b | ||
|
|
5dc8c54b8d | ||
|
|
20194bed42 | ||
|
|
06bbf494bb | ||
|
|
21b919a76b | ||
|
|
39f0707201 | ||
|
|
8d52a278a9 | ||
|
|
5fbba27d17 | ||
|
|
5c891bcfb5 | ||
|
|
547c700764 | ||
|
|
d30892ea60 | ||
|
|
0b5d550780 | ||
|
|
ac5ad0b9ce | ||
|
|
823c0ebb47 | ||
|
|
8fc87411fa | ||
|
|
5fb173149a | ||
|
|
02cf7274d2 | ||
|
|
43de0e7f16 | ||
|
|
f84530c285 | ||
|
|
6bf92979a2 | ||
|
|
c5dcac4dbb | ||
|
|
bb1b6c906d | ||
|
|
aa9fef7778 | ||
|
|
351f21c89f | ||
|
|
ca97130a29 | ||
|
|
9fea44cbc3 | ||
|
|
5e761a1068 | ||
|
|
afff751ff1 | ||
|
|
222186d5f7 | ||
|
|
632ad7d7f9 | ||
|
|
331412ddff | ||
|
|
04ac04e0ad | ||
|
|
29340152b6 | ||
|
|
8a34f7ca7b | ||
|
|
e2e3b81f32 | ||
|
|
b4b5eb5bab | ||
|
|
edde785219 | ||
|
|
b71e148cea | ||
|
|
0d939b5ab0 | ||
|
|
b983cf8b5f | ||
|
|
81f3a5cf94 | ||
|
|
3726b546d5 | ||
|
|
2702b82bc3 | ||
|
|
aee4f8d2fe | ||
|
|
c79c1b3913 | ||
|
|
3da72c1ff1 | ||
|
|
b926a4c67e | ||
|
|
29320f8aad | ||
|
|
2a59f45a3b | ||
|
|
2db7b2d948 | ||
|
|
d55fcd055d | ||
|
|
9e3032e919 | ||
|
|
c2e2994403 | ||
|
|
b92e3ca3ee | ||
|
|
2abea94f8e | ||
|
|
fcc648ecfd | ||
|
|
2e1046220a | ||
|
|
a532bd9cf1 | ||
|
|
f2d1f1efd6 | ||
|
|
745515b11f | ||
|
|
a7fd4e96f1 | ||
|
|
17091bd38c | ||
|
|
437aa168d1 | ||
|
|
f31ef3420d | ||
|
|
b37184ae57 | ||
|
|
716a83d1f7 | ||
|
|
6c7972470b | ||
|
|
40ce6724a9 | ||
|
|
e46e3027fa | ||
|
|
5ea46444e9 | ||
|
|
47bfb681c0 | ||
|
|
3f7f5f9429 | ||
|
|
a9cae7c9bd | ||
|
|
ebd92d736a | ||
|
|
96b7bfb32c | ||
|
|
5d9cf6a6d7 | ||
|
|
47db3452f4 | ||
|
|
40e03a05be | ||
|
|
bd70e6ae6d | ||
|
|
b9eb74a705 | ||
|
|
daaefed61b | ||
|
|
7b41839ea8 | ||
|
|
6532972e61 | ||
|
|
48026efddf | ||
|
|
e314510005 | ||
|
|
facc6ee6b3 | ||
|
|
9a2f86e9ad | ||
|
|
513b8959f5 | ||
|
|
8a00b62cba | ||
|
|
9bb847bb07 | ||
|
|
40bfce463d | ||
|
|
fc7d29edd3 | ||
|
|
4f7d14dfb2 | ||
|
|
cfc61a69ef | ||
|
|
ce0f98989c | ||
|
|
cf547be1d6 | ||
|
|
745ac240d7 | ||
|
|
16da1a4e81 | ||
|
|
73d67bb16a | ||
|
|
050c0752f9 | ||
|
|
ae62d30811 | ||
|
|
f59a0192b4 | ||
|
|
f56b4773cb | ||
|
|
1a4a8f1ef7 | ||
|
|
03aacc35b3 | ||
|
|
d5cd6f9a51 | ||
|
|
205bc96827 | ||
|
|
2bd61aed7a | ||
|
|
6706bed676 | ||
|
|
81e704648f | ||
|
|
c4debca11d | ||
|
|
e75b0cb743 | ||
|
|
29617737ca | ||
|
|
26cc73118a | ||
|
|
47e91e0660 | ||
|
|
c6eecb06d5 | ||
|
|
896b46d18e | ||
|
|
18ef8ea271 | ||
|
|
ad26eec9f2 | ||
|
|
3b422406a9 | ||
|
|
78c63c480a | ||
|
|
79a068e92b | ||
|
|
717a532c09 | ||
|
|
b2cc2e6765 | ||
|
|
af13e5fa4a | ||
|
|
8eac8132e3 | ||
|
|
50f579d301 | ||
|
|
02c72e59fa | ||
|
|
e7233c0c94 | ||
|
|
2bdf135cbc | ||
|
|
134b9fc466 | ||
|
|
10863a5949 | ||
|
|
bf02e04283 | ||
|
|
49fd53ee67 | ||
|
|
48f70e55aa | ||
|
|
3250d75320 | ||
|
|
1ad4d26f31 | ||
|
|
87ee48bd84 | ||
|
|
24f9bb41df | ||
|
|
2a02b6de44 | ||
|
|
21a0498a30 | ||
|
|
411d7aa6c4 | ||
|
|
d0e9b4ce9f | ||
|
|
50c5f8c389 | ||
|
|
619c79df27 | ||
|
|
246b2c0d1b | ||
|
|
55c67c7870 | ||
|
|
26ea11c44f | ||
|
|
de1825e54b | ||
|
|
e259503933 | ||
|
|
c089d30915 | ||
|
|
4e07b4c0e8 | ||
|
|
ce6e81c682 | ||
|
|
c44acb3575 | ||
|
|
bad5057a74 | ||
|
|
4b91d4b5c3 | ||
|
|
fe7b7773ba | ||
|
|
cef1aa6d1b | ||
|
|
2aa8979522 | ||
|
|
e93fdefd72 | ||
|
|
5b10db6f91 | ||
|
|
5dc9de41eb | ||
|
|
76c2de38ff | ||
|
|
5cd4e340eb | ||
|
|
816802774d | ||
|
|
541e40f29c | ||
|
|
b7559c1df6 | ||
|
|
1af56b1025 | ||
|
|
27d5b9cfd0 | ||
|
|
bbf3d960b2 | ||
|
|
e1df151d9b | ||
|
|
a2ccfc1e50 | ||
|
|
771d87781e | ||
|
|
883828c6cc | ||
|
|
fa94644bcf | ||
|
|
ad309f1036 | ||
|
|
56b12f6555 | ||
|
|
e48323775d | ||
|
|
0f10fc8458 | ||
|
|
2c1cd99738 | ||
|
|
07df5833be | ||
|
|
2728cdaf23 | ||
|
|
4117ada2fd | ||
|
|
3727bea29a | ||
|
|
c410ffd10b | ||
|
|
bb5b19c2fb | ||
|
|
b0dbb6708e | ||
|
|
5d2cf3d23c | ||
|
|
3c9809bfe6 | ||
|
|
c530b4fb97 | ||
|
|
fcd7dc8744 | ||
|
|
f9f1b16e76 | ||
|
|
fe3e4bd0ec | ||
|
|
5b6c2c32bf | ||
|
|
245c2d4eed | ||
|
|
095e2bf0b3 | ||
|
|
ffee413d2d | ||
|
|
80b655fa7e | ||
|
|
db95e6eba5 | ||
|
|
dab3495751 | ||
|
|
f0e8c9ead9 | ||
|
|
d92e9f38f8 | ||
|
|
71632ac2d2 | ||
|
|
68d9d1cec2 | ||
|
|
eff2e6c795 | ||
|
|
3bf0a27e45 | ||
|
|
68cb4baeb3 | ||
|
|
c28ba24525 | ||
|
|
fc18bea4bd | ||
|
|
01842a563d | ||
|
|
44a2cc872c | ||
|
|
ac6c43b5fb | ||
|
|
4663278f52 | ||
|
|
cacdac16aa | ||
|
|
5716556766 | ||
|
|
cccffc77cd | ||
|
|
eae9774cb6 | ||
|
|
8bf03d21cd | ||
|
|
62229d0a49 | ||
|
|
6586b97a54 | ||
|
|
7e59c70a9f | ||
|
|
bba7fe24e9 | ||
|
|
fb9544badd | ||
|
|
bfc2552841 | ||
|
|
39dc4fc992 | ||
|
|
14e2a5cc39 | ||
|
|
c04c57ea0f | ||
|
|
8333d41dbd | ||
|
|
dca4db9d4d | ||
|
|
4650458157 | ||
|
|
ce41710a7c | ||
|
|
97d472380f | ||
|
|
9ab6029280 | ||
|
|
7b90b0dfd9 | ||
|
|
24ddc8e026 | ||
|
|
9981cbb72c | ||
|
|
be6c4019f6 | ||
|
|
8b8712c15b | ||
|
|
4ffa408420 | ||
|
|
c7ffe606a6 | ||
|
|
26138ac46d | ||
|
|
ed457ac694 | ||
|
|
56aa568124 | ||
|
|
73c781a0cf | ||
|
|
3edbb564fc | ||
|
|
4e85bc66b8 | ||
|
|
d1c9701ccf | ||
|
|
ec5cc08fab | ||
|
|
b5d093e5ca | ||
|
|
10a52977f8 | ||
|
|
c43eccf591 | ||
|
|
d9dc7f0f38 | ||
|
|
4511f8855b | ||
|
|
007836f514 | ||
|
|
83dd1c7be2 | ||
|
|
8ed9d915ad | ||
|
|
f812866665 | ||
|
|
fde46ca78c | ||
|
|
ab59479a0c | ||
|
|
299c46f118 | ||
|
|
73bd65ead5 | ||
|
|
4b691703fe | ||
|
|
85bf025adc | ||
|
|
8fd8ddcbc1 | ||
|
|
0011b8fd48 | ||
|
|
0cba82ce9c | ||
|
|
eb7db62a64 | ||
|
|
8d0a0674c6 | ||
|
|
6c4f9f324b | ||
|
|
2863c35ab5 | ||
|
|
44d945cd08 | ||
|
|
0754da58da | ||
|
|
31df7af61f | ||
|
|
f55636bcb5 | ||
|
|
1fd8c7ac42 | ||
|
|
b0f9cd3022 | ||
|
|
0add06380f | ||
|
|
81624a601a | ||
|
|
045cd48687 | ||
|
|
56f66ce001 | ||
|
|
7121d8e427 | ||
|
|
57dc362d5d | ||
|
|
661558dafc | ||
|
|
6467ce1a97 | ||
|
|
5680a88c59 | ||
|
|
04a76371fc | ||
|
|
a90a0874b8 | ||
|
|
2d83ea86dc | ||
|
|
956dab69b4 | ||
|
|
abaf752a9b | ||
|
|
d63cfb41f1 | ||
|
|
9cfd0dd9d8 | ||
|
|
1e8fec9385 | ||
|
|
35f1055739 | ||
|
|
98d5ae91f5 | ||
|
|
83b89b9576 | ||
|
|
4c89f5d397 | ||
|
|
c2f83639d4 | ||
|
|
77e865fc8e | ||
|
|
1fa7e2994a | ||
|
|
0d7eb186d1 | ||
|
|
b6115d3c56 | ||
|
|
628187db16 | ||
|
|
de03f7f9ce | ||
|
|
6e149a2dd3 | ||
|
|
884bb60c7d | ||
|
|
57033bb599 | ||
|
|
005186bf4a | ||
|
|
95d24f1d30 | ||
|
|
dbb4ccbcc0 | ||
|
|
ed213c4d6d | ||
|
|
abb7695624 | ||
|
|
2cadda657c | ||
|
|
bedc7b7b69 | ||
|
|
d7d46def9d | ||
|
|
1639f5b83d | ||
|
|
2226d708ba | ||
|
|
ba33c51b8c | ||
|
|
aaa7d6a0ec | ||
|
|
483952eb78 | ||
|
|
5fa43c41eb | ||
|
|
00fb997995 | ||
|
|
c10acb1fb0 | ||
|
|
ecb44ad572 | ||
|
|
a3171cd429 | ||
|
|
2b2f1f2746 | ||
|
|
5a1887ed17 | ||
|
|
0998a108ea | ||
|
|
8b17a6ddd1 | ||
|
|
a7eae1031c | ||
|
|
df91b489c4 | ||
|
|
f17eb946f6 | ||
|
|
904881e207 | ||
|
|
b00d084243 | ||
|
|
75c1e7a193 | ||
|
|
5897ed896a | ||
|
|
47dd1da6fb | ||
|
|
b3efdf2109 | ||
|
|
e5c077243c | ||
|
|
af87038150 | ||
|
|
720f1d7123 | ||
|
|
678148b9aa | ||
|
|
549943fb10 | ||
|
|
2940f9591b | ||
|
|
2ebb8851f6 | ||
|
|
24192ff1ef | ||
|
|
6adb180911 | ||
|
|
fa8febbb31 | ||
|
|
8ba1bf02a4 | ||
|
|
4bdb028499 | ||
|
|
d18a8e849e | ||
|
|
c3fdd00aa4 | ||
|
|
13c7fe46cd | ||
|
|
ea0be8ea1a | ||
|
|
38ea71c6c9 | ||
|
|
37ad734cea | ||
|
|
e9462ba145 | ||
|
|
2b9322fc7d | ||
|
|
b775a1aa0e | ||
|
|
bf3a409569 | ||
|
|
68f6baf938 | ||
|
|
5994fadebb | ||
|
|
c6c4c53c8b | ||
|
|
16b7df3717 | ||
|
|
9bd8384a57 | ||
|
|
85d8300421 | ||
|
|
d03c66c924 | ||
|
|
b485d09847 | ||
|
|
ad5c93d673 | ||
|
|
202b757bc4 | ||
|
|
603e64154d | ||
|
|
52b80711f6 | ||
|
|
aec67e6be2 | ||
|
|
8b6230726f | ||
|
|
4050ff7c1f | ||
|
|
6b4cfe4f18 | ||
|
|
810d9fefd9 | ||
|
|
fb13e69b8e | ||
|
|
689f232243 | ||
|
|
f16b6406eb | ||
|
|
760427fc43 | ||
|
|
8931adc048 | ||
|
|
b752acdeef | ||
|
|
ba224f382d | ||
|
|
f2ff6f394b | ||
|
|
391d7fed52 | ||
|
|
07e28a9757 | ||
|
|
b05474fc30 | ||
|
|
47bd97b55d | ||
|
|
381b1a066d | ||
|
|
69ca279101 | ||
|
|
de1e39add9 | ||
|
|
ebd3b965fc | ||
|
|
40b2e24c6d | ||
|
|
ddfc5209d3 | ||
|
|
aea2fa1629 | ||
|
|
8e243edd20 | ||
|
|
a8b42fc21e | ||
|
|
86dd67f57d | ||
|
|
97d7a523a0 | ||
|
|
1d455c21d4 | ||
|
|
8f631d0693 | ||
|
|
002c203913 | ||
|
|
8a2b96c2f9 | ||
|
|
c6b9eb7855 | ||
|
|
38ea8bee93 | ||
|
|
a969f18137 | ||
|
|
0381102c27 | ||
|
|
e81dccb14e | ||
|
|
5c3e6307b4 | ||
|
|
8d94402d25 | ||
|
|
35d12b9e59 | ||
|
|
a81da0ec34 | ||
|
|
f1fbcd7c02 | ||
|
|
5c32f42fe9 | ||
|
|
a780252552 | ||
|
|
798b80e486 | ||
|
|
aa0384bcec | ||
|
|
dd654b9766 | ||
|
|
4c840d70a4 | ||
|
|
238621ee92 | ||
|
|
206054678b | ||
|
|
a5035dee74 | ||
|
|
d3369384d1 | ||
|
|
420aa4bc44 | ||
|
|
305e0538d2 | ||
|
|
8aee932525 | ||
|
|
8b737e9610 | ||
|
|
0b16a5531a | ||
|
|
b7fbd0ee50 | ||
|
|
2afdb7854b | ||
|
|
1bd784cf12 | ||
|
|
17fa2d8801 | ||
|
|
b89c869e7c | ||
|
|
1e6a491400 | ||
|
|
38ca3bac40 | ||
|
|
1a506ad49c | ||
|
|
b0d3c17f19 | ||
|
|
e967bc9c45 | ||
|
|
d6d21cb5f6 | ||
|
|
d177cf94da | ||
|
|
f4507d878d | ||
|
|
a3e0e67953 | ||
|
|
7045b920ef | ||
|
|
9a057623d6 | ||
|
|
b6a545b4a2 | ||
|
|
d4ef3c183c | ||
|
|
5c3b06b8a9 | ||
|
|
4d34d9c032 | ||
|
|
4f62d7a78f | ||
|
|
d39cf23b2f | ||
|
|
1c61e316b4 | ||
|
|
2d42d58738 | ||
|
|
80ed05d45d | ||
|
|
4cf172d46f | ||
|
|
d1fa63b389 | ||
|
|
9fe4bae52f | ||
|
|
cf93d9c3b4 | ||
|
|
40a7d38210 | ||
|
|
e4244c0cac | ||
|
|
3c88f3e6ee | ||
|
|
fa98f4c55d | ||
|
|
f2e87a204d | ||
|
|
c98b91f514 | ||
|
|
15d9bf4ebe | ||
|
|
6dd4e9ac60 | ||
|
|
2b0c2891e3 | ||
|
|
7939588702 | ||
|
|
99c4d932bf | ||
|
|
537401cf27 | ||
|
|
b2eede891a | ||
|
|
a2873c18ca | ||
|
|
70d38fe5b3 | ||
|
|
f15456f4ab | ||
|
|
9fc4246e1d | ||
|
|
291b0edbe0 | ||
|
|
452c4d13b0 | ||
|
|
70150718c5 | ||
|
|
8a89cfb158 | ||
|
|
86d2daf473 | ||
|
|
fbb357ac47 | ||
|
|
38de583db0 | ||
|
|
7fc254a81c | ||
|
|
752bb169ed | ||
|
|
4b101c2240 | ||
|
|
055ee75302 | ||
|
|
f95011a565 | ||
|
|
4facae674d | ||
|
|
39005634c6 | ||
|
|
2e452f5b27 | ||
|
|
9e9e0ebb1c | ||
|
|
dd8d20f089 | ||
|
|
6bb5ea7a81 | ||
|
|
efcde8f3dd | ||
|
|
057266653b | ||
|
|
8cbffdf0b4 | ||
|
|
000861da0d | ||
|
|
7ae097ef6b | ||
|
|
6868403383 | ||
|
|
d1cb925b59 | ||
|
|
229cc2ac43 | ||
|
|
cb9ac6dd34 | ||
|
|
2e7f4c1870 | ||
|
|
993b182f81 | ||
|
|
82d61f194a | ||
|
|
2755c74c29 | ||
|
|
541d0dce90 | ||
|
|
5ad5afe63b | ||
|
|
2c3843ee4c | ||
|
|
6f0ac133cc | ||
|
|
e5d1dd111e | ||
|
|
1b90e851f9 | ||
|
|
125713e938 | ||
|
|
e128ff4e8f | ||
|
|
2c8a82713e | ||
|
|
165f442d70 | ||
|
|
5365e9b3a5 | ||
|
|
7d2a17ea6e | ||
|
|
91b8c769bd | ||
|
|
2aa1450ab2 | ||
|
|
dc3cc655db | ||
|
|
e4bdc92834 | ||
|
|
87a74a44d3 | ||
|
|
ebbe18a426 | ||
|
|
6bc5dd75bd | ||
|
|
0257d660ad | ||
|
|
0637a71669 | ||
|
|
c63deda71a | ||
|
|
3ba4b2c1c1 | ||
|
|
45dc995967 | ||
|
|
e985436b3b | ||
|
|
a8a3812890 | ||
|
|
6c672d2575 | ||
|
|
99c5aca78b | ||
|
|
d8240a40b7 | ||
|
|
b587bdf863 | ||
|
|
adf34fb201 | ||
|
|
82e867a9a8 | ||
|
|
8706cbe1c4 | ||
|
|
7a557d31e0 | ||
|
|
de12503fad | ||
|
|
5238a27ab3 | ||
|
|
12162f53b4 | ||
|
|
ec3ca11d0d | ||
|
|
07dca90352 | ||
|
|
3338f3c5b2 | ||
|
|
de455e4cd0 | ||
|
|
5243dd153b | ||
|
|
e1659b0725 | ||
|
|
89c026924b | ||
|
|
4f0b138692 | ||
|
|
b6db0f72f5 | ||
|
|
9068ae68ad | ||
|
|
1bff63bd2e | ||
|
|
531baa8fc4 | ||
|
|
e67f5bc6bb | ||
|
|
316b090433 | ||
|
|
b2298d44a4 | ||
|
|
c029839971 | ||
|
|
e7e73e6fd1 | ||
|
|
bed0a5773f | ||
|
|
53a2262fef | ||
|
|
709206accd | ||
|
|
6ba142fd33 | ||
|
|
eeabf514ea | ||
|
|
faf1045ef5 | ||
|
|
6a82ff871f | ||
|
|
7e5428c697 | ||
|
|
036b72757c | ||
|
|
120e9a1e4c | ||
|
|
b49cfb2efd | ||
|
|
0340160ba7 | ||
|
|
4ede3fd771 | ||
|
|
3783c1af3e | ||
|
|
51c610de73 | ||
|
|
92862f93f3 | ||
|
|
05a9f0aa14 | ||
|
|
64810405ef | ||
|
|
382ce4cc61 | ||
|
|
178c983871 | ||
|
|
908e15bc90 | ||
|
|
df27a48e72 | ||
|
|
b959641ca8 | ||
|
|
c50bfa07ca | ||
|
|
416adeb169 | ||
|
|
61f591cc88 | ||
|
|
8f2106da2b | ||
|
|
1e988b1fea | ||
|
|
0febfce268 | ||
|
|
c4fd0af16d | ||
|
|
dd83f6f356 | ||
|
|
69354e808f | ||
|
|
3a7d3e3a54 | ||
|
|
4c76b31684 | ||
|
|
55eda16b61 | ||
|
|
3d0c90cbc5 | ||
|
|
9b9621e10d | ||
|
|
86eb923f29 | ||
|
|
14ca376902 | ||
|
|
77a9be845d | ||
|
|
9dd9e27fa8 | ||
|
|
74c68f09e5 | ||
|
|
b60e36ea7a | ||
|
|
fae7993f93 | ||
|
|
215659a234 | ||
|
|
99afd0a449 | ||
|
|
c0e0379bab | ||
|
|
c761531947 | ||
|
|
42b718b3e0 | ||
|
|
1e3a645abe | ||
|
|
7c47557554 | ||
|
|
b5ea20ac86 | ||
|
|
da9b6690e5 | ||
|
|
32366284a8 | ||
|
|
f17f51a9c1 | ||
|
|
d858bd9265 | ||
|
|
287e9c8d68 | ||
|
|
5e5ec5a66a | ||
|
|
ae5c10a71c | ||
|
|
4d5202353f | ||
|
|
142bcd6806 | ||
|
|
7075697f60 | ||
|
|
3a320462fa | ||
|
|
856133b07d | ||
|
|
0b2d809309 | ||
|
|
ec383aca03 | ||
|
|
8925e0c6c9 | ||
|
|
bc74425872 | ||
|
|
b15a53b672 | ||
|
|
ed7e4df014 | ||
|
|
3bf2935ee3 | ||
|
|
35f17acb38 | ||
|
|
58cf5f310d | ||
|
|
2d916b531b | ||
|
|
12952c9821 | ||
|
|
4ce8f965aa | ||
|
|
47e1c4e059 | ||
|
|
47119ddc7d | ||
|
|
500ee4c1bf | ||
|
|
fc105cf141 | ||
|
|
18f0961caa | ||
|
|
e65949f594 | ||
|
|
b05c1a9829 | ||
|
|
9fa3956aa8 | ||
|
|
02fc082e45 | ||
|
|
be1ffca6f4 | ||
|
|
987eb90e18 | ||
|
|
932aeebcf1 | ||
|
|
5f3a8cbe93 | ||
|
|
f808f1601b | ||
|
|
e5a3179468 | ||
|
|
672c3d7c6d | ||
|
|
72479041ae | ||
|
|
e286b510f1 | ||
|
|
315dafbe12 | ||
|
|
80e4338314 | ||
|
|
db176eec40 | ||
|
|
02f88fc7b2 | ||
|
|
56957b60e2 | ||
|
|
7126fd4b31 | ||
|
|
560af7a5b8 | ||
|
|
e38880a686 | ||
|
|
29dd4ad39b | ||
|
|
54ecf0f45f | ||
|
|
6900dd34a4 | ||
|
|
11b97af250 | ||
|
|
70dae328b5 | ||
|
|
5d4245ff01 | ||
|
|
24d28bc23a | ||
|
|
d786eca126 | ||
|
|
2fb4952137 | ||
|
|
dcf2c07f29 | ||
|
|
da512cef64 | ||
|
|
f41b037fbe | ||
|
|
0f5f1c98ca | ||
|
|
01338a7610 | ||
|
|
063b4286e7 | ||
|
|
271f85be3b | ||
|
|
b5f2b4af35 | ||
|
|
9967f2ab28 | ||
|
|
52c3960946 | ||
|
|
1b1170bcf6 | ||
|
|
eb03877aa4 | ||
|
|
4c4d185937 | ||
|
|
6998bb1f23 | ||
|
|
3a60bef2b6 | ||
|
|
eb1eb38c01 | ||
|
|
3c5598407e | ||
|
|
ed82cb108f | ||
|
|
4ffc4ee70a | ||
|
|
52db649022 | ||
|
|
38e46fff54 | ||
|
|
744ad84714 | ||
|
|
7d897a3f03 | ||
|
|
79eeeaee95 | ||
|
|
2c1b432613 | ||
|
|
0c3d5e99a2 | ||
|
|
dca8a05026 | ||
|
|
5cfc286972 | ||
|
|
bc46f70a90 | ||
|
|
5a63ddd645 | ||
|
|
8566f91303 | ||
|
|
b63aff77df | ||
|
|
5a1eb65ed6 | ||
|
|
98a2dcad90 | ||
|
|
77a021025f | ||
|
|
63123759ed | ||
|
|
6167291488 | ||
|
|
cf0b1f1f15 | ||
|
|
824dedbe9d | ||
|
|
da707736a0 | ||
|
|
8f57bb95fe | ||
|
|
0c3543ac43 | ||
|
|
d2e5b7cb76 | ||
|
|
6a56a509d3 | ||
|
|
dffa08adcc | ||
|
|
779885f9af | ||
|
|
d504197a78 | ||
|
|
542fcaff9a | ||
|
|
bc8c74eb42 | ||
|
|
3affb2e817 | ||
|
|
df0cd4dbc7 | ||
|
|
d54ad98802 | ||
|
|
1d90c4ea99 | ||
|
|
4da005e209 | ||
|
|
c3149a8d59 | ||
|
|
fd507ff597 | ||
|
|
8c2b93da72 | ||
|
|
ca82b45fe4 | ||
|
|
43def0873e | ||
|
|
da49befb18 | ||
|
|
e0d9d30bcf | ||
|
|
99f7dd0fd4 | ||
|
|
0c7ad924a8 | ||
|
|
a3e5307b93 | ||
|
|
ae6256f95a | ||
|
|
a961d5e6c8 | ||
|
|
237cca7a0d | ||
|
|
2c9938f0d5 | ||
|
|
ea83032863 | ||
|
|
6a4573b935 | ||
|
|
9421e42dad | ||
|
|
f4b658d7b1 | ||
|
|
7272b97e9a | ||
|
|
8a9f062b95 | ||
|
|
eac35c05e9 | ||
|
|
07b96f2430 | ||
|
|
269b3cef72 | ||
|
|
99cf2cbaa9 | ||
|
|
b63165b6e0 | ||
|
|
32ce790717 | ||
|
|
b5b57523f1 | ||
|
|
7524948a97 | ||
|
|
f9b67d3630 | ||
|
|
3beb94dc52 | ||
|
|
4371e6ad97 | ||
|
|
f44ca74e99 | ||
|
|
8bbe2569dc | ||
|
|
10fa5c20e7 | ||
|
|
f7833411a1 | ||
|
|
de4f9d68bd | ||
|
|
571b8cc85b | ||
|
|
883fc5d753 | ||
|
|
25b2a6e0cf | ||
|
|
4febdc3bcd | ||
|
|
c3617f5d1e | ||
|
|
fc78ba7c2f | ||
|
|
279359c1bd | ||
|
|
dc9fa7cf64 | ||
|
|
d6b28cdc57 | ||
|
|
75fb065526 | ||
|
|
6c5086a933 | ||
|
|
2b674d4cd9 | ||
|
|
5d0ddb3123 | ||
|
|
2d4b75428a | ||
|
|
f39d20ac97 | ||
|
|
db2b6f1268 | ||
|
|
99354ac576 | ||
|
|
e7b8531751 | ||
|
|
ff2f599142 | ||
|
|
f396b1bf73 | ||
|
|
e237dfc660 | ||
|
|
641029ab18 | ||
|
|
065ef29de2 | ||
|
|
aac0fa2b5f | ||
|
|
17edec8e4a | ||
|
|
8e667866fd | ||
|
|
01fe7d6620 | ||
|
|
f3aff45042 | ||
|
|
d6d94d9427 | ||
|
|
acb78205c8 | ||
|
|
dcb3c2c299 | ||
|
|
9048f8cffe | ||
|
|
4a2fb8336e | ||
|
|
34a16e0ab9 | ||
|
|
c2779b6f33 | ||
|
|
2e32b5f467 | ||
|
|
da5ec98f98 | ||
|
|
d54f5a3831 | ||
|
|
5e475acb85 | ||
|
|
f666d8a083 | ||
|
|
7ee7f00bf3 | ||
|
|
397a23499d | ||
|
|
d660bde324 | ||
|
|
94bd53c0f1 | ||
|
|
f70f4a4e85 | ||
|
|
f3eb9af046 | ||
|
|
0edf248cd1 | ||
|
|
514ffb74aa | ||
|
|
e6c8614801 | ||
|
|
05a9f2f0f5 | ||
|
|
115ef3249c | ||
|
|
a2461d9816 | ||
|
|
191cd21028 | ||
|
|
b3a785711c | ||
|
|
503b420292 | ||
|
|
0aa205044b | ||
|
|
00afe56cad | ||
|
|
1fd65c934d | ||
|
|
960e9edff5 | ||
|
|
b72720f6b6 | ||
|
|
f60a0c5ce0 | ||
|
|
ba903e21ed | ||
|
|
75b943b98a | ||
|
|
18565600b2 | ||
|
|
f4e4e734de | ||
|
|
6424bac47c | ||
|
|
bdd7d24ac1 | ||
|
|
5131759823 | ||
|
|
1e4ef81244 | ||
|
|
0fa807e7ad | ||
|
|
b6987b4287 | ||
|
|
ed0e2b52d7 | ||
|
|
168d35747d | ||
|
|
a01baab4f0 | ||
|
|
17c3e12eab | ||
|
|
71b001fdb7 | ||
|
|
833de9180e | ||
|
|
fb36561a68 | ||
|
|
67c60229ca | ||
|
|
f4bcb82041 | ||
|
|
983ccef87c | ||
|
|
a849dcadb6 | ||
|
|
d5afd0d7c2 | ||
|
|
ecc06aad24 | ||
|
|
cc83983ae5 | ||
|
|
ba5183b244 | ||
|
|
3d3584b36c | ||
|
|
c5e534c0cb | ||
|
|
a338a97d5b | ||
|
|
e11219888d | ||
|
|
e6638b4715 | ||
|
|
c9db8c6857 | ||
|
|
917a465ccd | ||
|
|
ce5adbf51e | ||
|
|
50e581d88a | ||
|
|
47d7fc70e8 | ||
|
|
e2574cf069 | ||
|
|
806ca4c842 | ||
|
|
ee1ec0428b | ||
|
|
3b17dca252 | ||
|
|
eef40cb3fd | ||
|
|
9f413ed174 | ||
|
|
233cfc29d6 | ||
|
|
e11330a5c8 | ||
|
|
0b2ad9deca | ||
|
|
227320f6f0 | ||
|
|
3bee6543fb | ||
|
|
581a3c5323 | ||
|
|
a59e84cadd | ||
|
|
d4627a0b1c | ||
|
|
95e45bbeac | ||
|
|
08a4763bff | ||
|
|
537f30f707 | ||
|
|
ad954d01de | ||
|
|
e3d70e6b62 | ||
|
|
cbf009a95d | ||
|
|
35cc763a92 | ||
|
|
cf05111622 | ||
|
|
e6224898d2 | ||
|
|
d566ffa678 | ||
|
|
6bf2e8a108 | ||
|
|
805ecde6a5 | ||
|
|
2a26b0ae91 | ||
|
|
916e088462 | ||
|
|
c918bbba25 | ||
|
|
57226b2e13 | ||
|
|
f46eecc1e7 | ||
|
|
5c062aaec4 | ||
|
|
b87106b6fe | ||
|
|
523e7b5084 | ||
|
|
41fa2d6c69 | ||
|
|
5947467339 | ||
|
|
0a11991340 | ||
|
|
0630609d6e | ||
|
|
205924ff29 | ||
|
|
7371e08625 | ||
|
|
bb5ec8cfb8 | ||
|
|
e6c8de5e4c | ||
|
|
bd403276f2 | ||
|
|
7f8dcf4f12 | ||
|
|
eef8f3b417 | ||
|
|
0fd8eeec23 | ||
|
|
7124c0aee5 | ||
|
|
852b2659e9 | ||
|
|
b41357e2a1 | ||
|
|
1cc816f662 | ||
|
|
bfe84a9ff7 | ||
|
|
339e620738 | ||
|
|
9ef710c557 | ||
|
|
df4ff26845 | ||
|
|
2e93a09d83 | ||
|
|
05aba0b4dd | ||
|
|
f098600c41 | ||
|
|
ad83825d4f | ||
|
|
3102440d40 | ||
|
|
715b1667d9 | ||
|
|
7d62e087c6 | ||
|
|
dcc65bbacb | ||
|
|
feaad50b6c | ||
|
|
7b2d54dffa | ||
|
|
e170217c33 | ||
|
|
aff58934c0 | ||
|
|
9f576369a9 | ||
|
|
7d7f43c205 | ||
|
|
30a5fe3061 | ||
|
|
b155e93ab1 | ||
|
|
3704ff57cb | ||
|
|
ee1d527497 | ||
|
|
f40f7b4d6e | ||
|
|
911510f999 | ||
|
|
45f5ac560d | ||
|
|
fe7020e2f8 | ||
|
|
17e161006a | ||
|
|
85d2ad4aea | ||
|
|
5b9cd0af64 | ||
|
|
8d298d5a06 | ||
|
|
3035c792dc | ||
|
|
2029b2b9ed | ||
|
|
900d8f3b0a | ||
|
|
e2de2f65d5 | ||
|
|
81da9f99e4 | ||
|
|
216f034b6d | ||
|
|
b96edd8b9a | ||
|
|
27ee95106d | ||
|
|
dac3138fd1 | ||
|
|
e0a7637626 | ||
|
|
8c4481733f | ||
|
|
d20e62dcd3 | ||
|
|
7805a3c527 | ||
|
|
0df3978cc5 | ||
|
|
bd4a88cd3e | ||
|
|
2dc1236dca | ||
|
|
2528d97f52 | ||
|
|
241b257556 | ||
|
|
83a42afddf | ||
|
|
780f83a118 | ||
|
|
ec3651d216 | ||
|
|
6154fc7686 | ||
|
|
1924459abd | ||
|
|
f66576f366 | ||
|
|
7470fc7f24 | ||
|
|
0e041a3b64 | ||
|
|
0406e3a7dd | ||
|
|
c8ae04a96a | ||
|
|
c809b6f95e | ||
|
|
1577efa25e | ||
|
|
fb93ae2128 | ||
|
|
25c9e9ef93 | ||
|
|
812dc9e898 | ||
|
|
bf4b698573 | ||
|
|
5162c55e5d | ||
|
|
096619dbbe | ||
|
|
fa02a09107 | ||
|
|
51e2ef39c2 | ||
|
|
b19bbf5473 | ||
|
|
e5c66d94f2 | ||
|
|
2a32713dfc | ||
|
|
acf26d5c63 | ||
|
|
39b14b6b81 | ||
|
|
ac81a3a5ef | ||
|
|
ab628eb2a3 | ||
|
|
b8c5a91940 | ||
|
|
f7d2c99a3a | ||
|
|
32408ed6a3 | ||
|
|
515b054a6e | ||
|
|
cef77ce5bb | ||
|
|
1267d995ef | ||
|
|
ec8091a102 | ||
|
|
5536df51f5 | ||
|
|
f48b12ff52 | ||
|
|
415a8d1e01 | ||
|
|
2a840460dd | ||
|
|
12f114c4be | ||
|
|
b593c3a9b9 | ||
|
|
8fa26db1b3 | ||
|
|
ecae0b3d97 | ||
|
|
63423c8ee1 | ||
|
|
ed16660867 | ||
|
|
9c9d6363af | ||
|
|
3a43b1d85d | ||
|
|
76f07a7f97 | ||
|
|
4d219df04e | ||
|
|
01bfadaeaa | ||
|
|
670d12219b | ||
|
|
da2c0a22f9 | ||
|
|
953ac6f3c7 | ||
|
|
545219b839 | ||
|
|
985fb44424 | ||
|
|
17c5502330 | ||
|
|
aa88837a31 | ||
|
|
a3ec9f3940 | ||
|
|
8cd9a1e4fc | ||
|
|
f4d9d34bbc | ||
|
|
20b4fc9198 | ||
|
|
e40112b40d | ||
|
|
cc09f9a7a5 | ||
|
|
4b505948f0 | ||
|
|
3cf6f1f79c | ||
|
|
905374c86e | ||
|
|
953ca2c21e | ||
|
|
8b42834c3f | ||
|
|
fb61c4fb34 | ||
|
|
30841d9470 | ||
|
|
7a4efcf67f | ||
|
|
6e0eb532a5 | ||
|
|
bfaabfb7b5 | ||
|
|
4578649f75 | ||
|
|
b6324246ff | ||
|
|
53e4713932 | ||
|
|
76e11b46b7 | ||
|
|
3dad4a9ff1 | ||
|
|
310f370b55 | ||
|
|
5b92922516 | ||
|
|
dbb0a0283f | ||
|
|
08f108e6cf | ||
|
|
5c947c7519 | ||
|
|
178b440f05 | ||
|
|
755dd67ec7 | ||
|
|
99e8499722 | ||
|
|
2e7606f569 | ||
|
|
22edd00211 | ||
|
|
c81f6b9f6f | ||
|
|
d0f0a99909 | ||
|
|
2793086c0d | ||
|
|
80d3a831f3 | ||
|
|
961539258b | ||
|
|
9749bbcedc | ||
|
|
aa5ac9dc3f | ||
|
|
0324bc5cf0 | ||
|
|
f6d7628254 | ||
|
|
e5f4d80bbe | ||
|
|
aa77b04860 | ||
|
|
5b479d63d6 | ||
|
|
8924f94d05 | ||
|
|
a873b7b6e8 | ||
|
|
7baa20d559 | ||
|
|
2b7f114c2d | ||
|
|
951bf5ec2e | ||
|
|
28a7458e48 | ||
|
|
e25bd28b73 | ||
|
|
a2a87fec54 | ||
|
|
d457f11717 | ||
|
|
bc5f73e6c3 | ||
|
|
1dc35db1fe | ||
|
|
427badcae9 | ||
|
|
e0b705fd54 | ||
|
|
854c23a751 | ||
|
|
fa48de33c2 | ||
|
|
fc7c4e64ff | ||
|
|
d9aa16aa82 | ||
|
|
976e32d3ae | ||
|
|
476116a972 | ||
|
|
f2dda646ec | ||
|
|
05ed20d336 | ||
|
|
b0476be36f | ||
|
|
a005088228 | ||
|
|
ef1c01d968 | ||
|
|
47fc0c7958 | ||
|
|
a9f690260a | ||
|
|
688171d016 | ||
|
|
a16dcc877c | ||
|
|
9a0dff08bc | ||
|
|
77dedf6648 | ||
|
|
212d8b6cfd | ||
|
|
9eb23a1208 | ||
|
|
ccfd028919 | ||
|
|
e5a919c32e | ||
|
|
eeaafe9f39 | ||
|
|
6430a232f8 | ||
|
|
24569a18db | ||
|
|
5c458e9111 | ||
|
|
0ef2622621 | ||
|
|
1ff9abe1b4 | ||
|
|
8e5948716e | ||
|
|
1e68d4fb75 | ||
|
|
1bec739195 | ||
|
|
025a7d2f0f | ||
|
|
ebf238be5d | ||
|
|
98484f0def | ||
|
|
892f061ad6 | ||
|
|
8bfb620a13 | ||
|
|
b6d425838f | ||
|
|
a83f13269f | ||
|
|
e963714ad6 | ||
|
|
6d4188f05e | ||
|
|
3e804757c1 | ||
|
|
cc43a49b6d | ||
|
|
b18b9464a4 | ||
|
|
71d4f65cb2 | ||
|
|
b5933e9d44 | ||
|
|
7abfe716b4 | ||
|
|
81b3c59711 | ||
|
|
410f5389ae | ||
|
|
290a14d29e | ||
|
|
a1183bf09a | ||
|
|
e109abbef7 | ||
|
|
43055e0199 | ||
|
|
1789c3242a | ||
|
|
f41380de77 | ||
|
|
0e0a6f5f8d | ||
|
|
ef95c68b4f | ||
|
|
0cada39c8a | ||
|
|
bdbbe00bdf | ||
|
|
a1241daa41 | ||
|
|
1f43da2ade | ||
|
|
1614dbf6ae | ||
|
|
96cd63cf1a | ||
|
|
974ca9d526 | ||
|
|
86985b454f | ||
|
|
c55a7b5f36 | ||
|
|
beb55235c6 | ||
|
|
9d5d3a9468 | ||
|
|
cf415a4312 | ||
|
|
bb3d56a0b2 | ||
|
|
8f181bb188 | ||
|
|
135d84ba37 | ||
|
|
77442dfcdc | ||
|
|
ed597146fa | ||
|
|
7a242f829f | ||
|
|
7fc2b13fe6 | ||
|
|
ee5372784e | ||
|
|
0dcea87b99 | ||
|
|
d5d5d78e3a | ||
|
|
a10f5e9e06 | ||
|
|
85e82e919e | ||
|
|
376ad1f024 | ||
|
|
9b96fe66a6 | ||
|
|
11045b92fb | ||
|
|
2ad5010dc3 | ||
|
|
40bba93a31 | ||
|
|
9410b63bbc | ||
|
|
4234c9a194 | ||
|
|
d43a814385 | ||
|
|
e46e7002a8 | ||
|
|
e6d20877b8 | ||
|
|
5ef8199dae | ||
|
|
e86e666c22 | ||
|
|
cf180f6142 | ||
|
|
67665a8b9d | ||
|
|
a50e555515 | ||
|
|
04518702d2 | ||
|
|
75b97cafb0 | ||
|
|
037cd74e8e | ||
|
|
82a81cd01f | ||
|
|
655290b022 | ||
|
|
b886a40471 | ||
|
|
c0d80a5828 | ||
|
|
adecd2960e | ||
|
|
9afecaaffe | ||
|
|
2af8105b46 | ||
|
|
4528becf4c | ||
|
|
d2a7f83bb5 | ||
|
|
b8b50bdb5a | ||
|
|
4485142a25 | ||
|
|
2a6afeb9a7 | ||
|
|
e2245446a3 | ||
|
|
08a9553ccc | ||
|
|
0a3fbdd128 | ||
|
|
cfbd2fc85c | ||
|
|
dd6718c2cd | ||
|
|
d5f72165fd | ||
|
|
c1a24d44a3 | ||
|
|
bf438f67e1 | ||
|
|
81f6511d34 | ||
|
|
a6012af00d | ||
|
|
f89b7ac9e1 | ||
|
|
a0d339f208 | ||
|
|
6cd348f155 | ||
|
|
2c7ce20ccf | ||
|
|
4bc4fd5b7e | ||
|
|
a92241d3cf | ||
|
|
344c293424 | ||
|
|
d20fb3a31b | ||
|
|
71cd6ef24b | ||
|
|
9b87a249b9 | ||
|
|
b84f7cd37f | ||
|
|
b5d8443f59 | ||
|
|
c08f428b5e | ||
|
|
20a79c7acf | ||
|
|
a4474b49cb | ||
|
|
0333dca550 | ||
|
|
af4352adf2 | ||
|
|
1877df0e70 | ||
|
|
a7e5e3d574 | ||
|
|
e81ac9e063 | ||
|
|
624f4641e2 | ||
|
|
dcba30a6aa | ||
|
|
25aded6b9b | ||
|
|
8d6c2b5d4a | ||
|
|
29a0a11b7e | ||
|
|
7582802f03 | ||
|
|
f8949ed5d1 | ||
|
|
7ae376b6cd | ||
|
|
390ce207db | ||
|
|
b93e398674 | ||
|
|
b70c680964 | ||
|
|
f9075e2a2f | ||
|
|
e596bf025b | ||
|
|
4a3ec65409 | ||
|
|
0f1fcd9743 | ||
|
|
f23bdde464 | ||
|
|
05d9e1bee5 | ||
|
|
a9d7acda27 | ||
|
|
1f5529752f | ||
|
|
b4eb9f2a11 | ||
|
|
c1039977f1 | ||
|
|
b1259876bf | ||
|
|
dfb6255f59 | ||
|
|
00b4843425 | ||
|
|
701acf59e2 | ||
|
|
380f65d309 | ||
|
|
316fee93f7 | ||
|
|
ca78374f30 | ||
|
|
670e83b300 | ||
|
|
44d3dadb03 | ||
|
|
9e9f2e13fe | ||
|
|
6602ff83dd | ||
|
|
8d284bab47 | ||
|
|
490ab9e2c5 | ||
|
|
0757dbf07f | ||
|
|
f35609d26c | ||
|
|
82ec40dd80 | ||
|
|
a52cdcb241 | ||
|
|
d1efb59fcd | ||
|
|
1523e116b9 | ||
|
|
90f2959076 | ||
|
|
6d4adfcedc | ||
|
|
f2ebe41a50 | ||
|
|
8f0c3f0e9b | ||
|
|
3b2679db29 | ||
|
|
4b350b9090 | ||
|
|
a3dfdd9d38 | ||
|
|
00d32f6b94 | ||
|
|
fad27fc1e7 | ||
|
|
3e6af5c876 | ||
|
|
75b169f391 | ||
|
|
df7772e301 | ||
|
|
63a97ff6fc | ||
|
|
cac6cef495 | ||
|
|
aab9766c53 | ||
|
|
ab54bf5149 | ||
|
|
55b587002e | ||
|
|
819683a073 | ||
|
|
7393dccde8 | ||
|
|
66effbfe08 | ||
|
|
ae94e8a855 | ||
|
|
f884fa6678 | ||
|
|
ac4688eac0 | ||
|
|
4691c3ec01 | ||
|
|
ca78ebce6d | ||
|
|
97e6b7c4ba | ||
|
|
ab6eb1c4b2 | ||
|
|
0919c1eb61 | ||
|
|
d554681174 | ||
|
|
551cf8ee94 | ||
|
|
61304d80d2 | ||
|
|
1bce285eca | ||
|
|
096fdfc61b | ||
|
|
8e4889bdf1 | ||
|
|
7b91e551c4 | ||
|
|
9d7abd58ac | ||
|
|
24360fd191 | ||
|
|
9017dcd0fd | ||
|
|
30d0f21079 | ||
|
|
d78bc12cbe | ||
|
|
2a9c1db0c9 | ||
|
|
4716627453 | ||
|
|
2f64684299 | ||
|
|
66b6f8c0ff | ||
|
|
e559f8b6a1 | ||
|
|
0d8dcdbbc9 | ||
|
|
da19ac98dd | ||
|
|
45568bf097 | ||
|
|
9908a7193a | ||
|
|
929d33fb22 | ||
|
|
a3e617987f | ||
|
|
c37eaff263 | ||
|
|
80f2ba640e | ||
|
|
f9a295a236 | ||
|
|
516c43ba15 | ||
|
|
84ba6393ad | ||
|
|
e00b8a7082 | ||
|
|
29ba891809 | ||
|
|
25357b208a | ||
|
|
80b422bdbe | ||
|
|
4e01956b33 | ||
|
|
1215638540 | ||
|
|
bbc71343bd | ||
|
|
a1aa3d9061 | ||
|
|
1aa3051e97 | ||
|
|
20f444f5f2 | ||
|
|
2d06663490 | ||
|
|
5e0698ba87 | ||
|
|
d7d347469c | ||
|
|
de006771c7 | ||
|
|
b4e5d303b5 | ||
|
|
a36bef7979 | ||
|
|
2fdd148598 | ||
|
|
3dc131757d | ||
|
|
1cb311cef9 | ||
|
|
ed56b6e67b | ||
|
|
049147a9d7 | ||
|
|
5c1f23b61a | ||
|
|
4d4e49f4d8 | ||
|
|
5f2baa59f5 | ||
|
|
c6aa42773a | ||
|
|
7a526fa8a9 | ||
|
|
598baa1b32 | ||
|
|
ef9b42aeb3 | ||
|
|
4979a45120 | ||
|
|
b66bacff9f | ||
|
|
9480e9b68b | ||
|
|
bf05012150 | ||
|
|
d8ace38041 | ||
|
|
bc20cf9fa3 | ||
|
|
019250eff8 | ||
|
|
ac095c89f1 | ||
|
|
f4da365abd | ||
|
|
b2f0d2d085 | ||
|
|
aefeda8c41 | ||
|
|
fdece3b102 | ||
|
|
cae380f068 | ||
|
|
3aa6e96904 | ||
|
|
a97e7b2758 | ||
|
|
2cda18f354 | ||
|
|
2e83c17e2d | ||
|
|
2f7d40d8db | ||
|
|
f228bf4555 | ||
|
|
a2cec8899a | ||
|
|
014168a29b | ||
|
|
39bc0664a7 | ||
|
|
853322e7d2 | ||
|
|
9cb1ac3de5 | ||
|
|
5b2474238e | ||
|
|
3c5cb15432 | ||
|
|
6e7d7c5017 | ||
|
|
1f2bd00d93 | ||
|
|
c7cad6ab60 | ||
|
|
0f5eb65210 | ||
|
|
fc239cb8a2 | ||
|
|
3fe7bd8bcc | ||
|
|
6b69184554 | ||
|
|
d5ca889cf5 | ||
|
|
062cb77539 | ||
|
|
b55e2776cc | ||
|
|
50d1d06b03 | ||
|
|
3eca1c3696 | ||
|
|
93a7df5a1b | ||
|
|
905432c7ae | ||
|
|
3355210878 | ||
|
|
ada26dd2cb | ||
|
|
f4b31dcb3a | ||
|
|
7abb214eaf | ||
|
|
77eb9bcfa0 | ||
|
|
c17b47518d | ||
|
|
1f7e6cae82 | ||
|
|
37d14f3a1d | ||
|
|
166d63ff60 | ||
|
|
d38851023e | ||
|
|
e35bd5d251 | ||
|
|
c77732b8ed | ||
|
|
16f79b70e4 | ||
|
|
43c2b22fca | ||
|
|
9a64c6b9f7 | ||
|
|
20cb4130d4 | ||
|
|
bfbe6c1660 | ||
|
|
dc78ab1c77 | ||
|
|
51edd472c2 | ||
|
|
1977ab35c0 | ||
|
|
296957b5b5 | ||
|
|
0d04a1221a | ||
|
|
6ac6537f10 | ||
|
|
883b1ff513 | ||
|
|
de1527eba8 | ||
|
|
2dcedd6951 | ||
|
|
c8322e89c6 | ||
|
|
18a9831cd3 | ||
|
|
9f77180af8 | ||
|
|
0bd4939695 | ||
|
|
605c05fc8b | ||
|
|
fa3aed4e59 | ||
|
|
217db8f9b2 | ||
|
|
a0dd03ea0e | ||
|
|
894114bfbd | ||
|
|
90353d90dc | ||
|
|
c9ce5664d4 | ||
|
|
e8ad16cf2a | ||
|
|
c3090d5480 | ||
|
|
f48aee5975 | ||
|
|
60f6b827f4 | ||
|
|
f05b4637b9 | ||
|
|
fffeca59d0 | ||
|
|
b14dd0e066 | ||
|
|
ec81ef7b8d | ||
|
|
e02c658eb5 | ||
|
|
0800bd1e19 | ||
|
|
0503b11840 | ||
|
|
b497faee27 | ||
|
|
7ee31276f5 | ||
|
|
5897f62fa9 | ||
|
|
0baab50191 | ||
|
|
0db1594f95 | ||
|
|
1e00fa79b3 | ||
|
|
573dea42d0 | ||
|
|
269055e71c | ||
|
|
2f222546da | ||
|
|
522fec5763 | ||
|
|
f2fc7d25c5 | ||
|
|
2d79e75788 | ||
|
|
781716277b | ||
|
|
9f57bfb5df | ||
|
|
4d00c48026 | ||
|
|
8fe8341d93 | ||
|
|
57273db8a6 | ||
|
|
bc9f88f3f9 | ||
|
|
70d413ab04 | ||
|
|
710d6ebd49 | ||
|
|
ac1ec99684 | ||
|
|
8e5718bf04 | ||
|
|
89561bec4f | ||
|
|
fae78b947f | ||
|
|
d35dfc12ce | ||
|
|
69112a17ac | ||
|
|
32ad8bbaac | ||
|
|
913d07a4a7 | ||
|
|
b40d8070f3 | ||
|
|
1fb21b781f | ||
|
|
25df2080ea | ||
|
|
5632022d79 | ||
|
|
d968fc51ea | ||
|
|
c7698e4dc3 | ||
|
|
4dd3839c41 | ||
|
|
9caaa9397e | ||
|
|
915bd2ec77 | ||
|
|
ba64b11ac0 | ||
|
|
40e3d37a72 | ||
|
|
2882eef42f | ||
|
|
0b02a6d123 | ||
|
|
40b5b6e9d2 | ||
|
|
78b40e6363 | ||
|
|
45c19e365d | ||
|
|
2469853175 | ||
|
|
0c5434d5e3 | ||
|
|
8ab7707898 | ||
|
|
baa7020036 | ||
|
|
f658a3cae1 | ||
|
|
a674b05e96 | ||
|
|
b7e7ef0bf3 | ||
|
|
0b8a7f1bd0 | ||
|
|
9c8cf7d433 | ||
|
|
180731c162 | ||
|
|
ea1173f8f6 | ||
|
|
ef97e5a063 | ||
|
|
61909d2480 | ||
|
|
7aeff7505b | ||
|
|
a3e94591bc | ||
|
|
24c1dc528d | ||
|
|
6f486a3393 | ||
|
|
c8f686b8a5 | ||
|
|
89c65de863 | ||
|
|
94accd8a4c | ||
|
|
b6e0d8dee0 | ||
|
|
2a14c71128 | ||
|
|
d714cd76dd | ||
|
|
5ac262bd61 | ||
|
|
174484a51c | ||
|
|
09ef30feb0 | ||
|
|
e7a65c1f8d | ||
|
|
f73a74967e | ||
|
|
bbbae3f42d | ||
|
|
0746794e81 | ||
|
|
2b77c9a74b | ||
|
|
75128e8f68 | ||
|
|
284d86ad76 | ||
|
|
852ff39856 | ||
|
|
7f974a543f | ||
|
|
6950100ff4 | ||
|
|
e9e2159b3b | ||
|
|
b08fc746d8 | ||
|
|
4a36834d3f | ||
|
|
5882714e23 | ||
|
|
7101bbedcb | ||
|
|
712b2b1bb2 | ||
|
|
3011d3768c | ||
|
|
5508feb6ce | ||
|
|
2e3da0cbbb | ||
|
|
f38c8e5eca | ||
|
|
0314624aeb | ||
|
|
2174cdcd0e | ||
|
|
6ce939491b | ||
|
|
8ffdc4859b | ||
|
|
9b19a51fc6 | ||
|
|
9eac9ef2b9 | ||
|
|
566667a263 | ||
|
|
8cb06e7af8 | ||
|
|
1b6bc5394b | ||
|
|
50fb525b28 | ||
|
|
8c9a773a90 | ||
|
|
e1e56936c9 | ||
|
|
33a8d845c1 | ||
|
|
9fe33bb67d | ||
|
|
0db8d3f6c6 | ||
|
|
7c57da3a28 | ||
|
|
1685548a4c | ||
|
|
191298ec93 | ||
|
|
e4a2aacd1d | ||
|
|
5686ee13b4 | ||
|
|
45c7a03a0d | ||
|
|
3df0bb5522 | ||
|
|
7fe697d896 | ||
|
|
0bdcaff00f | ||
|
|
8088185a43 | ||
|
|
2db86b950e | ||
|
|
9619d02be9 | ||
|
|
dccdeedb75 | ||
|
|
b371c028ad | ||
|
|
b017f8f2ab | ||
|
|
2b7b26f4c0 | ||
|
|
ae39217a7e | ||
|
|
78e42a75f1 | ||
|
|
e0e76ce82c | ||
|
|
559ed3f0a8 | ||
|
|
a10fe5f13e | ||
|
|
bd2f11ed8b | ||
|
|
5e458491f1 | ||
|
|
4ed5d6573c | ||
|
|
c2d15e6c3b | ||
|
|
f284558007 | ||
|
|
23bb4e8e15 | ||
|
|
cd518625bf | ||
|
|
b1ae4d776c | ||
|
|
95b9669213 | ||
|
|
b4bf71dd06 | ||
|
|
b35e69273d | ||
|
|
4560298b98 | ||
|
|
d892a47ac9 | ||
|
|
fa80a5c113 | ||
|
|
7fac859fbd | ||
|
|
02d8363019 | ||
|
|
84d93cca6e | ||
|
|
9446d0cbb4 | ||
|
|
8a41e2a011 | ||
|
|
36fe2ac87e | ||
|
|
3fe8fc0aa8 | ||
|
|
3d9fcee075 | ||
|
|
917bcb55fd | ||
|
|
026787fc73 | ||
|
|
d43c7603bf | ||
|
|
17dba9542a | ||
|
|
c96b20c559 | ||
|
|
8189a7c693 | ||
|
|
2f74f9eb40 | ||
|
|
ab17b2e0d6 | ||
|
|
8f16e9ad33 | ||
|
|
7d380570df | ||
|
|
80c9a8b8f6 | ||
|
|
8544819be1 | ||
|
|
45654ffc5c | ||
|
|
45512e6aba | ||
|
|
d7a64845fe | ||
|
|
4c47d22f4b | ||
|
|
931a4fafe3 | ||
|
|
83a0e82d5c | ||
|
|
e7fbf1b017 | ||
|
|
b5b21ecad7 | ||
|
|
9d079e5d2b | ||
|
|
18f505608b | ||
|
|
b797528b78 | ||
|
|
d8aa0ac36c | ||
|
|
49b957f7ea | ||
|
|
e01b90c4c6 | ||
|
|
1fdac57d61 | ||
|
|
0788d37c60 | ||
|
|
776b7074ea | ||
|
|
bb96f44861 | ||
|
|
30a6ae3daa | ||
|
|
37a852d2d1 | ||
|
|
59777333dd | ||
|
|
eb85f8572f | ||
|
|
b664af748e | ||
|
|
f108838ca9 | ||
|
|
2ddd03f597 | ||
|
|
bdef71bda0 | ||
|
|
d4eb5e7c6d | ||
|
|
8e8df26066 | ||
|
|
c91e43af34 | ||
|
|
b13c21f872 | ||
|
|
f975d9dfe4 | ||
|
|
a6baa5a6da | ||
|
|
26131ffc91 | ||
|
|
aeda293bd0 | ||
|
|
a67fa2651d | ||
|
|
509f25e46a | ||
|
|
f99daf8ff9 | ||
|
|
607125e795 | ||
|
|
f34dcffbd9 | ||
|
|
ce50a429fa | ||
|
|
3446e68ac2 | ||
|
|
e508ad37c1 | ||
|
|
f55d9e8c62 | ||
|
|
563e82feff | ||
|
|
5553df862a | ||
|
|
2e7028c976 | ||
|
|
78e4b64c8b | ||
|
|
d62f490814 | ||
|
|
6bf7716518 | ||
|
|
ae02624793 | ||
|
|
c3b0c0f32a | ||
|
|
6aef5593d5 | ||
|
|
975140634c | ||
|
|
f336f38ad5 | ||
|
|
f027bf81cd | ||
|
|
d67d8b6d6e | ||
|
|
02ee7f17e8 | ||
|
|
78320ee3a6 | ||
|
|
a9d926886e | ||
|
|
6291c08e01 | ||
|
|
4b9c3cc998 | ||
|
|
fdf7120aec | ||
|
|
e5e68d7350 | ||
|
|
d914290002 | ||
|
|
42ee3ab21c | ||
|
|
15cfd6fda7 | ||
|
|
0e34811886 | ||
|
|
5b3f536613 | ||
|
|
ce45a1cf94 | ||
|
|
79c63e3cf4 | ||
|
|
df2990b27e | ||
|
|
9d698c0887 | ||
|
|
1e27038b73 | ||
|
|
7e30c1dd82 | ||
|
|
78bf4564f2 | ||
|
|
665a517a47 | ||
|
|
57110cbe76 | ||
|
|
b0a2e5d3f7 | ||
|
|
f3eae7132f | ||
|
|
0463df62f0 | ||
|
|
a8823ae7d8 | ||
|
|
fdef224da1 | ||
|
|
59c642ed19 | ||
|
|
2b91962b32 | ||
|
|
61e695e143 | ||
|
|
aab9218558 | ||
|
|
c250cb955e | ||
|
|
f111275ddf | ||
|
|
2726c68b60 | ||
|
|
1288a72963 | ||
|
|
d66f6c8e8c | ||
|
|
a3ce194bf5 | ||
|
|
5a427dcee3 | ||
|
|
7d45f63b78 | ||
|
|
540800da95 | ||
|
|
1ff189ee90 | ||
|
|
692e41c41e | ||
|
|
cb8c83a42b | ||
|
|
bd11b1d61a | ||
|
|
96d19c09f3 | ||
|
|
d7f4bfedd5 | ||
|
|
391ed8655e | ||
|
|
aa0c70e198 | ||
|
|
82de68c3d3 | ||
|
|
4669107634 | ||
|
|
cf79c4ea48 | ||
|
|
ae932922c4 | ||
|
|
bacd05ea9e | ||
|
|
657b34c012 | ||
|
|
5eb594706b | ||
|
|
2b0a04ea9e | ||
|
|
f00a701ad1 | ||
|
|
dff9e18c1e | ||
|
|
d2f67bf249 | ||
|
|
8f64b28fb9 | ||
|
|
0d91f363cc | ||
|
|
23180ae078 | ||
|
|
b96eb1c823 | ||
|
|
635580091a | ||
|
|
a768bb1ab2 | ||
|
|
59799ba2b4 | ||
|
|
8147e6203f | ||
|
|
2641980ac2 | ||
|
|
683da1aa77 | ||
|
|
21b0128e9e | ||
|
|
d07afb54e4 | ||
|
|
1e8b3fe749 | ||
|
|
9040ee53e4 | ||
|
|
974390d5d2 | ||
|
|
8a57b845ae | ||
|
|
324771f858 | ||
|
|
dd7fdf0c2b | ||
|
|
bb7b756974 | ||
|
|
e805f589aa | ||
|
|
6941fbb182 | ||
|
|
7594796ee1 | ||
|
|
f53478f142 | ||
|
|
2a4e8972e0 | ||
|
|
2a61817bad | ||
|
|
e47a473e2c | ||
|
|
094d4cc325 | ||
|
|
a49fa5f87c | ||
|
|
ca59ecd107 | ||
|
|
f761ea5fc9 | ||
|
|
1698732cff | ||
|
|
a9f68e4d2a | ||
|
|
f12af17238 | ||
|
|
d1ecf3f323 | ||
|
|
9cddbc9a47 | ||
|
|
966773cdbb | ||
|
|
d2e61122c5 | ||
|
|
7229cd56ed | ||
|
|
521d404013 | ||
|
|
5591eac973 | ||
|
|
c8dec1fae5 | ||
|
|
c366bbaa54 | ||
|
|
72e7c50968 | ||
|
|
f4cca21fdf | ||
|
|
d7fe48d1b6 | ||
|
|
fddacf0a5a | ||
|
|
08a651dc9d | ||
|
|
65571249b2 | ||
|
|
b4205554a8 | ||
|
|
0865d0ef51 | ||
|
|
b57f69d14d | ||
|
|
07650b4646 | ||
|
|
ce582ccada | ||
|
|
ee5163ce64 | ||
|
|
bbe33f9503 | ||
|
|
2cb04ccb8f | ||
|
|
aaa327ca05 | ||
|
|
ce34c4086d | ||
|
|
fe9df64fc2 | ||
|
|
f124f4a9f5 | ||
|
|
a1af2cbb30 | ||
|
|
ec9e914798 | ||
|
|
ec5bd9d679 | ||
|
|
c38c79d71c | ||
|
|
45a854762b | ||
|
|
1806da0851 | ||
|
|
521641f3a8 | ||
|
|
a29c0371f1 | ||
|
|
a8f7af2079 | ||
|
|
7ae7fac234 | ||
|
|
d1fb4e9b03 | ||
|
|
ed0bff798b | ||
|
|
3f0bb1bb1d | ||
|
|
9a0b61e4af | ||
|
|
b81291cd5c | ||
|
|
a8a0ca8291 | ||
|
|
1c61be4113 | ||
|
|
91cc365143 | ||
|
|
f4a27afee9 | ||
|
|
be654f1769 | ||
|
|
73628db7e2 | ||
|
|
571c72f853 | ||
|
|
b788b38edf | ||
|
|
09861abab7 | ||
|
|
202035fc68 | ||
|
|
5ab1d509d2 | ||
|
|
1b83d88fe6 | ||
|
|
482962648f | ||
|
|
326f3cfc85 | ||
|
|
4ba8526745 | ||
|
|
0269825bc0 | ||
|
|
5cb3143c04 | ||
|
|
d1a2aecfa0 | ||
|
|
0fe4957274 | ||
|
|
e9f1bac062 | ||
|
|
58692e3565 | ||
|
|
7db733c9a0 | ||
|
|
abfbe9c937 | ||
|
|
f437705007 | ||
|
|
46ed79c87a | ||
|
|
e2b4d33627 | ||
|
|
7690dca67b | ||
|
|
c0bdcfedeb | ||
|
|
9b66b5eee3 | ||
|
|
2db59f3b76 | ||
|
|
44e21f6198 | ||
|
|
279f32b13d | ||
|
|
3a6187af3d | ||
|
|
516f776c94 | ||
|
|
cc62793d6f | ||
|
|
d87daaedd1 | ||
|
|
cf84ff3344 | ||
|
|
e419b2c18c | ||
|
|
58324473a9 | ||
|
|
62d842de31 | ||
|
|
aa678ba0ff | ||
|
|
e4391e6336 | ||
|
|
aa0412d83b | ||
|
|
861f5232d3 | ||
|
|
9831ad515d | ||
|
|
6650916435 | ||
|
|
64cc0b794a | ||
|
|
29363a185d | ||
|
|
e41082dccc | ||
|
|
97ccbf1bfb | ||
|
|
a20ef706fd | ||
|
|
adad8f2ebc | ||
|
|
0533db5d38 | ||
|
|
fb9c12df15 | ||
|
|
5a2a8717e3 | ||
|
|
0d50d29538 | ||
|
|
54aa998b52 | ||
|
|
10f1e2d51b | ||
|
|
9fd8634b62 | ||
|
|
fd07940b10 | ||
|
|
6f6051f7e3 | ||
|
|
f9778fda83 | ||
|
|
ea3fb53e4b | ||
|
|
a7d5bf6854 | ||
|
|
0e7a963173 | ||
|
|
4aa2733699 | ||
|
|
1eb6067c31 | ||
|
|
bd29551f9a | ||
|
|
32ccdd1f57 | ||
|
|
deaf0e99fd | ||
|
|
d99a1d8de0 | ||
|
|
0012030826 | ||
|
|
ec41170121 | ||
|
|
1d5ea5efae | ||
|
|
01ad485f65 | ||
|
|
447c59fd9b | ||
|
|
3de40bdf04 | ||
|
|
ba6c346b46 | ||
|
|
1c9f773900 | ||
|
|
ec651f219e | ||
|
|
ee8a9384d5 | ||
|
|
bba34a7a8e | ||
|
|
dfa12b2919 | ||
|
|
9b9f29a0b2 | ||
|
|
4a9aad2a33 | ||
|
|
69617b5c34 | ||
|
|
222ace3770 | ||
|
|
2e7d2a63c3 | ||
|
|
0523b4b2f1 | ||
|
|
a703835b5c | ||
|
|
bf3f3564e0 | ||
|
|
102d41ccb9 | ||
|
|
cfad5ba8b8 | ||
|
|
b4c1baada1 | ||
|
|
1ca3eeedff | ||
|
|
298b53e93a | ||
|
|
f13096a6f3 | ||
|
|
470f14b919 | ||
|
|
53311a30ad | ||
|
|
5634a4bb61 | ||
|
|
738e14348d | ||
|
|
787e2ef961 | ||
|
|
db4e9aeaad | ||
|
|
7850b04853 | ||
|
|
b6f18a9a0b | ||
|
|
b8d8be7013 | ||
|
|
84feff9500 | ||
|
|
81ba293561 | ||
|
|
8b3c099a12 | ||
|
|
2772a72095 | ||
|
|
e361ee9253 | ||
|
|
3edd4ce78f | ||
|
|
381cc3e6f8 | ||
|
|
d09694587d | ||
|
|
63451db3f6 | ||
|
|
7660afdb0f | ||
|
|
72d995d35f | ||
|
|
2a32df75f1 | ||
|
|
e16da7a166 | ||
|
|
5b55726a93 | ||
|
|
bbe93d0e1d | ||
|
|
5dd422e2d8 | ||
|
|
a564f495a7 | ||
|
|
995555f357 | ||
|
|
40f3857691 | ||
|
|
5d884c2f3d | ||
|
|
8f006a98c4 | ||
|
|
ebac0bdcca | ||
|
|
3575ef8a39 | ||
|
|
60bb8f25f7 | ||
|
|
2d3dd673e4 | ||
|
|
9d47de65d9 | ||
|
|
c6d9100649 | ||
|
|
44283dbbbb | ||
|
|
0cda431456 | ||
|
|
bbfe4de310 | ||
|
|
36b388ab8c | ||
|
|
c0b3d7e1b4 | ||
|
|
9abd95fad3 | ||
|
|
50d9b29347 | ||
|
|
90a5ba01a3 | ||
|
|
6c2673ae2a | ||
|
|
256c228efd | ||
|
|
3fdd110e07 | ||
|
|
1cd3b41825 | ||
|
|
4148211086 | ||
|
|
4ba9a5ef75 | ||
|
|
6a6dbec033 | ||
|
|
df891f4ad2 | ||
|
|
08461c7049 | ||
|
|
5462453bf2 | ||
|
|
e4f3605054 | ||
|
|
f65ede9c38 | ||
|
|
a6ad37c691 | ||
|
|
ba0812c447 | ||
|
|
dbde9a0940 | ||
|
|
d3f38c9f43 | ||
|
|
971e7321c6 | ||
|
|
eeb1c463e3 | ||
|
|
99d9456b3a | ||
|
|
97eef2b88c | ||
|
|
c25ef1d9a8 | ||
|
|
661b0084f3 | ||
|
|
f714e97d63 | ||
|
|
a507063174 | ||
|
|
3caf51b075 | ||
|
|
92ec46b62e | ||
|
|
9b06d952a2 | ||
|
|
531710142c | ||
|
|
59827b6dfd | ||
|
|
61bef7d4b0 | ||
|
|
f200dd4395 | ||
|
|
a8ac0ed549 | ||
|
|
6f2ba0c619 | ||
|
|
0a14ac1f60 | ||
|
|
02140b2f76 | ||
|
|
c6b89b99b9 | ||
|
|
51a840f46a | ||
|
|
b081c3e94b | ||
|
|
ec99e3ed62 | ||
|
|
97e1a6dfde | ||
|
|
56c86b6567 | ||
|
|
28599fe652 | ||
|
|
d3e7ef70e8 | ||
|
|
fea532af4d | ||
|
|
f5b22dfd5b | ||
|
|
48e62bb50a | ||
|
|
513078e1f7 | ||
|
|
23151100de | ||
|
|
eb68b66c58 | ||
|
|
1ddb43b0d3 | ||
|
|
9fcd470aca | ||
|
|
23419e4c26 | ||
|
|
34b42566b6 | ||
|
|
f7ff48f806 | ||
|
|
30cf56bdb5 | ||
|
|
77094f8d2b | ||
|
|
51cd4e8519 | ||
|
|
bd249b276d | ||
|
|
b6ae2bff01 | ||
|
|
21c1f89eba | ||
|
|
df61970b39 | ||
|
|
f82afca84d | ||
|
|
eca119d695 | ||
|
|
40162cd6b7 | ||
|
|
a41a05e6c0 | ||
|
|
a83cdbeb39 | ||
|
|
6d4fe5c56f | ||
|
|
3a8f6e6576 | ||
|
|
38eb79705e | ||
|
|
f7ddd44c2e | ||
|
|
2165733ddc | ||
|
|
d22b21c56f | ||
|
|
4188419b30 | ||
|
|
d98d7003ed | ||
|
|
1692380ac7 | ||
|
|
01a28ddf8d | ||
|
|
e8d19659c0 | ||
|
|
b673b6835d | ||
|
|
ef7494359f | ||
|
|
b8e8517725 | ||
|
|
def0454952 | ||
|
|
2f5862713e | ||
|
|
6729c27b77 | ||
|
|
fbfa391965 | ||
|
|
38beabb508 | ||
|
|
a8d5c83251 | ||
|
|
370a007ee2 | ||
|
|
7747a23a78 | ||
|
|
c573670821 | ||
|
|
a752d44313 | ||
|
|
9406ff714b | ||
|
|
cc29e27acc | ||
|
|
b2563528ee | ||
|
|
70ad69d38c | ||
|
|
cb0c43bc68 | ||
|
|
7efffbf102 | ||
|
|
2d8deb6082 | ||
|
|
5de79cdb10 | ||
|
|
6837c2ef1e | ||
|
|
4e9440396c | ||
|
|
32c23ef562 | ||
|
|
107f80892a | ||
|
|
fbcb711945 | ||
|
|
e95a494041 | ||
|
|
7732532964 | ||
|
|
bb09b8a385 | ||
|
|
b9b46a3f88 | ||
|
|
7bb461380e | ||
|
|
f5f79b39b8 | ||
|
|
14e55e8bd6 | ||
|
|
bc9d5f5a48 | ||
|
|
c2cdd41e81 | ||
|
|
256cd6baac | ||
|
|
843cc1481a | ||
|
|
cf4dc2caa8 | ||
|
|
1258f9bb21 | ||
|
|
5f41d06bb9 | ||
|
|
8f4fe106ef | ||
|
|
d74274c7e4 | ||
|
|
d59268a5d8 | ||
|
|
f364343b55 | ||
|
|
9debfa348a | ||
|
|
32e903e956 | ||
|
|
bd8fe768d3 | ||
|
|
848c038970 | ||
|
|
24fa201218 | ||
|
|
1a77fb4c1d | ||
|
|
76467b5a35 | ||
|
|
d5db25808a | ||
|
|
6824fb9f93 | ||
|
|
b2216f8203 | ||
|
|
0799a0a3be | ||
|
|
a2e0574fce | ||
|
|
68d7ab6b55 | ||
|
|
4a2c805270 | ||
|
|
7d5b266227 | ||
|
|
1f56ff5407 | ||
|
|
95f5f3d44d | ||
|
|
7a5213cc8e | ||
|
|
f1f19372ad | ||
|
|
276f44328e | ||
|
|
da3f1326e0 | ||
|
|
a013ddbb91 | ||
|
|
1c6faa3a00 | ||
|
|
b7f15ccac1 | ||
|
|
1fb7b9baae | ||
|
|
a1e4940bea | ||
|
|
287ffe93f6 | ||
|
|
2407379623 | ||
|
|
7162403292 | ||
|
|
004468f231 | ||
|
|
2d7e307e74 | ||
|
|
d7466ade46 | ||
|
|
01c0e5c46c | ||
|
|
86f840843f | ||
|
|
9a0f0181a5 | ||
|
|
25ebac8d0b | ||
|
|
edf6da7189 | ||
|
|
059da4d017 | ||
|
|
a59d1b22f6 | ||
|
|
dd4a66353a | ||
|
|
2cf54c465d | ||
|
|
d3491c9165 | ||
|
|
8ca877bdd3 | ||
|
|
b704f977da | ||
|
|
59e04aed1b | ||
|
|
436e91a1e1 | ||
|
|
6f4c45a489 | ||
|
|
157bbb14b5 | ||
|
|
5c22f59c4f | ||
|
|
aa62bad07b | ||
|
|
d3f2d2a2db | ||
|
|
c5d08fd5fd | ||
|
|
22729da2a2 | ||
|
|
c97cc1487c | ||
|
|
428b4dbad6 | ||
|
|
264abef817 | ||
|
|
548bf884a4 | ||
|
|
a0baa480e3 | ||
|
|
765dd5569b | ||
|
|
c19a1a6b82 | ||
|
|
8b61e546fe | ||
|
|
7206e8af3a | ||
|
|
7808689198 | ||
|
|
966d1586c0 | ||
|
|
edffd9f183 | ||
|
|
7edc505c2f | ||
|
|
4df78b06cf | ||
|
|
492609d20b | ||
|
|
0f76af261c | ||
|
|
9d00db06b2 | ||
|
|
141f3e21b2 | ||
|
|
fe6cbb414c | ||
|
|
e13d65eea3 | ||
|
|
4d6050f8e5 | ||
|
|
0ebce75c7d | ||
|
|
91bb4bdf50 | ||
|
|
be2b7c0b5f | ||
|
|
2d45f9f385 | ||
|
|
44b2503572 | ||
|
|
3f90da5643 | ||
|
|
d27a627c4f | ||
|
|
55ab5360d9 | ||
|
|
bfeeb76143 | ||
|
|
f2d3be2e67 | ||
|
|
60b818eb24 | ||
|
|
ebe70a41b9 | ||
|
|
da79662081 | ||
|
|
72f3f7c172 | ||
|
|
713a796d9f | ||
|
|
69c6d8b617 | ||
|
|
e084a85e79 | ||
|
|
a1f046992d | ||
|
|
cd5630476f | ||
|
|
f7f20c5917 | ||
|
|
44797fe988 | ||
|
|
c5333b5187 | ||
|
|
2d045a12bf | ||
|
|
a2fe22412f | ||
|
|
df69465357 | ||
|
|
e4361cb202 | ||
|
|
58cf9d832c | ||
|
|
cf5383fdbe | ||
|
|
6126070a1d | ||
|
|
459166116d | ||
|
|
776bc51172 | ||
|
|
df57c90d2d | ||
|
|
5a563b8e76 | ||
|
|
0653a2e0a9 | ||
|
|
d19dfc87a6 | ||
|
|
dc8c7a2d2e | ||
|
|
ba2ede0a8f | ||
|
|
6892ba4cd8 | ||
|
|
5ad9b48f1d | ||
|
|
7972de13ca | ||
|
|
ea54987ca4 | ||
|
|
b2474334a7 | ||
|
|
2a0d4a2011 | ||
|
|
be27fb5644 | ||
|
|
ebfa1a12b9 | ||
|
|
21f2df399d | ||
|
|
43521bb10b | ||
|
|
c95d7c69eb | ||
|
|
f12b0fe316 | ||
|
|
8944d7a7a2 | ||
|
|
6300f47cdc | ||
|
|
2b95580cc0 | ||
|
|
93b84f1262 | ||
|
|
1ffae1327f | ||
|
|
01a8292d65 | ||
|
|
9d3ce55978 | ||
|
|
7e6febe2a6 | ||
|
|
e73df9ed1d | ||
|
|
b101a8f6fb | ||
|
|
ddeab48f9b | ||
|
|
d074c53889 | ||
|
|
039eb58524 | ||
|
|
29c9e7c0a2 | ||
|
|
f15a06c0c2 | ||
|
|
ab89eb050a | ||
|
|
eca1f84328 | ||
|
|
3bde7b8f18 | ||
|
|
9db1148650 | ||
|
|
502fed198d | ||
|
|
411c510778 | ||
|
|
dd6e3d873d | ||
|
|
f9b092c619 | ||
|
|
edc7c0837b | ||
|
|
f535d438b2 | ||
|
|
119ffd2d2d | ||
|
|
2c3bec3d7c | ||
|
|
f1564b4cff | ||
|
|
c9252d49f7 | ||
|
|
411abdf8a7 | ||
|
|
1fcc863298 | ||
|
|
e37c1ed981 | ||
|
|
0c5a2925ad | ||
|
|
272ffe6983 | ||
|
|
368bb18935 | ||
|
|
22f172d697 | ||
|
|
fe9abcfaae | ||
|
|
dfbe2eaf98 | ||
|
|
a9711895cf | ||
|
|
8882ffc0de | ||
|
|
fdd7faab51 | ||
|
|
d004017b01 | ||
|
|
f2d27d543d | ||
|
|
1db3409f36 | ||
|
|
cfa2ac2d0a | ||
|
|
ebc66d7008 | ||
|
|
3f0eb84ecf | ||
|
|
fbc6c60805 | ||
|
|
02e82e496e | ||
|
|
8e586008dd | ||
|
|
50c7c33ed1 | ||
|
|
ca52d39abe | ||
|
|
28d07fd6b2 | ||
|
|
5a7b994e59 | ||
|
|
4512a4cdd4 | ||
|
|
342fda94e4 | ||
|
|
cc264b2d60 | ||
|
|
33c34984e6 | ||
|
|
fe392a3144 | ||
|
|
eeed7077ca | ||
|
|
dba1854837 | ||
|
|
c107bcfbd9 | ||
|
|
912ebfebff | ||
|
|
76bf892f9f | ||
|
|
12a9b49c6d | ||
|
|
aecf9e32ef | ||
|
|
879bc71927 | ||
|
|
4da7fcb41d | ||
|
|
3a84e7051e | ||
|
|
161050df07 | ||
|
|
29284319a5 | ||
|
|
86e73fd313 | ||
|
|
62e141a89c | ||
|
|
cd8b7687c1 | ||
|
|
4436cd9ade | ||
|
|
ddbe3c7426 | ||
|
|
b8c7b2f81d | ||
|
|
696c6e88ea | ||
|
|
a83eb14ff6 | ||
|
|
8e6dc0b66b | ||
|
|
41ec5403e1 | ||
|
|
77eb6c5761 | ||
|
|
89c6cda303 | ||
|
|
d49afead67 | ||
|
|
0a10215371 | ||
|
|
64f5d80ff2 | ||
|
|
28a593e1ce | ||
|
|
f738902107 | ||
|
|
364972a292 | ||
|
|
0eb0256502 | ||
|
|
679fb7d0d2 | ||
|
|
45247d1595 | ||
|
|
3be6ef6bfc | ||
|
|
c5827c8b4f | ||
|
|
bb381daae3 | ||
|
|
d0090f09fb | ||
|
|
afb86aa908 | ||
|
|
3b97a9f766 | ||
|
|
d3c779f635 | ||
|
|
4f285911f0 | ||
|
|
8ccddfefd9 | ||
|
|
4351a83d16 | ||
|
|
ddefe3b3ac | ||
|
|
b77c5ae61e | ||
|
|
dd2d12350c | ||
|
|
ade91f8190 | ||
|
|
d04aef4c44 | ||
|
|
689a6dc085 | ||
|
|
0b487122f6 | ||
|
|
ac4a8fde3a | ||
|
|
31aaf40ade | ||
|
|
af7c7642bb | ||
|
|
d939173c0e | ||
|
|
a87efe45e0 | ||
|
|
55515a25d1 | ||
|
|
7d7a254238 | ||
|
|
564a5ea4d5 | ||
|
|
d9c59a19fb | ||
|
|
83b5adf194 | ||
|
|
a26d1794fe | ||
|
|
06a1258a9a | ||
|
|
d31d3df4ea | ||
|
|
91801d2e2c | ||
|
|
95c686de6e | ||
|
|
bcb94f8238 | ||
|
|
1d2260b44e | ||
|
|
81c10fc739 | ||
|
|
191a2fd5be | ||
|
|
97be144913 | ||
|
|
8c99228c8a | ||
|
|
f984502499 | ||
|
|
315ce6d880 | ||
|
|
3da8f9b13c | ||
|
|
a14b87baf2 | ||
|
|
90fd23e0cd | ||
|
|
d96e985be0 | ||
|
|
c8788204a9 | ||
|
|
be99c7fe12 | ||
|
|
48963f62f9 | ||
|
|
00ae6bdac6 | ||
|
|
a606173e07 | ||
|
|
d8e6fd5df0 | ||
|
|
ec950de205 | ||
|
|
62e7fa6a23 | ||
|
|
2935c5fe1a | ||
|
|
021584d782 | ||
|
|
a5c111ef4f | ||
|
|
7868e47643 | ||
|
|
b4e3cd000f | ||
|
|
9c3568800c | ||
|
|
9cf105f8ea | ||
|
|
a8456782b5 | ||
|
|
2afdba48f0 | ||
|
|
4250895243 | ||
|
|
bfeb89075f | ||
|
|
721f61a71d | ||
|
|
a6e5d26aea | ||
|
|
d586f64e40 | ||
|
|
a0900ba052 | ||
|
|
40b00ab362 | ||
|
|
18208fab84 | ||
|
|
8f810a3dcf | ||
|
|
c598bbb8a9 | ||
|
|
e6f388d869 | ||
|
|
24e2eedd0f | ||
|
|
c75f76f740 | ||
|
|
006efbd906 | ||
|
|
28386d7471 | ||
|
|
f9545dc359 | ||
|
|
e527a52f6a | ||
|
|
a7ed50ecd4 | ||
|
|
06dcaaa821 | ||
|
|
36ac48779c | ||
|
|
88669fa033 | ||
|
|
225aa28a1b | ||
|
|
f1245206ce | ||
|
|
7f453949a1 | ||
|
|
38f385f67d | ||
|
|
5f5342c0d3 | ||
|
|
15e003f030 | ||
|
|
5edbc00865 | ||
|
|
723a49ccee | ||
|
|
ff487a0271 | ||
|
|
337735094b | ||
|
|
01b5b13475 | ||
|
|
fd9f792f90 | ||
|
|
e8ded61efb | ||
|
|
b0e098bb68 | ||
|
|
f26c698f4a | ||
|
|
a341c889b7 | ||
|
|
0cd82ec680 | ||
|
|
1f87fef968 | ||
|
|
c8d0a2b4bb | ||
|
|
385709853b | ||
|
|
0405a49df1 | ||
|
|
76484f1541 | ||
|
|
b6543beca2 | ||
|
|
da198fdda5 | ||
|
|
24f912e0b2 | ||
|
|
d7abacb7b2 | ||
|
|
08aeeadd71 | ||
|
|
c214692f66 | ||
|
|
35a9a468ce | ||
|
|
28943af494 | ||
|
|
9abff11f86 | ||
|
|
5f1eb18da4 | ||
|
|
ae3ca2b7df | ||
|
|
d49c5b3d8e | ||
|
|
9ea904c12d | ||
|
|
9a4cbc05a6 | ||
|
|
08fbe17627 | ||
|
|
c766cf9565 | ||
|
|
722d7ff38d | ||
|
|
5d6657f77a | ||
|
|
d83b907cdc | ||
|
|
202817740a | ||
|
|
9b08051703 | ||
|
|
9c71b74d37 | ||
|
|
535a54040f | ||
|
|
68030d12cf | ||
|
|
3494fddd7c | ||
|
|
424af13891 | ||
|
|
e4674142c6 | ||
|
|
9081ddb455 | ||
|
|
1ccf836ebb | ||
|
|
5e9e1b2c91 | ||
|
|
baed7d339e | ||
|
|
6759a28579 | ||
|
|
0db2fe6e39 | ||
|
|
845945e70a | ||
|
|
089509ab87 | ||
|
|
ae6ae88151 | ||
|
|
7b73a689e1 | ||
|
|
0d119d83b0 | ||
|
|
945689d01c | ||
|
|
d70f69566f | ||
|
|
48495f41e8 | ||
|
|
47f7750f26 | ||
|
|
81e3aa4fc8 | ||
|
|
8f6e01a70b | ||
|
|
b0d5b9fd2c | ||
|
|
75468c255a | ||
|
|
e52f64e3d2 | ||
|
|
7d7ef5ac4e | ||
|
|
b368e0a1f9 | ||
|
|
dff2cdc650 | ||
|
|
dcaef756e7 | ||
|
|
2be515e7bb | ||
|
|
699d5d1081 | ||
|
|
8847e39fb7 | ||
|
|
55e9bd3660 | ||
|
|
fb1e6ca6c1 | ||
|
|
88d29a7b4b | ||
|
|
cbedb50cb3 | ||
|
|
78b2a4af1a | ||
|
|
457cc48043 | ||
|
|
b711c050db | ||
|
|
928f1bfa7b | ||
|
|
2b3b6268dd | ||
|
|
97ebf9021c | ||
|
|
c49e4f52ae | ||
|
|
1d89198444 | ||
|
|
8c5d5b8e1c | ||
|
|
d3bec0b2f9 | ||
|
|
c15e3de637 | ||
|
|
24bffd4418 | ||
|
|
da6abe5462 | ||
|
|
1e523414f8 | ||
|
|
190f78fb5a | ||
|
|
64acf3acbc | ||
|
|
a076a248bf | ||
|
|
1ca47074bc | ||
|
|
b380b618bc | ||
|
|
a036d88a4e | ||
|
|
2a57f716d3 | ||
|
|
86598705ef | ||
|
|
5d24f62b95 | ||
|
|
dd3f69eaf3 | ||
|
|
fc54f54b98 | ||
|
|
80b88d819e | ||
|
|
24c10ae733 | ||
|
|
3b18c82c88 | ||
|
|
be83855acf | ||
|
|
10ed334e8c | ||
|
|
c4a14c27cf | ||
|
|
819a331c4a | ||
|
|
9fa6593d7f | ||
|
|
256472f9eb | ||
|
|
9b3b2efe9a | ||
|
|
da9a8d54de | ||
|
|
af8449cef8 | ||
|
|
0365f5d52c | ||
|
|
110ef6201e | ||
|
|
0d5daea93d | ||
|
|
983e170f20 | ||
|
|
f66c6bfebf | ||
|
|
fe77ab4d71 | ||
|
|
763c700372 | ||
|
|
2498df68c7 | ||
|
|
d36aa4fc89 | ||
|
|
f4e1b2123a | ||
|
|
63ee0daac5 | ||
|
|
b58177e3c6 | ||
|
|
f888548e0e | ||
|
|
6ff192c4ea | ||
|
|
64753effd1 | ||
|
|
be9442e7b3 | ||
|
|
ef2890fe51 | ||
|
|
614dcb8bce | ||
|
|
3ba81c8bb6 | ||
|
|
588d022fbb | ||
|
|
96990fc1c5 | ||
|
|
4506d80198 | ||
|
|
72353bf044 | ||
|
|
2696deb2a1 | ||
|
|
9f9fdc1434 | ||
|
|
e2b79c34bc | ||
|
|
69573c6afe | ||
|
|
5c937c5642 | ||
|
|
e500a08f15 | ||
|
|
82aec69302 | ||
|
|
9584ca080c | ||
|
|
f510cd3111 | ||
|
|
e1ddee6c26 | ||
|
|
86b550e43e | ||
|
|
3bf9dc9f18 | ||
|
|
0ca7aa8c09 | ||
|
|
58efd7553c | ||
|
|
0484f5b0dc | ||
|
|
961540160f | ||
|
|
93096a9db8 | ||
|
|
f757285ea8 | ||
|
|
baedd25309 | ||
|
|
bbc1a1f1fb | ||
|
|
addf696db8 | ||
|
|
9327ac0ba7 | ||
|
|
a8a5cb05a7 | ||
|
|
bff33a98ce | ||
|
|
66c8658898 | ||
|
|
d6b2c8f296 | ||
|
|
4e89895391 | ||
|
|
0f5da31eb2 | ||
|
|
3206a46a92 | ||
|
|
42b35c5ac9 | ||
|
|
04180985cb | ||
|
|
42433c0b44 | ||
|
|
f4d47f825d | ||
|
|
44137be88d | ||
|
|
a524f0c2c1 | ||
|
|
d79d6c7055 | ||
|
|
e51035ba9a | ||
|
|
d4645ec609 | ||
|
|
51f34b6b07 | ||
|
|
9cbbc92062 | ||
|
|
23c7086605 | ||
|
|
b00c22916a | ||
|
|
41057ac364 | ||
|
|
1c982315dd | ||
|
|
bf99906386 | ||
|
|
3c88184177 | ||
|
|
f4968e9f45 | ||
|
|
100412267a | ||
|
|
00b98730f7 | ||
|
|
242da95eed | ||
|
|
0eb5dd6d21 | ||
|
|
0fa34c6880 | ||
|
|
bfe8e1e2e9 | ||
|
|
761afd029d | ||
|
|
93565ea768 | ||
|
|
1f82beb2ef | ||
|
|
c076e72cbf | ||
|
|
26139ee06f | ||
|
|
bd394ba6dc | ||
|
|
1f0e603992 | ||
|
|
f5c10f249c | ||
|
|
69f9842ec9 | ||
|
|
d2d71b8630 | ||
|
|
ff3aa6c663 | ||
|
|
dcb5f62413 | ||
|
|
c3e2505b66 | ||
|
|
c7cc595906 | ||
|
|
2dd9e27a44 | ||
|
|
26ed0b0f34 | ||
|
|
374aadc97e | ||
|
|
86dd4e7ee0 | ||
|
|
714a93022f | ||
|
|
35fd21531a | ||
|
|
ca00ae2e23 | ||
|
|
b8655dd3bc | ||
|
|
9e6f43e3ff | ||
|
|
9ec258b74d | ||
|
|
8ca4fb3784 | ||
|
|
d860dd753e | ||
|
|
b4ccc62596 | ||
|
|
07f5bdde60 | ||
|
|
5b0a17359d | ||
|
|
1ad90b8662 | ||
|
|
54ceef0ba1 | ||
|
|
c38edfcb32 | ||
|
|
5b9afd7555 | ||
|
|
e665afcc2a | ||
|
|
b0ec0e9eac | ||
|
|
49e4016ba2 | ||
|
|
9ee7d60afe | ||
|
|
1964fa05e1 | ||
|
|
caf3a69d99 | ||
|
|
769ad4a836 | ||
|
|
062c03c9f7 | ||
|
|
2cf4ac26fd | ||
|
|
405725875d | ||
|
|
5f61f57b2c | ||
|
|
fbeb33479b | ||
|
|
ffd4557447 | ||
|
|
cf5df259e5 | ||
|
|
3d6359f2e7 | ||
|
|
5a229234e7 | ||
|
|
b1a77b2235 | ||
|
|
6db6fef29f | ||
|
|
31fbd19c86 | ||
|
|
a085f4df7f | ||
|
|
cd2c6779b7 | ||
|
|
d39cd088a1 | ||
|
|
e98fcf68f0 | ||
|
|
7d5e066056 | ||
|
|
ba920260b8 | ||
|
|
2988d96cf0 | ||
|
|
36717e5f32 | ||
|
|
4dff54bcb8 | ||
|
|
7a9fe0907a | ||
|
|
bc5a675cdf | ||
|
|
f23e8f8d41 | ||
|
|
61fa97baab | ||
|
|
047163b884 | ||
|
|
6409237b29 | ||
|
|
598a428c6b | ||
|
|
1cfb83f003 | ||
|
|
2aad4c2cf9 | ||
|
|
e2692a4baa | ||
|
|
474a1267d7 | ||
|
|
ed5ca9e4cc | ||
|
|
8d61efa0e8 | ||
|
|
b816a575eb | ||
|
|
a99d28dea9 | ||
|
|
628e565a6c | ||
|
|
84bf705811 | ||
|
|
a721f39945 | ||
|
|
1b9722c65a | ||
|
|
62a60e5542 | ||
|
|
539d06f02d | ||
|
|
9c23fe5ab6 | ||
|
|
f78e9001f3 | ||
|
|
dee1841394 | ||
|
|
a5201a90e8 | ||
|
|
5f5e4ee6b9 | ||
|
|
cf6519da99 | ||
|
|
63eaf643a8 | ||
|
|
a57a3c709e | ||
|
|
bcebd1d5b9 | ||
|
|
4cacfe59bd | ||
|
|
f3ad7b9a16 | ||
|
|
b909c878b1 | ||
|
|
b155f2260f | ||
|
|
63256bc9b2 | ||
|
|
87519e107a | ||
|
|
a38710aa4e | ||
|
|
020fea3031 | ||
|
|
b4102489aa | ||
|
|
871ee0f571 | ||
|
|
f0d90005ea | ||
|
|
933e105f32 | ||
|
|
9b4e6e1ec0 | ||
|
|
46e4d2d573 | ||
|
|
2aa3acae6b | ||
|
|
8514789da9 | ||
|
|
20dcf37976 | ||
|
|
38d513181d | ||
|
|
f121b74bec | ||
|
|
cb8cccc537 | ||
|
|
2924b9182e | ||
|
|
5a59cd9b8c | ||
|
|
ba463afbdc | ||
|
|
6f2a5117dc | ||
|
|
b13241564b | ||
|
|
76816de3aa | ||
|
|
49108c230b | ||
|
|
b32bba47c8 | ||
|
|
3b1ab5e79c | ||
|
|
dcf7946673 | ||
|
|
fdd2da905a | ||
|
|
2cceca49e9 | ||
|
|
bb0e4044bf | ||
|
|
7244dfce1d | ||
|
|
fb5ac37ca2 | ||
|
|
f0a588547d | ||
|
|
04d3ac9aaf | ||
|
|
565126a888 | ||
|
|
395268da22 | ||
|
|
ac3075bef7 | ||
|
|
1f4c596841 | ||
|
|
6613275cc2 | ||
|
|
e7d9863432 | ||
|
|
b9af0645c2 | ||
|
|
9fb7a12849 | ||
|
|
4633273279 | ||
|
|
d0482133a5 | ||
|
|
4ff31d0a41 | ||
|
|
f73c82632f | ||
|
|
8389d8677d | ||
|
|
7fa944ed95 | ||
|
|
2340092008 | ||
|
|
6cd3296c08 | ||
|
|
d86bc0b6cf | ||
|
|
e01d4f289b | ||
|
|
8e1e301764 | ||
|
|
bd37f59829 | ||
|
|
72edc9cd6c | ||
|
|
93123e1fa8 | ||
|
|
4b6dcbb057 | ||
|
|
47f7165b07 | ||
|
|
ae2c0e6552 | ||
|
|
200eabe052 | ||
|
|
5042200492 | ||
|
|
2e73e6bfb6 | ||
|
|
c1d10bbbcb | ||
|
|
746acc21f7 | ||
|
|
f5226a748f | ||
|
|
6a3995014e | ||
|
|
534a537319 | ||
|
|
10eefc4eed | ||
|
|
3d4b3b6a92 | ||
|
|
0f4ceedbb4 | ||
|
|
656e5fd052 | ||
|
|
5735cad457 | ||
|
|
648f972cf0 | ||
|
|
baab9b6fbc | ||
|
|
60b0f9af90 | ||
|
|
9d04406f9a | ||
|
|
29ac533cc9 | ||
|
|
79340c5147 | ||
|
|
b9f5076cfc | ||
|
|
241607e7d7 | ||
|
|
bd7d851758 | ||
|
|
5de1a1ce10 | ||
|
|
8b974f8f74 | ||
|
|
96d94551f9 | ||
|
|
ba8d9c0f0b | ||
|
|
68cbebe1a5 | ||
|
|
0174cb10ae | ||
|
|
293df6308c | ||
|
|
af29822f04 | ||
|
|
0df4f9c114 | ||
|
|
69c9f4588c | ||
|
|
53627c89a7 | ||
|
|
f7f0d2b265 | ||
|
|
2d799f2c11 | ||
|
|
aa5b7eb98a | ||
|
|
1c22e8ae7e | ||
|
|
4d301bc5a6 | ||
|
|
4ccd9ae6da | ||
|
|
c8c9916b59 | ||
|
|
5490919557 | ||
|
|
3f920da413 | ||
|
|
2393db3943 | ||
|
|
a88ec1b1af | ||
|
|
553b3a5c6c | ||
|
|
a6cb25020b | ||
|
|
26c465ad0c | ||
|
|
f2d7083183 | ||
|
|
ef09a29854 | ||
|
|
c23ce16caf | ||
|
|
78a70fed2f | ||
|
|
9dfe5dee64 | ||
|
|
36ef1d1bc6 | ||
|
|
10db51e6c2 | ||
|
|
61aa33af1d | ||
|
|
d8dc055dce | ||
|
|
ce686d2c06 | ||
|
|
7119976199 | ||
|
|
dd7edc8ced | ||
|
|
4428f70ea2 | ||
|
|
0bb7589418 | ||
|
|
0513463256 | ||
|
|
8a9d743f6f | ||
|
|
4cab74c18c | ||
|
|
615c97132d | ||
|
|
4b707db4b3 | ||
|
|
70c5f347c4 | ||
|
|
5217d89543 | ||
|
|
ca55bbdaed | ||
|
|
366e735ad8 | ||
|
|
c363fc71eb | ||
|
|
9f3ea71d5d | ||
|
|
75058e54b8 | ||
|
|
ed5405d4f7 | ||
|
|
8dd4270a6a | ||
|
|
c29f622b90 | ||
|
|
bc0e415926 | ||
|
|
c48965ea2f | ||
|
|
bb995f1bb6 | ||
|
|
857e13e9b8 | ||
|
|
593423434c | ||
|
|
25caeee854 | ||
|
|
20ce7a2d9f | ||
|
|
1ba74d824b | ||
|
|
be7b706486 | ||
|
|
78e18fcdcf | ||
|
|
706598313e | ||
|
|
b96f09bb3a | ||
|
|
4b191fb558 | ||
|
|
de1abf9981 | ||
|
|
c69f6ca1f4 | ||
|
|
d4b04d22ed | ||
|
|
b1f4b9759b | ||
|
|
650f882265 | ||
|
|
a2747403f2 | ||
|
|
3f9412add2 | ||
|
|
29877963be | ||
|
|
302c5afdee | ||
|
|
9f90806027 | ||
|
|
519862115c | ||
|
|
4d97ea106c | ||
|
|
d3aa50c9c3 | ||
|
|
1708769d42 | ||
|
|
4e223f816a | ||
|
|
8cf6b4064f | ||
|
|
17907f11a3 | ||
|
|
cb7df797e1 | ||
|
|
7db86a4e05 | ||
|
|
122d7281f7 | ||
|
|
4bfd34b479 | ||
|
|
962d9f36d0 | ||
|
|
216d41cd64 | ||
|
|
4af104384b | ||
|
|
aa78d51521 | ||
|
|
16e7ec7bfe | ||
|
|
fce1dc083b | ||
|
|
bcfa72ed31 | ||
|
|
b92cc852d1 | ||
|
|
6762af4158 | ||
|
|
f691e8981a | ||
|
|
6875a540ec | ||
|
|
e569f5d6eb | ||
|
|
61a5e81bc6 | ||
|
|
ee153f64d4 | ||
|
|
4c4db6f73c | ||
|
|
fa5a382c4b | ||
|
|
a73c385831 | ||
|
|
91b35c5349 | ||
|
|
056db37c66 | ||
|
|
5cb71fa5da | ||
|
|
55d00243fb | ||
|
|
8a269823d2 | ||
|
|
5ec5b127d0 | ||
|
|
0cf9e498b9 | ||
|
|
c407e72dcc | ||
|
|
8e3b796a2f | ||
|
|
17e7b276f6 | ||
|
|
306ce3819e | ||
|
|
f80aff4a65 | ||
|
|
c7cbd41c16 | ||
|
|
41542e6886 | ||
|
|
a039869ba0 | ||
|
|
192e85ffa4 | ||
|
|
b334201797 | ||
|
|
3ea84d7eab | ||
|
|
a80c45940e | ||
|
|
ab71e33d83 | ||
|
|
fe57e7059b | ||
|
|
2de65ab39f | ||
|
|
0559db9cf8 | ||
|
|
bae7b034e6 | ||
|
|
74a40adece | ||
|
|
1767a07f4d | ||
|
|
af7549d2f6 | ||
|
|
e785b723aa | ||
|
|
f520cd92d0 | ||
|
|
eb6fd311df | ||
|
|
5a12944b39 | ||
|
|
987619130b | ||
|
|
2b2723cb74 | ||
|
|
e485ecb3b4 | ||
|
|
8c5203f7e1 | ||
|
|
dfaf1a1075 | ||
|
|
bf5c0e0b0d | ||
|
|
167e754a1b | ||
|
|
34b804e9dc | ||
|
|
7338649fa5 | ||
|
|
ae1103c5a3 | ||
|
|
a7e4553ea7 | ||
|
|
6f27e8db38 | ||
|
|
292b02b58c | ||
|
|
e60f527cb0 | ||
|
|
b5a5a91b13 | ||
|
|
4c84a2ce61 | ||
|
|
18e0e4b597 | ||
|
|
74b574d0b1 | ||
|
|
9ba1b8d720 | ||
|
|
d726c921eb | ||
|
|
bd45bb3ad3 | ||
|
|
fee8503093 | ||
|
|
fabf7081d3 | ||
|
|
6083cd2559 | ||
|
|
d11e80e1b3 | ||
|
|
6942c715d0 | ||
|
|
427652e9bd | ||
|
|
106b4fdd2d | ||
|
|
f164ddf155 | ||
|
|
d9ddf7561f | ||
|
|
37368bda65 | ||
|
|
de1b3d5113 | ||
|
|
830b01bd2a | ||
|
|
90187eae37 | ||
|
|
7399f7a087 | ||
|
|
a3e47d26f6 | ||
|
|
d3bef2adc3 | ||
|
|
7b459ec355 | ||
|
|
301072a86c | ||
|
|
3b7b3ef2bb | ||
|
|
b6e4611a91 | ||
|
|
2929bb672a | ||
|
|
a4765bf954 | ||
|
|
0c2045beff | ||
|
|
22f6687f44 | ||
|
|
e56633d5b0 | ||
|
|
a44795e6c3 | ||
|
|
5805a54097 | ||
|
|
350519d429 | ||
|
|
8f94c721bf | ||
|
|
c7652fc29c | ||
|
|
e537d53389 | ||
|
|
a890ee6864 | ||
|
|
4f81d64517 | ||
|
|
b5875c3af9 | ||
|
|
ed87dbc141 | ||
|
|
059886a1e4 | ||
|
|
ba52af786e | ||
|
|
929f524e77 | ||
|
|
cd49ec92e3 | ||
|
|
ee39e3cf72 | ||
|
|
a17f280f7d | ||
|
|
7b4cfffc03 | ||
|
|
db9c2992e3 | ||
|
|
b23284cba2 | ||
|
|
0c163c4d03 | ||
|
|
e4145deeb7 | ||
|
|
33258803ea | ||
|
|
179730e485 | ||
|
|
106b3257e4 | ||
|
|
312cc415ce | ||
|
|
1f2a408be0 | ||
|
|
0d232c612b | ||
|
|
68da4d90dc | ||
|
|
545dc5cf65 | ||
|
|
a089064588 | ||
|
|
a06f7fbe2e | ||
|
|
7c4d9519c8 | ||
|
|
6fa0807550 | ||
|
|
c545ada746 | ||
|
|
868a0d8a90 | ||
|
|
5079dff338 | ||
|
|
9e3d130ad9 | ||
|
|
b531486dab | ||
|
|
6df98f080b | ||
|
|
69487389d3 | ||
|
|
0cb5f009b4 | ||
|
|
c7b2ec8bba | ||
|
|
12b0a9f35f | ||
|
|
fff30b1c3d | ||
|
|
6ad35e3d84 | ||
|
|
3d80073a0e | ||
|
|
959c3ba89d | ||
|
|
1029939f56 | ||
|
|
fd5d1416d9 | ||
|
|
def5edf93c | ||
|
|
6bdde985ce | ||
|
|
dba38821bc | ||
|
|
9d6a4c1d05 | ||
|
|
94bef08f15 | ||
|
|
0178840c19 | ||
|
|
d04c73ae00 | ||
|
|
495f21c08c | ||
|
|
d238cbea19 | ||
|
|
5d0646c9e1 | ||
|
|
93e5449c08 | ||
|
|
4872a30e2b | ||
|
|
f5fcdf1de4 | ||
|
|
888bf76e4b | ||
|
|
22a650ade8 | ||
|
|
391807b46c | ||
|
|
921a2e0dc4 | ||
|
|
5afe8e5aa1 | ||
|
|
ba84d6ff7c | ||
|
|
d786502f19 | ||
|
|
63063450b3 | ||
|
|
90463ee67d | ||
|
|
6e04dd96a1 | ||
|
|
f7c837aad0 | ||
|
|
bd3d323849 | ||
|
|
e26b558e53 | ||
|
|
85e5cd7f98 | ||
|
|
1d8cac6e73 | ||
|
|
52f6bd03b7 | ||
|
|
75c10eaff5 | ||
|
|
53a796afcc | ||
|
|
f94a8698dd | ||
|
|
ffb8059c24 | ||
|
|
bc7c0ed844 | ||
|
|
ac9250fc4a | ||
|
|
f1492945ec | ||
|
|
10ccdbacba | ||
|
|
d683573402 | ||
|
|
ddce0412ac | ||
|
|
609e42cdd8 | ||
|
|
7235c20854 | ||
|
|
e7bedf4433 | ||
|
|
23d30ab2c5 | ||
|
|
741afeea41 | ||
|
|
cd989977b8 | ||
|
|
1216508dc2 | ||
|
|
5c7dfcfe43 | ||
|
|
cff866172a | ||
|
|
31a612aa89 | ||
|
|
b782c46e51 | ||
|
|
eaa47760bc | ||
|
|
7ec6879887 | ||
|
|
c4a3487f0c | ||
|
|
e6de9bfa4e | ||
|
|
c0260ff701 | ||
|
|
fba2603304 | ||
|
|
7d5acef20a | ||
|
|
cda8fb3380 | ||
|
|
862a310075 | ||
|
|
98146eae07 | ||
|
|
c277039fb4 | ||
|
|
92577ddaed | ||
|
|
b99b6b5ae9 | ||
|
|
cda81e35db | ||
|
|
271a41b7dd | ||
|
|
69aeddd185 | ||
|
|
99bd69adfe | ||
|
|
115a53225e | ||
|
|
36c196e18c | ||
|
|
0c8219e683 | ||
|
|
de9c44fc56 | ||
|
|
d1dbc50a1c | ||
|
|
0fbea73581 | ||
|
|
10f7199c63 | ||
|
|
49d6605377 | ||
|
|
11c8cabf28 | ||
|
|
00132cd977 | ||
|
|
5e1b61eb02 | ||
|
|
dfb49558f4 | ||
|
|
4e1c308162 | ||
|
|
5c2692a8ea | ||
|
|
9c240de303 | ||
|
|
2536dc39b5 | ||
|
|
cf0bff8582 | ||
|
|
9c12ba5708 | ||
|
|
8639eda70f | ||
|
|
1874346c46 | ||
|
|
16040063dc | ||
|
|
2b0b03eebc | ||
|
|
df2b687a95 | ||
|
|
44fa4d1081 | ||
|
|
ce4bb8e5ec | ||
|
|
8154453803 | ||
|
|
b29fe50f70 | ||
|
|
cce46722d8 | ||
|
|
85ae07e7c8 | ||
|
|
e3da813360 | ||
|
|
9a42d63516 | ||
|
|
4620eb32d2 | ||
|
|
1c8f63f1e5 | ||
|
|
c40f6060da | ||
|
|
5776af30e8 | ||
|
|
30d083ac3c | ||
|
|
4ca0c2cfd1 | ||
|
|
12db46dcad | ||
|
|
9e6547a887 | ||
|
|
017ea0d624 | ||
|
|
a29b8b369e | ||
|
|
6b26b4e3b8 | ||
|
|
7df92ba62c | ||
|
|
9cad4c11fe | ||
|
|
5b42edb42a | ||
|
|
a26d8609a9 | ||
|
|
001e4276d3 | ||
|
|
94437a8fcd | ||
|
|
91f751d105 | ||
|
|
0db5a8673d | ||
|
|
91f2e05d5d | ||
|
|
58fe4f5cb3 | ||
|
|
2ebd9a2774 | ||
|
|
8db428458a | ||
|
|
f8b612a2c0 | ||
|
|
76043d97bd | ||
|
|
07bd396837 | ||
|
|
f7468ab473 | ||
|
|
1213893a71 | ||
|
|
5f1ccc25b6 | ||
|
|
42c0f83ec5 | ||
|
|
5dfaeaf526 | ||
|
|
1214469311 | ||
|
|
f4a9529968 | ||
|
|
3d55134953 | ||
|
|
1c0fe89368 | ||
|
|
73bef17365 | ||
|
|
9398e49eb7 | ||
|
|
50cf095c00 | ||
|
|
5d64fb5946 | ||
|
|
bf55a8e98c | ||
|
|
59e0a0fd7c | ||
|
|
d15be53034 | ||
|
|
b6b2420ff7 | ||
|
|
4bd0e083d1 | ||
|
|
d9c7b39b88 | ||
|
|
583f7df9c8 | ||
|
|
8377aa72a8 | ||
|
|
c57926d799 | ||
|
|
380e3e64cb | ||
|
|
77a03e376c | ||
|
|
5dade2b608 | ||
|
|
877b3361c8 | ||
|
|
2fbfc2a8f1 | ||
|
|
e09b49288f | ||
|
|
6aa98a1e91 | ||
|
|
14b74069f8 | ||
|
|
c1cfcc78fe | ||
|
|
2c299a9f37 | ||
|
|
288697cda2 | ||
|
|
9fa771f9fe | ||
|
|
d1aa672388 | ||
|
|
b21f6fd619 | ||
|
|
39245238fd | ||
|
|
43d8090182 | ||
|
|
d13dae6b06 | ||
|
|
0998ef0c4e | ||
|
|
543bf51eff | ||
|
|
5513feb15b | ||
|
|
e03faaeb8f | ||
|
|
966dd03195 | ||
|
|
5041774fd3 | ||
|
|
c5453d476d | ||
|
|
54eae7830e | ||
|
|
4e74c7e3b1 | ||
|
|
fe52400b75 | ||
|
|
18feef0753 | ||
|
|
6ec021aafa | ||
|
|
954957bd8a | ||
|
|
14e92f53f1 | ||
|
|
d3183467e0 | ||
|
|
b62614bbd4 | ||
|
|
618155e6ab | ||
|
|
bd75d32c1b | ||
|
|
5acfef8edb | ||
|
|
7ce3ebc46d | ||
|
|
0353b0e04f | ||
|
|
ca81ab784a | ||
|
|
3262d819de | ||
|
|
a8cdbd44e8 | ||
|
|
04820ba09e | ||
|
|
52120b367a | ||
|
|
d6d96e8c89 | ||
|
|
2b34dd7373 | ||
|
|
7a87343c71 | ||
|
|
5f80121637 | ||
|
|
5920a96da7 | ||
|
|
0acaa839b9 | ||
|
|
f8b767ed32 | ||
|
|
d0b0d0ec72 | ||
|
|
e0463f5a74 | ||
|
|
1b30210120 | ||
|
|
a1e28bb669 | ||
|
|
dc4bd531a4 | ||
|
|
c5aedb14a9 | ||
|
|
ec28dee728 | ||
|
|
3e459ed434 | ||
|
|
d66be62516 | ||
|
|
98fd919647 | ||
|
|
0a9b2b6b15 | ||
|
|
bb469deb85 | ||
|
|
96402a2354 | ||
|
|
4fec7aa991 | ||
|
|
b5dfc54be3 | ||
|
|
848e3f6c5d | ||
|
|
1f5818cec8 | ||
|
|
06ec5424c7 | ||
|
|
b9551862b4 | ||
|
|
e0a75f68d5 | ||
|
|
a5f1fa3168 | ||
|
|
1375ed6aea | ||
|
|
f1a3b281d4 | ||
|
|
59da3dfe03 | ||
|
|
52f06cabd2 | ||
|
|
612efe56f1 | ||
|
|
07c0bc7b04 | ||
|
|
f5774bba6f | ||
|
|
714832bb49 | ||
|
|
3bc8d4d0eb | ||
|
|
8083a86581 | ||
|
|
b3528c314a | ||
|
|
65587be737 | ||
|
|
9c24e1ccfb | ||
|
|
0147186565 | ||
|
|
8924cb0960 | ||
|
|
869735e4b5 | ||
|
|
605381f83d | ||
|
|
71f70b4377 | ||
|
|
c6daf4d41c | ||
|
|
3f1dc22c0e | ||
|
|
02527552fd | ||
|
|
ac5b9f2382 | ||
|
|
a2931cd17d | ||
|
|
fc65496d1d | ||
|
|
be98466b0d | ||
|
|
0fd60d1e80 | ||
|
|
35857931ef | ||
|
|
a4c3058f84 | ||
|
|
6cb7afcbc0 | ||
|
|
32a0f5b04a | ||
|
|
3bc6190bdd | ||
|
|
4fb9571136 | ||
|
|
e70bb371d9 | ||
|
|
2099ac0615 | ||
|
|
5e28b1216e | ||
|
|
e858ee811b | ||
|
|
a498fc8e72 | ||
|
|
7063b6cb6d | ||
|
|
917d0ced4a | ||
|
|
969418ce73 | ||
|
|
7f3df847a2 | ||
|
|
e0424fe6cc | ||
|
|
b67397861c | ||
|
|
de15a2ace1 | ||
|
|
4369ee2ca7 | ||
|
|
a1163b70a6 | ||
|
|
2030aea175 | ||
|
|
969b66b315 | ||
|
|
4442da306a | ||
|
|
911fd6c654 | ||
|
|
9cee3dda1f | ||
|
|
cc0f026cec | ||
|
|
f1b5c333ff | ||
|
|
123fe58c26 | ||
|
|
fd1e163bf4 | ||
|
|
ab8b4d5c36 | ||
|
|
4a044351a9 | ||
|
|
e0a2268b0e | ||
|
|
3432771150 | ||
|
|
768615f2f1 | ||
|
|
9ae215291f | ||
|
|
1cf206d764 | ||
|
|
4c406ec9c0 | ||
|
|
500b896d50 | ||
|
|
18a239e808 | ||
|
|
5aa07bda7c | ||
|
|
379fd33484 | ||
|
|
ed6629002f | ||
|
|
bcb4ac7aae | ||
|
|
5395b173aa | ||
|
|
735f9c7a45 | ||
|
|
9cbca24f7a | ||
|
|
6f8d29ad80 | ||
|
|
eb947acebe | ||
|
|
01e84edd0a | ||
|
|
b7538b6ada | ||
|
|
232742a5e6 | ||
|
|
a33ddf373b | ||
|
|
b57e735199 | ||
|
|
38816d7e41 | ||
|
|
3a89bb0db2 | ||
|
|
865c38995d | ||
|
|
beae28f2db | ||
|
|
81b2c5ac68 | ||
|
|
35b5f60f99 | ||
|
|
13d0db5f9a | ||
|
|
96f23758b4 | ||
|
|
f7601756e9 | ||
|
|
54059b2f15 | ||
|
|
f00887ea42 | ||
|
|
08a5884c9f | ||
|
|
0f3b7dd6e9 | ||
|
|
bab73edcef | ||
|
|
42d26f01d6 | ||
|
|
8aadc2837c | ||
|
|
ea37882b95 | ||
|
|
599a0c66b2 | ||
|
|
57e0bfc5a9 | ||
|
|
9f424bb208 | ||
|
|
4e5b813aa8 | ||
|
|
6a2c32bd23 | ||
|
|
febcb90ece | ||
|
|
4b300f8274 | ||
|
|
8da8e02dc8 | ||
|
|
3e9b6a330d | ||
|
|
b54c4df74d | ||
|
|
f0a33c00bc | ||
|
|
8631b28130 | ||
|
|
9b3662e5ad | ||
|
|
3fb690a0f6 | ||
|
|
76d41fc250 | ||
|
|
15fa300e04 | ||
|
|
47c86828c6 | ||
|
|
6eaf35a142 | ||
|
|
ea8364eba5 | ||
|
|
fc4b1693f9 | ||
|
|
52f3d6722d | ||
|
|
126628546b | ||
|
|
2540ecc0ac | ||
|
|
b49972a623 | ||
|
|
b82a9a6594 | ||
|
|
be701677d6 | ||
|
|
1e8fc8b062 | ||
|
|
b6c765c9dc | ||
|
|
1d2797dc1f | ||
|
|
4b984f9819 | ||
|
|
e8882a5167 | ||
|
|
4f0490f26f | ||
|
|
7fe6bc52d0 | ||
|
|
b7408fa39e | ||
|
|
7ca5b5c928 | ||
|
|
6f5f613d9f | ||
|
|
52f2509280 | ||
|
|
c07f694a07 | ||
|
|
c49198fd71 | ||
|
|
864bad0ebb | ||
|
|
051858300e | ||
|
|
75d16e4852 | ||
|
|
a756c0b182 | ||
|
|
550cab41fb | ||
|
|
45bd81fe8c | ||
|
|
3f7ee613fc | ||
|
|
93f061f78a | ||
|
|
7517c76ae4 | ||
|
|
e26f771cbe | ||
|
|
bf5a1f662a | ||
|
|
d9753989bf | ||
|
|
391b98f72c | ||
|
|
d40a087ec2 | ||
|
|
138c14d43f | ||
|
|
dc6a594277 | ||
|
|
9f5c61b1fd | ||
|
|
3bca640521 | ||
|
|
73082a338b | ||
|
|
1593ebec1f | ||
|
|
2413968021 | ||
|
|
44b542814a | ||
|
|
2848f5dab4 | ||
|
|
f0f5a8f2b5 | ||
|
|
0563ce93a1 | ||
|
|
6a927be76c | ||
|
|
c8e3ea955d | ||
|
|
b33a9a71f6 | ||
|
|
dc80431438 | ||
|
|
8af3dc140e | ||
|
|
3c7d2d4cea | ||
|
|
de697a4267 | ||
|
|
ca35db76b8 | ||
|
|
b6eded1119 | ||
|
|
c8d8ae89d7 | ||
|
|
b2d949ce9a | ||
|
|
f12ebffa39 | ||
|
|
9b4d32b68c | ||
|
|
f4e708a02f | ||
|
|
b4e83b6537 | ||
|
|
c7637a0c53 | ||
|
|
9b1195c896 | ||
|
|
732c6134dd | ||
|
|
e98c871781 | ||
|
|
d616099de6 | ||
|
|
e3070eb170 | ||
|
|
319b02a757 | ||
|
|
64cdbb8e3b | ||
|
|
edeba4ca34 | ||
|
|
7e03f612b3 | ||
|
|
578f1b8ece | ||
|
|
e2a15d0ec9 | ||
|
|
3c74aec973 | ||
|
|
61e3ef2552 | ||
|
|
136e5fdf95 | ||
|
|
75fe9f9cc4 | ||
|
|
73dad85867 | ||
|
|
91895c52ca | ||
|
|
fc28af8518 | ||
|
|
3545626950 | ||
|
|
6a7079a594 | ||
|
|
42db2bc93d | ||
|
|
a2f5b55d10 | ||
|
|
8e7e9b7040 | ||
|
|
43eefb5929 | ||
|
|
dcdcba9f1f | ||
|
|
dec37b3dbe | ||
|
|
9431112f77 | ||
|
|
7bdd5c9e0d | ||
|
|
c963aa98e8 | ||
|
|
0f6e1c1c05 | ||
|
|
ce8d49a47d | ||
|
|
70dc305f12 | ||
|
|
df45374041 | ||
|
|
22a5a91bd5 | ||
|
|
d5788ba53a | ||
|
|
4d8a1c67c3 | ||
|
|
ea34e4bad8 | ||
|
|
258e2d197a | ||
|
|
e75e09dae8 | ||
|
|
4aee8ba27f | ||
|
|
90c6276fe2 | ||
|
|
1cae3baaea | ||
|
|
209882d5a9 | ||
|
|
2999096221 | ||
|
|
d076255c98 | ||
|
|
b2f2deffe6 | ||
|
|
b31aa4aacb | ||
|
|
85962a3eb1 | ||
|
|
a9696abdce | ||
|
|
e22448fb5c | ||
|
|
db0a102703 | ||
|
|
9034765790 | ||
|
|
3377b29957 | ||
|
|
5390594f40 | ||
|
|
e95753b184 | ||
|
|
6bd0d57c1e | ||
|
|
192b5a41f0 | ||
|
|
c76da2e77d | ||
|
|
8bf45536d3 | ||
|
|
e1fca2a1ab | ||
|
|
f5fe37ab09 | ||
|
|
08813f1650 | ||
|
|
8f7dd2f858 | ||
|
|
05050381d3 | ||
|
|
95d6d2644f | ||
|
|
dbd981939c | ||
|
|
2e45b41902 | ||
|
|
7776c56c6c | ||
|
|
4decceea76 | ||
|
|
26b97722c6 | ||
|
|
38fe928d06 | ||
|
|
c229223e01 | ||
|
|
ab59e41e1a | ||
|
|
392ee70fd5 | ||
|
|
7abad2ff99 | ||
|
|
d337cc6618 | ||
|
|
3a8bff228e | ||
|
|
5ba39fef9a | ||
|
|
c7160e3d25 | ||
|
|
6171d164d7 | ||
|
|
b1e0018b74 | ||
|
|
9b8aa8d09e | ||
|
|
3bed94f4ad | ||
|
|
a895a0d79e | ||
|
|
32522b61f2 | ||
|
|
1da3828a09 | ||
|
|
982ff8733f | ||
|
|
ebe374d572 | ||
|
|
dd45e7b4eb | ||
|
|
63eb0e3a38 | ||
|
|
f472071f6f | ||
|
|
7b695aa684 | ||
|
|
de4b5978c3 | ||
|
|
f23f8f7f5d | ||
|
|
f64acadd58 | ||
|
|
68ea1d0289 | ||
|
|
1574043a9e | ||
|
|
a2a5580e68 | ||
|
|
2696cf9b9e | ||
|
|
d9f962ee6f | ||
|
|
7468d8a000 | ||
|
|
270bb4e2d9 | ||
|
|
d3d9b06eb7 | ||
|
|
e7131bc8f8 | ||
|
|
1df1c15e48 | ||
|
|
986244eeea | ||
|
|
526bc36b40 | ||
|
|
9bdb7bef5d | ||
|
|
54e7d5d260 | ||
|
|
5265c190d4 | ||
|
|
4b7c052ed8 | ||
|
|
b62e7e7d8b | ||
|
|
fd290882fd | ||
|
|
09015f8924 | ||
|
|
b5f382f0ea | ||
|
|
ccd13dd643 | ||
|
|
d66715648a | ||
|
|
e07ff7d3fb | ||
|
|
0d60789f69 | ||
|
|
e769fbaffb | ||
|
|
5721f9f3a9 | ||
|
|
cca9f2392e | ||
|
|
928fa44154 | ||
|
|
a795f03c48 | ||
|
|
8f7b869c08 | ||
|
|
c5294f994e | ||
|
|
34f52e47eb | ||
|
|
f950d27b3d | ||
|
|
2a2da48d18 | ||
|
|
0b1cd826b0 | ||
|
|
11c1573b55 | ||
|
|
b3525b8657 | ||
|
|
8d5556764c | ||
|
|
f965209eee | ||
|
|
5c526995d8 | ||
|
|
50ee82e8bd | ||
|
|
8a3c909c74 | ||
|
|
3a8e1e0484 | ||
|
|
3b53cd56ef | ||
|
|
30e88a4f6b | ||
|
|
e5f47cd14b | ||
|
|
6368b09337 | ||
|
|
b97102da01 | ||
|
|
dbeae16dc1 | ||
|
|
edbcba6f11 | ||
|
|
ed876a9c52 | ||
|
|
67fe8fc4a7 | ||
|
|
55b530f0fd | ||
|
|
3a2c3ea8fa | ||
|
|
aae51a9b23 | ||
|
|
cd2b811555 | ||
|
|
15d1a6c937 | ||
|
|
9ab335626c | ||
|
|
451db7dd98 | ||
|
|
d6293730fc | ||
|
|
8e410f14b1 | ||
|
|
49000dadda | ||
|
|
9bde18492a | ||
|
|
b22fa9f7f4 | ||
|
|
a7b2d23e9b | ||
|
|
ba94f824b9 | ||
|
|
8aec437c23 | ||
|
|
98f656cfcb | ||
|
|
e558ddae3f | ||
|
|
2c665e5e4c | ||
|
|
2fe3d16bbe | ||
|
|
2844f276b9 | ||
|
|
414b5ea6f3 | ||
|
|
c42dcd5ac9 | ||
|
|
b9723aa85b | ||
|
|
03fb13e749 | ||
|
|
e04f04ef0f | ||
|
|
0f3c2c4b24 | ||
|
|
8a94a4938f | ||
|
|
b553ffd55d | ||
|
|
e45958b967 | ||
|
|
006ca4421a | ||
|
|
0bfdb45b41 | ||
|
|
8cbccb20ef | ||
|
|
f506f73d3f | ||
|
|
7734bbfe4d | ||
|
|
d35c5bcb2f | ||
|
|
c699d3a17a | ||
|
|
d16ac62a51 | ||
|
|
2fa5b8c0a2 | ||
|
|
15feeb7bfe | ||
|
|
02ecc93998 | ||
|
|
34291d5938 | ||
|
|
e726adc27b | ||
|
|
642f460dca | ||
|
|
1d7d9818fa | ||
|
|
c2dcc68803 | ||
|
|
d7c9f2ccba | ||
|
|
7dd61c05dc | ||
|
|
1c1155513a | ||
|
|
f84151e1fe | ||
|
|
5ec3d3e36d | ||
|
|
4b13f0e025 | ||
|
|
2869ccfe39 | ||
|
|
8ead4745f8 | ||
|
|
15b241cc3e | ||
|
|
2b07a69b93 | ||
|
|
5068ce0569 | ||
|
|
0b1b11ea53 | ||
|
|
ea9f169a6c | ||
|
|
cbd7f89066 | ||
|
|
146ff6f703 | ||
|
|
326ae5ff6b | ||
|
|
8c16f12d7a | ||
|
|
477228d4ff | ||
|
|
9baaa6fa56 | ||
|
|
49d11ed9f8 | ||
|
|
7834274bff | ||
|
|
d2565d0f61 | ||
|
|
4fde0bf62e | ||
|
|
a679081993 | ||
|
|
177292de13 | ||
|
|
efcb4abfd0 | ||
|
|
1501d1c570 | ||
|
|
59a56ac77f | ||
|
|
35f09f4f74 | ||
|
|
421dfce599 | ||
|
|
b240c15014 | ||
|
|
9de8df496a | ||
|
|
4f65066572 | ||
|
|
c38687725d | ||
|
|
099f236f45 | ||
|
|
996cd7e2ab | ||
|
|
77df590f65 | ||
|
|
ce064188c6 | ||
|
|
5d6f59a598 | ||
|
|
f4a4cf1402 | ||
|
|
032ef0ca34 | ||
|
|
5a7e8d8520 | ||
|
|
63146821d7 | ||
|
|
9ed8eac8c6 | ||
|
|
40bb1699a5 | ||
|
|
74827133b2 | ||
|
|
7c8706757d | ||
|
|
3dc066a143 | ||
|
|
43251ed8ce | ||
|
|
1a16822987 | ||
|
|
fdd4c1b9d1 | ||
|
|
1bd1050160 | ||
|
|
525a0478b0 | ||
|
|
ce28760c2a | ||
|
|
438cb1d7e0 | ||
|
|
87c8cf4892 | ||
|
|
f2fefb91d5 | ||
|
|
4d05d477f8 | ||
|
|
cc95c3e9c8 | ||
|
|
f0a7a6a1e2 | ||
|
|
4090843fef | ||
|
|
c6c18261a0 | ||
|
|
d9e83eb53a | ||
|
|
1cf404177d | ||
|
|
ed9ffec5ba | ||
|
|
582607c0f0 | ||
|
|
6cd5826d21 | ||
|
|
b7e953f50e | ||
|
|
9f630b6653 | ||
|
|
024af91df8 | ||
|
|
3017dbc8c1 | ||
|
|
5d33b34be7 | ||
|
|
f2104b0a5a | ||
|
|
84b004399e | ||
|
|
e8a01f0916 | ||
|
|
4f1d579ba1 | ||
|
|
c34d8286a3 | ||
|
|
4eb389f2d9 | ||
|
|
999ac60a87 | ||
|
|
30af694e30 | ||
|
|
fa76da1dab | ||
|
|
1500691cc2 | ||
|
|
fae5ea749a | ||
|
|
c2dac55edb | ||
|
|
4c5a74284b | ||
|
|
d0a3cfe765 | ||
|
|
580f1f1213 | ||
|
|
b87d164f2f | ||
|
|
f3c8f342ff | ||
|
|
63a1d8d0db | ||
|
|
93f5cc1e60 | ||
|
|
68a503049b | ||
|
|
fae43010c5 | ||
|
|
30351f5ade | ||
|
|
325a5b4af4 | ||
|
|
021c81cb62 | ||
|
|
7099e09a5c | ||
|
|
97b990c9bf | ||
|
|
db3d99f7c7 | ||
|
|
8fb4f37670 | ||
|
|
dfd4115f7a | ||
|
|
e58ad35fb0 | ||
|
|
31db5078c1 | ||
|
|
40c78d23e6 | ||
|
|
ec1d6d537e | ||
|
|
06bfd2b502 | ||
|
|
fd708b28b8 | ||
|
|
03e3281beb | ||
|
|
f247b9ce20 | ||
|
|
67909b55fc | ||
|
|
43ba690eda | ||
|
|
3425267368 | ||
|
|
0c3d9af333 | ||
|
|
67c2b309d1 | ||
|
|
df0fa9883c | ||
|
|
9821a39549 | ||
|
|
692e117c8a | ||
|
|
d96ca61f2b | ||
|
|
fc58b8cc0d | ||
|
|
c8503daf5a | ||
|
|
45e1f93e56 | ||
|
|
77807d439e | ||
|
|
e062c4e6b5 | ||
|
|
755edd2110 | ||
|
|
f51124397f | ||
|
|
e42111545b | ||
|
|
5112b4b963 | ||
|
|
99c5c7ab28 | ||
|
|
edb1473f13 | ||
|
|
f2171173fe | ||
|
|
7f30863df2 | ||
|
|
a6a2c02b6a | ||
|
|
d3ee99d677 | ||
|
|
4abfd4053a | ||
|
|
05e0ed5173 | ||
|
|
00b480527a | ||
|
|
e4231efd20 | ||
|
|
922d2165b3 | ||
|
|
9cee52c668 | ||
|
|
50e32c3d8a | ||
|
|
5e576bff63 | ||
|
|
e1338f5a7f | ||
|
|
672143d3a2 | ||
|
|
2d94a038a5 | ||
|
|
174d55cf3d | ||
|
|
f2889d24e6 | ||
|
|
db58b62235 | ||
|
|
f3b560b453 | ||
|
|
43e064749c | ||
|
|
4af339da63 | ||
|
|
4cd6e7ec91 | ||
|
|
197b5de9da | ||
|
|
cdfddc0fc5 | ||
|
|
f4d3ec908d | ||
|
|
918aaa64e2 | ||
|
|
2417396a93 | ||
|
|
0a051ff2cd | ||
|
|
d702133ded | ||
|
|
2aaee311f3 | ||
|
|
e8d431c2f6 | ||
|
|
0f4c012321 | ||
|
|
f13a8f725c | ||
|
|
e6690c818d | ||
|
|
5d32aa94d9 | ||
|
|
d413b6eba8 | ||
|
|
f0847e6f32 | ||
|
|
50d7554ccd | ||
|
|
b28d3015fe | ||
|
|
75d521d42a | ||
|
|
1ebaacfd5e | ||
|
|
52cd8652bb | ||
|
|
c6bdf7e891 | ||
|
|
11e19a06b7 | ||
|
|
880ca35681 | ||
|
|
650e98b2a9 | ||
|
|
f84946c135 | ||
|
|
508969a183 | ||
|
|
c39e3613a8 | ||
|
|
4eec9a2fba | ||
|
|
6d1b64065a | ||
|
|
5751437c93 | ||
|
|
9fa0490c44 | ||
|
|
6711ceb662 | ||
|
|
dc7677f5fa | ||
|
|
78fb6f55ed | ||
|
|
c5981cbc9a | ||
|
|
2f52b6c164 | ||
|
|
5d59462e49 | ||
|
|
1b09c64856 | ||
|
|
24b90b475b | ||
|
|
2312f03eac | ||
|
|
1d09e4b620 | ||
|
|
6ea1cf71b5 | ||
|
|
302fe94705 | ||
|
|
38ea8d1d86 | ||
|
|
67ed7e40be | ||
|
|
20f211b70a | ||
|
|
ebb07def7e | ||
|
|
55ab968edf | ||
|
|
3f6d6745de | ||
|
|
d1daae1b59 | ||
|
|
350ea2bf28 | ||
|
|
2f73d24ab1 | ||
|
|
1a05696a84 | ||
|
|
fc804751a2 | ||
|
|
938ef930d4 | ||
|
|
ee21d87d1b | ||
|
|
b1888afa10 | ||
|
|
856cc7d6b8 | ||
|
|
d79e81a069 | ||
|
|
f7d9523c7d | ||
|
|
d93e1c84ac | ||
|
|
2a7ff3018b | ||
|
|
c83da012ff | ||
|
|
46e9c4299e | ||
|
|
e1af81ea55 | ||
|
|
99848ab3bb | ||
|
|
90d48d60d8 | ||
|
|
48c0efd20e | ||
|
|
adfc748bfa | ||
|
|
5cef672f9a | ||
|
|
015c7243b9 | ||
|
|
d1480d9f56 | ||
|
|
f3cb17ac3b | ||
|
|
fb2d2c5585 | ||
|
|
945ba5d788 | ||
|
|
3e7edf504d | ||
|
|
3285c71995 | ||
|
|
669e111118 | ||
|
|
360fda15e9 | ||
|
|
2018b88093 | ||
|
|
837b9224cc | ||
|
|
c22da3da1c | ||
|
|
470915a55b | ||
|
|
d9a67d64b1 | ||
|
|
2a26c898ca | ||
|
|
69fc10d5ad | ||
|
|
3647b74d33 | ||
|
|
441946b9d3 | ||
|
|
d376d2a590 | ||
|
|
9328edfdcd | ||
|
|
d105f324af | ||
|
|
23213a91ed | ||
|
|
184c544a24 | ||
|
|
6cc60ba477 | ||
|
|
c5578d7964 | ||
|
|
95cf1aafa0 | ||
|
|
f72a3113f5 | ||
|
|
3c29b46c42 | ||
|
|
f2397c942c | ||
|
|
eb2df761d5 | ||
|
|
1ce8ce896b | ||
|
|
85daf26eb1 | ||
|
|
286be43963 | ||
|
|
d951534d8f | ||
|
|
515f3bf111 | ||
|
|
3852b5ce7f | ||
|
|
d753ae4cf1 | ||
|
|
2ce1e3678a | ||
|
|
365d690d7d | ||
|
|
e75616517d | ||
|
|
5cb2fa5981 | ||
|
|
e854562803 | ||
|
|
fad9594b31 | ||
|
|
1447499776 | ||
|
|
4fe3b5c6a6 | ||
|
|
417da13353 | ||
|
|
69dc1b03c3 | ||
|
|
d7089ab471 | ||
|
|
039f56f390 | ||
|
|
d7cae1ce2a | ||
|
|
d7cf7316be | ||
|
|
b4cbb3aeb1 | ||
|
|
de3012ccf1 | ||
|
|
53a0920f20 | ||
|
|
5fe9021375 | ||
|
|
fd28550ad2 | ||
|
|
c0cb21a07c | ||
|
|
c865f17dc0 | ||
|
|
e23f86faa9 | ||
|
|
7ba1217a13 | ||
|
|
60ac0cef5c | ||
|
|
a42b236587 | ||
|
|
8db5d3ba5c | ||
|
|
d05fd9632e | ||
|
|
ca0bc2bb7b | ||
|
|
3fbb955cf2 | ||
|
|
04b4897dd8 | ||
|
|
c2bc6a04ab | ||
|
|
96c61fc5f2 | ||
|
|
1b82fb7349 | ||
|
|
7b28c42693 | ||
|
|
58ffa31e91 | ||
|
|
0b5bad4aa7 | ||
|
|
2bce61d18b | ||
|
|
9cebd24987 | ||
|
|
0d2c90cc2e | ||
|
|
54c88dfae9 | ||
|
|
d1c23477df | ||
|
|
8fb1356623 | ||
|
|
d2fec56456 | ||
|
|
bd2d99aced | ||
|
|
71308fe8c1 | ||
|
|
da649e397e | ||
|
|
1dbcfaa2c6 | ||
|
|
2d471e39dc | ||
|
|
e5dec8671e | ||
|
|
5fa2aa6d48 | ||
|
|
0edac8810b | ||
|
|
b085a3243c | ||
|
|
d256e8e9f2 | ||
|
|
250d286f1d | ||
|
|
eac9c8a7e6 | ||
|
|
a67213627c | ||
|
|
852d19f209 | ||
|
|
b1f091e4d7 | ||
|
|
8cd583fd8c | ||
|
|
bf190be5b4 | ||
|
|
092e7378cd | ||
|
|
2a59392ba8 | ||
|
|
feabaedd83 | ||
|
|
c9b8f404e0 | ||
|
|
39df2a475e | ||
|
|
957abf1c1b | ||
|
|
7c34911b1c | ||
|
|
7688bf3f21 | ||
|
|
242cb047d4 | ||
|
|
43fbbfe0df | ||
|
|
72bdca009c | ||
|
|
fef93af0a6 | ||
|
|
3e7a76cc64 | ||
|
|
49c4aa1a54 | ||
|
|
afbbc9cd72 | ||
|
|
05bec13bdc | ||
|
|
8fc321ca62 | ||
|
|
6590ca02de | ||
|
|
20fc4ee021 | ||
|
|
a322254f2a | ||
|
|
fd7b668a16 | ||
|
|
5786fd2221 | ||
|
|
419b4ecfde | ||
|
|
69920fb717 | ||
|
|
863a979754 | ||
|
|
8d66fbccfa | ||
|
|
a4caaefd32 | ||
|
|
e50e687191 | ||
|
|
c96f121d41 | ||
|
|
72b7b19937 | ||
|
|
4e3d295c90 | ||
|
|
3b1554db2e | ||
|
|
37d07a7d2a | ||
|
|
75fbf21e6b | ||
|
|
27b61b1456 | ||
|
|
9f4f967ead | ||
|
|
9763c46b7e | ||
|
|
f682325924 | ||
|
|
abe362bdd4 | ||
|
|
ea331b043c | ||
|
|
1a4a921528 | ||
|
|
1982fc807f | ||
|
|
30fd17c58d | ||
|
|
4ebee195cc | ||
|
|
98eeff7538 | ||
|
|
f2fdc91ad5 | ||
|
|
d88c25c982 | ||
|
|
f70fd95361 | ||
|
|
be3a272a80 | ||
|
|
631eb4b2c2 | ||
|
|
6a1d1867f0 | ||
|
|
b3b566c907 | ||
|
|
dd5023e494 | ||
|
|
18bc12c21c | ||
|
|
1d4dc7e27c | ||
|
|
0d84c77c6c | ||
|
|
400eb748eb | ||
|
|
73b30de9cb | ||
|
|
7a8d0a03f6 | ||
|
|
d140620008 | ||
|
|
50a1e0c618 | ||
|
|
ef73880459 | ||
|
|
98f3242e73 | ||
|
|
0b7365e2db | ||
|
|
f88dc84091 | ||
|
|
3099562a21 | ||
|
|
588d22974c | ||
|
|
4c2bbe3c41 | ||
|
|
b634c08d0e | ||
|
|
2d9d4dfeb3 | ||
|
|
d882b3274b | ||
|
|
1aa48ddfaa | ||
|
|
ad02d5589d | ||
|
|
0e8991fec2 | ||
|
|
b651604e8b | ||
|
|
1932e72603 | ||
|
|
be4eb4eeb8 | ||
|
|
89fa36ce2a | ||
|
|
80df97e734 | ||
|
|
8dd7fab38d | ||
|
|
400d5790f3 | ||
|
|
c8e83d6edc | ||
|
|
c8b8c6cb14 | ||
|
|
44dcbeaaa4 | ||
|
|
0c23843b61 | ||
|
|
0a34b96e11 | ||
|
|
f30d2b489a | ||
|
|
81c740178d | ||
|
|
36b5f6acfe | ||
|
|
eae88b0815 | ||
|
|
58c9f516b3 | ||
|
|
8ce4814835 | ||
|
|
2656aeaf9c | ||
|
|
bf3ea2cd47 | ||
|
|
07cd0c870f | ||
|
|
2b1e672316 | ||
|
|
5adb41a0ed | ||
|
|
98fa996b3f | ||
|
|
07e890a79a | ||
|
|
3f9e39a9e3 | ||
|
|
b51bcba263 | ||
|
|
17d004d52b | ||
|
|
d94e61a7b6 |
29
.gitignore
vendored
29
.gitignore
vendored
@@ -14,24 +14,30 @@
|
||||
*.rej
|
||||
# OSX .DS_Store files
|
||||
.DS_Store
|
||||
# version scripts (repo master only)
|
||||
.version*
|
||||
Thumbs.db
|
||||
|
||||
|
||||
## Ignore RedMatrix site specific files and folders
|
||||
## Ignore site specific files and folders
|
||||
.htconfig.php
|
||||
favicon.*
|
||||
addon/
|
||||
widget/
|
||||
custom/
|
||||
/store/
|
||||
# site apps
|
||||
apps/
|
||||
!doc/context/*/apps
|
||||
# default startpage
|
||||
home.html
|
||||
# page header plugin
|
||||
pageheader.html
|
||||
# Ignore site TOS
|
||||
doc/SiteTOS.md
|
||||
# themes except for redbasic
|
||||
view/theme/*
|
||||
! view/theme/redbasic
|
||||
!view/theme/redbasic
|
||||
# site theme schemas
|
||||
view/theme/redbasic/schema/default.php
|
||||
# Doxygen API documentation, run 'doxygen util/Doxyfile' to generate it
|
||||
@@ -40,7 +46,8 @@ doc/html/
|
||||
.zotshrc
|
||||
# external repositories for themes/addons
|
||||
extend/
|
||||
|
||||
# files generated by phpunit
|
||||
tests/results/
|
||||
|
||||
## exclude IDE files
|
||||
# config files and folders from Eclipse
|
||||
@@ -56,11 +63,15 @@ nbproject/
|
||||
.idea/
|
||||
|
||||
|
||||
# composer files (at the moment composer is not officially supported and only used to add SabreDAV, we should add these)
|
||||
composer.*
|
||||
|
||||
# When we include composer we should exclude vendor/
|
||||
## composer
|
||||
# locally installed composer binary
|
||||
composer.phar
|
||||
# allow composer.lock, as it is required to have a common state
|
||||
!composer.lock
|
||||
# vendor/ is managed by composer, no need to include in our repository
|
||||
# requires new deployment and needs discussion first
|
||||
#vendor/
|
||||
# Exclude at least some vendor test files, examples, etc.
|
||||
vendor/sabre/*/tests/
|
||||
# Exclude at least some vendor test files, examples, etc. so far
|
||||
vendor/**/tests/
|
||||
vendor/**/Test/
|
||||
vendor/sabre/*/examples/
|
||||
|
||||
147
.gitlab-ci.yml
Normal file
147
.gitlab-ci.yml
Normal file
@@ -0,0 +1,147 @@
|
||||
# Select image from https://hub.docker.com/_/php/
|
||||
#image: php:7.2
|
||||
# Use a prepared Hubzilla image to optimise pipeline duration
|
||||
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.2
|
||||
|
||||
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
||||
|
||||
|
||||
# Select what we should cache
|
||||
cache:
|
||||
paths:
|
||||
- vendor/
|
||||
- .cache/
|
||||
|
||||
|
||||
# global variables for all jobs, if no job specific variables
|
||||
variables:
|
||||
# Tell composer to use the project workspace .cache folder
|
||||
COMPOSER_CACHE_DIR: "$CI_PROJECT_DIR/.cache/composer"
|
||||
# Ignore a Composer warning
|
||||
COMPOSER_ALLOW_SUPERUSER: 1
|
||||
# Configure MySQL/MariaDB service (https://hub.docker.com/_/mysql/, https://hub.docker.com/_/mariadb/)
|
||||
MYSQL_DATABASE: hello_world_test
|
||||
MYSQL_ROOT_PASSWORD: mysql
|
||||
# Configure PostgreSQL service (https://hub.docker.com/_/postgres/)
|
||||
POSTGRES_DB: ci-db
|
||||
POSTGRES_USER: ci-user
|
||||
POSTGRES_PASSWORD: ci-pass
|
||||
|
||||
|
||||
before_script:
|
||||
# pecl and composer do not work with PHP production restrictions (from Hubzilla Docker image)
|
||||
- if [ -f /usr/local/etc/php/conf.d/z_prod.ini ]; then mv /usr/local/etc/php/conf.d/z_prod.ini /usr/local/etc/php/conf.d/z_prod.ini.off; fi
|
||||
# Install & enable Xdebug for code coverage reports
|
||||
- pecl install xdebug
|
||||
- docker-php-ext-enable xdebug
|
||||
# Install composer
|
||||
- curl -sS https://getcomposer.org/installer | php
|
||||
# Install dev libraries from composer
|
||||
- php ./composer.phar install --no-progress
|
||||
|
||||
|
||||
# hidden job definition with template for MySQL/MariaDB
|
||||
.job_template_mysql: &job_definition_mysql
|
||||
stage: test
|
||||
script:
|
||||
- echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
|
||||
- vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text
|
||||
|
||||
# hidden job definition with template for PostgreSQL
|
||||
.job_template_postgres: &job_definition_postgres
|
||||
stage: test
|
||||
services:
|
||||
- postgres:latest
|
||||
script:
|
||||
- export PGPASSWORD=$POSTGRES_PASSWORD
|
||||
- psql --version
|
||||
- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT VERSION();"
|
||||
# Import hubzilla's DB schema
|
||||
- psql -h "postgres" -U "$POSTGRES_USER" -v ON_ERROR_STOP=1 --quiet "$POSTGRES_DB" < ./install/schema_postgres.sql
|
||||
# Show databases and relations/tables of hubzilla's database
|
||||
#- psql -h "postgres" -U "$POSTGRES_USER" -l
|
||||
#- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "\dt;"
|
||||
# Run the actual tests
|
||||
- vendor/bin/phpunit --configuration tests/phpunit-pgsql.xml --testdox
|
||||
|
||||
# hidden job definition with artifacts config template
|
||||
.artifacts_template:
|
||||
artifacts: &artifacts_template
|
||||
expire_in: 1 week
|
||||
# Gitlab should show the results, but has problems parsing PHPUnit's junit file.
|
||||
reports:
|
||||
junit: tests/results/junit.xml
|
||||
# Archive test results (coverage, testdox, junit)
|
||||
name: "$CI_COMMIT_REF_SLUG-$CI_JOB_NAME"
|
||||
paths:
|
||||
- tests/results/
|
||||
|
||||
|
||||
# PHP7.2 with MySQL 5.7
|
||||
php7.2_mysql5.7:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- mysql:5.7
|
||||
|
||||
|
||||
# PHP7.2 with MySQL 8 (latest)
|
||||
php7.2_mysql8:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- name: mysql:8
|
||||
command: ["--default-authentication-plugin=mysql_native_password"]
|
||||
|
||||
|
||||
# PHP7.2 with MariaDB 10.2
|
||||
php7.2_mariadb10.2:
|
||||
<<: *job_definition_mysql
|
||||
services:
|
||||
- name: mariadb:10.2
|
||||
alias: mysql
|
||||
|
||||
|
||||
# PHP7.3 with MariaDB 10.3 (latest)
|
||||
php7.3_mariadb10.3:
|
||||
<<: *job_definition_mysql
|
||||
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
services:
|
||||
- name: mariadb:10.3
|
||||
alias: mysql
|
||||
|
||||
|
||||
# PHP7.2 with PostgreSQL latest (11)
|
||||
php7.2_postgres11:
|
||||
<<: *job_definition_postgres
|
||||
artifacts: *artifacts_template
|
||||
|
||||
|
||||
# PHP7.3 with PostgreSQL latest (11)
|
||||
php7.3_postgres11:
|
||||
<<: *job_definition_postgres
|
||||
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
|
||||
artifacts: *artifacts_template
|
||||
|
||||
|
||||
# Generate Doxygen API Documentation and deploy it as GitLab pages
|
||||
pages:
|
||||
stage: deploy
|
||||
cache: {}
|
||||
image: php:7-cli-alpine
|
||||
before_script:
|
||||
- apk update
|
||||
- apk add doxygen ttf-freefont graphviz
|
||||
script:
|
||||
- doxygen util/Doxyfile
|
||||
- mv doc/html/ public/
|
||||
- echo "API documentation should be accessible at https://hubzilla.frama.io/core/ soon"
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
# Only generate it on main repo's master branch
|
||||
- master@hubzilla/core
|
||||
147
.homeinstall/README.md
Normal file
147
.homeinstall/README.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# How to use
|
||||
|
||||
## Disclaimers
|
||||
|
||||
- This script does work with Debian 10 only.
|
||||
- This script has to be used on a fresh debian install only (it does not take account for a possibly already installed and configured webserver or sql implementation).
|
||||
|
||||
## Preconditions
|
||||
|
||||
Hardware
|
||||
|
||||
+ Internet connection and router at home
|
||||
+ Mini-pc connected to your router (a Raspberry 3 will do for very small Hubs)
|
||||
+ USB drive for backups
|
||||
|
||||
Software
|
||||
|
||||
+ Fresh installation of Debian 10 (Stretch)
|
||||
+ Router with open ports 80 and 443 for your web server
|
||||
|
||||
## How to run the script
|
||||
|
||||
+ Register your own domain (for example at selfHOST) or a free subdomain (for example at freeDNS)
|
||||
+ Log on to your fresh Debian
|
||||
- apt-get install git
|
||||
- mkdir -p /var/www
|
||||
- cd /var/www
|
||||
- git clone https://framagit.org/hubzilla/core.git html
|
||||
- cd html/.homeinstall
|
||||
- cp hubzilla-config.txt.template hubzilla-config.txt
|
||||
- nano hubzilla-config.txt
|
||||
- Read the comments carefully
|
||||
- Enter your values: db pass, domain, values for dyn DNS
|
||||
- Prepare your external disk for backups
|
||||
- hubzilla-setup.sh as root
|
||||
- ... wait, wait, wait until the script is finised
|
||||
+ Open your domain with a browser and step throught the initial configuration of hubzilla.
|
||||
|
||||
## Optional - Set path to imagemagick
|
||||
|
||||
In Admin settings of hubzilla or via terminal
|
||||
|
||||
cd /var/www/html
|
||||
util/config system.imagick_convert_path /usr/bin/convert
|
||||
|
||||
## Optional - Switch verification of email on/off
|
||||
|
||||
Do this just befor you register the user.
|
||||
|
||||
In Admin settings of hubzilla or via terminal
|
||||
|
||||
cd /var/www/html
|
||||
|
||||
Check the current setting
|
||||
|
||||
util/config system verify_email
|
||||
|
||||
Switch the verification on/off (1/0)
|
||||
|
||||
util/config system verify_email 0
|
||||
|
||||
## What the script will do for you...
|
||||
|
||||
+ install everything required by Hubzilla, basically a web server (Apache), PHP, a database (MySQL), certbot,...
|
||||
+ create a database
|
||||
+ run certbot to have everything for a secure connection (httpS)
|
||||
+ create a script for daily maintenance
|
||||
- backup to external disk (certificates, database, /var/www/)
|
||||
- renew certfificate (letsencrypt)
|
||||
- update of Hubzilla
|
||||
- update of Debian
|
||||
- restart
|
||||
+ create cron jobs for
|
||||
- DynDNS (selfHOST.de or freedns.afraid.org) every 5 minutes
|
||||
- Master.php for Zap/Hubzilla every 10 minutes
|
||||
- daily maintenance script every day at 05:30
|
||||
|
||||
The script is known to work without adjustments with
|
||||
|
||||
+ Hardware
|
||||
- Mini-PC with Debian 10 (stretch), or
|
||||
- Rapberry 3 with Raspbian, Debian 10
|
||||
+ DynDNS
|
||||
- selfHOST.de
|
||||
- freedns.afraid.org
|
||||
|
||||
The script can install both [Hubzilla](https://zotlabs.org/page/hubzilla/hubzilla-project) and [Zap](https://zotlabs.com/zap/). Make sure to use the correct GIT repositories.
|
||||
|
||||
+ Hubzilla
|
||||
- core: git clone https://framagit.org/hubzilla/core.git html (in this readme)
|
||||
- addons: util/add_addon_repo https://framagit.org/hubzilla/addons.git hzaddons (in hubzilla-setup.sh)
|
||||
+ Zap
|
||||
- core: git clone https://framagit.org/zot/zap.git html (in this readme)
|
||||
- addons: util/add_addon_repo https://framagit.org/zot/zap-addons.git zaddons (in hubzilla-setup.sh)
|
||||
|
||||
|
||||
|
||||
# Step-by-Step - some Details
|
||||
|
||||
## Preparations
|
||||
|
||||
## Configure your Router
|
||||
|
||||
Your web has to be visible in the internet.
|
||||
|
||||
Open the ports 80 and 443 on your router for your Debian. Make sure your web server is marked as "exposed host".
|
||||
|
||||
## Preparations Dynamic IP Address
|
||||
|
||||
Follow the instructions in .homeinstall/hubzilla-config.txt.
|
||||
|
||||
In short...
|
||||
|
||||
Your Hubzilla must be reachable by a domain that you can type in your browser
|
||||
|
||||
cooldomain.org
|
||||
|
||||
You can use subdomains as well
|
||||
|
||||
my.cooldomain.org
|
||||
|
||||
There are two ways to get a domain...
|
||||
|
||||
### Method 1: Buy a Domain
|
||||
|
||||
...for example buy at selfHOST.de
|
||||
|
||||
The cost is 1,50 € per month (2019).
|
||||
|
||||
### Method 2: Register a free subdomain
|
||||
|
||||
...for example register at freedns.afraid.org
|
||||
|
||||
## Note on Rasperry
|
||||
|
||||
The script was tested with an Raspberry 3 under Raspian, Debian 10.
|
||||
|
||||
It is recommended to run the Raspi without graphical frontend (X-Server). Use...
|
||||
|
||||
sudo raspi-config
|
||||
|
||||
to boot the Rapsi to the client console.
|
||||
|
||||
DO NOT FORGET TO CHANGE THE DEFAULT PASSWORD FOR USER PI!
|
||||
|
||||
|
||||
|
||||
163
.homeinstall/hubzilla-config.txt.template
Normal file
163
.homeinstall/hubzilla-config.txt.template
Normal file
@@ -0,0 +1,163 @@
|
||||
###############################################
|
||||
### MANDATORY - database password #############
|
||||
#
|
||||
# Please give your database password
|
||||
# It is better to not use blanks inside the password.
|
||||
# Example: db_pass=pass_word_with_no_blanks_in_it
|
||||
db_pass=
|
||||
|
||||
###############################################
|
||||
### MANDATORY - let's encrypt #################
|
||||
#
|
||||
# Hubilla requires encrypted communication via secure HTTP (HTTPS).
|
||||
# This script automates installation of an SSL certificate from
|
||||
# Let's Encrypt (https://letsencrypt.org)
|
||||
#
|
||||
# Please give the domain name of your hub
|
||||
#
|
||||
# Example: my.cooldomain.org
|
||||
# Example: cooldomain.org
|
||||
#
|
||||
# You might use "localhost" for a LOCAL TEST installation.
|
||||
# This is usefull if you want to debug the server inside a VM.
|
||||
#
|
||||
# Example: localhost
|
||||
#
|
||||
# Email is optional if you use "localhost".
|
||||
#
|
||||
#
|
||||
le_domain=
|
||||
le_email=
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - selfHOST - dynamic IP address ##
|
||||
#
|
||||
# 1. Register a domain at selfhost.de
|
||||
# - choose offer "DOMAIN dynamisch" 1,50€/mon at 04/2019
|
||||
# 2. Get your configuration for dynamic IP update
|
||||
# - Log in at selfhost.de
|
||||
# - go to "DynDNS Accounte"
|
||||
# - klick "Details" of your (freshly) registered domain
|
||||
# - You will find the configuration there
|
||||
# - Benutzername (user name) > use this for "selfhost_user="
|
||||
# - Passwort (pass word) > use this for "selfhost_pass="
|
||||
#
|
||||
#
|
||||
selfhost_user=
|
||||
selfhost_pass=
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - FreeDNS - dynamic IP address ###
|
||||
#
|
||||
# Please give the alpha-numeric-key of freedns
|
||||
#
|
||||
# Get a free subdomain from freedns and use it for your dynamic ip address
|
||||
# Documentation under http://www.techjawab.com/2013/06/setup-dynamic-dns-dyndns-for-free-on.html
|
||||
#
|
||||
# - Register for a Free domain at http://freedns.afraid.org/signup/
|
||||
# - WATCH THIS: Make sure you choose a domain with as less subdomains as
|
||||
# possible. Why? Let's encrpyt issues a limited count of certificates each
|
||||
# day. Possible other users of this domain will try to issue a certificate
|
||||
# at the same day.
|
||||
# - Logon to FreeDNS (where you just registered)
|
||||
# - Goto http://freedns.afraid.org/dynamic/
|
||||
# - Right click on "Direct Link" and copy the URL and paste it somewhere.
|
||||
# - You should notice a large and unique alpha-numeric key in the URL
|
||||
#
|
||||
# http://freedns.afraid.org/dynamic/update.php?alpha-numeric-key
|
||||
#
|
||||
# Provided your url from freedns is
|
||||
#
|
||||
# http://freedns.afraid.org/dynamic/update.php?U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
|
||||
#
|
||||
# Then you have to provide
|
||||
#
|
||||
# freedns_key=U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
|
||||
#
|
||||
#
|
||||
freedns_key=
|
||||
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - Backup to external device ######
|
||||
#
|
||||
# The script can use an external device for the daily backup.
|
||||
# The file system of the device (USB stick for example) must be compatible with
|
||||
#
|
||||
# - encrypted LUKS + ext4, or
|
||||
# - ext4
|
||||
#
|
||||
# You should test to mount the device befor you run the script
|
||||
# (hubzilla-setup.sh).
|
||||
# How to find your (pluged-in) devices?
|
||||
#
|
||||
# fdisk -l
|
||||
#
|
||||
# Provided your device was listed as is /dev/sdb1. You could check with:
|
||||
#
|
||||
# blkid | grep /dev/sdb1
|
||||
#
|
||||
# Try to decrypt
|
||||
# (You might install cryptsetup befor using apt-get install.
|
||||
#
|
||||
# apt-get install cryptsetup
|
||||
# cryptsetup luksOpen /dev/sdb1 cryptobackup
|
||||
#
|
||||
# Try to mount
|
||||
# You might create the directory /media/hubzilla_backup it it does not exist
|
||||
# using mkdir.
|
||||
#
|
||||
# mkdir /media/hubzilla_backup
|
||||
# mount /dev/mapper/cryptobackup /media/hubzilla_backup
|
||||
#
|
||||
# Unmounting device goes like this
|
||||
#
|
||||
# umount /media/hubzilla_backup
|
||||
# cryptsetup luksClose cryptobackup
|
||||
#
|
||||
# To check if still mounted
|
||||
#
|
||||
# lsof /media/hubzilla_backup
|
||||
#
|
||||
# If you leave the following parameters
|
||||
#
|
||||
# - "backup_device_name" and
|
||||
# - "backup_device_pass"
|
||||
#
|
||||
# empty the script will create daily backups on the internal disk (which could
|
||||
# save you as well).
|
||||
#
|
||||
# Example: backup_device_name=/dev/sdc1
|
||||
#
|
||||
# Leave "backup_device_pass=" empty if the external device is not encrypted.
|
||||
#
|
||||
backup_device_name=
|
||||
backup_device_pass=
|
||||
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - do not mess with things below ##
|
||||
# (...if you are not certain)
|
||||
#
|
||||
# Usually you are done here
|
||||
# Everything below is OPTIONAL
|
||||
#
|
||||
###############################################
|
||||
#
|
||||
# Database for hubzilla
|
||||
hubzilla_db_name=hubzilla
|
||||
hubzilla_db_user=hubzilla
|
||||
hubzilla_db_pass=$db_pass
|
||||
#
|
||||
#
|
||||
# Password for package mysql-server
|
||||
# Example: mysqlpass=aberhallo
|
||||
# Example: mysqlpass="aber hallo has blanks in it"
|
||||
#
|
||||
mysqlpass=$db_pass
|
||||
|
||||
# Password for package phpmyadmin
|
||||
# Example: phpmyadminpass=aberhallo
|
||||
# Example: phpmyadminpass="aber hallo has blanks in it"
|
||||
phpmyadminpass=$db_pass
|
||||
|
||||
656
.homeinstall/hubzilla-setup.sh
Executable file
656
.homeinstall/hubzilla-setup.sh
Executable file
@@ -0,0 +1,656 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# How to use
|
||||
# ----------
|
||||
#
|
||||
# This file automates the installation of
|
||||
# - hubzilla: https://zotlabs.org/page/hubzilla/hubzilla-project and
|
||||
# - zap: https://zotlabs.com/zap/
|
||||
# under Debian Linux
|
||||
#
|
||||
# 1) Copy the file "hubzilla-config.txt.template" to "hubzilla-config.txt"
|
||||
# Follow the instuctions there
|
||||
#
|
||||
# 2) Switch to user "root" by typing "su -"
|
||||
#
|
||||
# 3) Run with "./hubzilla-setup.sh"
|
||||
# If this fails check if you can execute the script.
|
||||
# - To make it executable type "chmod +x hubzilla-setup.sh"
|
||||
# - or run "bash hubzilla-setup.sh"
|
||||
#
|
||||
#
|
||||
# What does this script do basically?
|
||||
# -----------------------------------
|
||||
#
|
||||
# This file automates the installation of hubzilla under Debian Linux
|
||||
# - install
|
||||
# * apache webserer,
|
||||
# * php,
|
||||
# * mariadb - the database for hubzilla,
|
||||
# * adminer,
|
||||
# * git to download and update addons
|
||||
# - configure cron
|
||||
# * "Master.php" for regular background prozesses of hubzilla
|
||||
# * "apt-get update" and "apt-get dist-upgrade" and "apt-get autoremove" to keep linux up-to-date
|
||||
# * run command to keep the IP up-to-date > DynDNS provided by selfHOST.de or freedns.afraid.org
|
||||
# * backup hubzillas database and files (rsync)
|
||||
# - run letsencrypt to create, register and use a certifacte for https
|
||||
#
|
||||
#
|
||||
# Discussion
|
||||
# ----------
|
||||
#
|
||||
# Security - password is the same for mysql-server, phpmyadmin and hubzilla db
|
||||
# - The script runs into installation errors for phpmyadmin if it uses
|
||||
# different passwords. For the sake of simplicity one singel password.
|
||||
#
|
||||
# How to restore from backup
|
||||
# --------------------------
|
||||
#
|
||||
# Daily backup
|
||||
# - - - - - -
|
||||
#
|
||||
# The installation
|
||||
# - writes a script /var/www/hubzilla-daily.sh
|
||||
# - creates a daily cron that runs the hubzilla-daily.sh
|
||||
#
|
||||
# hubzilla-daily.sh makes a (daily) backup of all relevant files
|
||||
# - /var/lib/mysql/ > database
|
||||
# - /var/www/ > hubzilla/zap from github
|
||||
# - /etc/letsencrypt/ > certificates
|
||||
#
|
||||
# hubzilla-daily.sh writes the backup to an external disk compatible to LUKS+ext4 (see hubzilla-config.txt)
|
||||
#
|
||||
# Credits
|
||||
# -------
|
||||
#
|
||||
# The script is based on Thomas Willinghams script "debian-setup.sh"
|
||||
# which he used to install the red#matrix.
|
||||
#
|
||||
# The documentation for bash is here
|
||||
# https://www.gnu.org/software/bash/manual/bash.html
|
||||
#
|
||||
function check_sanity {
|
||||
# Do some sanity checking.
|
||||
print_info "Sanity check..."
|
||||
if [ $(/usr/bin/id -u) != "0" ]
|
||||
then
|
||||
die 'Must be run by root user'
|
||||
fi
|
||||
|
||||
if [ -f /etc/lsb-release ]
|
||||
then
|
||||
die "Distribution is not supported"
|
||||
fi
|
||||
if [ ! -f /etc/debian_version ]
|
||||
then
|
||||
die "Debian is supported only"
|
||||
fi
|
||||
if ! grep -q 'Linux 10' /etc/issue
|
||||
then
|
||||
die "Linux 10 (buster) is supported only"x
|
||||
fi
|
||||
}
|
||||
|
||||
function check_config {
|
||||
print_info "config check..."
|
||||
# Check for required parameters
|
||||
if [ -z "$db_pass" ]
|
||||
then
|
||||
die "db_pass not set in $configfile"
|
||||
fi
|
||||
if [ -z "$le_domain" ]
|
||||
then
|
||||
die "le_domain not set in $configfile"
|
||||
fi
|
||||
# backup is important and should be checked
|
||||
if [ -n "$backup_device_name" ]
|
||||
then
|
||||
if [ ! -d "$backup_mount_point" ]
|
||||
then
|
||||
mkdir "$backup_mount_point"
|
||||
fi
|
||||
device_mounted=0
|
||||
if fdisk -l | grep -i "$backup_device_name.*linux"
|
||||
then
|
||||
print_info "ok - filesystem of external device is linux"
|
||||
if [ -n "$backup_device_pass" ]
|
||||
then
|
||||
echo "$backup_device_pass" | cryptsetup luksOpen $backup_device_name cryptobackup
|
||||
if mount /dev/mapper/cryptobackup /media/hubzilla_backup
|
||||
then
|
||||
device_mounted=1
|
||||
print_info "ok - could encrypt and mount external backup device"
|
||||
umount /media/hubzilla_backup
|
||||
else
|
||||
print_warn "backup to external device will fail because encryption failed"
|
||||
fi
|
||||
cryptsetup luksClose cryptobackup
|
||||
else
|
||||
if mount $backup_device_name /media/hubzilla_backup
|
||||
then
|
||||
device_mounted=1
|
||||
print_info "ok - could mount external backup device"
|
||||
umount /media/hubzilla_backup
|
||||
else
|
||||
print_warn "backup to external device will fail because mount failed"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
print_warn "backup to external device will fail because filesystem is either not linux or 'backup_device_name' is not correct in $configfile"
|
||||
fi
|
||||
if [ $device_mounted == 0 ]
|
||||
then
|
||||
die "backup device not ready"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function die {
|
||||
echo "ERROR: $1" > /dev/null 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
function update_upgrade {
|
||||
print_info "updated and upgrade..."
|
||||
# Run through the apt-get update/upgrade first. This should be done before
|
||||
# we try to install any package
|
||||
apt-get -q -y update && apt-get -q -y dist-upgrade
|
||||
print_info "updated and upgraded linux"
|
||||
}
|
||||
|
||||
function check_install {
|
||||
if [ -z "`which "$1" 2>/dev/null`" ]
|
||||
then
|
||||
# export DEBIAN_FRONTEND=noninteractive ... answers from the package
|
||||
# configuration database
|
||||
# - q ... without progress information
|
||||
# - y ... answer interactive questions with "yes"
|
||||
# DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -q -y install $2
|
||||
print_info "installed $2 installed for $1"
|
||||
else
|
||||
print_warn "$2 already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
function nocheck_install {
|
||||
# export DEBIAN_FRONTEND=noninteractive ... answers from the package configuration database
|
||||
# - q ... without progress information
|
||||
# - y ... answer interactive questions with "yes"
|
||||
# DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
|
||||
# DEBIAN_FRONTEND=noninteractive apt-get --install-suggests -q -y install $1
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -q -y install $1
|
||||
print_info "installed $1"
|
||||
}
|
||||
|
||||
|
||||
function print_info {
|
||||
echo -n -e '\e[1;34m'
|
||||
echo -n $1
|
||||
echo -e '\e[0m'
|
||||
}
|
||||
|
||||
function print_warn {
|
||||
echo -n -e '\e[1;31m'
|
||||
echo -n $1
|
||||
echo -e '\e[0m'
|
||||
}
|
||||
|
||||
function stop_hubzilla {
|
||||
print_info "stopping apache webserver..."
|
||||
systemctl stop apache2
|
||||
print_info "stopping mysql db..."
|
||||
systemctl stop mariadb
|
||||
}
|
||||
|
||||
function install_apache {
|
||||
print_info "installing apache..."
|
||||
nocheck_install "apache2 apache2-utils"
|
||||
a2enmod rewrite
|
||||
systemctl restart apache2
|
||||
}
|
||||
|
||||
function install_imagemagick {
|
||||
print_info "installing imagemagick..."
|
||||
nocheck_install "imagemagick"
|
||||
}
|
||||
|
||||
function install_curl {
|
||||
print_info "installing curl..."
|
||||
nocheck_install "curl"
|
||||
}
|
||||
|
||||
function install_wget {
|
||||
print_info "installing wget..."
|
||||
nocheck_install "wget"
|
||||
}
|
||||
|
||||
function install_sendmail {
|
||||
print_info "installing sendmail..."
|
||||
nocheck_install "sendmail sendmail-bin"
|
||||
}
|
||||
|
||||
function install_php {
|
||||
# openssl and mbstring are included in libapache2-mod-php
|
||||
print_info "installing php..."
|
||||
nocheck_install "libapache2-mod-php php php-pear php-curl php-gd php-mysqli php-mbstring php-xml php-zip"
|
||||
sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/7.3/apache2/php.ini
|
||||
sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/7.3/apache2/php.ini
|
||||
}
|
||||
|
||||
function install_mysql {
|
||||
print_info "installing mysql..."
|
||||
if [ -z "$mysqlpass" ]
|
||||
then
|
||||
die "mysqlpass not set in $configfile"
|
||||
fi
|
||||
if type mysql ; then
|
||||
echo "Yes, mysql is installed"
|
||||
else
|
||||
echo "mariadb-server"
|
||||
nocheck_install "mariadb-server"
|
||||
systemctl status mariadb
|
||||
systemctl start mariadb
|
||||
mysql --user=root <<_EOF_
|
||||
UPDATE mysql.user SET Password=PASSWORD('${db_root_password}') WHERE User='root';
|
||||
DELETE FROM mysql.user WHERE User='';
|
||||
DROP DATABASE IF EXISTS test;
|
||||
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
|
||||
FLUSH PRIVILEGES;
|
||||
_EOF_
|
||||
fi
|
||||
}
|
||||
|
||||
function install_adminer {
|
||||
print_info "installing adminer..."
|
||||
nocheck_install "adminer"
|
||||
if [ ! -f /etc/adminer/adminer.conf ]
|
||||
then
|
||||
echo "Alias /adminer /usr/share/adminer/adminer" > /etc/adminer/adminer.conf
|
||||
ln -s /etc/adminer/adminer.conf /etc/apache2/conf-available/adminer.conf
|
||||
else
|
||||
print_info "file /etc/adminer/adminer.conf exists already"
|
||||
fi
|
||||
|
||||
a2enmod rewrite
|
||||
|
||||
if [ ! -f /etc/apache2/apache2.conf ]
|
||||
then
|
||||
die "could not find file /etc/apache2/apache2.conf"
|
||||
fi
|
||||
sed -i \
|
||||
"s/AllowOverride None/AllowOverride all/" \
|
||||
/etc/apache2/apache2.conf
|
||||
|
||||
a2enconf adminer
|
||||
systemctl restart mariadb
|
||||
systemctl reload apache2
|
||||
}
|
||||
|
||||
function create_hubzilla_db {
|
||||
print_info "creating hubzilla database..."
|
||||
if [ -z "$hubzilla_db_name" ]
|
||||
then
|
||||
die "hubzilla_db_name not set in $configfile"
|
||||
fi
|
||||
if [ -z "$hubzilla_db_user" ]
|
||||
then
|
||||
die "hubzilla_db_user not set in $configfile"
|
||||
fi
|
||||
if [ -z "$hubzilla_db_pass" ]
|
||||
then
|
||||
die "hubzilla_db_pass not set in $configfile"
|
||||
fi
|
||||
systemctl restart mariadb
|
||||
Q1="CREATE DATABASE IF NOT EXISTS $hubzilla_db_name;"
|
||||
Q2="GRANT USAGE ON *.* TO $hubzilla_db_user@localhost IDENTIFIED BY '$hubzilla_db_pass';"
|
||||
Q3="GRANT ALL PRIVILEGES ON $hubzilla_db_name.* to $hubzilla_db_user@localhost identified by '$hubzilla_db_pass';"
|
||||
Q4="FLUSH PRIVILEGES;"
|
||||
SQL="${Q1}${Q2}${Q3}${Q4}"
|
||||
mysql -uroot -p$phpmyadminpass -e "$SQL"
|
||||
}
|
||||
|
||||
function run_freedns {
|
||||
print_info "run freedns (dynamic IP)..."
|
||||
if [ -z "$freedns_key" ]
|
||||
then
|
||||
print_info "freedns was not started because 'freedns_key' is empty in $configfile"
|
||||
else
|
||||
if [ -n "$selfhost_user" ]
|
||||
then
|
||||
die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
|
||||
fi
|
||||
wget --no-check-certificate -O - https://freedns.afraid.org/dynamic/update.php?$freedns_key
|
||||
fi
|
||||
}
|
||||
|
||||
function install_run_selfhost {
|
||||
print_info "install and start selfhost (dynamic IP)..."
|
||||
if [ -z "$selfhost_user" ]
|
||||
then
|
||||
print_info "selfHOST was not started because 'selfhost_user' is empty in $configfile"
|
||||
else
|
||||
if [ -n "$freedns_key" ]
|
||||
then
|
||||
die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
|
||||
fi
|
||||
if [ -z "$selfhost_pass" ]
|
||||
then
|
||||
die "selfHOST was not started because 'selfhost_pass' is empty in $configfile"
|
||||
fi
|
||||
if [ ! -d $selfhostdir ]
|
||||
then
|
||||
mkdir $selfhostdir
|
||||
fi
|
||||
# the old way
|
||||
# https://carol.selfhost.de/update?username=123456&password=supersafe
|
||||
#
|
||||
# the prefered way
|
||||
wget --output-document=$selfhostdir/$selfhostscript http://jonaspasche.de/selfhost-updater
|
||||
echo "router" > $selfhostdir/device
|
||||
echo "$selfhost_user" > $selfhostdir/user
|
||||
echo "$selfhost_pass" > $selfhostdir/pass
|
||||
bash $selfhostdir/$selfhostscript update
|
||||
fi
|
||||
}
|
||||
|
||||
function ping_domain {
|
||||
print_info "ping domain $domain..."
|
||||
# Is the domain resolved? Try to ping 6 times à 10 seconds
|
||||
COUNTER=0
|
||||
for i in {1..6}
|
||||
do
|
||||
print_info "loop $i for ping -c 1 $domain ..."
|
||||
if ping -c 4 -W 1 $le_domain
|
||||
then
|
||||
print_info "$le_domain resolved"
|
||||
break
|
||||
else
|
||||
if [ $i -gt 5 ]
|
||||
then
|
||||
die "Failed to: ping -c 1 $domain not resolved"
|
||||
fi
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
sleep 5
|
||||
}
|
||||
|
||||
function configure_cron_freedns {
|
||||
print_info "configure cron for freedns..."
|
||||
if [ -z "$freedns_key" ]
|
||||
then
|
||||
print_info "freedns is not configured because freedns_key is empty in $configfile"
|
||||
else
|
||||
# Use cron for dynamich ip update
|
||||
# - at reboot
|
||||
# - every 30 minutes
|
||||
if [ -z "`grep 'freedns.afraid.org' /etc/crontab`" ]
|
||||
then
|
||||
echo "@reboot root https://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
|
||||
echo "*/30 * * * * root wget --no-check-certificate -O - https://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
|
||||
else
|
||||
print_info "cron for freedns was configured already"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function configure_cron_selfhost {
|
||||
print_info "configure cron for selfhost..."
|
||||
if [ -z "$selfhost_user" ]
|
||||
then
|
||||
print_info "selfhost is not configured because selfhost_key is empty in $configfile"
|
||||
else
|
||||
# Use cron for dynamich ip update
|
||||
# - at reboot
|
||||
# - every 5 minutes
|
||||
if [ -z "`grep 'selfhost-updater.sh' /etc/crontab`" ]
|
||||
then
|
||||
echo "@reboot root bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
|
||||
echo "*/5 * * * * root /bin/bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
|
||||
else
|
||||
print_info "cron for selfhost was configured already"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function install_letsencrypt {
|
||||
print_info "installing let's encrypt ..."
|
||||
# check if user gave domain
|
||||
if [ -z "$le_domain" ]
|
||||
then
|
||||
die "Failed to install let's encrypt: 'le_domain' is empty in $configfile"
|
||||
fi
|
||||
if [ -z "$le_email" ]
|
||||
then
|
||||
die "Failed to install let's encrypt: 'le_email' is empty in $configfile"
|
||||
fi
|
||||
nocheck_install "certbot python-certbot-apache"
|
||||
print_info "run certbot ..."
|
||||
certbot --apache -w /var/www/html -d $le_domain -m $le_email --agree-tos --non-interactive --redirect --hsts --uir
|
||||
service apache2 restart
|
||||
}
|
||||
|
||||
function check_https {
|
||||
print_info "checking httpS > testing ..."
|
||||
url_https=https://$le_domain
|
||||
wget_output=$(wget -nv --spider --max-redirect 0 $url_https)
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
print_warn "check not ok"
|
||||
else
|
||||
print_info "check ok"
|
||||
fi
|
||||
}
|
||||
|
||||
function install_hubzilla {
|
||||
print_info "installing addons..."
|
||||
cd /var/www/html/
|
||||
if git remote -v | grep -i "origin.*hubzilla.*core"
|
||||
then
|
||||
print_info "hubzilla"
|
||||
util/add_addon_repo https://framagit.org/hubzilla/addons hzaddons
|
||||
elif git remote -v | grep -i "origin.*zap.*core"
|
||||
then
|
||||
print_info "zap"
|
||||
util/add_addon_repo https://framagit.org/zot/zap-addons.git zaddons
|
||||
else
|
||||
die "neither zap nor hubzilla repository > did not install addons or zap/hubzilla"
|
||||
fi
|
||||
mkdir -p "store/[data]/smarty3"
|
||||
chmod -R 777 store
|
||||
touch .htconfig.php
|
||||
chmod ou+w .htconfig.php
|
||||
cd /var/www/
|
||||
chown -R www-data:www-data html
|
||||
chown root:www-data /var/www/html/
|
||||
chown root:www-data /var/www/html/.htaccess
|
||||
chmod 0644 /var/www/html/.htaccess
|
||||
print_info "installed addons"
|
||||
}
|
||||
|
||||
function install_rsync {
|
||||
print_info "installing rsync..."
|
||||
nocheck_install "rsync"
|
||||
}
|
||||
|
||||
function install_cryptosetup {
|
||||
print_info "installing cryptsetup..."
|
||||
nocheck_install "cryptsetup"
|
||||
}
|
||||
|
||||
function configure_cron_daily {
|
||||
print_info "configuring cron..."
|
||||
# every 10 min for poller.php
|
||||
if [ -z "`grep 'Master.php' /etc/crontab`" ]
|
||||
then
|
||||
echo "*/10 * * * * www-data cd /var/www/html; php Zotlabs/Daemon/Master.php Cron >> /dev/null 2>&1" >> /etc/crontab
|
||||
fi
|
||||
# Run external script daily at 05:30
|
||||
# - stop apache and mysql-server
|
||||
# - renew the certificate of letsencrypt
|
||||
# - backup db, files (/var/www/html), certificates if letsencrypt
|
||||
# - update hubzilla core and addon
|
||||
# - update and upgrade linux
|
||||
# - reboot is done by "shutdown -h now" because "reboot" hangs sometimes depending on the system
|
||||
echo "#!/bin/sh" > /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "echo \" \"" >> /var/www/$hubzilladaily
|
||||
echo "echo \"+++ \$(date) +++\"" >> /var/www/$hubzilladaily
|
||||
echo "echo \" \"" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - renew certificate...\"" >> /var/www/$hubzilladaily
|
||||
echo "certbot renew --noninteractive" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - stopping apache and mysql...\"" >> /var/www/$hubzilladaily
|
||||
echo "service apache2 stop" >> /var/www/$hubzilladaily
|
||||
echo "/etc/init.d/mysql stop # to avoid inconsistencies" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "# backup" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - try to mount external device for backup...\"" >> /var/www/$hubzilladaily
|
||||
echo "backup_device_name=$backup_device_name" >> /var/www/$hubzilladaily
|
||||
echo "backup_device_pass=$backup_device_pass" >> /var/www/$hubzilladaily
|
||||
echo "backup_mount_point=$backup_mount_point" >> /var/www/$hubzilladaily
|
||||
echo "device_mounted=0" >> /var/www/$hubzilladaily
|
||||
echo "if [ -n \"$backup_device_name\" ]" >> /var/www/$hubzilladaily
|
||||
echo "then" >> /var/www/$hubzilladaily
|
||||
echo " if blkid | grep $backup_device_name" >> /var/www/$hubzilladaily
|
||||
echo " then" >> /var/www/$hubzilladaily
|
||||
if [ -n "$backup_device_pass" ]
|
||||
then
|
||||
echo " echo \"decrypting backup device...\"" >> /var/www/$hubzilladaily
|
||||
echo " echo "\"$backup_device_pass\"" | cryptsetup luksOpen $backup_device_name cryptobackup" >> /var/www/$hubzilladaily
|
||||
fi
|
||||
echo " if [ ! -d $backup_mount_point ]" >> /var/www/$hubzilladaily
|
||||
echo " then" >> /var/www/$hubzilladaily
|
||||
echo " mkdir $backup_mount_point" >> /var/www/$hubzilladaily
|
||||
echo " fi" >> /var/www/$hubzilladaily
|
||||
echo " echo \"mounting backup device...\"" >> /var/www/$hubzilladaily
|
||||
if [ -n "$backup_device_pass" ]
|
||||
then
|
||||
echo " if mount /dev/mapper/cryptobackup $backup_mount_point" >> /var/www/$hubzilladaily
|
||||
else
|
||||
echo " if mount $backup_device_name $backup_mount_point" >> /var/www/$hubzilladaily
|
||||
fi
|
||||
echo " then" >> /var/www/$hubzilladaily
|
||||
echo " device_mounted=1" >> /var/www/$hubzilladaily
|
||||
echo " echo \"device $backup_device_name is now mounted. Starting backup...\"" >> /var/www/$hubzilladaily
|
||||
echo " rsync -a --delete /var/lib/mysql/ /media/hubzilla_backup/mysql" >> /var/www/$hubzilladaily
|
||||
echo " rsync -a --delete /var/www/ /media/hubzilla_backup/www" >> /var/www/$hubzilladaily
|
||||
echo " rsync -a --delete /etc/letsencrypt/ /media/hubzilla_backup/letsencrypt" >> /var/www/$hubzilladaily
|
||||
echo " echo \"\$(date) - disk sizes...\"" >> /var/www/$hubzilladaily
|
||||
echo " df -h" >> /var/www/$hubzilladaily
|
||||
echo " echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
|
||||
echo " du -h $backup_mount_point | grep mysql/hubzilla" >> /var/www/$hubzilladaily
|
||||
echo " echo \"unmounting backup device...\"" >> /var/www/$hubzilladaily
|
||||
echo " umount $backup_mount_point" >> /var/www/$hubzilladaily
|
||||
echo " else" >> /var/www/$hubzilladaily
|
||||
echo " echo \"failed to mount device $backup_device_name\"" >> /var/www/$hubzilladaily
|
||||
echo " fi" >> /var/www/$hubzilladaily
|
||||
if [ -n "$backup_device_pass" ]
|
||||
then
|
||||
echo " echo \"closing decrypted backup device...\"" >> /var/www/$hubzilladaily
|
||||
echo " cryptsetup luksClose cryptobackup" >> /var/www/$hubzilladaily
|
||||
fi
|
||||
echo " fi" >> /var/www/$hubzilladaily
|
||||
echo "fi" >> /var/www/$hubzilladaily
|
||||
echo "if [ \$device_mounted == 0 ]" >> /var/www/$hubzilladaily
|
||||
echo "then" >> /var/www/$hubzilladaily
|
||||
echo " echo \"device could not be mounted $backup_device_name. No backup written.\"" >> /var/www/$hubzilladaily
|
||||
echo "fi" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
|
||||
echo "du -h /var/lib/mysql/ | grep mysql/hubzilla" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "# update" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - updating core and addons...\"" >> /var/www/$hubzilladaily
|
||||
echo "(cd /var/www/html/ ; util/udall)" >> /var/www/$hubzilladaily
|
||||
echo "chown -R www-data:www-data /var/www/html/ # make all accessable for the webserver" >> /var/www/$hubzilladaily
|
||||
echo "chown root:www-data /var/www/html/.htaccess" >> /var/www/$hubzilladaily
|
||||
echo "chmod 0644 /var/www/html/.htaccess # www-data can read but not write it" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - updating linux...\"" >> /var/www/$hubzilladaily
|
||||
echo "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # update linux and upgrade" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - Backup and update finished. Rebooting...\"" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "shutdown -r now" >> /var/www/$hubzilladaily
|
||||
|
||||
if [ -z "`grep 'hubzilla-daily.sh' /etc/crontab`" ]
|
||||
then
|
||||
echo "30 05 * * * root /bin/bash /var/www/$hubzilladaily >> /var/www/html/hubzilla-daily.log 2>&1" >> /etc/crontab
|
||||
echo "0 0 1 * * root rm /var/www/html/hubzilla-daily.log" >> /etc/crontab
|
||||
fi
|
||||
|
||||
# This is active after either "reboot" or "/etc/init.d/cron reload"
|
||||
print_info "configured cron for updates/upgrades"
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# START OF PROGRAM
|
||||
########################################################################
|
||||
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
||||
|
||||
check_sanity
|
||||
|
||||
# Read config file edited by user
|
||||
configfile=hubzilla-config.txt
|
||||
source $configfile
|
||||
|
||||
selfhostdir=/etc/selfhost
|
||||
selfhostscript=selfhost-updater.sh
|
||||
hubzilladaily=hubzilla-daily.sh
|
||||
backup_mount_point=/media/hubzilla_backup
|
||||
|
||||
#set -x # activate debugging from here
|
||||
|
||||
check_config
|
||||
stop_hubzilla
|
||||
update_upgrade
|
||||
install_curl
|
||||
install_wget
|
||||
install_sendmail
|
||||
install_apache
|
||||
install_imagemagick
|
||||
install_php
|
||||
install_mysql
|
||||
install_adminer
|
||||
create_hubzilla_db
|
||||
run_freedns
|
||||
install_run_selfhost
|
||||
ping_domain
|
||||
configure_cron_freedns
|
||||
configure_cron_selfhost
|
||||
|
||||
if [ "$le_domain" != "localhost" ]
|
||||
then
|
||||
install_letsencrypt
|
||||
configure_apache_for_https
|
||||
check_https
|
||||
else
|
||||
print_info "is localhost - skipped installation of letsencrypt and configuration of apache for https"
|
||||
fi
|
||||
|
||||
install_hubzilla
|
||||
|
||||
if [ "$le_domain" != "localhost" ]
|
||||
then
|
||||
rewrite_to_https
|
||||
install_rsnapshot
|
||||
else
|
||||
print_info "is localhost - skipped rewrite to https and installation of rsnapshot"
|
||||
fi
|
||||
|
||||
configure_cron_daily
|
||||
|
||||
if [ "$le_domain" != "localhost" ]
|
||||
then
|
||||
install_cryptosetup
|
||||
write_uninstall_script
|
||||
else
|
||||
print_info "is localhost - skipped installation of cryptosetup"
|
||||
fi
|
||||
|
||||
|
||||
#set +x # stop debugging from here
|
||||
|
||||
|
||||
@@ -24,7 +24,11 @@ AddType audio/ogg .oga
|
||||
# Also place auth information into REMOTE_USER for sites running
|
||||
# in CGI mode.
|
||||
|
||||
RewriteCond %{REQUEST_URI} ^/\.well\-known/.*
|
||||
RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
|
||||
</IfModule>
|
||||
|
||||
|
||||
94
.openshift/README.md
Normal file
94
.openshift/README.md
Normal file
@@ -0,0 +1,94 @@
|
||||
#Hubzilla on OpenShift
|
||||
You will notice a new .openshift folder when you fetch from upstream, i.e. from https://github.com/redmatrix/hubzilla.git , which contains a deploy script to set up Hubzilla on OpenShift.
|
||||
|
||||
Create an account on OpenShift, then use the registration e-mail and password to create your first Hubzilla instance. Install git and RedHat's command line tools - rhc - if you have not already done so.
|
||||
|
||||
```
|
||||
rhc app-create your_app_name php-5.4 mysql-5.5 cron phpmyadmin --namespace your_domain --from-code https://github.com/redmatrix/hubzilla.git -l your@email.address -p your_account_password
|
||||
```
|
||||
|
||||
Make a note of the database username and password OpenShift creates for your instance, and use these at https://your_app_name-your_domain.rhcloud.com/ to complete the setup.
|
||||
|
||||
NOTE: PostgreSQL is NOT supported by the deploy script yet.
|
||||
|
||||
Update
|
||||
To update, consider your own workflow first. I have forked Hubzilla code into my GitHub account to be able to try things out, this remote repo is called origin. Here is how I fetch new code from upstream, merge into my local repo, then push the updated code both into origin and the remote repo called openshift.
|
||||
|
||||
```
|
||||
git fetch upstream;git checkout master;git merge upstream/master;git push origin;git push openshift HEAD
|
||||
```
|
||||
|
||||
##Administration
|
||||
Symptoms of need for MySQL database administration are:
|
||||
- you can visit your domain and see the Hubzilla frontpage, but trying to login throws you back to login. This can mean your session table is marked as crashed.
|
||||
- you can login, but your channel posts are not visible. This can mean your item table is marked as crashed.
|
||||
- you can login and you can see your channel posts, but apparently nobody is getting your posts, comments, likes and so on. This can mean your outq table is marked as crashed.
|
||||
|
||||
You can check your OpenShift logs by doing
|
||||
|
||||
```
|
||||
rhc tail -a your_app_name -n your_domain -l your@email.address -p your_account_password
|
||||
```
|
||||
|
||||
and you might be able to confirm the above suspicions about crashed tables, or other problems you need to fix.
|
||||
|
||||
###How to fix crashed tables in MySQL
|
||||
Using MySQL and the MyISAM database engine can result in table indexes coming out of sync, and you have at least two options for fixing tables marked as crashed.
|
||||
- Use the database username and password OpenShift creates for your instance at https://your_app_name-your_domain.rhcloud.com/phpmyadmin/ to login via the web into your phpMyAdmin web interface, click your database in the left column, in the right column scroll down to the bottom of the list of tables and click the checkbox for marking all tables, then select Check tables from the drop down menu. This will check the tables for problems, and you can then checkmark only those tables with problems, and select Repair table from the same drop down menu at the bottom.
|
||||
- You can login to your instance with SSH - see OpenShift for details - then
|
||||
|
||||
```
|
||||
cd mysql/data/your_database
|
||||
myisamchk -r *.MYI
|
||||
```
|
||||
|
||||
or if you get
|
||||
|
||||
```
|
||||
Can't create new tempfile
|
||||
```
|
||||
|
||||
check your OpenShift's gear quota with
|
||||
|
||||
```
|
||||
quota -gus
|
||||
```
|
||||
|
||||
and if you are short on space, then locally (not SSH) do
|
||||
|
||||
```
|
||||
rhc app-tidy your_app_name -l your_login -p your_password
|
||||
```
|
||||
|
||||
to have rhc delete temporary files and OpenShift logs to free space first, then check the size of your local repo dir and execute
|
||||
|
||||
```
|
||||
git gc
|
||||
```
|
||||
|
||||
against it and check the size again, and then to minimize your remote repo connect via SSH to your application gear and execute the same command against it by changing to the remote repo directory - your repo should be in
|
||||
|
||||
```
|
||||
~/git/your_app_name.git
|
||||
```
|
||||
|
||||
(if not, do find -size +1M to find it), then do
|
||||
|
||||
```
|
||||
cd ~/mysql/data/yourdatabase
|
||||
myisamchk -r -v -f*.MYI
|
||||
```
|
||||
|
||||
and hopefully your database tables are now okay.
|
||||
|
||||
##NOTES
|
||||
Note 1: definitely DO turn off feeds and discovery by default if you are on the Free or Bronze plan on OpenShift with a single 1Gb gear by visiting https://your-app-name.rhcloud.com/admin/site when logged in as administrator of your Hubzilla site.
|
||||
Note 2: DO add the above defaults into the deploy script.
|
||||
Note 3: DO add git gc to the deploy script to clean up git.
|
||||
Note 4: MAYBE DO add myisamchk - only checking? to the end of the deploy script.
|
||||
|
||||
The OpenShift `php` cartridge documentation can be found at:
|
||||
http://openshift.github.io/documentation/oo_cartridge_guide.html#php
|
||||
|
||||
For information about .openshift directory, consult the documentation:
|
||||
http://openshift.github.io/documentation/oo_user_guide.html#the-openshift-directory
|
||||
3
.openshift/action_hooks/README.md
Normal file
3
.openshift/action_hooks/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
For information about action hooks, consult the documentation:
|
||||
|
||||
http://openshift.github.io/documentation/oo_user_guide.html#action-hooks
|
||||
218
.openshift/action_hooks/deploy
Executable file
218
.openshift/action_hooks/deploy
Executable file
@@ -0,0 +1,218 @@
|
||||
#!/bin/bash
|
||||
# This deploy hook gets executed after dependencies are resolved and the
|
||||
# build hook has been run but before the application has been started back
|
||||
# up again. This script gets executed directly, so it could be python, php,
|
||||
# ruby, etc.
|
||||
|
||||
# Bash help: http://www.panix.com/~elflord/unix/bash-tute.html
|
||||
|
||||
# For information about action hooks supported by OpenShift, consult the documentation:
|
||||
# http://openshift.github.io/documentation/oo_user_guide.html#the-openshift-directory
|
||||
|
||||
####
|
||||
|
||||
# Hubzilla specific deploy script
|
||||
|
||||
# Place this file in /.openshift/action_hooks/ (The .openshift folder will be in the root of your repo)
|
||||
# The file name should be "deploy" such that you have:
|
||||
# .openshift/action_hooks/deploy
|
||||
|
||||
# Conventions: Vars in curley braces have the slash after implied so no need to add it.
|
||||
# e.g. ${OPENSHIFT_REPO_DIR}php/foobar = /repo/php/foobar
|
||||
# See all OpenShift vars here:
|
||||
# https://www.openshift.com/developers/openshift-environment-variables
|
||||
|
||||
# HME - NOTE - leftover from original openshift-drupal-deploy
|
||||
# In config.php you can leverage the enviroment variables like this:
|
||||
# // Define env vars.
|
||||
# if (array_key_exists('OPENSHIFT_APP_NAME', $_SERVER)) {
|
||||
# $src = $_SERVER;
|
||||
# } else {
|
||||
# $src = $_ENV;
|
||||
# }
|
||||
#
|
||||
# $conf["file_private_path"] = $src['OPENSHIFT_DATA_DIR'] . "private";
|
||||
# $conf["file_temporary_path"] = $src['OPENSHIFT_DATA_DIR'] . "tmp";
|
||||
|
||||
|
||||
####
|
||||
|
||||
# Start Deploy
|
||||
|
||||
echo "Starting Deploy..."
|
||||
|
||||
# Let's create the Hubzilla files directory in the Openshift data folder ($OPENSHIFT_DATA_DIR).
|
||||
|
||||
echo "Check for the files directory called store, if not created - create it"
|
||||
|
||||
if [ ! -d ${OPENSHIFT_DATA_DIR}store ]; then
|
||||
mkdir -p ${OPENSHIFT_DATA_DIR}"store/[data]/smarty3"
|
||||
echo "Done creating files directory"
|
||||
|
||||
else
|
||||
|
||||
echo "The files directory called store already exists"
|
||||
|
||||
fi
|
||||
|
||||
####
|
||||
|
||||
# Set permissions on the files directory.
|
||||
|
||||
echo "Now chmod 777 -R files"
|
||||
|
||||
chmod -R 777 ${OPENSHIFT_DATA_DIR}store
|
||||
|
||||
echo "chmod done, permissions set to 777"
|
||||
|
||||
####
|
||||
|
||||
# Symlink our files folder to the repo.
|
||||
|
||||
# Note the "php" directory below seems to be the best way to serve OpenShift files.
|
||||
# This is good as that allows us for directories one level above such as tmp and private
|
||||
|
||||
echo "Create sym links for writeable directories"
|
||||
|
||||
ln -sf ${OPENSHIFT_DATA_DIR}store ${OPENSHIFT_REPO_DIR}store
|
||||
|
||||
echo "Files sym links created"
|
||||
|
||||
####
|
||||
|
||||
# Copy .htconfig.php from the repo, rename it and place it in the data directory.
|
||||
# if it's there already, skip it.
|
||||
|
||||
if [ ! -f ${OPENSHIFT_DATA_DIR}.htconfig.php ];
|
||||
|
||||
then
|
||||
|
||||
cp ${OPENSHIFT_REPO_DIR}.htconfig.php ${OPENSHIFT_DATA_DIR}.htconfig.php
|
||||
|
||||
echo ".htconfig.php copied."
|
||||
|
||||
else
|
||||
|
||||
echo "Looks like the .htconfig.php file is already there, we won't overwrite it."
|
||||
|
||||
fi
|
||||
|
||||
####
|
||||
|
||||
# symlink the .htconfig.php file.
|
||||
|
||||
echo "Create sym link for .htconfig.php"
|
||||
|
||||
ln -sf ${OPENSHIFT_DATA_DIR}.htconfig.php ${OPENSHIFT_REPO_DIR}.htconfig.php
|
||||
|
||||
echo ".htconfig.php symlink created"
|
||||
|
||||
####
|
||||
# Copy .htaccess from the repo, rename it and place it in the data directory.
|
||||
# if it's there already, skip it.
|
||||
|
||||
if [ ! -f ${OPENSHIFT_DATA_DIR}.htaccess ];
|
||||
|
||||
then
|
||||
|
||||
cp ${OPENSHIFT_REPO_DIR}.htaccess ${OPENSHIFT_DATA_DIR}.htaccess
|
||||
|
||||
echo ".htaccess copied."
|
||||
|
||||
else
|
||||
|
||||
echo "Looks like the .htaccess file is already there, we won't overwrite it."
|
||||
|
||||
fi
|
||||
|
||||
####
|
||||
|
||||
# symlink the .htaccess file.
|
||||
|
||||
echo "Create sym link for .htaccess"
|
||||
|
||||
ln -sf ${OPENSHIFT_DATA_DIR}.htaccess ${OPENSHIFT_REPO_DIR}.htaccess
|
||||
|
||||
echo ".htaccess symlink created"
|
||||
|
||||
####
|
||||
|
||||
echo "Check for the poller at .openshift/cron/minutely/poller , if not created - create it"
|
||||
|
||||
if [ ! -f ${OPENSHIFT_REPO_DIR}.openshift/cron/minutely/poller ]; then
|
||||
printf '%s\n' '#!/bin/bash' 'if [ ! -f $OPENSHIFT_DATA_DIR/last_run ]; then' ' touch $OPENSHIFT_DATA_DIR/last_run' 'fi' 'if [[ $(find $OPENSHIFT_DATA_DIR/last_run -mmin +9) ]]; then #run every 10 mins' ' rm -f $OPENSHIFT_DATA_DIR/last_run' ' touch $OPENSHIFT_DATA_DIR/last_run' ' # The command(s) that you want to run every 10 minutes' 'cd /var/lib/openshift/${OPENSHIFT_APP_UUID}/app-root/repo; /opt/rh/php54/root/usr/bin/php include/poller.php' 'fi' >${OPENSHIFT_REPO_DIR}.openshift/cron/minutely/poller
|
||||
echo "Done creating file .openshift/cron/minutely/poller"
|
||||
|
||||
else
|
||||
|
||||
echo "The poller already exists"
|
||||
|
||||
fi
|
||||
|
||||
####
|
||||
|
||||
# Set permissions on the poller script to make it executable.
|
||||
|
||||
echo "Now chmod 777 -R poller"
|
||||
|
||||
chmod -R 777 ${OPENSHIFT_REPO_DIR}.openshift/cron/minutely/poller
|
||||
|
||||
echo "chmod done, permissions set to 777 on poller script."
|
||||
|
||||
####
|
||||
|
||||
### echo "Check for the hot deploy marker at .openshift/markers/hot_deploy , if not created - create it"
|
||||
|
||||
### if [ ! -f ${OPENSHIFT_REPO_DIR}.openshift/markers/hot_deploy ]; then
|
||||
|
||||
### touch ${OPENSHIFT_REPO_DIR}.openshift/markers/hot_deploy
|
||||
|
||||
### echo "Done creating file .openshift/markers/hot_deploy"
|
||||
|
||||
### else
|
||||
|
||||
### echo "The hot deploy marker already exists"
|
||||
|
||||
### fi
|
||||
|
||||
####
|
||||
|
||||
# Hubzilla configuration - changes to default settings
|
||||
# to make Hubzilla on OpenShift a more pleasant experience
|
||||
echo "Changing default configuration to conserve space and autocreate a social private channel upon account registration"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/config system auto_channel_create
|
||||
util/config system default_permissions_role social_private
|
||||
util/config system workflow_channel_next channel
|
||||
util/config system expire_delivery_reports 3
|
||||
util/config system feed_contacts 0
|
||||
util/config system diaspora_enabled 0
|
||||
util/config system disable_discover_tab 1
|
||||
util/config directory safemode 0
|
||||
util/config directory globaldir 1
|
||||
util/config directory pubforums 0
|
||||
|
||||
# Hubzill addons
|
||||
echo "Try to add or update Hubzilla addons"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_addon_repo https://github.com/redmatrix/hubzilla-addons.git HubzillaAddons
|
||||
|
||||
# Hubzilla themes - unofficial repo
|
||||
echo "Try to add or update Hubzilla themes - unofficial repo"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_theme_repo https://github.com/DeadSuperHero/hubzilla-themes.git DeadSuperHeroThemes insecure
|
||||
|
||||
# Hubzilla ownMapp - unofficial repo
|
||||
echo "Try to add or update Hubzilla ownMapp - unofficial repo"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_addon_repo https://gitlab.com/zot/ownmapp.git ownMapp insecure
|
||||
|
||||
# Hubzilla Chess - unofficial repo
|
||||
echo "Try to add or update Hubzilla chess - unofficial repo"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_addon_repo https://gitlab.com/zot/hubzilla-chess.git Chess insecure
|
||||
|
||||
# Hubzilla Hubsites - unofficial repo
|
||||
echo "Try to add or update Hubzilla Hubsites - unofficial repo"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_addon_repo https://gitlab.com/zot/hubsites.git Hubsites insecure
|
||||
27
.openshift/cron/README.cron
Normal file
27
.openshift/cron/README.cron
Normal file
@@ -0,0 +1,27 @@
|
||||
Run scripts or jobs on a periodic basis
|
||||
=======================================
|
||||
Any scripts or jobs added to the minutely, hourly, daily, weekly or monthly
|
||||
directories will be run on a scheduled basis (frequency is as indicated by the
|
||||
name of the directory) using run-parts.
|
||||
|
||||
run-parts ignores any files that are hidden or dotfiles (.*) or backup
|
||||
files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved}
|
||||
|
||||
The presence of two specially named files jobs.deny and jobs.allow controls
|
||||
how run-parts executes your scripts/jobs.
|
||||
jobs.deny ===> Prevents specific scripts or jobs from being executed.
|
||||
jobs.allow ===> Only execute the named scripts or jobs (all other/non-named
|
||||
scripts that exist in this directory are ignored).
|
||||
|
||||
The principles of jobs.deny and jobs.allow are the same as those of cron.deny
|
||||
and cron.allow and are described in detail at:
|
||||
http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-Automating_System_Tasks.html#s2-autotasks-cron-access
|
||||
|
||||
See: man crontab or above link for more details and see the the weekly/
|
||||
directory for an example.
|
||||
|
||||
PLEASE NOTE: The Cron cartridge must be installed in order to run the configured jobs.
|
||||
|
||||
For more information about cron, consult the documentation:
|
||||
http://openshift.github.io/documentation/oo_cartridge_guide.html#cron
|
||||
http://openshift.github.io/documentation/oo_user_guide.html#cron
|
||||
0
.openshift/cron/minutely/.gitignore
vendored
Normal file
0
.openshift/cron/minutely/.gitignore
vendored
Normal file
0
.openshift/cron/monthly/.gitignore
vendored
Normal file
0
.openshift/cron/monthly/.gitignore
vendored
Normal file
16
.openshift/cron/weekly/README
Normal file
16
.openshift/cron/weekly/README
Normal file
@@ -0,0 +1,16 @@
|
||||
Run scripts or jobs on a weekly basis
|
||||
=====================================
|
||||
Any scripts or jobs added to this directory will be run on a scheduled basis
|
||||
(weekly) using run-parts.
|
||||
|
||||
run-parts ignores any files that are hidden or dotfiles (.*) or backup
|
||||
files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} and handles
|
||||
the files named jobs.deny and jobs.allow specially.
|
||||
|
||||
In this specific example, the chronograph script is the only script or job file
|
||||
executed on a weekly basis (due to white-listing it in jobs.allow). And the
|
||||
README and chrono.dat file are ignored either as a result of being black-listed
|
||||
in jobs.deny or because they are NOT white-listed in the jobs.allow file.
|
||||
|
||||
For more details, please see ../README.cron file.
|
||||
|
||||
1
.openshift/cron/weekly/chrono.dat
Normal file
1
.openshift/cron/weekly/chrono.dat
Normal file
@@ -0,0 +1 @@
|
||||
Time And Relative D...n In Execution (Open)Shift!
|
||||
3
.openshift/cron/weekly/chronograph
Executable file
3
.openshift/cron/weekly/chronograph
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "`date`: `cat $(dirname \"$0\")/chrono.dat`"
|
||||
12
.openshift/cron/weekly/jobs.allow
Normal file
12
.openshift/cron/weekly/jobs.allow
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# Script or job files listed in here (one entry per line) will be
|
||||
# executed on a weekly-basis.
|
||||
#
|
||||
# Example: The chronograph script will be executed weekly but the README
|
||||
# and chrono.dat files in this directory will be ignored.
|
||||
#
|
||||
# The README file is actually ignored due to the entry in the
|
||||
# jobs.deny which is checked before jobs.allow (this file).
|
||||
#
|
||||
chronograph
|
||||
|
||||
7
.openshift/cron/weekly/jobs.deny
Normal file
7
.openshift/cron/weekly/jobs.deny
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Any script or job files listed in here (one entry per line) will NOT be
|
||||
# executed (read as ignored by run-parts).
|
||||
#
|
||||
|
||||
README
|
||||
|
||||
4
.openshift/markers/README.md
Normal file
4
.openshift/markers/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
For information about markers, consult the documentation:
|
||||
|
||||
http://openshift.github.io/documentation/oo_user_guide.html#markers
|
||||
http://openshift.github.io/documentation/oo_cartridge_guide.html#php-markers
|
||||
0
.openshift/pear.txt
Normal file
0
.openshift/pear.txt
Normal file
186
.travis.yml
Normal file
186
.travis.yml
Normal file
@@ -0,0 +1,186 @@
|
||||
#
|
||||
# Travis-CI configuration file for Hubzilla
|
||||
#
|
||||
## configure things
|
||||
#
|
||||
|
||||
# see http://about.travis-ci.org/docs/user/languages/php/ for more hints
|
||||
language: php
|
||||
|
||||
# use newer 'trusty' based distro, old one is 'precise'
|
||||
dist: trusty
|
||||
# use docker based containers
|
||||
sudo: false
|
||||
|
||||
# Git branches whitelist to build on Travis CI
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- dev
|
||||
# whitelist our tags for release deployments e.g. 2.2
|
||||
- /^\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||
|
||||
# Install additional software
|
||||
addons:
|
||||
# Install dependencies for generating API documentation with doxygen
|
||||
apt:
|
||||
packages:
|
||||
- doxygen
|
||||
- doxygen-latex
|
||||
- graphviz
|
||||
- ttf-liberation
|
||||
|
||||
# enable and start databases on a per job basis
|
||||
#services:
|
||||
# - mariadb
|
||||
# - postgresql
|
||||
|
||||
# any PHP version we want to test against, current stable phpunit requires PHP >= 7.0
|
||||
php:
|
||||
- '7.0'
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
# HHVM does not fulfil PHPUnit platform requirements as being compatible with PHP7 yet
|
||||
#- 'hhvm'
|
||||
|
||||
# list of environments to test
|
||||
env:
|
||||
global:
|
||||
# used for doxygen deployment script
|
||||
- DOXYFILE: $TRAVIS_BUILD_DIR/util/Doxyfile
|
||||
# Uncomment if a newer/specific version of Doxygen should be used
|
||||
#- DOXY_VER: 1.8.12
|
||||
# Code Coverage is slow, no need to have it in every build
|
||||
- PHPUCOV: "--no-coverage"
|
||||
# use matrix only for PHP and MySQL, all other combinations added through includes
|
||||
matrix:
|
||||
# trusty default MySQL 5.6
|
||||
- DB=mysql MYSQL_VERSION=5.6
|
||||
|
||||
# Matrix configuration details
|
||||
matrix:
|
||||
fast_finish: true
|
||||
# Additional check combinations
|
||||
include:
|
||||
# PHP7.2, mariadb 10.2
|
||||
- php: '7.2'
|
||||
env: DB=mariadb MARIADB_VERSION=10.2 CODECOV=1
|
||||
# use mariadb instead of MySQL
|
||||
addons:
|
||||
mariadb: '10.2'
|
||||
# PHP7.2, PostgreSQL 9.6
|
||||
- php: '7.2'
|
||||
env: DB=pgsql POSTGRESQL_VERSION=9.6 PHPUNITFILE=phpunit-pgsql.xml
|
||||
# Use newer postgres than 9.2 default
|
||||
addons:
|
||||
postgresql: '9.6'
|
||||
services:
|
||||
- postgresql
|
||||
# PostgreSQL 10 with Docker container
|
||||
- php: '7.2'
|
||||
env: DB=pgsql POSTGRESQL_VERSION=10 PHPUNITFILE=phpunit-pgsql.xml
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
# PHP7.2, old precise distribution with MySQL 5.5
|
||||
- php: '7.2'
|
||||
env: DB=mysql MYSQL_VERSION=5.5
|
||||
dist: precise
|
||||
services:
|
||||
- mysql
|
||||
# MySQL 5.7 with Docker container
|
||||
- php: '7.2'
|
||||
env: DB=mysql MYSQL_VERSION=5.7
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
# Excludes from default matrix combinations
|
||||
# exclude:
|
||||
# - php: hhvm
|
||||
# env: DB=pgsql # PDO driver for pgsql is unsupported by HHVM (3rd party install for support)
|
||||
|
||||
# cache composer downloads between runs
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
#- $HOME/doxygen/doxygen-$DOXY_VER/bin
|
||||
|
||||
|
||||
|
||||
#
|
||||
## execute things
|
||||
#
|
||||
|
||||
before_install:
|
||||
- travis_retry composer self-update
|
||||
# Start MySQL 5.7 Docker container, needs some time to come up
|
||||
- if [[ "$MYSQL_VERSION" == "5.7" ]]; then sudo service mysql stop; docker run -d -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql:5.7 && sleep 25 && docker ps; fi
|
||||
# Start PostgreSQL 10 Docker container, needs some time to come up
|
||||
- if [[ "$POSTGRESQL_VERSION" == "10" ]]; then sudo service postgresql stop; docker run -d -p 5432:5432 postgres:10-alpine && sleep 35 && docker ps; fi
|
||||
|
||||
# Install composer dev libs
|
||||
install:
|
||||
- travis_retry composer install --optimize-autoloader --no-progress
|
||||
|
||||
# execute any number of scripts before the test run, custom env's are available as variables
|
||||
before_script:
|
||||
# Use code coverage config for phpunit
|
||||
- if [[ ! -z $CODECOV ]]; then export PHPUCOV=""; fi
|
||||
# Some preparation tasks of environment
|
||||
- ./tests/travis/prepare.sh
|
||||
# DB specific prepare scripts
|
||||
- if [[ "$DB" == "mysql" ]]; then ./tests/travis/prepare_mysql.sh; fi
|
||||
- if [[ "$DB" == "mariadb" ]]; then ./tests/travis/prepare_mysql.sh; fi
|
||||
- if [[ "$DB" == "pgsql" ]]; then ./tests/travis/prepare_pgsql.sh; fi
|
||||
|
||||
# omitting "script:" will default to phpunit
|
||||
script:
|
||||
- ./vendor/bin/phpunit $PHPUCOV -c tests/$PHPUNITFILE
|
||||
|
||||
after_success:
|
||||
- cat tests/results/testdox.txt
|
||||
# Generate API documentation and prepare for deployment
|
||||
- ./tests/travis/gen_apidocs.sh
|
||||
after_failure:
|
||||
- cat tests/results/testdox.txt
|
||||
|
||||
# Deploying release and API documentation to GitHub
|
||||
before_deploy:
|
||||
- if [[ "$CODECOV" == "1" ]]; then zip -9 -r -q tests/hubzilla-testresults.zip tests/results; fi
|
||||
deploy:
|
||||
- provider: pages
|
||||
skip_cleanup: true
|
||||
local_dir: $TRAVIS_BUILD_DIR/doc/html
|
||||
github_token: $GH_TOKEN
|
||||
on:
|
||||
repo: redmatrix/hubzilla
|
||||
branch: master
|
||||
condition: '(-n "$GH_TOKEN") && ("$TRAVIS_JOB_NUMBER" == "${TRAVIS_BUILD_NUMBER}.1")'
|
||||
# add API documentation to release, could also be used to provide full packages if we want to drop vendor from our repo
|
||||
- provider: releases
|
||||
skip_cleanup: true
|
||||
api_key: $GH_TOKEN
|
||||
file: 'doc/hubzilla-api-documentation.zip'
|
||||
on:
|
||||
repo: redmatrix/hubzilla
|
||||
tags: true
|
||||
condition: '(-n "$GH_TOKEN") && ("$TRAVIS_JOB_NUMBER" == "${TRAVIS_BUILD_NUMBER}.1")'
|
||||
# add code coverage and test results to release
|
||||
- provider: releases
|
||||
skip_cleanup: true
|
||||
api_key: $GH_TOKEN
|
||||
file: 'tests/hubzilla-testresults.zip'
|
||||
on:
|
||||
repo: redmatrix/hubzilla
|
||||
tags: true
|
||||
condition: '(-n "$GH_TOKEN") && ("$CODECOV" == "1")'
|
||||
#after_deploy:
|
||||
|
||||
#after_script:
|
||||
|
||||
|
||||
|
||||
# configure notifications (email, IRC, campfire etc)
|
||||
#notifications:
|
||||
# irc: "irc.freenode.org#yourfavouriteroomfortravis"
|
||||
# a plugin/script to post to a hubzilla channel would be neat here
|
||||
37
DEVELOPERS
Normal file
37
DEVELOPERS
Normal file
@@ -0,0 +1,37 @@
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
1 Letterman Drive
|
||||
Suite D4700
|
||||
San Francisco, CA, 94129
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
11
LICENSE
11
LICENSE
@@ -1,4 +1,5 @@
|
||||
Copyright (c) 2010-2015 Hubzilla
|
||||
Copyright (c) 2019 Hubzilla Community
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -8,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
50
README.md
50
README.md
@@ -1,42 +1,32 @@
|
||||

|
||||
|
||||
Hubzilla
|
||||
========
|
||||
|
||||
###Websites. Redefined.
|
||||
Hubzilla - Community Server
|
||||
===========================
|
||||
|
||||
|
||||

|
||||
<p align="center" markdown="1">
|
||||
<em><a href="https://framagit.org/hubzilla/core/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
||||
</p>
|
||||
|
||||
**What are Hubs?**
|
||||
**What is Hubzilla?**
|
||||
|
||||
Hubs are independent general-purpose websites that not only connect with their associated members and viewers, but also connect together to exchange personal communications and other information with each other.
|
||||
This allows hub members on any hub to securely and privately share anything; with anybody, on any hub - anywhere; or share stuff publicly with anybody on the internet if desired.
|
||||
Hubzilla is a general purpose communication server integrated with a web publishing system and a decentralised permission system. If this sounds like a bunch of technical mumbo-jumbo to you, just think of it as an independent platform for sharing stuff online (publicly or privately).
|
||||
|
||||
**Hubzilla** is the server software which makes this possible. It is a sophisticated and unique combination of an open source content management system and a decentralised identity, communications, and permissions framework and protocol suite, built using common webserver technology (PHP/MySQL/Apache, although Mariadb or Postgres and Nginx could also be used - we're pretty easy). The end result is a level of systems integration, privacy control, and communications features that you wouldn't think are possible in either a content management system or a decentralised communications network. It also brings a new level of cooperation and privacy to the web and introduces the concept of personally owned "single sign-on" to web services across the entire internet.
|
||||
Hubzilla contains some social network bits, some cloud storage bits, some blog and forum bits, and some content management bits. These are all integrated within a common privacy framework - and it is all decentralised.
|
||||
|
||||
Hubzilla hubs are
|
||||
Everything you publish or share can be restricted to those channels and people you wish to share them with; and these permissions work completely invisibly - **even with channels on different servers or other communications services**.
|
||||
|
||||
* decentralised
|
||||
* inherently social
|
||||
* optionally inter-networked with other hubs
|
||||
* privacy-enabled (privacy exclusions work across the entire internet to any registered identity on any compatible hubs)
|
||||
Migration and live backups of your connections, settings, and everything you publish are built-in, so you never need worry about server failure.
|
||||
|
||||
Possible website applications include
|
||||
|
||||
* decentralised social networking nodes
|
||||
* personal cloud storage
|
||||
* file dropboxes
|
||||
* managing organisational communications and activities
|
||||
* collaboration and community decision-making
|
||||
* small business websites
|
||||
* public and private media/file libraries
|
||||
* blogs
|
||||
* event promotion
|
||||
* feed aggregation and republishing
|
||||
* forums
|
||||
* dating websites
|
||||
* pretty much anything you can do on a traditional blog or community website, but that you could do better if you could easily connect it with other websites or privately share things across website boundaries.
|
||||
Hubzilla is completely decentralised and open source, for you modify or adapt to your needs and desires. Plugins, themes, and numerous configuration options extend the overall capabilities to do anything you can imagine.
|
||||
|
||||
|
||||
**Who Are We?**
|
||||
|
||||
This project is under development and is not yet available for general use.
|
||||
The Hubzilla community consists of passionate volunteers creating an open source commons of decentralised services which are highly integrated and can rival the feature set of large centralised providers. We do our best to provide ethical software which places you in control of your online communications and privacy expectations.
|
||||
|
||||
Build status master branch:
|
||||
[](https://framagit.org/hubzilla/core/badges/master/build.svg)
|
||||
|
||||
Build status dev branch:
|
||||
[](https://framagit.org/hubzilla/core/badges/dev/build.svg)
|
||||
|
||||
164
Zotlabs/Access/AccessList.php
Normal file
164
Zotlabs/Access/AccessList.php
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
/**
|
||||
* @brief AccessList class which represents individual content ACLs.
|
||||
*
|
||||
* A class to hold an AccessList object with allowed and denied contacts and
|
||||
* groups.
|
||||
*
|
||||
* After evaluating @ref ::Zotlabs::Access::PermissionLimits "PermissionLimits"
|
||||
* and @ref ::Zotlabs::Lib::Permcat "Permcat"s individual content ACLs are evaluated.
|
||||
* These answer the question "Can Joe view *this* album/photo?".
|
||||
*/
|
||||
class AccessList {
|
||||
/**
|
||||
* @brief Allow contacts
|
||||
* @var string
|
||||
*/
|
||||
private $allow_cid;
|
||||
/**
|
||||
* @brief Allow groups
|
||||
* @var string
|
||||
*/
|
||||
private $allow_gid;
|
||||
/**
|
||||
* @brief Deny contacts
|
||||
* @var string
|
||||
*/
|
||||
private $deny_cid;
|
||||
/**
|
||||
* @brief Deny groups
|
||||
* @var string
|
||||
*/
|
||||
private $deny_gid;
|
||||
/**
|
||||
* @brief Indicates if we are using the default constructor values or
|
||||
* values that have been set explicitly.
|
||||
* @var boolean
|
||||
*/
|
||||
private $explicit;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Constructor for AccessList class.
|
||||
*
|
||||
* @note The array to pass to the constructor is different from the array
|
||||
* that you provide to the set() or set_from_array() functions.
|
||||
*
|
||||
* @param array $channel A channel array, where these entries are evaluated:
|
||||
* * \e string \b channel_allow_cid => string of allowed cids
|
||||
* * \e string \b channel_allow_gid => string of allowed gids
|
||||
* * \e string \b channel_deny_cid => string of denied cids
|
||||
* * \e string \b channel_deny_gid => string of denied gids
|
||||
*/
|
||||
function __construct($channel) {
|
||||
if($channel) {
|
||||
$this->allow_cid = $channel['channel_allow_cid'];
|
||||
$this->allow_gid = $channel['channel_allow_gid'];
|
||||
$this->deny_cid = $channel['channel_deny_cid'];
|
||||
$this->deny_gid = $channel['channel_deny_gid'];
|
||||
}
|
||||
else {
|
||||
$this->allow_cid = '';
|
||||
$this->allow_gid = '';
|
||||
$this->deny_cid = '';
|
||||
$this->deny_gid = '';
|
||||
}
|
||||
|
||||
$this->explicit = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get if we are using the default constructor values
|
||||
* or values that have been set explicitly.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function get_explicit() {
|
||||
return $this->explicit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set access list from strings such as those in already
|
||||
* existing stored data items.
|
||||
*
|
||||
* @note The array to pass to this set function is different from the array
|
||||
* that you provide to the constructor or set_from_array().
|
||||
*
|
||||
* @param array $arr
|
||||
* * \e string \b allow_cid => string of allowed cids
|
||||
* * \e string \b allow_gid => string of allowed gids
|
||||
* * \e string \b deny_cid => string of denied cids
|
||||
* * \e string \b deny_gid => string of denied gids
|
||||
* @param boolean $explicit (optional) default true
|
||||
*/
|
||||
function set($arr, $explicit = true) {
|
||||
$this->allow_cid = $arr['allow_cid'];
|
||||
$this->allow_gid = $arr['allow_gid'];
|
||||
$this->deny_cid = $arr['deny_cid'];
|
||||
$this->deny_gid = $arr['deny_gid'];
|
||||
|
||||
$this->explicit = $explicit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return an array consisting of the current access list components
|
||||
* where the elements are directly storable.
|
||||
*
|
||||
* @return array An associative array with:
|
||||
* * \e string \b allow_cid => string of allowed cids
|
||||
* * \e string \b allow_gid => string of allowed gids
|
||||
* * \e string \b deny_cid => string of denied cids
|
||||
* * \e string \b deny_gid => string of denied gids
|
||||
*/
|
||||
function get() {
|
||||
return [
|
||||
'allow_cid' => $this->allow_cid,
|
||||
'allow_gid' => $this->allow_gid,
|
||||
'deny_cid' => $this->deny_cid,
|
||||
'deny_gid' => $this->deny_gid,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set access list components from arrays, such as those provided by
|
||||
* acl_selector().
|
||||
*
|
||||
* For convenience, a string (or non-array) input is assumed to be a
|
||||
* comma-separated list and auto-converted into an array.
|
||||
*
|
||||
* @note The array to pass to this set function is different from the array
|
||||
* that you provide to the constructor or set().
|
||||
*
|
||||
* @param array $arr An associative array with:
|
||||
* * \e array|string \b contact_allow => array with cids or comma-seperated string
|
||||
* * \e array|string \b group_allow => array with gids or comma-seperated string
|
||||
* * \e array|string \b contact_deny => array with cids or comma-seperated string
|
||||
* * \e array|string \b group_deny => array with gids or comma-seperated string
|
||||
* @param boolean $explicit (optional) default true
|
||||
*/
|
||||
function set_from_array($arr, $explicit = true) {
|
||||
$this->allow_cid = perms2str((is_array($arr['contact_allow']))
|
||||
? $arr['contact_allow'] : explode(',', $arr['contact_allow']));
|
||||
$this->allow_gid = perms2str((is_array($arr['group_allow']))
|
||||
? $arr['group_allow'] : explode(',', $arr['group_allow']));
|
||||
$this->deny_cid = perms2str((is_array($arr['contact_deny']))
|
||||
? $arr['contact_deny'] : explode(',', $arr['contact_deny']));
|
||||
$this->deny_gid = perms2str((is_array($arr['group_deny']))
|
||||
? $arr['group_deny'] : explode(',', $arr['group_deny']));
|
||||
|
||||
$this->explicit = $explicit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if any access lists component is set.
|
||||
*
|
||||
* @return boolean Return true if any of allow_* deny_* values is set.
|
||||
*/
|
||||
function is_private() {
|
||||
return (($this->allow_cid || $this->allow_gid || $this->deny_cid || $this->deny_gid) ? true : false);
|
||||
}
|
||||
|
||||
}
|
||||
91
Zotlabs/Access/PermissionLimits.php
Normal file
91
Zotlabs/Access/PermissionLimits.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
use Zotlabs\Lib\PConfig;
|
||||
|
||||
/**
|
||||
* @brief Permission limits.
|
||||
*
|
||||
* Permission limits are a very high level permission setting. They are hard
|
||||
* limits by design.
|
||||
* "Who can view my photos (at all)?"
|
||||
* "Who can post photos in my albums (at all)?"
|
||||
*
|
||||
* For viewing permissions we generally set these to 'anybody' and for write
|
||||
* permissions we generally set them to 'those I allow', though many people
|
||||
* restrict the viewing permissions further for things like 'Can view my connections'.
|
||||
*
|
||||
* People get confused enough by permissions that we wanted a place to set their
|
||||
* privacy expectations once and be done with it.
|
||||
*
|
||||
* Connection related permissions like "Can Joe view my photos?" are handled by
|
||||
* @ref ::Zotlabs::Lib::Permcat "Permcat" and inherit from the channel's Permission
|
||||
* limits.
|
||||
*
|
||||
* @see Permissions
|
||||
*/
|
||||
class PermissionLimits {
|
||||
|
||||
/**
|
||||
* @brief Get standard permission limits.
|
||||
*
|
||||
* Viewing permissions and post_comments permission are set to 'anybody',
|
||||
* other permissions are set to 'those I allow'.
|
||||
*
|
||||
* The list of permissions comes from Permissions::Perms().
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function Std_Limits() {
|
||||
$limits = [];
|
||||
$perms = Permissions::Perms();
|
||||
|
||||
foreach($perms as $k => $v) {
|
||||
if(strstr($k, 'view'))
|
||||
$limits[$k] = PERMS_PUBLIC;
|
||||
else
|
||||
$limits[$k] = PERMS_SPECIFIC;
|
||||
}
|
||||
|
||||
return $limits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a permission limit for a channel.
|
||||
*
|
||||
* @param int $channel_id
|
||||
* @param string $perm
|
||||
* @param int $perm_limit one of PERMS_* constants
|
||||
*/
|
||||
static public function Set($channel_id, $perm, $perm_limit) {
|
||||
PConfig::Set($channel_id, 'perm_limits', $perm, $perm_limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a channel's permission limits.
|
||||
*
|
||||
* Return a channel's permission limits from PConfig. If $perm is set just
|
||||
* return this permission limit, if not set, return an array with all
|
||||
* permission limits.
|
||||
*
|
||||
* @param int $channel_id
|
||||
* @param string $perm (optional)
|
||||
* @return
|
||||
* * \b false if no perm_limits set for this channel
|
||||
* * \b int if $perm is set, return one of PERMS_* constants for this permission, default 0
|
||||
* * \b array with all permission limits, if $perm is not set
|
||||
*/
|
||||
static public function Get($channel_id, $perm = '') {
|
||||
if($perm) {
|
||||
return intval(PConfig::Get($channel_id, 'perm_limits', $perm));
|
||||
}
|
||||
|
||||
PConfig::Load($channel_id);
|
||||
if(array_key_exists($channel_id, \App::$config)
|
||||
&& array_key_exists('perm_limits', \App::$config[$channel_id]))
|
||||
return \App::$config[$channel_id]['perm_limits'];
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
316
Zotlabs/Access/PermissionRoles.php
Normal file
316
Zotlabs/Access/PermissionRoles.php
Normal file
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
/**
|
||||
* @brief PermissionRoles class.
|
||||
*
|
||||
* @see Permissions
|
||||
*/
|
||||
class PermissionRoles {
|
||||
|
||||
/**
|
||||
* @brief PermissionRoles version.
|
||||
*
|
||||
* This must match the version in Permissions.php before permission updates can run.
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
static public function version() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
static function role_perms($role) {
|
||||
|
||||
$ret = array();
|
||||
|
||||
$ret['role'] = $role;
|
||||
|
||||
switch($role) {
|
||||
case 'social':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = true;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'chat', 'post_like', 'republish'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'social_federation':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = true;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'chat', 'post_like', 'republish'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
$ret['limits']['post_comments'] = PERMS_AUTHED;
|
||||
$ret['limits']['post_mail'] = PERMS_AUTHED;
|
||||
$ret['limits']['post_like'] = PERMS_AUTHED;
|
||||
$ret['limits']['chat'] = PERMS_AUTHED;
|
||||
break;
|
||||
|
||||
|
||||
case 'social_restricted':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = true;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'chat', 'post_like'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'social_private':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = false;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
|
||||
|
||||
break;
|
||||
|
||||
case 'forum':
|
||||
$ret['perms_auto'] = true;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
|
||||
'post_mail', 'post_like' , 'republish', 'chat'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'forum_restricted':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
|
||||
'post_mail', 'post_like' , 'chat' ];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'forum_private':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = false;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like' , 'chat'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
$ret['limits']['view_profile'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_pages'] = PERMS_SPECIFIC;
|
||||
$ret['limits']['view_wiki'] = PERMS_SPECIFIC;
|
||||
|
||||
break;
|
||||
|
||||
case 'feed':
|
||||
$ret['perms_auto'] = true;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like' , 'republish'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'feed_restricted':
|
||||
$ret['perms_auto'] = false;
|
||||
$ret['default_collection'] = true;
|
||||
$ret['directory_publish'] = false;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
|
||||
'post_mail', 'post_like' , 'republish'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'soapbox':
|
||||
$ret['perms_auto'] = true;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'post_like' , 'republish'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'repository':
|
||||
$ret['perms_auto'] = true;
|
||||
$ret['default_collection'] = false;
|
||||
$ret['directory_publish'] = true;
|
||||
$ret['online'] = false;
|
||||
$ret['perms_connect'] = [
|
||||
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
|
||||
'view_pages', 'view_wiki', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
|
||||
'post_mail', 'post_like' , 'republish', 'chat', 'write_wiki'
|
||||
];
|
||||
$ret['limits'] = PermissionLimits::Std_Limits();
|
||||
|
||||
break;
|
||||
|
||||
case 'custom':
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$x = get_config('system','role_perms');
|
||||
// let system settings over-ride any or all
|
||||
if($x && is_array($x) && array_key_exists($role,$x))
|
||||
$ret = array_merge($ret,$x[$role]);
|
||||
|
||||
/**
|
||||
* @hooks get_role_perms
|
||||
* * \e array
|
||||
*/
|
||||
call_hooks('get_role_perms', $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static public function new_custom_perms($uid,$perm,$abooks) {
|
||||
|
||||
// set permissionlimits for this permission here, for example:
|
||||
|
||||
// if($perm === 'mynewperm')
|
||||
// \Zotlabs\Access\PermissionLimits::Set($uid,$perm,1);
|
||||
|
||||
if($perm === 'view_wiki')
|
||||
\Zotlabs\Access\PermissionLimits::Set($uid, $perm, PERMS_PUBLIC);
|
||||
|
||||
if($perm === 'write_wiki')
|
||||
\Zotlabs\Access\PermissionLimits::Set($uid, $perm, PERMS_SPECIFIC);
|
||||
|
||||
|
||||
// set autoperms here if applicable
|
||||
// choices are to set to 0, 1, or the value of an existing perm
|
||||
|
||||
if(get_pconfig($uid,'system','autoperms')) {
|
||||
|
||||
$c = channelx_by_n($uid);
|
||||
$value = 0;
|
||||
|
||||
// if($perm === 'mynewperm')
|
||||
// $value = get_abconfig($uid,$c['channel_hash'],'autoperms','someexistingperm');
|
||||
|
||||
if($perm === 'view_wiki')
|
||||
$value = get_abconfig($uid,$c['channel_hash'],'autoperms','view_pages');
|
||||
|
||||
if($perm === 'write_wiki')
|
||||
$value = get_abconfig($uid,$c['channel_hash'],'autoperms','write_pages');
|
||||
|
||||
if($c) {
|
||||
set_abconfig($uid,$c['channel_hash'],'autoperms',$perm,$value);
|
||||
}
|
||||
}
|
||||
|
||||
// now set something for all existing connections.
|
||||
|
||||
if($abooks) {
|
||||
foreach($abooks as $ab) {
|
||||
switch($perm) {
|
||||
// case 'mynewperm':
|
||||
// choices are to set to 1, set to 0, or clone an existing perm
|
||||
// set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
|
||||
// intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','someexistingperm')));
|
||||
|
||||
case 'view_wiki':
|
||||
set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
|
||||
intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','view_pages')));
|
||||
|
||||
case 'write_wiki':
|
||||
set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
|
||||
intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','write_pages')));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Array with translated role names and grouping.
|
||||
*
|
||||
* Return an associative array with grouped role names that can be used
|
||||
* to create select groups like in \e field_select_grouped.tpl.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function roles() {
|
||||
$roles = [
|
||||
t('Social Networking') => [
|
||||
'social_federation' => t('Social - Federation'),
|
||||
'social' => t('Social - Mostly Public'),
|
||||
'social_restricted' => t('Social - Restricted'),
|
||||
'social_private' => t('Social - Private')
|
||||
],
|
||||
|
||||
t('Community Forum') => [
|
||||
'forum' => t('Forum - Mostly Public'),
|
||||
'forum_restricted' => t('Forum - Restricted'),
|
||||
'forum_private' => t('Forum - Private')
|
||||
],
|
||||
|
||||
t('Feed Republish') => [
|
||||
'feed' => t('Feed - Mostly Public'),
|
||||
'feed_restricted' => t('Feed - Restricted')
|
||||
],
|
||||
|
||||
t('Special Purpose') => [
|
||||
'soapbox' => t('Special - Celebrity/Soapbox'),
|
||||
'repository' => t('Special - Group Repository')
|
||||
],
|
||||
|
||||
t('Other') => [
|
||||
'custom' => t('Custom/Expert Mode')
|
||||
]
|
||||
];
|
||||
|
||||
call_hooks('list_permission_roles',$roles);
|
||||
|
||||
return $roles;
|
||||
}
|
||||
|
||||
}
|
||||
286
Zotlabs/Access/Permissions.php
Normal file
286
Zotlabs/Access/Permissions.php
Normal file
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
use Zotlabs\Lib as Zlib;
|
||||
|
||||
/**
|
||||
* @brief Extensible permissions.
|
||||
*
|
||||
* To add new permissions, add to the list of $perms below, with a simple description.
|
||||
*
|
||||
* Also visit PermissionRoles.php and add to the $ret['perms_connect'] property for any role
|
||||
* if this permission should be granted to new connections.
|
||||
*
|
||||
* Next look at PermissionRoles::new_custom_perms() and provide a handler for updating custom
|
||||
* permission roles. You will want to set a default PermissionLimit for each channel and also
|
||||
* provide a sane default for any existing connections. You may or may not wish to provide a
|
||||
* default auto permission. If in doubt, leave this alone as custom permissions by definition
|
||||
* are the responsibility of the channel owner to manage. You just don't want to create any
|
||||
* suprises or break things so you have an opportunity to provide sane settings.
|
||||
*
|
||||
* Update the version here and in PermissionRoles.
|
||||
*
|
||||
*
|
||||
* Permissions with 'view' in the name are considered read permissions. Anything
|
||||
* else requires authentication. Read permission limits are PERMS_PUBLIC and anything else
|
||||
* is given PERMS_SPECIFIC.
|
||||
*
|
||||
* PermissionLimits::Std_limits() retrieves the standard limits. A permission role
|
||||
* MAY alter an individual setting after retrieving the Std_limits if you require
|
||||
* something different for a specific permission within the given role.
|
||||
*
|
||||
*/
|
||||
class Permissions {
|
||||
|
||||
/**
|
||||
* @brief Permissions version.
|
||||
*
|
||||
* This must match the version in PermissionRoles.php before permission updates can run.
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
static public function version() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return an array with Permissions.
|
||||
*
|
||||
* @param string $filter (optional) only passed to hook permissions_list
|
||||
* @return array Associative array with permissions and short description.
|
||||
*/
|
||||
static public function Perms($filter = '') {
|
||||
|
||||
$perms = [
|
||||
'view_stream' => t('Can view my channel stream and posts'),
|
||||
'send_stream' => t('Can send me their channel stream and posts'),
|
||||
'view_profile' => t('Can view my default channel profile'),
|
||||
'view_contacts' => t('Can view my connections'),
|
||||
'view_storage' => t('Can view my file storage and photos'),
|
||||
'write_storage' => t('Can upload/modify my file storage and photos'),
|
||||
'view_pages' => t('Can view my channel webpages'),
|
||||
'view_wiki' => t('Can view my wiki pages'),
|
||||
'write_pages' => t('Can create/edit my channel webpages'),
|
||||
'write_wiki' => t('Can write to my wiki pages'),
|
||||
'post_wall' => t('Can post on my channel (wall) page'),
|
||||
'post_comments' => t('Can comment on or like my posts'),
|
||||
'post_mail' => t('Can send me private mail messages'),
|
||||
'post_like' => t('Can like/dislike profiles and profile things'),
|
||||
'tag_deliver' => t('Can forward to all my channel connections via ! mentions in posts'),
|
||||
'chat' => t('Can chat with me'),
|
||||
'republish' => t('Can source my public posts in derived channels'),
|
||||
'delegate' => t('Can administer my channel')
|
||||
];
|
||||
|
||||
$x = [
|
||||
'permissions' => $perms,
|
||||
'filter' => $filter
|
||||
];
|
||||
/**
|
||||
* @hooks permissions_list
|
||||
* * \e array \b permissions
|
||||
* * \e string \b filter
|
||||
*/
|
||||
call_hooks('permissions_list', $x);
|
||||
|
||||
return($x['permissions']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perms from the above list that are blocked from anonymous observers.
|
||||
*
|
||||
* e.g. you must be authenticated.
|
||||
*
|
||||
* @return array Associative array with permissions and short description.
|
||||
*/
|
||||
static public function BlockedAnonPerms() {
|
||||
|
||||
$res = [];
|
||||
$perms = PermissionLimits::Std_limits();
|
||||
foreach($perms as $perm => $limit) {
|
||||
if($limit != PERMS_PUBLIC) {
|
||||
$res[] = $perm;
|
||||
}
|
||||
}
|
||||
|
||||
$x = ['permissions' => $res];
|
||||
/**
|
||||
* @hooks write_perms
|
||||
* * \e array \b permissions
|
||||
*/
|
||||
call_hooks('write_perms', $x);
|
||||
|
||||
return($x['permissions']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts indexed perms array to associative perms array.
|
||||
*
|
||||
* Converts [ 0 => 'view_stream', ... ]
|
||||
* to [ 'view_stream' => 1 ] for any permissions in $arr;
|
||||
* Undeclared permissions which exist in Perms() are added and set to 0.
|
||||
*
|
||||
* @param array $arr
|
||||
* @return array
|
||||
*/
|
||||
static public function FilledPerms($arr) {
|
||||
if(is_null($arr)) {
|
||||
btlogger('FilledPerms: null');
|
||||
$arr = [];
|
||||
}
|
||||
|
||||
$everything = self::Perms();
|
||||
$ret = [];
|
||||
foreach($everything as $k => $v) {
|
||||
if(in_array($k, $arr))
|
||||
$ret[$k] = 1;
|
||||
else
|
||||
$ret[$k] = 0;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert perms array to indexed array.
|
||||
*
|
||||
* Converts [ 'view_stream' => 1 ] for any permissions in $arr
|
||||
* to [ 0 => ['name' => 'view_stream', 'value' => 1], ... ]
|
||||
*
|
||||
* @param array $arr associative perms array 'view_stream' => 1
|
||||
* @return array Indexed array with elements that look like
|
||||
* * \e string \b name the perm name (e.g. view_stream)
|
||||
* * \e int \b value the value of the perm (e.g. 1)
|
||||
*/
|
||||
static public function OPerms($arr) {
|
||||
$ret = [];
|
||||
if($arr) {
|
||||
foreach($arr as $k => $v) {
|
||||
$ret[] = [ 'name' => $k, 'value' => $v ];
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param int $channel_id
|
||||
* @return boolean|array
|
||||
*/
|
||||
static public function FilledAutoperms($channel_id) {
|
||||
if(! intval(get_pconfig($channel_id,'system','autoperms')))
|
||||
return false;
|
||||
|
||||
$arr = [];
|
||||
$r = q("select * from pconfig where uid = %d and cat = 'autoperms'",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$arr[$rr['k']] = intval($rr['v']);
|
||||
}
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compares that all Permissions from $p1 exist also in $p2.
|
||||
*
|
||||
* @param array $p1 The perms that have to exist in $p2
|
||||
* @param array $p2 The perms to compare against
|
||||
* @return boolean true if all perms from $p1 exist also in $p2
|
||||
*/
|
||||
static public function PermsCompare($p1, $p2) {
|
||||
foreach($p1 as $k => $v) {
|
||||
if(! array_key_exists($k, $p2))
|
||||
return false;
|
||||
|
||||
if($p1[$k] != $p2[$k])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param int $channel_id A channel id
|
||||
* @return array Associative array with
|
||||
* * \e array \b perms Permission array
|
||||
* * \e int \b automatic 0 or 1
|
||||
*/
|
||||
static public function connect_perms($channel_id) {
|
||||
|
||||
$my_perms = [];
|
||||
$permcat = null;
|
||||
$automatic = 0;
|
||||
|
||||
// If a default permcat exists, use that
|
||||
|
||||
$pc = ((feature_enabled($channel_id,'permcats')) ? get_pconfig($channel_id,'system','default_permcat') : 'default');
|
||||
if(! in_array($pc, [ '','default' ])) {
|
||||
$pcp = new Zlib\Permcat($channel_id);
|
||||
$permcat = $pcp->fetch($pc);
|
||||
if($permcat && $permcat['perms']) {
|
||||
foreach($permcat['perms'] as $p) {
|
||||
$my_perms[$p['name']] = $p['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look up the permission role to see if it specified auto-connect
|
||||
// and if there was no permcat or a default permcat, set the perms
|
||||
// from the role
|
||||
|
||||
$role = get_pconfig($channel_id,'system','permissions_role');
|
||||
if($role) {
|
||||
$xx = PermissionRoles::role_perms($role);
|
||||
if($xx['perms_auto'])
|
||||
$automatic = 1;
|
||||
|
||||
if((! $my_perms) && ($xx['perms_connect'])) {
|
||||
$default_perms = $xx['perms_connect'];
|
||||
$my_perms = Permissions::FilledPerms($default_perms);
|
||||
}
|
||||
}
|
||||
|
||||
// If we reached this point without having any permission information,
|
||||
// it is likely a custom permissions role. First see if there are any
|
||||
// automatic permissions.
|
||||
|
||||
if(! $my_perms) {
|
||||
$m = Permissions::FilledAutoperms($channel_id);
|
||||
if($m) {
|
||||
$automatic = 1;
|
||||
$my_perms = $m;
|
||||
}
|
||||
}
|
||||
|
||||
// If we reached this point with no permissions, the channel is using
|
||||
// custom perms but they are not automatic. They will be stored in abconfig with
|
||||
// the channel's channel_hash (the 'self' connection).
|
||||
|
||||
if(! $my_perms) {
|
||||
$r = q("select channel_hash from channel where channel_id = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
$x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
|
||||
intval($channel_id),
|
||||
dbesc($r[0]['channel_hash'])
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
$my_perms[$xv['k']] = intval($xv['v']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] );
|
||||
}
|
||||
|
||||
}
|
||||
14
Zotlabs/Daemon/Addon.php
Normal file
14
Zotlabs/Daemon/Addon.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
|
||||
class Addon {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
call_hooks('daemon_addon',$argv);
|
||||
|
||||
}
|
||||
}
|
||||
27
Zotlabs/Daemon/Cache_embeds.php
Normal file
27
Zotlabs/Daemon/Cache_embeds.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
|
||||
class Cache_embeds {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if(! $argc == 2)
|
||||
return;
|
||||
|
||||
$c = q("select body from item where id = %d ",
|
||||
dbesc(intval($argv[1]))
|
||||
);
|
||||
|
||||
if(! $c)
|
||||
return;
|
||||
|
||||
$item = $c[0];
|
||||
|
||||
// bbcode conversion by default processes embeds that aren't already cached.
|
||||
// Ignore the returned html output.
|
||||
|
||||
bbcode($item['body']);
|
||||
}
|
||||
}
|
||||
54
Zotlabs/Daemon/Checksites.php
Normal file
54
Zotlabs/Daemon/Checksites.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
|
||||
|
||||
class Checksites {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
logger('checksites: start');
|
||||
|
||||
if(($argc > 1) && ($argv[1]))
|
||||
$site_id = $argv[1];
|
||||
|
||||
if($site_id)
|
||||
$sql_options = " and site_url = '" . dbesc($argv[1]) . "' ";
|
||||
|
||||
$days = intval(get_config('system','sitecheckdays'));
|
||||
if($days < 1)
|
||||
$days = 30;
|
||||
|
||||
$r = q("select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ",
|
||||
db_utcnow(), db_quoteinterval($days . ' DAY'),
|
||||
intval(SITE_TYPE_ZOT)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
foreach($r as $rr) {
|
||||
if(! strcasecmp($rr['site_url'],z_root()))
|
||||
continue;
|
||||
|
||||
$x = ping_site($rr['site_url']);
|
||||
if($x['success']) {
|
||||
logger('checksites: ' . $rr['site_url']);
|
||||
q("update site set site_update = '%s' where site_url = '%s' ",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($rr['site_url'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
logger('marking dead site: ' . $x['message']);
|
||||
q("update site set site_dead = 1 where site_url = '%s' ",
|
||||
dbesc($rr['site_url'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
14
Zotlabs/Daemon/Cli_suggest.php
Normal file
14
Zotlabs/Daemon/Cli_suggest.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
|
||||
class Cli_suggest {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
update_suggestions();
|
||||
|
||||
}
|
||||
}
|
||||
236
Zotlabs/Daemon/Cron.php
Normal file
236
Zotlabs/Daemon/Cron.php
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Cron {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
$maxsysload = intval(get_config('system','maxloadavg'));
|
||||
if($maxsysload < 1)
|
||||
$maxsysload = 50;
|
||||
if(function_exists('sys_getloadavg')) {
|
||||
$load = sys_getloadavg();
|
||||
if(intval($load[0]) > $maxsysload) {
|
||||
logger('system: load ' . $load . ' too high. Cron deferred to next scheduled run.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
|
||||
$lockfile = 'store/[data]/cron';
|
||||
if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
|
||||
&& (! get_config('system','override_cron_lockfile'))) {
|
||||
logger("cron: Already running");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
|
||||
file_put_contents($lockfile, $x);
|
||||
|
||||
logger('cron: start');
|
||||
|
||||
// run queue delivery process in the background
|
||||
|
||||
Master::Summon(array('Queue'));
|
||||
|
||||
Master::Summon(array('Poller'));
|
||||
|
||||
// maintenance for mod sharedwithme - check for updated items and remove them
|
||||
|
||||
require_once('include/sharedwithme.php');
|
||||
apply_updates();
|
||||
|
||||
// expire any expired mail
|
||||
|
||||
q("delete from mail where expires > '%s' and expires < %s ",
|
||||
dbesc(NULL_DATE),
|
||||
db_utcnow()
|
||||
);
|
||||
|
||||
// expire any expired items
|
||||
|
||||
$r = q("select id,item_wall from item where expires > '2001-01-01 00:00:00' and expires < %s
|
||||
and item_deleted = 0 ",
|
||||
db_utcnow()
|
||||
);
|
||||
if($r) {
|
||||
require_once('include/items.php');
|
||||
foreach($r as $rr) {
|
||||
drop_item($rr['id'],false,(($rr['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL));
|
||||
if($rr['item_wall']) {
|
||||
// The notifier isn't normally invoked unless item_drop is interactive.
|
||||
Master::Summon( [ 'Notifier', 'drop', $rr['id'] ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// delete expired access tokens
|
||||
|
||||
$r = q("select atoken_id from atoken where atoken_expires > '%s' and atoken_expires < %s",
|
||||
dbesc(NULL_DATE),
|
||||
db_utcnow()
|
||||
);
|
||||
if($r) {
|
||||
require_once('include/security.php');
|
||||
foreach($r as $rr) {
|
||||
atoken_delete($rr['atoken_id']);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that every channel pings a directory server once a month. This way we can discover
|
||||
// channels and sites that quietly vanished and prevent the directory from accumulating stale
|
||||
// or dead entries.
|
||||
|
||||
$r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s and channel_removed = 0",
|
||||
db_utcnow(),
|
||||
db_quoteinterval('30 DAY')
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
Master::Summon(array('Directory',$rr['channel_id'],'force'));
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean expired photos from cache
|
||||
|
||||
$r = q("SELECT DISTINCT xchan, content FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s",
|
||||
intval(PHOTO_CACHE),
|
||||
db_utcnow(),
|
||||
db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY')
|
||||
);
|
||||
if($r) {
|
||||
q("DELETE FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s",
|
||||
intval(PHOTO_CACHE),
|
||||
db_utcnow(),
|
||||
db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY')
|
||||
);
|
||||
foreach($r as $rr) {
|
||||
$file = dbunescbin($rr['content']);
|
||||
if(is_file($file)) {
|
||||
@unlink($file);
|
||||
@rmdir(dirname($file));
|
||||
logger('info: deleted cached photo file ' . $file, LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// publish any applicable items that were set to be published in the future
|
||||
// (time travel posts). Restrict to items that have come of age in the last
|
||||
// couple of days to limit the query to something reasonable.
|
||||
|
||||
$r = q("select id from item where item_delayed = 1 and created <= %s and created > '%s' ",
|
||||
db_utcnow(),
|
||||
dbesc(datetime_convert('UTC','UTC','now - 2 days'))
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$x = q("update item set item_delayed = 0 where id = %d",
|
||||
intval($rr['id'])
|
||||
);
|
||||
if($x) {
|
||||
$z = q("select * from item where id = %d",
|
||||
intval($message_id)
|
||||
);
|
||||
if($z) {
|
||||
xchan_query($z);
|
||||
$sync_item = fetch_post_tags($z);
|
||||
build_sync_packet($sync_item[0]['uid'],
|
||||
[
|
||||
'item' => [ encode_item($sync_item[0],true) ]
|
||||
]
|
||||
);
|
||||
}
|
||||
Master::Summon(array('Notifier','wall-new',$rr['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require_once('include/attach.php');
|
||||
attach_upgrade();
|
||||
|
||||
$abandon_days = intval(get_config('system','account_abandon_days'));
|
||||
if($abandon_days < 1)
|
||||
$abandon_days = 0;
|
||||
|
||||
|
||||
// once daily run birthday_updates and then expire in background
|
||||
|
||||
// FIXME: add birthday updates, both locally and for xprof for use
|
||||
// by directory servers
|
||||
|
||||
$d1 = intval(get_config('system','last_expire_day'));
|
||||
$d2 = intval(datetime_convert('UTC','UTC','now','d'));
|
||||
|
||||
// Allow somebody to staggger daily activities if they have more than one site on their server,
|
||||
// or if it happens at an inconvenient (busy) hour.
|
||||
|
||||
$h1 = intval(get_config('system','cron_hour'));
|
||||
$h2 = intval(datetime_convert('UTC','UTC','now','G'));
|
||||
|
||||
|
||||
if(($d2 != $d1) && ($h1 == $h2)) {
|
||||
Master::Summon(array('Cron_daily'));
|
||||
}
|
||||
|
||||
// update any photos which didn't get imported properly
|
||||
// This should be rare
|
||||
|
||||
$r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = ''
|
||||
and xchan_photo_date < %s - INTERVAL %s",
|
||||
db_utcnow(),
|
||||
db_quoteinterval('1 DAY')
|
||||
);
|
||||
if($r) {
|
||||
require_once('include/photo/photo_driver.php');
|
||||
foreach($r as $rr) {
|
||||
$photos = import_xchan_photo($rr['xchan_photo_l'], $rr['xchan_hash'], false, true);
|
||||
$x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
|
||||
where xchan_hash = '%s'",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc($photos[3]),
|
||||
dbesc($rr['xchan_hash'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// pull in some public posts
|
||||
|
||||
$disable_discover_tab = get_config('system','disable_discover_tab') || get_config('system','disable_discover_tab') === false;
|
||||
if(! $disable_discover_tab)
|
||||
Master::Summon(array('Externals'));
|
||||
|
||||
$generation = 0;
|
||||
|
||||
$restart = false;
|
||||
|
||||
if(($argc > 1) && ($argv[1] == 'restart')) {
|
||||
$restart = true;
|
||||
$generation = intval($argv[2]);
|
||||
if(! $generation)
|
||||
return;
|
||||
}
|
||||
|
||||
reload_plugins();
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
// TODO check to see if there are any cronhooks before wasting a process
|
||||
|
||||
if(! $restart)
|
||||
Master::Summon(array('Cronhooks'));
|
||||
|
||||
set_config('system','lastcron',datetime_convert());
|
||||
|
||||
//All done - clear the lockfile
|
||||
@unlink($lockfile);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
103
Zotlabs/Daemon/Cron_daily.php
Normal file
103
Zotlabs/Daemon/Cron_daily.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Cron_daily {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
logger('cron_daily: start');
|
||||
|
||||
/**
|
||||
* Cron Daily
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
require_once('include/dir_fns.php');
|
||||
check_upstream_directory();
|
||||
|
||||
|
||||
// Fire off the Cron_weekly process if it's the correct day.
|
||||
|
||||
$d3 = intval(datetime_convert('UTC','UTC','now','N'));
|
||||
if($d3 == 7) {
|
||||
Master::Summon(array('Cron_weekly'));
|
||||
}
|
||||
|
||||
// once daily run birthday_updates and then expire in background
|
||||
|
||||
// FIXME: add birthday updates, both locally and for xprof for use
|
||||
// by directory servers
|
||||
|
||||
update_birthdays();
|
||||
|
||||
// expire any read notifications over a month old
|
||||
|
||||
q("delete from notify where seen = 1 and created < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('30 DAY')
|
||||
);
|
||||
|
||||
// expire any unread notifications over a year old
|
||||
|
||||
q("delete from notify where seen = 0 and created < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('1 YEAR')
|
||||
);
|
||||
|
||||
// Clean up emdedded content cache
|
||||
q("DELETE FROM cache WHERE updated < %s - INTERVAL %s",
|
||||
db_utcnow(),
|
||||
db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY')
|
||||
);
|
||||
|
||||
//update statistics in config
|
||||
require_once('include/statistics_fns.php');
|
||||
update_channels_total_stat();
|
||||
update_channels_active_halfyear_stat();
|
||||
update_channels_active_monthly_stat();
|
||||
update_local_posts_stat();
|
||||
update_local_comments_stat();
|
||||
|
||||
|
||||
// expire old delivery reports
|
||||
|
||||
$keep_reports = intval(get_config('system','expire_delivery_reports'));
|
||||
if($keep_reports === 0)
|
||||
$keep_reports = 10;
|
||||
|
||||
q("delete from dreport where dreport_time < %s - INTERVAL %s",
|
||||
db_utcnow(),
|
||||
db_quoteinterval($keep_reports . ' DAY')
|
||||
);
|
||||
|
||||
// expire any expired accounts
|
||||
downgrade_accounts();
|
||||
|
||||
// If this is a directory server, request a sync with an upstream
|
||||
// directory at least once a day, up to once every poll interval.
|
||||
// Pull remote changes and push local changes.
|
||||
// potential issue: how do we keep from creating an endless update loop?
|
||||
|
||||
$dirmode = get_config('system','directory_mode');
|
||||
|
||||
if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
|
||||
require_once('include/dir_fns.php');
|
||||
sync_directories($dirmode);
|
||||
}
|
||||
|
||||
|
||||
Master::Summon(array('Expire'));
|
||||
Master::Summon(array('Cli_suggest'));
|
||||
|
||||
remove_obsolete_hublocs();
|
||||
z6_discover();
|
||||
|
||||
call_hooks('cron_daily',datetime_convert());
|
||||
|
||||
set_config('system','last_expire_day',intval(datetime_convert('UTC','UTC','now','d')));
|
||||
|
||||
/**
|
||||
* End Cron Daily
|
||||
*/
|
||||
}
|
||||
}
|
||||
62
Zotlabs/Daemon/Cron_weekly.php
Normal file
62
Zotlabs/Daemon/Cron_weekly.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Cron_weekly {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
/**
|
||||
* Cron Weekly
|
||||
*
|
||||
* Actions in the following block are executed once per day only on Sunday (once per week).
|
||||
*
|
||||
*/
|
||||
|
||||
call_hooks('cron_weekly',datetime_convert());
|
||||
|
||||
z_check_cert();
|
||||
|
||||
prune_hub_reinstalls();
|
||||
|
||||
mark_orphan_hubsxchans();
|
||||
|
||||
// Find channels that were removed in the last three weeks, but
|
||||
// haven't been finally cleaned up. These should be older than 10
|
||||
// days to ensure that "purgeall" messages have gone out or bounced
|
||||
// or timed out.
|
||||
|
||||
$r = q("select channel_id from channel where channel_removed = 1 and
|
||||
channel_deleted > %s - INTERVAL %s and channel_deleted < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('21 DAY'),
|
||||
db_utcnow(), db_quoteinterval('10 DAY')
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rv) {
|
||||
channel_remove_final($rv['channel_id']);
|
||||
}
|
||||
}
|
||||
|
||||
// get rid of really old poco records
|
||||
|
||||
q("delete from xlink where xlink_updated < %s - INTERVAL %s and xlink_static = 0 ",
|
||||
db_utcnow(), db_quoteinterval('14 DAY')
|
||||
);
|
||||
|
||||
$dirmode = intval(get_config('system','directory_mode'));
|
||||
if($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) {
|
||||
logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())),true));
|
||||
}
|
||||
|
||||
// Check for dead sites
|
||||
Master::Summon(array('Checksites'));
|
||||
|
||||
// update searchable doc indexes
|
||||
Master::Summon(array('Importdoc'));
|
||||
|
||||
/**
|
||||
* End Cron Weekly
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
17
Zotlabs/Daemon/Cronhooks.php
Normal file
17
Zotlabs/Daemon/Cronhooks.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Cronhooks {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
logger('cronhooks: start');
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
call_hooks('cron', $d);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
55
Zotlabs/Daemon/CurlAuth.php
Normal file
55
Zotlabs/Daemon/CurlAuth.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
// generate a curl compatible cookie file with an authenticated session for the given channel_id.
|
||||
// If this file is then used with curl and the destination url is sent through zid() or manually
|
||||
// manipulated to add a zid, it should allow curl to provide zot magic-auth across domains.
|
||||
|
||||
// Handles expiration of stale cookies currently by deleting them and rewriting the file.
|
||||
|
||||
class CurlAuth {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if($argc != 2)
|
||||
return;
|
||||
|
||||
\App::$session->start();
|
||||
|
||||
$_SESSION['authenticated'] = 1;
|
||||
$_SESSION['uid'] = $argv[1];
|
||||
|
||||
$x = session_id();
|
||||
|
||||
$f = 'store/[data]/cookie_' . $argv[1];
|
||||
$c = 'store/[data]/cookien_' . $argv[1];
|
||||
|
||||
$e = file_exists($f);
|
||||
|
||||
$output = '';
|
||||
|
||||
if($e) {
|
||||
$lines = file($f);
|
||||
if($lines) {
|
||||
foreach($lines as $line) {
|
||||
if(strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) {
|
||||
$tokens = explode("\t", $line);
|
||||
$tokens = array_map('trim', $tokens);
|
||||
if($tokens[4] > time()) {
|
||||
$output .= $line . "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
$output .= $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
$t = time() + (24 * 3600);
|
||||
file_put_contents($f, $output . 'HttpOnly_' . \App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0));
|
||||
|
||||
file_put_contents($c,$x);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
93
Zotlabs/Daemon/Deliver.php
Normal file
93
Zotlabs/Daemon/Deliver.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
use Zotlabs\Lib\DReport;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/queue_fn.php');
|
||||
|
||||
|
||||
class Deliver {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if($argc < 2)
|
||||
return;
|
||||
|
||||
logger('deliver: invoked: ' . print_r($argv,true), LOGGER_DATA);
|
||||
|
||||
for($x = 1; $x < $argc; $x ++) {
|
||||
|
||||
if(! $argv[$x])
|
||||
continue;
|
||||
|
||||
$dresult = null;
|
||||
$r = q("select * from outq where outq_hash = '%s' limit 1",
|
||||
dbesc($argv[$x])
|
||||
);
|
||||
if($r) {
|
||||
|
||||
$notify = json_decode($r[0]['outq_notify'],true);
|
||||
|
||||
// Messages without an outq_msg will need to go via the web, even if it's a
|
||||
// local delivery. This includes conversation requests and refresh packets.
|
||||
|
||||
if(($r[0]['outq_posturl'] === z_root() . '/post') && ($r[0]['outq_msg'])) {
|
||||
logger('deliver: local delivery', LOGGER_DEBUG);
|
||||
|
||||
// local delivery
|
||||
// we should probably batch these and save a few delivery processes
|
||||
|
||||
if($r[0]['outq_msg']) {
|
||||
$m = json_decode($r[0]['outq_msg'],true);
|
||||
if(array_key_exists('message_list',$m)) {
|
||||
foreach($m['message_list'] as $mm) {
|
||||
$msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $mm)))));
|
||||
zot_import($msg,z_root());
|
||||
}
|
||||
}
|
||||
else {
|
||||
$msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $m)))));
|
||||
$dresult = zot_import($msg,z_root());
|
||||
}
|
||||
|
||||
remove_queue_item($r[0]['outq_hash']);
|
||||
|
||||
if($dresult && is_array($dresult)) {
|
||||
|
||||
// delivery reports for local deliveries do not require encryption
|
||||
|
||||
foreach($dresult as $xx) {
|
||||
if(is_array($xx) && array_key_exists('message_id',$xx)) {
|
||||
if(DReport::is_storable($xx)) {
|
||||
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
|
||||
dbesc($xx['message_id']),
|
||||
dbesc($xx['location']),
|
||||
dbesc($xx['recipient']),
|
||||
dbesc(($xx['name']) ? $xx['name'] : EMPTY_STR),
|
||||
dbesc($xx['status']),
|
||||
dbesc(datetime_convert($xx['date'])),
|
||||
dbesc($xx['sender'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
q("delete from dreport where dreport_queue = '%s'",
|
||||
dbesc($argv[$x])
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise it's a remote delivery - call queue_deliver() with the $immediate flag
|
||||
|
||||
queue_deliver($r[0],true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Zotlabs/Daemon/Deliver_hooks.php
Normal file
24
Zotlabs/Daemon/Deliver_hooks.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
|
||||
class Deliver_hooks {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if($argc < 2)
|
||||
return;
|
||||
|
||||
|
||||
$r = q("select * from item where id = '%d'",
|
||||
intval($argv[1])
|
||||
);
|
||||
if($r)
|
||||
call_hooks('notifier_normal',$r[0]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
100
Zotlabs/Daemon/Directory.php
Normal file
100
Zotlabs/Daemon/Directory.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/dir_fns.php');
|
||||
require_once('include/queue_fn.php');
|
||||
|
||||
|
||||
class Directory {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
if($argc < 2)
|
||||
return;
|
||||
|
||||
$force = false;
|
||||
$pushall = true;
|
||||
|
||||
if($argc > 2) {
|
||||
if($argv[2] === 'force')
|
||||
$force = true;
|
||||
if($argv[2] === 'nopush')
|
||||
$pushall = false;
|
||||
}
|
||||
|
||||
logger('directory update', LOGGER_DEBUG);
|
||||
|
||||
$dirmode = get_config('system','directory_mode');
|
||||
if($dirmode === false)
|
||||
$dirmode = DIRECTORY_MODE_NORMAL;
|
||||
|
||||
$x = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($argv[1])
|
||||
);
|
||||
if(! $x)
|
||||
return;
|
||||
|
||||
$channel = $x[0];
|
||||
|
||||
if($dirmode != DIRECTORY_MODE_NORMAL) {
|
||||
|
||||
// this is an in-memory update and we don't need to send a network packet.
|
||||
|
||||
local_dir_update($argv[1],$force);
|
||||
|
||||
q("update channel set channel_dirdate = '%s' where channel_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
// Now update all the connections
|
||||
if($pushall)
|
||||
Master::Summon(array('Notifier','refresh_all',$channel['channel_id']));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise send the changes upstream
|
||||
|
||||
$directory = find_upstream_directory($dirmode);
|
||||
$url = $directory['url'] . '/post';
|
||||
|
||||
// ensure the upstream directory is updated
|
||||
|
||||
$packet = zot_build_packet($channel,(($force) ? 'force_refresh' : 'refresh'));
|
||||
$z = zot_zot($url,$packet);
|
||||
|
||||
// re-queue if unsuccessful
|
||||
|
||||
if(! $z['success']) {
|
||||
|
||||
/** @FIXME we aren't updating channel_dirdate if we have to queue
|
||||
* the directory packet. That means we'll try again on the next poll run.
|
||||
*/
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
queue_insert(array(
|
||||
'hash' => $hash,
|
||||
'account_id' => $channel['channel_account_id'],
|
||||
'channel_id' => $channel['channel_id'],
|
||||
'posturl' => $url,
|
||||
'notify' => $packet,
|
||||
));
|
||||
|
||||
}
|
||||
else {
|
||||
q("update channel set channel_dirdate = '%s' where channel_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
// Now update all the connections
|
||||
if($pushall)
|
||||
Master::Summon(array('Notifier','refresh_all',$channel['channel_id']));
|
||||
|
||||
}
|
||||
}
|
||||
94
Zotlabs/Daemon/Expire.php
Normal file
94
Zotlabs/Daemon/Expire.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
|
||||
class Expire {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
cli_startup();
|
||||
|
||||
// perform final cleanup on previously delete items
|
||||
|
||||
$r = q("select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('10 DAY')
|
||||
);
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
drop_item($rr['id'], false, DROPITEM_PHASE2);
|
||||
}
|
||||
}
|
||||
|
||||
// physically remove anything that has been deleted for more than two months
|
||||
/** @FIXME - this is a wretchedly inefficient query */
|
||||
|
||||
$r = q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('36 DAY')
|
||||
);
|
||||
|
||||
/** @FIXME make this optional as it could have a performance impact on large sites */
|
||||
|
||||
if (intval(get_config('system', 'optimize_items')))
|
||||
q("optimize table item");
|
||||
|
||||
logger('expire: start', LOGGER_DEBUG);
|
||||
|
||||
$site_expire = intval(get_config('system', 'default_expire_days'));
|
||||
$commented_days = intval(get_config('system','active_expire_days'));
|
||||
|
||||
logger('site_expire: ' . $site_expire);
|
||||
|
||||
$r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true");
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
|
||||
// expire the sys channel separately
|
||||
if (intval($rr['channel_system']))
|
||||
continue;
|
||||
|
||||
// service class default (if non-zero) over-rides the site default
|
||||
|
||||
$service_class_expire = service_class_fetch($rr['channel_id'], 'expire_days');
|
||||
if (intval($service_class_expire))
|
||||
$channel_expire = $service_class_expire;
|
||||
else
|
||||
$channel_expire = $site_expire;
|
||||
|
||||
if (intval($channel_expire) && (intval($channel_expire) < intval($rr['channel_expire_days'])) ||
|
||||
intval($rr['channel_expire_days'] == 0)) {
|
||||
$expire_days = $channel_expire;
|
||||
} else {
|
||||
$expire_days = $rr['channel_expire_days'];
|
||||
}
|
||||
|
||||
// if the site or service class expiration is non-zero and less than person expiration, use that
|
||||
logger('Expire: ' . $rr['channel_address'] . ' interval: ' . $expire_days, LOGGER_DEBUG);
|
||||
item_expire($rr['channel_id'], $expire_days, $commented_days);
|
||||
}
|
||||
}
|
||||
|
||||
$x = get_sys_channel();
|
||||
if ($x) {
|
||||
|
||||
// this should probably just fetch the channel_expire_days from the sys channel,
|
||||
// but there's no convenient way to set it.
|
||||
|
||||
$expire_days = get_config('system', 'sys_expire_days');
|
||||
if ($expire_days === false)
|
||||
$expire_days = 30;
|
||||
|
||||
if (intval($site_expire) && (intval($site_expire) < intval($expire_days))) {
|
||||
$expire_days = $site_expire;
|
||||
}
|
||||
|
||||
logger('Expire: sys interval: ' . $expire_days, LOGGER_DEBUG);
|
||||
|
||||
if ($expire_days)
|
||||
item_expire($x['channel_id'], $expire_days, $commented_days);
|
||||
|
||||
logger('Expire: sys: done', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Zotlabs/Daemon/Externals.php
Normal file
98
Zotlabs/Daemon/Externals.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/channel.php');
|
||||
|
||||
|
||||
class Externals {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
$total = 0;
|
||||
$attempts = 0;
|
||||
|
||||
logger('externals: startup', LOGGER_DEBUG);
|
||||
|
||||
// pull in some public posts
|
||||
|
||||
|
||||
while($total == 0 && $attempts < 3) {
|
||||
$arr = array('url' => '');
|
||||
call_hooks('externals_url_select',$arr);
|
||||
|
||||
if($arr['url']) {
|
||||
$url = $arr['url'];
|
||||
}
|
||||
else {
|
||||
$randfunc = db_getfunc('RAND');
|
||||
|
||||
// fixme this query does not deal with directory realms.
|
||||
|
||||
$r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1",
|
||||
dbesc(z_root()),
|
||||
intval(DIRECTORY_MODE_STANDALONE),
|
||||
intval(SITE_TYPE_ZOT)
|
||||
);
|
||||
if($r)
|
||||
$url = $r[0]['site_url'];
|
||||
}
|
||||
|
||||
$blacklisted = false;
|
||||
|
||||
if(! check_siteallowed($url)) {
|
||||
logger('blacklisted site: ' . $url);
|
||||
$blacklisted = true;
|
||||
}
|
||||
|
||||
$attempts ++;
|
||||
|
||||
// make sure we can eventually break out if somebody blacklists all known sites
|
||||
|
||||
if($blacklisted) {
|
||||
if($attempts > 20)
|
||||
break;
|
||||
$attempts --;
|
||||
continue;
|
||||
}
|
||||
|
||||
if($url) {
|
||||
if($r[0]['site_pull'] > NULL_DATE)
|
||||
$mindate = urlencode(datetime_convert('','',$r[0]['site_pull'] . ' - 1 day'));
|
||||
else {
|
||||
$days = get_config('externals','since_days');
|
||||
if($days === false)
|
||||
$days = 15;
|
||||
$mindate = urlencode(datetime_convert('','','now - ' . intval($days) . ' days'));
|
||||
}
|
||||
|
||||
$feedurl = $url . '/zotfeed?f=&mindate=' . $mindate;
|
||||
|
||||
logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG);
|
||||
|
||||
$x = z_fetch_url($feedurl);
|
||||
if(($x) && ($x['success'])) {
|
||||
|
||||
q("update site set site_pull = '%s' where site_url = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($url)
|
||||
);
|
||||
|
||||
$j = json_decode($x['body'],true);
|
||||
if($j['success'] && $j['messages']) {
|
||||
$sys = get_sys_channel();
|
||||
foreach($j['messages'] as $message) {
|
||||
// on these posts, clear any route info.
|
||||
$message['route'] = '';
|
||||
$results = process_delivery(array('hash' => 'undefined'), get_item_elements($message),
|
||||
array(array('hash' => $sys['xchan_hash'])), false, true);
|
||||
$total ++;
|
||||
}
|
||||
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Zotlabs/Daemon/Gprobe.php
Normal file
33
Zotlabs/Daemon/Gprobe.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
|
||||
// performs zot_finger on $argv[1], which is a hex_encoded webbie/reddress
|
||||
|
||||
class Gprobe {
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if($argc != 2)
|
||||
return;
|
||||
|
||||
$url = hex2bin($argv[1]);
|
||||
|
||||
if(! strpos($url,'@'))
|
||||
return;
|
||||
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' limit 1",
|
||||
dbesc($url)
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
$j = \Zotlabs\Zot\Finger::run($url,null);
|
||||
if($j['success']) {
|
||||
$y = import_xchan($j);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
41
Zotlabs/Daemon/Importdoc.php
Executable file
41
Zotlabs/Daemon/Importdoc.php
Executable file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
|
||||
class Importdoc {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
require_once('include/help.php');
|
||||
|
||||
self::update_docs_dir('doc/*');
|
||||
|
||||
}
|
||||
|
||||
static public function update_docs_dir($s) {
|
||||
$f = basename($s);
|
||||
$d = dirname($s);
|
||||
if($s === 'doc/html')
|
||||
return;
|
||||
$files = glob("$d/$f");
|
||||
if($files) {
|
||||
foreach($files as $fi) {
|
||||
if($fi === 'doc/html') {
|
||||
continue;
|
||||
}
|
||||
if(is_dir($fi)) {
|
||||
self::update_docs_dir("$fi/*");
|
||||
}
|
||||
else {
|
||||
// don't update media content
|
||||
if(strpos(z_mime_content_type($fi),'text') === 0) {
|
||||
store_doc_file($fi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
47
Zotlabs/Daemon/Importfile.php
Normal file
47
Zotlabs/Daemon/Importfile.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Importfile {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
logger('Importfile: ' . print_r($argv,true));
|
||||
|
||||
if($argc < 3)
|
||||
return;
|
||||
|
||||
$channel = channelx_by_n($argv[1]);
|
||||
if(! $channel)
|
||||
return;
|
||||
|
||||
$srcfile = $argv[2];
|
||||
$folder = (($argc > 3) ? $argv[3] : '');
|
||||
$dstname = (($argc > 4) ? $argv[4] : '');
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
$arr = [
|
||||
'src' => $srcfile,
|
||||
'filename' => (($dstname) ? $dstname : basename($srcfile)),
|
||||
'hash' => $hash,
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid'],
|
||||
'preserve_original' => true,
|
||||
'replace' => true
|
||||
];
|
||||
|
||||
if($folder)
|
||||
$arr['folder'] = $folder;
|
||||
|
||||
attach_store($channel,$channel['channel_hash'],'import',$arr);
|
||||
|
||||
$sync = attach_export_data($channel,$hash);
|
||||
if($sync)
|
||||
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
59
Zotlabs/Daemon/Master.php
Normal file
59
Zotlabs/Daemon/Master.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
if(array_search( __file__ , get_included_files()) === 0) {
|
||||
require_once('include/cli_startup.php');
|
||||
array_shift($argv);
|
||||
$argc = count($argv);
|
||||
|
||||
if($argc)
|
||||
Master::Release($argc,$argv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Master {
|
||||
|
||||
static public function Summon($arr) {
|
||||
$hookinfo = [
|
||||
'argv'=>$arr
|
||||
];
|
||||
|
||||
call_hooks ('daemon_master_summon',$hookinfo);
|
||||
|
||||
$arr = $hookinfo['argv'];
|
||||
$argc = count($arr);
|
||||
|
||||
if ((!is_array($arr) || (count($arr) < 1))) {
|
||||
logger("Summon handled by hook.",LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
$phpbin = get_config('system','phpbin','php');
|
||||
proc_run($phpbin,'Zotlabs/Daemon/Master.php',$arr);
|
||||
}
|
||||
|
||||
static public function Release($argc,$argv) {
|
||||
cli_startup();
|
||||
|
||||
$hookinfo = [
|
||||
'argv'=>$argv
|
||||
];
|
||||
|
||||
call_hooks ('daemon_master_release',$hookinfo);
|
||||
|
||||
$argv = $hookinfo['argv'];
|
||||
$argc = count($argv);
|
||||
|
||||
if ((!is_array($argv) || (count($argv) < 1))) {
|
||||
logger("Release handled by hook.",LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
logger('Master: release: ' . json_encode($argv), LOGGER_ALL,LOG_DEBUG);
|
||||
$cls = '\\Zotlabs\\Daemon\\' . $argv[0];
|
||||
$cls::run($argc,$argv);
|
||||
}
|
||||
}
|
||||
778
Zotlabs/Daemon/Notifier.php
Normal file
778
Zotlabs/Daemon/Notifier.php
Normal file
@@ -0,0 +1,778 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
use Zotlabs\Lib\Libzot;
|
||||
|
||||
require_once('include/queue_fn.php');
|
||||
require_once('include/html2plain.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/zot.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This file was at one time responsible for doing all deliveries, but this caused
|
||||
* big problems on shared hosting systems, where the process might get killed by the
|
||||
* hosting provider and nothing would get delivered.
|
||||
* It now only delivers one message under certain cases, and invokes a queued
|
||||
* delivery mechanism (include/deliver.php) to deliver individual contacts at
|
||||
* controlled intervals.
|
||||
* This has a much better chance of surviving random processes getting killed
|
||||
* by the hosting provider.
|
||||
*
|
||||
* The basic flow is:
|
||||
* Identify the type of message
|
||||
* Collect any information that needs to be sent
|
||||
* Convert it into a suitable generic format for sending
|
||||
* Figure out who the recipients are and if we need to relay
|
||||
* through a conversation owner
|
||||
* Once we know what recipients are involved, collect a list of
|
||||
* destination sites
|
||||
* Build and store a queue item for each unique site and invoke
|
||||
* a delivery process for each site or a small number of sites (1-3)
|
||||
* and add a slight delay between each delivery invocation if desired (usually)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The notifier is typically called with:
|
||||
*
|
||||
* Zotlabs\Daemon\Master::Summon(array('Notifier', COMMAND, ITEM_ID));
|
||||
*
|
||||
* where COMMAND is one of the following:
|
||||
*
|
||||
* activity (in diaspora.php, dfrn_confirm.php, profiles.php)
|
||||
* comment-import (in diaspora.php, items.php)
|
||||
* comment-new (in item.php)
|
||||
* drop (in diaspora.php, items.php, photos.php)
|
||||
* edit_post (in item.php)
|
||||
* event (in events.php)
|
||||
* expire (in items.php)
|
||||
* like (in like.php, poke.php)
|
||||
* mail (in message.php)
|
||||
* tag (in photos.php, poke.php, tagger.php)
|
||||
* tgroup (in items.php)
|
||||
* wall-new (in photos.php, item.php)
|
||||
*
|
||||
* and ITEM_ID is the id of the item in the database that needs to be sent to others.
|
||||
*
|
||||
* ZOT
|
||||
* permission_create abook_id
|
||||
* permission_accept abook_id
|
||||
* permission_reject abook_id
|
||||
* permission_update abook_id
|
||||
* refresh_all channel_id
|
||||
* purge_all channel_id
|
||||
* expire channel_id
|
||||
* relay item_id (item was relayed to owner, we will deliver it as owner)
|
||||
* single_activity item_id (deliver to a singleton network from the appropriate clone)
|
||||
* single_mail mail_id (deliver to a singleton network from the appropriate clone)
|
||||
* location channel_id
|
||||
* request channel_id xchan_hash message_id
|
||||
* rating xlink_id
|
||||
* keychange channel_id
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
class Notifier {
|
||||
|
||||
static public function run($argc,$argv){
|
||||
|
||||
if($argc < 3)
|
||||
return;
|
||||
|
||||
logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
|
||||
|
||||
$cmd = $argv[1];
|
||||
|
||||
$item_id = $argv[2];
|
||||
|
||||
if(! $item_id)
|
||||
return;
|
||||
|
||||
$sys = get_sys_channel();
|
||||
|
||||
$deliveries = array();
|
||||
|
||||
$request = false;
|
||||
$mail = false;
|
||||
$top_level = false;
|
||||
$location = false;
|
||||
$recipients = array();
|
||||
$url_recipients = array();
|
||||
$normal_mode = true;
|
||||
$packet_type = 'undefined';
|
||||
|
||||
if($cmd === 'mail' || $cmd === 'single_mail') {
|
||||
$normal_mode = false;
|
||||
$mail = true;
|
||||
$private = true;
|
||||
$message = q("SELECT * FROM mail WHERE id = %d LIMIT 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if(! $message) {
|
||||
return;
|
||||
}
|
||||
xchan_mail_query($message[0]);
|
||||
$uid = $message[0]['channel_id'];
|
||||
$recipients[] = $message[0]['from_xchan']; // include clones
|
||||
$recipients[] = $message[0]['to_xchan'];
|
||||
$item = $message[0];
|
||||
|
||||
$encoded_item = encode_mail($item);
|
||||
|
||||
$s = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($item['channel_id'])
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
|
||||
}
|
||||
elseif($cmd === 'request') {
|
||||
$channel_id = $item_id;
|
||||
$xchan = $argv[3];
|
||||
$request_message_id = $argv[4];
|
||||
|
||||
$s = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
|
||||
$private = true;
|
||||
$recipients[] = $xchan;
|
||||
$packet_type = 'request';
|
||||
$normal_mode = false;
|
||||
}
|
||||
elseif($cmd === 'keychange') {
|
||||
$channel = channelx_by_n($item_id);
|
||||
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$recipients[] = $rr['abook_xchan'];
|
||||
}
|
||||
}
|
||||
$private = false;
|
||||
$packet_type = 'keychange';
|
||||
$normal_mode = false;
|
||||
}
|
||||
elseif(in_array($cmd, [ 'permission_update', 'permission_reject', 'permission_accept', 'permission_create' ])) {
|
||||
// Get the (single) recipient
|
||||
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
$uid = $r[0]['abook_channel'];
|
||||
// Get the sender
|
||||
$channel = channelx_by_n($uid);
|
||||
if($channel) {
|
||||
$perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
|
||||
|
||||
if($cmd === 'permission_create')
|
||||
call_hooks('permissions_create',$perm_update);
|
||||
elseif($cmd === 'permission_accept')
|
||||
call_hooks('permissions_accept',$perm_update);
|
||||
elseif($cmd === 'permission_reject')
|
||||
call_hooks('permissions_reject',$perm_update);
|
||||
else
|
||||
call_hooks('permissions_update',$perm_update);
|
||||
|
||||
if($perm_update['success']) {
|
||||
if($perm_update['deliveries']) {
|
||||
$deliveries[] = $perm_update['deliveries'];
|
||||
do_delivery($deliveries);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$recipients[] = $r[0]['abook_xchan'];
|
||||
$private = false;
|
||||
$packet_type = 'refresh';
|
||||
$packet_recips = array(array('guid' => $r[0]['xchan_guid'],'guid_sig' => $r[0]['xchan_guid_sig'],'hash' => $r[0]['xchan_hash']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif($cmd === 'refresh_all') {
|
||||
logger('notifier: refresh_all: ' . $item_id);
|
||||
$uid = $item_id;
|
||||
$channel = channelx_by_n($item_id);
|
||||
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$recipients[] = $rr['abook_xchan'];
|
||||
}
|
||||
}
|
||||
$private = false;
|
||||
$packet_type = 'refresh';
|
||||
}
|
||||
elseif($cmd === 'location') {
|
||||
logger('notifier: location: ' . $item_id);
|
||||
$s = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
$uid = $item_id;
|
||||
$recipients = array();
|
||||
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$recipients[] = $rr['abook_xchan'];
|
||||
}
|
||||
}
|
||||
|
||||
$encoded_item = array('locations' => zot_encode_locations($channel),'type' => 'location', 'encoding' => 'zot');
|
||||
$target_item = array('aid' => $channel['channel_account_id'],'uid' => $channel['channel_id']);
|
||||
$private = false;
|
||||
$packet_type = 'location';
|
||||
$location = true;
|
||||
}
|
||||
elseif($cmd === 'purge_all') {
|
||||
logger('notifier: purge_all: ' . $item_id);
|
||||
$s = q("select * from channel where channel_id = %d limit 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
$uid = $item_id;
|
||||
$recipients = array();
|
||||
$r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 0",
|
||||
intval($item_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$recipients[] = $rr['abook_xchan'];
|
||||
}
|
||||
}
|
||||
$private = false;
|
||||
$packet_type = 'purge';
|
||||
}
|
||||
else {
|
||||
|
||||
// Normal items
|
||||
|
||||
// Fetch the target item
|
||||
|
||||
$r = q("SELECT * FROM item WHERE id = %d and parent != 0 LIMIT 1",
|
||||
intval($item_id)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
xchan_query($r);
|
||||
|
||||
$r = fetch_post_tags($r);
|
||||
|
||||
$target_item = $r[0];
|
||||
$deleted_item = false;
|
||||
|
||||
if(intval($target_item['item_deleted'])) {
|
||||
logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG);
|
||||
$deleted_item = true;
|
||||
}
|
||||
|
||||
if(! in_array(intval($target_item['item_type']), [ ITEM_TYPE_POST ] )) {
|
||||
$hookinfo=[
|
||||
'targetitem'=>$target_item,
|
||||
'deliver'=>false
|
||||
];
|
||||
if (intval($target_item['item_type'] == ITEM_TYPE_CUSTOM)) {
|
||||
call_hooks('customitem_deliver',$hookinfo);
|
||||
}
|
||||
|
||||
if (!$hookinfo['deliver']) {
|
||||
logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
$target_item = $hookinfo['targetitem'];
|
||||
|
||||
}
|
||||
|
||||
// Check for non published items, but allow an exclusion for transmitting hidden file activities
|
||||
|
||||
if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) ||
|
||||
intval($target_item['item_blocked']) ||
|
||||
( intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) {
|
||||
logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strpos($target_item['postopts'],'nodeliver') !== false) {
|
||||
logger('notifier: target item is undeliverable', LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
$s = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
|
||||
intval($target_item['uid'])
|
||||
);
|
||||
if($s)
|
||||
$channel = $s[0];
|
||||
|
||||
if($channel['channel_hash'] !== $target_item['author_xchan'] && $channel['channel_hash'] !== $target_item['owner_xchan']) {
|
||||
logger("notifier: Sending channel {$channel['channel_hash']} is not owner {$target_item['owner_xchan']} or author {$target_item['author_xchan']}", LOGGER_NORMAL, LOG_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if($target_item['mid'] === $target_item['parent_mid']) {
|
||||
$parent_item = $target_item;
|
||||
$top_level_post = true;
|
||||
}
|
||||
else {
|
||||
// fetch the parent item
|
||||
$r = q("SELECT * from item where id = %d order by id asc",
|
||||
intval($target_item['parent'])
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
if(strpos($r[0]['postopts'],'nodeliver') !== false) {
|
||||
logger('notifier: target item is undeliverable', LOGGER_DEBUG, LOG_NOTICE);
|
||||
return;
|
||||
}
|
||||
|
||||
xchan_query($r);
|
||||
$r = fetch_post_tags($r);
|
||||
|
||||
$parent_item = $r[0];
|
||||
$top_level_post = false;
|
||||
}
|
||||
|
||||
// avoid looping of discover items 12/4/2014
|
||||
|
||||
if($sys && $parent_item['uid'] == $sys['channel_id'])
|
||||
return;
|
||||
|
||||
$encoded_item = encode_item($target_item);
|
||||
|
||||
// activitystreams version
|
||||
$m = get_iconfig($target_item,'activitystreams','signed_data');
|
||||
if($m) {
|
||||
$activity = json_decode($m,true);
|
||||
}
|
||||
else {
|
||||
$activity = \Zotlabs\Lib\Activity::encode_activity($target_item);
|
||||
}
|
||||
|
||||
// Send comments to the owner to re-deliver to everybody in the conversation
|
||||
// We only do this if the item in question originated on this site. This prevents looping.
|
||||
// To clarify, a site accepting a new comment is responsible for sending it to the owner for relay.
|
||||
// Relaying should never be initiated on a post that arrived from elsewhere.
|
||||
|
||||
// We should normally be able to rely on ITEM_ORIGIN, but start_delivery_chain() incorrectly set this
|
||||
// flag on comments for an extended period. So we'll also call comment_local_origin() which looks at
|
||||
// the hostname in the message_id and provides a second (fallback) opinion.
|
||||
|
||||
$relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false);
|
||||
|
||||
|
||||
|
||||
$uplink = false;
|
||||
|
||||
// $cmd === 'relay' indicates the owner is sending it to the original recipients
|
||||
// don't allow the item in the relay command to relay to owner under any circumstances, it will loop
|
||||
|
||||
logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG);
|
||||
logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
// tag_deliver'd post which needs to be sent back to the original author
|
||||
|
||||
if(($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) {
|
||||
logger('notifier: uplink');
|
||||
$uplink = true;
|
||||
}
|
||||
|
||||
if(($relay_to_owner || $uplink) && ($cmd !== 'relay')) {
|
||||
logger('notifier: followup relay', LOGGER_DEBUG);
|
||||
$recipients = array(($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']);
|
||||
$private = true;
|
||||
if(! $encoded_item['flags'])
|
||||
$encoded_item['flags'] = array();
|
||||
$encoded_item['flags'][] = 'relay';
|
||||
$upstream = true;
|
||||
}
|
||||
else {
|
||||
logger('notifier: normal distribution', LOGGER_DEBUG);
|
||||
if($cmd === 'relay')
|
||||
logger('notifier: owner relay');
|
||||
$upstream = false;
|
||||
// if our parent is a tag_delivery recipient, uplink to the original author causing
|
||||
// a delivery fork.
|
||||
|
||||
if(($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) {
|
||||
// don't uplink a relayed post to the relay owner
|
||||
if($parent_item['source_xchan'] !== $parent_item['owner_xchan']) {
|
||||
logger('notifier: uplinking this item');
|
||||
Master::Summon(array('Notifier','uplink',$item_id));
|
||||
}
|
||||
}
|
||||
|
||||
$private = false;
|
||||
$recipients = collect_recipients($parent_item,$private);
|
||||
|
||||
|
||||
if ($top_level_post) {
|
||||
// remove clones who will receive the post via sync
|
||||
$recipients = array_diff($recipients, [ $target_item['owner_xchan'] ]);
|
||||
}
|
||||
|
||||
// FIXME add any additional recipients such as mentions, etc.
|
||||
|
||||
// don't send deletions onward for other people's stuff
|
||||
// TODO verify this is needed - copied logic from same place in old code
|
||||
|
||||
if(intval($target_item['item_deleted']) && (! intval($target_item['item_wall']))) {
|
||||
logger('notifier: ignoring delete notification for non-wall item', LOGGER_NORMAL, LOG_NOTICE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$walltowall = (($top_level_post && $channel['xchan_hash'] === $target_item['author_xchan']) ? true : false);
|
||||
|
||||
// Generic delivery section, we have an encoded item and recipients
|
||||
// Now start the delivery process
|
||||
|
||||
$x = $encoded_item;
|
||||
$x['title'] = 'private';
|
||||
$x['body'] = 'private';
|
||||
logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
//logger('notifier: encoded activity: ' . print_r($activity,true), LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
stringify_array_elms($recipients);
|
||||
if(! $recipients) {
|
||||
logger('no recipients');
|
||||
return;
|
||||
}
|
||||
|
||||
// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
|
||||
|
||||
$env_recips = (($private) ? array() : null);
|
||||
|
||||
$details = q("select xchan_hash, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . protect_sprintf(implode(',',$recipients)) . ")");
|
||||
|
||||
|
||||
$recip_list = array();
|
||||
|
||||
if($details) {
|
||||
foreach($details as $d) {
|
||||
|
||||
$recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')';
|
||||
if($private) {
|
||||
$env_recips[] = [
|
||||
'guid' => $d['xchan_guid'],
|
||||
'guid_sig' => $d['xchan_guid_sig'],
|
||||
'hash' => $d['xchan_hash']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$narr = [
|
||||
'channel' => $channel,
|
||||
'upstream' => $upstream,
|
||||
'env_recips' => $env_recips,
|
||||
'packet_recips' => $packet_recips,
|
||||
'recipients' => $recipients,
|
||||
'item' => $item,
|
||||
'target_item' => $target_item,
|
||||
'parent_item' => $parent_item,
|
||||
'top_level_post' => $top_level_post,
|
||||
'private' => $private,
|
||||
'relay_to_owner' => $relay_to_owner,
|
||||
'uplink' => $uplink,
|
||||
'cmd' => $cmd,
|
||||
'mail' => $mail,
|
||||
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
|
||||
'location' => $location,
|
||||
'request' => $request,
|
||||
'normal_mode' => $normal_mode,
|
||||
'packet_type' => $packet_type,
|
||||
'walltowall' => $walltowall,
|
||||
'queued' => []
|
||||
];
|
||||
|
||||
call_hooks('notifier_process', $narr);
|
||||
if($narr['queued']) {
|
||||
foreach($narr['queued'] as $pq)
|
||||
$deliveries[] = $pq;
|
||||
}
|
||||
|
||||
// notifier_process can alter the recipient list
|
||||
|
||||
$recipients = $narr['recipients'];
|
||||
$env_recips = $narr['env_recips'];
|
||||
$packet_recips = $narr['packet_recips'];
|
||||
|
||||
if(($private) && (! $env_recips)) {
|
||||
// shouldn't happen
|
||||
logger('notifier: private message with no envelope recipients.' . print_r($argv,true), LOGGER_NORMAL, LOG_NOTICE);
|
||||
}
|
||||
|
||||
logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list,true), LOGGER_DEBUG);
|
||||
|
||||
|
||||
// Now we have collected recipients (except for external mentions, FIXME)
|
||||
// Let's reduce this to a set of hubs; checking that the site is not dead.
|
||||
|
||||
$r = q("select hubloc.*, site.site_crypto, site.site_flags from hubloc left join site on site_url = hubloc_url where hubloc_hash in (" . protect_sprintf(implode(',',$recipients)) . ")
|
||||
and hubloc_error = 0 and hubloc_deleted = 0 and ( site_dead = 0 OR site_dead is null ) "
|
||||
);
|
||||
|
||||
|
||||
if(! $r) {
|
||||
logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE);
|
||||
return;
|
||||
}
|
||||
|
||||
$hubs = $r;
|
||||
|
||||
/**
|
||||
* Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey,
|
||||
* since it may have been a re-install which has not yet been detected and pruned.
|
||||
* For other networks which don't have or require sitekeys, we'll have to use the URL
|
||||
*/
|
||||
|
||||
|
||||
$hublist = []; // this provides an easily printable list for the logs
|
||||
$dhubs = []; // delivery hubs where we store our resulting unique array
|
||||
$keys = []; // array of keys to check uniquness for zot hubs
|
||||
$urls = []; // array of urls to check uniqueness of hubs from other networks
|
||||
$hub_env = []; // per-hub envelope so we don't broadcast the entire envelope to all
|
||||
|
||||
foreach($hubs as $hub) {
|
||||
|
||||
if($env_recips) {
|
||||
foreach($env_recips as $er) {
|
||||
if($hub['hubloc_hash'] === $er['hash']) {
|
||||
if(! array_key_exists($hub['hubloc_host'] . $hub['hubloc_sitekey'], $hub_env)) {
|
||||
$hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] = [];
|
||||
}
|
||||
$hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']][] = $er;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($hub['hubloc_network'] == 'zot') {
|
||||
if(! in_array($hub['hubloc_sitekey'],$keys)) {
|
||||
$hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network'];
|
||||
$dhubs[] = $hub;
|
||||
$keys[] = $hub['hubloc_sitekey'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(! in_array($hub['hubloc_url'],$urls)) {
|
||||
$hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network'];
|
||||
$dhubs[] = $hub;
|
||||
$urls[] = $hub['hubloc_url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG);
|
||||
|
||||
foreach($dhubs as $hub) {
|
||||
|
||||
logger('notifier_hub: ' . $hub['hubloc_url'],LOGGER_DEBUG);
|
||||
|
||||
if(! in_array($hub['hubloc_network'], [ 'zot','zot6' ])) {
|
||||
$narr = [
|
||||
'channel' => $channel,
|
||||
'upstream' => $upstream,
|
||||
'env_recips' => $env_recips,
|
||||
'packet_recips' => $packet_recips,
|
||||
'recipients' => $recipients,
|
||||
'item' => $item,
|
||||
'target_item' => $target_item,
|
||||
'parent_item' => $parent_item,
|
||||
'hub' => $hub,
|
||||
'top_level_post' => $top_level_post,
|
||||
'private' => $private,
|
||||
'relay_to_owner' => $relay_to_owner,
|
||||
'uplink' => $uplink,
|
||||
'cmd' => $cmd,
|
||||
'mail' => $mail,
|
||||
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
|
||||
'location' => $location,
|
||||
'request' => $request,
|
||||
'normal_mode' => $normal_mode,
|
||||
'packet_type' => $packet_type,
|
||||
'walltowall' => $walltowall,
|
||||
'queued' => []
|
||||
];
|
||||
|
||||
|
||||
call_hooks('notifier_hub',$narr);
|
||||
if($narr['queued']) {
|
||||
foreach($narr['queued'] as $pq)
|
||||
$deliveries[] = $pq;
|
||||
}
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// singleton deliveries by definition 'not got zot'.
|
||||
// Single deliveries are other federated networks (plugins) and we're essentially
|
||||
// delivering only to those that have this site url in their abook_instance
|
||||
// and only from within a sync operation. This means if you post from a clone,
|
||||
// and a connection is connected to one of your other clones; assuming that hub
|
||||
// is running it will receive a sync packet. On receipt of this sync packet it
|
||||
// will invoke a delivery to those connections which are connected to just that
|
||||
// hub instance.
|
||||
|
||||
if($cmd === 'single_mail' || $cmd === 'single_activity') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(! in_array($hub['hubloc_network'], [ 'zot','zot6' ])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do not change this to a uuid as long as we have traditional zot servers
|
||||
// in the loop. The signature verification step can't handle dashes in the
|
||||
// hashes.
|
||||
|
||||
$hash = random_string(48);
|
||||
|
||||
$packet = null;
|
||||
$pmsg = '';
|
||||
|
||||
if($packet_type === 'refresh' || $packet_type === 'purge') {
|
||||
if($hub['hubloc_network'] === 'zot6') {
|
||||
$packet = Libzot::build_packet($channel, $packet_type, ids_to_array($packet_recips,'hash'));
|
||||
}
|
||||
else {
|
||||
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
||||
}
|
||||
}
|
||||
if($packet_type === 'keychange' && $hub['hubloc_network'] === 'zot') {
|
||||
$pmsg = get_pconfig($channel['channel_id'],'system','keychange');
|
||||
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
||||
}
|
||||
elseif($packet_type === 'request' && $hub['hubloc_network'] === 'zot') {
|
||||
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
|
||||
$packet = zot_build_packet($channel,$packet_type,$env,$hub['hubloc_sitekey'],$hub['site_crypto'],
|
||||
$hash, array('message_id' => $request_message_id)
|
||||
);
|
||||
}
|
||||
|
||||
if($packet) {
|
||||
queue_insert(array(
|
||||
'hash' => $hash,
|
||||
'account_id' => $channel['channel_account_id'],
|
||||
'channel_id' => $channel['channel_id'],
|
||||
'posturl' => $hub['hubloc_callback'],
|
||||
'driver' => $hub['hubloc_network'],
|
||||
'notify' => $packet,
|
||||
'msg' => (($pmsg) ? json_encode($pmsg) : '')
|
||||
));
|
||||
}
|
||||
else {
|
||||
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
|
||||
|
||||
|
||||
if($hub['hubloc_network'] === 'zot6') {
|
||||
$zenv = [];
|
||||
if($env) {
|
||||
foreach($env as $e) {
|
||||
$zenv[] = $e['hash'];
|
||||
}
|
||||
}
|
||||
|
||||
$packet_type = (($upstream || $uplink) ? 'response' : 'activity');
|
||||
|
||||
// block zot private reshares from zot6, as this could cause a number of privacy issues
|
||||
// due to parenting differences between the reshare implementations. In zot a reshare is
|
||||
// a standalone parent activity and in zot6 it is a followup/child of the original activity.
|
||||
// For public reshares, some comments to the reshare on the zot fork will not make it to zot6
|
||||
// due to these different message models. This cannot be prevented at this time.
|
||||
|
||||
if($packet_type === 'activity' && $activity['type'] === 'Announce' && intval($target_item['item_private'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$packet = Libzot::build_packet($channel,$packet_type,$zenv,$activity,'activitystreams',(($private) ? $hub['hubloc_sitekey'] : null),$hub['site_crypto']);
|
||||
}
|
||||
else {
|
||||
// currently zot6 delivery is only performed on normal items and not sync items or mail or anything else
|
||||
// Eventually we will do this for all deliveries, but for now ensure this is precisely what we are dealing
|
||||
// with before switching to zot6 as the primary zot6 handler checks for the existence of a message delivery report
|
||||
// to trigger dequeue'ing
|
||||
|
||||
$z6 = (($encoded_item && $encoded_item['type'] === 'activity' && (! array_key_exists('allow_cid',$encoded_item))) ? true : false);
|
||||
if($z6) {
|
||||
$packet = zot6_build_packet($channel,'notify',$env, json_encode($encoded_item), (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash);
|
||||
}
|
||||
else {
|
||||
$packet = zot_build_packet($channel,'notify',$env, (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
queue_insert(
|
||||
[
|
||||
'hash' => $hash,
|
||||
'account_id' => $target_item['aid'],
|
||||
'channel_id' => $target_item['uid'],
|
||||
'posturl' => $hub['hubloc_callback'],
|
||||
'driver' => $hub['hubloc_network'],
|
||||
'notify' => $packet,
|
||||
'msg' => json_encode($encoded_item)
|
||||
]
|
||||
);
|
||||
|
||||
// only create delivery reports for normal undeleted items
|
||||
if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) {
|
||||
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ",
|
||||
dbesc($target_item['mid']),
|
||||
dbesc($hub['hubloc_host']),
|
||||
dbesc($hub['hubloc_host']),
|
||||
dbesc('queued'),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($channel['channel_hash']),
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$deliveries[] = $hash;
|
||||
}
|
||||
|
||||
if($normal_mode) {
|
||||
$x = q("select * from hook where hook = 'notifier_normal'");
|
||||
if($x) {
|
||||
Master::Summon( [ 'Deliver_hooks', $target_item['id'] ] );
|
||||
}
|
||||
}
|
||||
|
||||
if($deliveries)
|
||||
do_delivery($deliveries);
|
||||
|
||||
logger('notifier: basic loop complete.', LOGGER_DEBUG);
|
||||
|
||||
call_hooks('notifier_end',$target_item);
|
||||
|
||||
logger('notifer: complete.');
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
76
Zotlabs/Daemon/Onedirsync.php
Normal file
76
Zotlabs/Daemon/Onedirsync.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/dir_fns.php');
|
||||
|
||||
|
||||
class Onedirsync {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
logger('onedirsync: start ' . intval($argv[1]));
|
||||
|
||||
if(($argc > 1) && (intval($argv[1])))
|
||||
$update_id = intval($argv[1]);
|
||||
|
||||
if(! $update_id) {
|
||||
logger('onedirsync: no update');
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select * from updates where ud_id = %d limit 1",
|
||||
intval($update_id)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
if(($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (! $r[0]['ud_addr']))
|
||||
return;
|
||||
|
||||
// Have we probed this channel more recently than the other directory server
|
||||
// (where we received this update from) ?
|
||||
// If we have, we don't need to do anything except mark any older entries updated
|
||||
|
||||
$x = q("select * from updates where ud_addr = '%s' and ud_date > '%s' and ( ud_flags & %d )>0 order by ud_date desc limit 1",
|
||||
dbesc($r[0]['ud_addr']),
|
||||
dbesc($r[0]['ud_date']),
|
||||
intval(UPDATE_FLAGS_UPDATED)
|
||||
);
|
||||
if($x) {
|
||||
$y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'",
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc($r[0]['ud_addr']),
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc($x[0]['ud_date'])
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore doing an update if this ud_addr refers to a known dead hubloc
|
||||
|
||||
$h = q("select * from hubloc where hubloc_addr = '%s' limit 1",
|
||||
dbesc($r[0]['ud_addr'])
|
||||
);
|
||||
if(($h) && ($h[0]['hubloc_status'] & HUBLOC_OFFLINE)) {
|
||||
$y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ",
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc($r[0]['ud_addr']),
|
||||
intval(UPDATE_FLAGS_UPDATED)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// we might have to pull this out some day, but for now update_directory_entry()
|
||||
// runs zot_finger() and is kind of zot specific
|
||||
|
||||
if($h && $h[0]['hubloc_network'] !== 'zot')
|
||||
return;
|
||||
|
||||
update_directory_entry($r[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
181
Zotlabs/Daemon/Onepoll.php
Normal file
181
Zotlabs/Daemon/Onepoll.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/socgraph.php');
|
||||
|
||||
|
||||
class Onepoll {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
logger('onepoll: start');
|
||||
|
||||
if(($argc > 1) && (intval($argv[1])))
|
||||
$contact_id = intval($argv[1]);
|
||||
|
||||
if(! $contact_id) {
|
||||
logger('onepoll: no contact');
|
||||
return;
|
||||
}
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
$contacts = q("SELECT abook.*, xchan.*, account.*
|
||||
FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan
|
||||
where abook_id = %d
|
||||
and abook_pending = 0 and abook_archived = 0 and abook_blocked = 0 and abook_ignored = 0
|
||||
AND (( account_flags = %d ) OR ( account_flags = %d )) limit 1",
|
||||
intval($contact_id),
|
||||
intval(ACCOUNT_OK),
|
||||
intval(ACCOUNT_UNVERIFIED)
|
||||
);
|
||||
|
||||
if(! $contacts) {
|
||||
logger('onepoll: abook_id not found: ' . $contact_id);
|
||||
return;
|
||||
}
|
||||
|
||||
$contact = $contacts[0];
|
||||
|
||||
$t = $contact['abook_updated'];
|
||||
|
||||
$importer_uid = $contact['abook_channel'];
|
||||
|
||||
$r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
|
||||
intval($importer_uid)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
$importer = $r[0];
|
||||
|
||||
logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}");
|
||||
|
||||
$last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE))
|
||||
? datetime_convert('UTC','UTC','now - 7 days')
|
||||
: datetime_convert('UTC','UTC',$contact['abook_updated'] . ' - 2 days')
|
||||
);
|
||||
|
||||
if($contact['xchan_network'] === 'rss') {
|
||||
logger('onepoll: processing feed ' . $contact['xchan_name'], LOGGER_DEBUG);
|
||||
$alive = handle_feed($importer['channel_id'],$contact_id,$contact['xchan_hash']);
|
||||
if ($alive) {
|
||||
q("update abook set abook_connected = '%s' where abook_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(! in_array($contact['xchan_network'],['zot','zot6']))
|
||||
return;
|
||||
|
||||
// update permissions
|
||||
|
||||
$x = zot_refresh($contact,$importer);
|
||||
|
||||
$responded = false;
|
||||
$updated = datetime_convert();
|
||||
$connected = datetime_convert();
|
||||
if(! $x) {
|
||||
// mark for death by not updating abook_connected, this is caught in include/poller.php
|
||||
q("update abook set abook_updated = '%s' where abook_id = %d",
|
||||
dbesc($updated),
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
q("update abook set abook_updated = '%s', abook_connected = '%s' where abook_id = %d",
|
||||
dbesc($updated),
|
||||
dbesc($connected),
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
$responded = true;
|
||||
}
|
||||
|
||||
if(! $responded)
|
||||
return;
|
||||
|
||||
if($contact['xchan_connurl']) {
|
||||
$fetch_feed = true;
|
||||
$x = null;
|
||||
|
||||
// They haven't given us permission to see their stream
|
||||
|
||||
$can_view_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'their_perms','view_stream'));
|
||||
|
||||
if(! $can_view_stream)
|
||||
$fetch_feed = false;
|
||||
|
||||
// we haven't given them permission to send us their stream
|
||||
|
||||
$can_send_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'my_perms','send_stream'));
|
||||
|
||||
if(! $can_send_stream)
|
||||
$fetch_feed = false;
|
||||
|
||||
if($fetch_feed) {
|
||||
|
||||
if(strpos($contact['xchan_connurl'],z_root()) === 0) {
|
||||
// local channel - save a network fetch
|
||||
$c = channelx_by_hash($contact['xchan_hash']);
|
||||
if($c) {
|
||||
$x = [
|
||||
'success' => true,
|
||||
'body' => json_encode( [
|
||||
'success' => true,
|
||||
'messages' => zot_feed($c['channel_id'], $importer['xchan_hash'], [ 'mindate' => $last_update ])
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// remote fetch
|
||||
|
||||
$feedurl = str_replace('/poco/','/zotfeed/',$contact['xchan_connurl']);
|
||||
$feedurl .= '?f=&mindate=' . urlencode($last_update) . '&zid=' . $importer['channel_address'] . '@' . \App::get_hostname();
|
||||
$recurse = 0;
|
||||
$x = z_fetch_url($feedurl, false, $recurse, [ 'session' => true ]);
|
||||
}
|
||||
|
||||
logger('feed_update: ' . print_r($x,true), LOGGER_DATA);
|
||||
}
|
||||
|
||||
if(($x) && ($x['success'])) {
|
||||
$total = 0;
|
||||
logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl);
|
||||
|
||||
$j = json_decode($x['body'],true);
|
||||
if($j['success'] && $j['messages']) {
|
||||
foreach($j['messages'] as $message) {
|
||||
$results = process_delivery(array('hash' => $contact['xchan_hash']), get_item_elements($message),
|
||||
array(array('hash' => $importer['xchan_hash'])), false);
|
||||
logger('onepoll: feed_update: process_delivery: ' . print_r($results,true), LOGGER_DATA);
|
||||
$total ++;
|
||||
}
|
||||
logger("onepoll: $total messages processed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update the poco details for this connection
|
||||
|
||||
if($contact['xchan_connurl']) {
|
||||
$r = q("SELECT xlink_id from xlink
|
||||
where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1",
|
||||
intval($contact['xchan_hash']),
|
||||
db_utcnow(), db_quoteinterval('1 DAY')
|
||||
);
|
||||
if(! $r) {
|
||||
poco_load($contact['xchan_hash'],$contact['xchan_connurl']);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
207
Zotlabs/Daemon/Poller.php
Normal file
207
Zotlabs/Daemon/Poller.php
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Poller {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
$maxsysload = intval(get_config('system','maxloadavg'));
|
||||
if($maxsysload < 1)
|
||||
$maxsysload = 50;
|
||||
if(function_exists('sys_getloadavg')) {
|
||||
$load = sys_getloadavg();
|
||||
if(intval($load[0]) > $maxsysload) {
|
||||
logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$interval = intval(get_config('system','poll_interval'));
|
||||
if(! $interval)
|
||||
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
|
||||
|
||||
// Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it.
|
||||
$lockfile = 'store/[data]/poller';
|
||||
if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600))
|
||||
&& (! get_config('system','override_poll_lockfile'))) {
|
||||
logger("poller: Already running");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a lockfile. Needs two vars, but $x doesn't need to contain anything.
|
||||
file_put_contents($lockfile, $x);
|
||||
|
||||
logger('poller: start');
|
||||
|
||||
$manual_id = 0;
|
||||
$generation = 0;
|
||||
|
||||
$force = false;
|
||||
$restart = false;
|
||||
|
||||
if(($argc > 1) && ($argv[1] == 'force'))
|
||||
$force = true;
|
||||
|
||||
if(($argc > 1) && ($argv[1] == 'restart')) {
|
||||
$restart = true;
|
||||
$generation = intval($argv[2]);
|
||||
if(! $generation)
|
||||
return;
|
||||
}
|
||||
|
||||
if(($argc > 1) && intval($argv[1])) {
|
||||
$manual_id = intval($argv[1]);
|
||||
$force = true;
|
||||
}
|
||||
|
||||
|
||||
$sql_extra = (($manual_id) ? " AND abook_id = " . intval($manual_id) . " " : "");
|
||||
|
||||
reload_plugins();
|
||||
|
||||
$d = datetime_convert();
|
||||
|
||||
// Only poll from those with suitable relationships
|
||||
|
||||
$abandon_sql = (($abandon_days)
|
||||
? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY'))
|
||||
: ''
|
||||
);
|
||||
|
||||
$randfunc = db_getfunc('RAND');
|
||||
|
||||
$contacts = q("SELECT abook.abook_updated, abook.abook_connected, abook.abook_feed,
|
||||
abook.abook_channel, abook.abook_id, abook.abook_archived, abook.abook_pending,
|
||||
abook.abook_ignored, abook.abook_blocked,
|
||||
xchan.xchan_network,
|
||||
account.account_lastlog, account.account_flags
|
||||
FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash
|
||||
LEFT JOIN account on abook_account = account_id
|
||||
where abook_self = 0
|
||||
$sql_extra
|
||||
AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc",
|
||||
intval(ACCOUNT_OK),
|
||||
intval(ACCOUNT_UNVERIFIED) // FIXME
|
||||
);
|
||||
|
||||
if($contacts) {
|
||||
|
||||
foreach($contacts as $contact) {
|
||||
|
||||
$update = false;
|
||||
|
||||
$t = $contact['abook_updated'];
|
||||
$c = $contact['abook_connected'];
|
||||
|
||||
if(intval($contact['abook_feed'])) {
|
||||
$min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes');
|
||||
if(! $min)
|
||||
$min = intval(get_config('system','minimum_feedcheck_minutes'));
|
||||
if(! $min)
|
||||
$min = 60;
|
||||
$x = datetime_convert('UTC','UTC',"now - $min minutes");
|
||||
if($c < $x) {
|
||||
Master::Summon(array('Onepoll',$contact['abook_id']));
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(! in_array($contact['xchan_network'],['zot','zot6']))
|
||||
continue;
|
||||
|
||||
if($c == $t) {
|
||||
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
|
||||
$update = true;
|
||||
}
|
||||
else {
|
||||
|
||||
// if we've never connected with them, start the mark for death countdown from now
|
||||
|
||||
if($c <= NULL_DATE) {
|
||||
$r = q("update abook set abook_connected = '%s' where abook_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
$c = datetime_convert();
|
||||
$update = true;
|
||||
}
|
||||
|
||||
// He's dead, Jim
|
||||
|
||||
if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) {
|
||||
$r = q("update abook set abook_archived = 1 where abook_id = %d",
|
||||
intval($contact['abook_id'])
|
||||
);
|
||||
$update = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(intval($contact['abook_archived'])) {
|
||||
$update = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// might be dead, so maybe don't poll quite so often
|
||||
|
||||
// recently deceased, so keep up the regular schedule for 3 days
|
||||
|
||||
if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0)
|
||||
&& (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0))
|
||||
$update = true;
|
||||
|
||||
// After that back off and put them on a morphine drip
|
||||
|
||||
if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) {
|
||||
$update = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked']))
|
||||
continue;
|
||||
|
||||
if((! $update) && (! $force))
|
||||
continue;
|
||||
|
||||
Master::Summon(array('Onepoll',$contact['abook_id']));
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
|
||||
$r = q("SELECT u.ud_addr, u.ud_id, u.ud_last FROM updates AS u INNER JOIN (SELECT ud_addr, max(ud_id) AS ud_id FROM updates WHERE ( ud_flags & %d ) = 0 AND ud_addr != '' AND ( ud_last <= '%s' OR ud_last > %s - INTERVAL %s ) GROUP BY ud_addr) AS s ON s.ud_id = u.ud_id ",
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc(NULL_DATE),
|
||||
db_utcnow(), db_quoteinterval('7 DAY')
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
|
||||
// If they didn't respond when we attempted before, back off to once a day
|
||||
// After 7 days we won't bother anymore
|
||||
|
||||
if($rr['ud_last'] > NULL_DATE)
|
||||
if($rr['ud_last'] > datetime_convert('UTC','UTC', 'now - 1 day'))
|
||||
continue;
|
||||
Master::Summon(array('Onedirsync',$rr['ud_id']));
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_config('system','lastpoll',datetime_convert());
|
||||
|
||||
//All done - clear the lockfile
|
||||
|
||||
@unlink($lockfile);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
85
Zotlabs/Daemon/Queue.php
Normal file
85
Zotlabs/Daemon/Queue.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/queue_fn.php');
|
||||
require_once('include/zot.php');
|
||||
|
||||
class Queue {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
require_once('include/items.php');
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
if($argc > 1)
|
||||
$queue_id = $argv[1];
|
||||
else
|
||||
$queue_id = EMPTY_STR;
|
||||
|
||||
logger('queue: start');
|
||||
|
||||
// delete all queue items more than 3 days old
|
||||
// but first mark these sites dead if we haven't heard from them in a month
|
||||
|
||||
$r = q("select outq_posturl from outq where outq_created < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('3 DAY')
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$site_url = '';
|
||||
$h = parse_url($rr['outq_posturl']);
|
||||
$desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
|
||||
q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s",
|
||||
dbesc($desturl),
|
||||
db_utcnow(), db_quoteinterval('1 MONTH')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("DELETE FROM outq WHERE outq_created < %s - INTERVAL %s",
|
||||
db_utcnow(), db_quoteinterval('3 DAY')
|
||||
);
|
||||
|
||||
if($queue_id) {
|
||||
$r = q("SELECT * FROM outq WHERE outq_hash = '%s' LIMIT 1",
|
||||
dbesc($queue_id)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
// For the first 12 hours we'll try to deliver every 15 minutes
|
||||
// After that, we'll only attempt delivery once per hour.
|
||||
// This currently only handles the default queue drivers ('zot' or '') which we will group by posturl
|
||||
// so that we don't start off a thousand deliveries for a couple of dead hubs.
|
||||
// The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made).
|
||||
// Other drivers will have to do something different here and may need their own query.
|
||||
|
||||
// Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the
|
||||
// "every 15 minutes" category. We probably need to prioritise them when inserted into the queue
|
||||
// or just prior to this query based on recent and long-term delivery history. If we have good reason to believe
|
||||
// the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once
|
||||
// or twice a day.
|
||||
|
||||
$sqlrandfunc = db_getfunc('rand');
|
||||
|
||||
$r = q("SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1",
|
||||
db_utcnow()
|
||||
);
|
||||
while ($r) {
|
||||
foreach($r as $rv) {
|
||||
queue_deliver($rv);
|
||||
}
|
||||
$r = q("SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1",
|
||||
db_utcnow()
|
||||
);
|
||||
}
|
||||
}
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
foreach($r as $rv) {
|
||||
queue_deliver($rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Zotlabs/Daemon/README.md
Normal file
43
Zotlabs/Daemon/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
Daemon (background) Processes
|
||||
=============================
|
||||
|
||||
|
||||
This directory provides background tasks which are executed by a
|
||||
command-line process and detached from normal web processing.
|
||||
|
||||
Background tasks are invoked by calling
|
||||
|
||||
|
||||
Zotlabs\Daemon\Master::Summon([ $cmd, $arg1, $argn... ]);
|
||||
|
||||
The Master class loads the desired command file and passes the arguments.
|
||||
|
||||
|
||||
To create a background task 'Foo' use the following template.
|
||||
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
class Foo {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
The Master class "summons" the command by creating an executable script
|
||||
from the provided arguments, then it invokes "Release" to execute the script
|
||||
detached from web processing. This process calls the static::run() function
|
||||
with any command line arguments using the traditional argc, argv format.
|
||||
|
||||
Please note: These are *real* $argc, $argv variables passed from the command
|
||||
line, and not the parsed argc() and argv() functions/variables which were
|
||||
obtained from parsing path components of the request URL by web processes.
|
||||
|
||||
Background processes do not emit displayable output except through logs. They
|
||||
should also not make any assumptions about their HTML and web environment
|
||||
(as they do not have a web environment), particularly with respect to global
|
||||
variables such as $_SERVER, $_REQUEST, $_GET, $_POST, $_COOKIES, and $_SESSION.
|
||||
|
||||
121
Zotlabs/Daemon/Ratenotif.php
Normal file
121
Zotlabs/Daemon/Ratenotif.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/queue_fn.php');
|
||||
|
||||
|
||||
class Ratenotif {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
require_once("datetime.php");
|
||||
require_once('include/items.php');
|
||||
|
||||
if($argc < 3)
|
||||
return;
|
||||
|
||||
|
||||
logger('ratenotif: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
|
||||
|
||||
$cmd = $argv[1];
|
||||
|
||||
$item_id = $argv[2];
|
||||
|
||||
|
||||
if($cmd === 'rating') {
|
||||
$r = q("select * from xlink where xlink_id = %d and xlink_static = 1 limit 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if(! $r) {
|
||||
logger('rating not found');
|
||||
return;
|
||||
}
|
||||
|
||||
$encoded_item = array(
|
||||
'type' => 'rating',
|
||||
'encoding' => 'zot',
|
||||
'target' => $r[0]['xlink_link'],
|
||||
'rating' => intval($r[0]['xlink_rating']),
|
||||
'rating_text' => $r[0]['xlink_rating_text'],
|
||||
'signature' => $r[0]['xlink_sig'],
|
||||
'edited' => $r[0]['xlink_updated']
|
||||
);
|
||||
}
|
||||
|
||||
$channel = channelx_by_hash($r[0]['xlink_xchan']);
|
||||
if(! $channel) {
|
||||
logger('no channel');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$primary = get_directory_primary();
|
||||
|
||||
if(! $primary)
|
||||
return;
|
||||
|
||||
|
||||
$interval = ((get_config('system','delivery_interval') !== false)
|
||||
? intval(get_config('system','delivery_interval')) : 2 );
|
||||
|
||||
$deliveries_per_process = intval(get_config('system','delivery_batch_count'));
|
||||
|
||||
if($deliveries_per_process <= 0)
|
||||
$deliveries_per_process = 1;
|
||||
|
||||
$deliver = array();
|
||||
|
||||
$x = z_fetch_url($primary . '/regdir');
|
||||
if($x['success']) {
|
||||
$j = json_decode($x['body'],true);
|
||||
if($j && $j['success'] && is_array($j['directories'])) {
|
||||
|
||||
foreach($j['directories'] as $h) {
|
||||
if($h == z_root())
|
||||
continue;
|
||||
|
||||
$hash = random_string();
|
||||
$n = zot_build_packet($channel,'notify',null,null,'',$hash);
|
||||
|
||||
queue_insert(array(
|
||||
'hash' => $hash,
|
||||
'account_id' => $channel['channel_account_id'],
|
||||
'channel_id' => $channel['channel_id'],
|
||||
'posturl' => $h . '/post',
|
||||
'notify' => $n,
|
||||
'msg' => json_encode($encoded_item)
|
||||
));
|
||||
|
||||
|
||||
$x = q("select count(outq_hash) as total from outq where outq_delivered = 0");
|
||||
if(intval($x[0]['total']) > intval(get_config('system','force_queue_threshold',300))) {
|
||||
logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO);
|
||||
update_queue_item($hash);
|
||||
continue;
|
||||
}
|
||||
|
||||
$deliver[] = $hash;
|
||||
|
||||
if(count($deliver) >= $deliveries_per_process) {
|
||||
Master::Summon(array('Deliver',$deliver));
|
||||
$deliver = array();
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
}
|
||||
|
||||
// catch any stragglers
|
||||
|
||||
if(count($deliver)) {
|
||||
Master::Summon(array('Deliver',$deliver));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger('ratenotif: complete.');
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
78
Zotlabs/Daemon/Thumbnail.php
Normal file
78
Zotlabs/Daemon/Thumbnail.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
|
||||
class Thumbnail {
|
||||
|
||||
static public function run($argc,$argv) {
|
||||
|
||||
if(! $argc == 2)
|
||||
return;
|
||||
|
||||
$c = q("select * from attach where hash = '%s' ",
|
||||
dbesc($argv[1])
|
||||
);
|
||||
|
||||
if(! $c)
|
||||
return;
|
||||
|
||||
$attach = $c[0];
|
||||
|
||||
$preview_style = intval(get_config('system','thumbnail_security',0));
|
||||
$preview_width = intval(get_config('system','thumbnail_width',300));
|
||||
$preview_height = intval(get_config('system','thumbnail_height',300));
|
||||
|
||||
$p = [
|
||||
'attach' => $attach,
|
||||
'preview_style' => $preview_style,
|
||||
'preview_width' => $preview_width,
|
||||
'preview_height' => $preview_height,
|
||||
'thumbnail' => null
|
||||
];
|
||||
|
||||
/**
|
||||
* @hooks thumbnail
|
||||
* * \e array \b attach
|
||||
* * \e int \b preview_style
|
||||
* * \e int \b preview_width
|
||||
* * \e int \b preview_height
|
||||
* * \e string \b thumbnail
|
||||
*/
|
||||
|
||||
call_hooks('thumbnail',$p);
|
||||
if($p['thumbnail']) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$default_controller = null;
|
||||
|
||||
$files = glob('Zotlabs/Thumbs/*.php');
|
||||
if($files) {
|
||||
foreach($files as $f) {
|
||||
$clsname = '\\Zotlabs\\Thumbs\\' . ucfirst(basename($f,'.php'));
|
||||
if(class_exists($clsname)) {
|
||||
$x = new $clsname();
|
||||
if(method_exists($x,'Match')) {
|
||||
$matched = $x->Match($attach['filetype']);
|
||||
if($matched) {
|
||||
$x->Thumb($attach,$preview_style,$preview_width,$preview_height);
|
||||
}
|
||||
}
|
||||
if(method_exists($x,'MatchDefault')) {
|
||||
$default_matched = $x->MatchDefault(substr($attach['filetype'],0,strpos($attach['filetype'],'/')));
|
||||
if($default_matched) {
|
||||
$default_controller = $x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(($default_controller)
|
||||
&& ((! file_exists(dbunescbin($attach['content']) . '.thumb'))
|
||||
|| (filectime(dbunescbin($attach['content']) . 'thumb') < (time() - 60)))) {
|
||||
$default_controller->Thumb($attach,$preview_style,$preview_width,$preview_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Zotlabs/Extend/Hook.php
Normal file
122
Zotlabs/Extend/Hook.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Extend;
|
||||
|
||||
use App;
|
||||
|
||||
/**
|
||||
* @brief Hook class.
|
||||
*
|
||||
*/
|
||||
class Hook {
|
||||
|
||||
static public function register($hook,$file,$function,$version = 1,$priority = 0) {
|
||||
if(is_array($function)) {
|
||||
$function = serialize($function);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' and priority = %d and hook_version = %d LIMIT 1",
|
||||
dbesc($hook),
|
||||
dbesc($file),
|
||||
dbesc($function),
|
||||
intval($priority),
|
||||
intval($version)
|
||||
);
|
||||
if($r)
|
||||
return true;
|
||||
|
||||
// To aid in upgrade and transition, remove old settings for any registered hooks that match in all respects except
|
||||
// for priority or hook_version
|
||||
|
||||
$r = q("DELETE FROM hook where hook = '%s' and file = '%s' and fn = '%s'",
|
||||
dbesc($hook),
|
||||
dbesc($file),
|
||||
dbesc($function)
|
||||
);
|
||||
|
||||
$r = q("INSERT INTO hook (hook, file, fn, priority, hook_version) VALUES ( '%s', '%s', '%s', %d, %d )",
|
||||
dbesc($hook),
|
||||
dbesc($file),
|
||||
dbesc($function),
|
||||
intval($priority),
|
||||
intval($version)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
static public function register_array($file,$arr) {
|
||||
if($arr) {
|
||||
foreach($arr as $k => $v) {
|
||||
self::register($k,$file,$v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public function unregister($hook,$file,$function,$version = 1,$priority = 0) {
|
||||
if(is_array($function)) {
|
||||
$function = serialize($function);
|
||||
}
|
||||
$r = q("DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' and priority = %d and hook_version = %d",
|
||||
dbesc($hook),
|
||||
dbesc($file),
|
||||
dbesc($function),
|
||||
intval($priority),
|
||||
intval($version)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister all hooks with this file component.
|
||||
*
|
||||
* Useful for addon upgrades where you want to clean out old interfaces.
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
static public function unregister_by_file($file) {
|
||||
$r = q("DELETE FROM hook WHERE file = '%s' ",
|
||||
dbesc($file)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts a hook into a page request.
|
||||
*
|
||||
* Insert a short-lived hook into the running page request.
|
||||
* Hooks are normally persistent so that they can be called
|
||||
* across asynchronous processes such as delivery and poll
|
||||
* processes.
|
||||
*
|
||||
* insert_hook lets you attach a hook callback immediately
|
||||
* which will not persist beyond the life of this page request
|
||||
* or the current process.
|
||||
*
|
||||
* @param string $hook
|
||||
* name of hook to attach callback
|
||||
* @param string $fn
|
||||
* function name of callback handler
|
||||
* @param int $version
|
||||
* hook interface version, 0 uses two callback params, 1 uses one callback param
|
||||
* @param int $priority
|
||||
* currently not implemented in this function, would require the hook array to be resorted
|
||||
*/
|
||||
static public function insert($hook, $fn, $version = 0, $priority = 0) {
|
||||
if(is_array($fn)) {
|
||||
$fn = serialize($fn);
|
||||
}
|
||||
|
||||
if(! is_array(App::$hooks))
|
||||
App::$hooks = array();
|
||||
|
||||
if(! array_key_exists($hook, App::$hooks))
|
||||
App::$hooks[$hook] = array();
|
||||
|
||||
App::$hooks[$hook][] = array('', $fn, $priority, $version);
|
||||
}
|
||||
|
||||
}
|
||||
48
Zotlabs/Extend/Route.php
Normal file
48
Zotlabs/Extend/Route.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Extend;
|
||||
|
||||
|
||||
class Route {
|
||||
|
||||
static function register($file,$modname) {
|
||||
$rt = self::get();
|
||||
$rt[] = [ $file, $modname ];
|
||||
self::set($rt);
|
||||
}
|
||||
|
||||
static function unregister($file,$modname) {
|
||||
$rt = self::get();
|
||||
if($rt) {
|
||||
$n = [];
|
||||
foreach($rt as $r) {
|
||||
if($r[0] !== $file && $r[1] !== $modname) {
|
||||
$n[] = $r;
|
||||
}
|
||||
}
|
||||
self::set($n);
|
||||
}
|
||||
}
|
||||
|
||||
static function unregister_by_file($file) {
|
||||
$rt = self::get();
|
||||
if($rt) {
|
||||
$n = [];
|
||||
foreach($rt as $r) {
|
||||
if($r[0] !== $file) {
|
||||
$n[] = $r;
|
||||
}
|
||||
}
|
||||
self::set($n);
|
||||
}
|
||||
}
|
||||
|
||||
static function get() {
|
||||
return get_config('system','routes',[]);
|
||||
}
|
||||
|
||||
static function set($r) {
|
||||
return set_config('system','routes',$r);
|
||||
}
|
||||
}
|
||||
|
||||
47
Zotlabs/Extend/Widget.php
Normal file
47
Zotlabs/Extend/Widget.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Extend;
|
||||
|
||||
|
||||
class Widget {
|
||||
|
||||
static function register($file,$widget) {
|
||||
$rt = self::get();
|
||||
$rt[] = [ $file, $widget ];
|
||||
self::set($rt);
|
||||
}
|
||||
|
||||
static function unregister($file,$widget) {
|
||||
$rt = self::get();
|
||||
if($rt) {
|
||||
$n = [];
|
||||
foreach($rt as $r) {
|
||||
if($r[0] !== $file && $r[1] !== $widget) {
|
||||
$n[] = $r;
|
||||
}
|
||||
}
|
||||
self::set($n);
|
||||
}
|
||||
}
|
||||
|
||||
static function unregister_by_file($file) {
|
||||
$rt = self::get();
|
||||
if($rt) {
|
||||
$n = [];
|
||||
foreach($rt as $r) {
|
||||
if($r[0] !== $file) {
|
||||
$n[] = $r;
|
||||
}
|
||||
}
|
||||
self::set($n);
|
||||
}
|
||||
}
|
||||
|
||||
static function get() {
|
||||
return get_config('system','widgets',[]);
|
||||
}
|
||||
|
||||
static function set($r) {
|
||||
return set_config('system','widgets',$r);
|
||||
}
|
||||
}
|
||||
18
Zotlabs/Identity/BasicId.php
Normal file
18
Zotlabs/Identity/BasicId.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Identity\BasicId;
|
||||
|
||||
class BasicId {
|
||||
|
||||
private $name;
|
||||
private $profile_photo;
|
||||
private $profile_url;
|
||||
private $address;
|
||||
private $protocol;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
35
Zotlabs/Identity/OAuth2Server.php
Normal file
35
Zotlabs/Identity/OAuth2Server.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Identity;
|
||||
|
||||
class OAuth2Server extends \OAuth2\Server {
|
||||
|
||||
public function __construct(OAuth2Storage $storage, $config = null) {
|
||||
|
||||
if(! is_array($config)) {
|
||||
$config = [
|
||||
'use_openid_connect' => true,
|
||||
'issuer' => \Zotlabs\Lib\System::get_site_name()
|
||||
];
|
||||
}
|
||||
|
||||
parent::__construct($storage, $config);
|
||||
|
||||
// Add the "Client Credentials" grant type (it is the simplest of the grant types)
|
||||
$this->addGrantType(new \OAuth2\GrantType\ClientCredentials($storage));
|
||||
|
||||
// Add the "Authorization Code" grant type (this is where the oauth magic happens)
|
||||
// Need to use OpenID\GrantType to return id_token (see:https://github.com/bshaffer/oauth2-server-php/issues/443)
|
||||
$this->addGrantType(new \OAuth2\OpenID\GrantType\AuthorizationCode($storage));
|
||||
|
||||
$keyStorage = new \OAuth2\Storage\Memory( [
|
||||
'keys' => [
|
||||
'public_key' => get_config('system', 'pubkey'),
|
||||
'private_key' => get_config('system', 'prvkey')
|
||||
]
|
||||
]);
|
||||
|
||||
$this->addStorage($keyStorage, 'public_key');
|
||||
}
|
||||
|
||||
}
|
||||
139
Zotlabs/Identity/OAuth2Storage.php
Normal file
139
Zotlabs/Identity/OAuth2Storage.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Identity;
|
||||
|
||||
|
||||
class OAuth2Storage extends \OAuth2\Storage\Pdo {
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
public function checkUserCredentials($username, $password)
|
||||
{
|
||||
if ($user = $this->getUser($username)) {
|
||||
return $this->checkPassword($user, $password);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getUserDetails($username)
|
||||
{
|
||||
return $this->getUser($username);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $user
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkPassword($user, $password)
|
||||
{
|
||||
|
||||
$x = account_verify_password($user,$password);
|
||||
return((array_key_exists('channel',$x) && ! empty($x['channel'])) ? true : false);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getUser($username)
|
||||
{
|
||||
|
||||
$x = channelx_by_n($username);
|
||||
if(! $x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$a = q("select * from account where account_id = %d",
|
||||
intval($x['channel_account_id'])
|
||||
);
|
||||
|
||||
$n = explode(' ', $x['channel_name']);
|
||||
|
||||
return( [
|
||||
'webfinger' => channel_reddress($x),
|
||||
'portable_id' => $x['channel_hash'],
|
||||
'email' => $a[0]['account_email'],
|
||||
'username' => $x['channel_address'],
|
||||
'user_id' => $x['channel_id'],
|
||||
'name' => $x['channel_name'],
|
||||
'firstName' => ((count($n) > 1) ? $n[1] : $n[0]),
|
||||
'lastName' => ((count($n) > 2) ? $n[count($n) - 1] : ''),
|
||||
'picture' => $x['xchan_photo_l']
|
||||
] );
|
||||
}
|
||||
|
||||
public function scopeExists($scope) {
|
||||
// Report that the scope is valid even if it's not.
|
||||
// We will only return a very small subset no matter what.
|
||||
// @TODO: Truly validate the scope
|
||||
// see vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php and
|
||||
// vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php
|
||||
// for more info.
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDefaultScope($client_id=null) {
|
||||
// Do not REQUIRE a scope
|
||||
// see vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php and
|
||||
// for more info.
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getUserClaims ($user_id, $claims) {
|
||||
// Populate the CLAIMS requested (if any).
|
||||
// @TODO: create a more reasonable/comprehensive list.
|
||||
// @TODO: present claims on the AUTHORIZATION screen
|
||||
|
||||
$userClaims = Array();
|
||||
$claims = explode (' ', trim($claims));
|
||||
$validclaims = Array ("name","preferred_username","webfinger","portable_id","email","picture","firstName","lastName");
|
||||
$claimsmap = Array (
|
||||
"webfinger" => 'webfinger',
|
||||
"portable_id" => 'portable_id',
|
||||
"name" => 'name',
|
||||
"email" => 'email',
|
||||
"preferred_username" => 'username',
|
||||
"picture" => 'picture',
|
||||
"given_name" => 'firstName',
|
||||
"family_name" => 'lastName'
|
||||
);
|
||||
$userinfo = $this->getUser($user_id);
|
||||
foreach ($validclaims as $validclaim) {
|
||||
if (in_array($validclaim,$claims)) {
|
||||
$claimkey = $claimsmap[$validclaim];
|
||||
$userClaims[$validclaim] = $userinfo[$claimkey];
|
||||
} else {
|
||||
$userClaims[$validclaim] = $validclaim;
|
||||
}
|
||||
}
|
||||
$userClaims["sub"]=$user_id;
|
||||
return $userClaims;
|
||||
}
|
||||
|
||||
/**
|
||||
* plaintext passwords are bad! Override this for your application
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $firstName
|
||||
* @param string $lastName
|
||||
* @return bool
|
||||
*/
|
||||
public function setUser($username, $password, $firstName = null, $lastName = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
16
Zotlabs/Identity/ProfilePhoto.php
Normal file
16
Zotlabs/Identity/ProfilePhoto.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace Zotlabs\Identity\ProfilePhoto;
|
||||
|
||||
class ProfilePhoto {
|
||||
|
||||
private $photo_large_url;
|
||||
private $photo_medium_url;
|
||||
private $photo_small_url;
|
||||
private $photo_mimetype;
|
||||
private $photo_updated;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
25
Zotlabs/Lib/AConfig.php
Normal file
25
Zotlabs/Lib/AConfig.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
// account configuration storage is built on top of the under-utilised xconfig
|
||||
|
||||
class AConfig {
|
||||
|
||||
static public function Load($account_id) {
|
||||
return XConfig::Load('a_' . $account_id);
|
||||
}
|
||||
|
||||
static public function Get($account_id,$family,$key,$default = false) {
|
||||
return XConfig::Get('a_' . $account_id,$family,$key, $default);
|
||||
}
|
||||
|
||||
static public function Set($account_id,$family,$key,$value) {
|
||||
return XConfig::Set('a_' . $account_id,$family,$key,$value);
|
||||
}
|
||||
|
||||
static public function Delete($account_id,$family,$key) {
|
||||
return XConfig::Delete('a_' . $account_id,$family,$key);
|
||||
}
|
||||
|
||||
}
|
||||
75
Zotlabs/Lib/AbConfig.php
Normal file
75
Zotlabs/Lib/AbConfig.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class AbConfig {
|
||||
|
||||
static public function Load($chan,$xhash,$family = '') {
|
||||
if($family)
|
||||
$where = sprintf(" and cat = '%s' ",dbesc($family));
|
||||
$r = q("select * from abconfig where chan = %d and xchan = '%s' $where",
|
||||
intval($chan),
|
||||
dbesc($xhash)
|
||||
);
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
static public function Get($chan,$xhash,$family,$key, $default = false) {
|
||||
$r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
|
||||
intval($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
if($r) {
|
||||
return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
static public function Set($chan,$xhash,$family,$key,$value) {
|
||||
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
if(self::Get($chan,$xhash,$family,$key) === false) {
|
||||
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( %d, '%s', '%s', '%s', '%s' ) ",
|
||||
intval($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("update abconfig set v = '%s' where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||
dbesc($dbvalue),
|
||||
dbesc($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
}
|
||||
|
||||
if($r)
|
||||
return $value;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static public function Delete($chan,$xhash,$family,$key) {
|
||||
|
||||
$r = q("delete from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||
intval($chan),
|
||||
dbesc($xhash),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
2668
Zotlabs/Lib/Activity.php
Normal file
2668
Zotlabs/Lib/Activity.php
Normal file
File diff suppressed because it is too large
Load Diff
408
Zotlabs/Lib/ActivityStreams.php
Normal file
408
Zotlabs/Lib/ActivityStreams.php
Normal file
@@ -0,0 +1,408 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief ActivityStreams class.
|
||||
*
|
||||
* Parses an ActivityStream JSON string.
|
||||
*/
|
||||
|
||||
class ActivityStreams {
|
||||
|
||||
public $raw = null;
|
||||
public $data = null;
|
||||
public $valid = false;
|
||||
public $deleted = false;
|
||||
public $id = '';
|
||||
public $parent_id = '';
|
||||
public $type = '';
|
||||
public $actor = null;
|
||||
public $obj = null;
|
||||
public $tgt = null;
|
||||
public $origin = null;
|
||||
public $owner = null;
|
||||
public $signer = null;
|
||||
public $ldsig = null;
|
||||
public $sigok = false;
|
||||
public $recips = null;
|
||||
public $raw_recips = null;
|
||||
|
||||
/**
|
||||
* @brief Constructor for ActivityStreams.
|
||||
*
|
||||
* Takes a JSON string as parameter, decodes it and sets up this object.
|
||||
*
|
||||
* @param string $string
|
||||
*/
|
||||
function __construct($string) {
|
||||
|
||||
$this->raw = $string;
|
||||
|
||||
if(is_array($string)) {
|
||||
$this->data = $string;
|
||||
}
|
||||
else {
|
||||
$this->data = json_decode($string, true);
|
||||
}
|
||||
|
||||
if($this->data) {
|
||||
|
||||
// verify and unpack JSalmon signature if present
|
||||
|
||||
if(is_array($this->data) && array_key_exists('signed',$this->data)) {
|
||||
$ret = JSalmon::verify($this->data);
|
||||
$tmp = JSalmon::unpack($this->data['data']);
|
||||
if($ret && $ret['success']) {
|
||||
if($ret['signer']) {
|
||||
$saved = json_encode($this->data,JSON_UNESCAPED_SLASHES);
|
||||
$this->data = $tmp;
|
||||
$this->data['signer'] = $ret['signer'];
|
||||
$this->data['signed_data'] = $saved;
|
||||
if($ret['hubloc']) {
|
||||
$this->data['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->valid = true;
|
||||
|
||||
if(array_key_exists('type',$this->data) && array_key_exists('actor',$this->data) && array_key_exists('object',$this->data)) {
|
||||
if($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
|
||||
$this->deleted = $this->data['actor'];
|
||||
$this->valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($this->is_valid()) {
|
||||
$this->id = $this->get_property_obj('id');
|
||||
$this->type = $this->get_primary_type();
|
||||
$this->actor = $this->get_actor('actor','','');
|
||||
$this->obj = $this->get_compound_property('object');
|
||||
$this->tgt = $this->get_compound_property('target');
|
||||
$this->origin = $this->get_compound_property('origin');
|
||||
$this->recips = $this->collect_recips();
|
||||
|
||||
$this->ldsig = $this->get_compound_property('signature');
|
||||
if($this->ldsig) {
|
||||
$this->signer = $this->get_compound_property('creator',$this->ldsig);
|
||||
if($this->signer && is_array($this->signer) && array_key_exists('publicKey',$this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
|
||||
$this->sigok = LDSignatures::verify($this->data,$this->signer['publicKey']['publicKeyPem']);
|
||||
}
|
||||
}
|
||||
|
||||
if(! $this->obj) {
|
||||
$this->obj = $this->data;
|
||||
$this->type = 'Create';
|
||||
if(! $this->actor) {
|
||||
$this->actor = $this->get_actor('attributedTo',$this->obj);
|
||||
}
|
||||
}
|
||||
|
||||
if($this->obj && is_array($this->obj) && $this->obj['actor'])
|
||||
$this->obj['actor'] = $this->get_actor('actor',$this->obj);
|
||||
if($this->tgt && is_array($this->tgt) && $this->tgt['actor'])
|
||||
$this->tgt['actor'] = $this->get_actor('actor',$this->tgt);
|
||||
|
||||
$this->parent_id = $this->get_property_obj('inReplyTo');
|
||||
|
||||
if((! $this->parent_id) && is_array($this->obj)) {
|
||||
$this->parent_id = $this->obj['inReplyTo'];
|
||||
}
|
||||
if((! $this->parent_id) && is_array($this->obj)) {
|
||||
$this->parent_id = $this->obj['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return if instantiated ActivityStream is valid.
|
||||
*
|
||||
* @return boolean Return true if the JSON string could be decoded.
|
||||
*/
|
||||
function is_valid() {
|
||||
return $this->valid;
|
||||
}
|
||||
|
||||
function set_recips($arr) {
|
||||
$this->saved_recips = $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Collects all recipients.
|
||||
*
|
||||
* @param string $base
|
||||
* @param string $namespace (optional) default empty
|
||||
* @return array
|
||||
*/
|
||||
function collect_recips($base = '', $namespace = '') {
|
||||
$x = [];
|
||||
$fields = [ 'to', 'cc', 'bto', 'bcc', 'audience'];
|
||||
foreach($fields as $f) {
|
||||
$y = $this->get_compound_property($f, $base, $namespace);
|
||||
if($y) {
|
||||
$x = array_merge($x, $y);
|
||||
if(! is_array($this->raw_recips))
|
||||
$this->raw_recips = [];
|
||||
|
||||
$this->raw_recips[$f] = $x;
|
||||
}
|
||||
}
|
||||
// not yet ready for prime time
|
||||
// $x = $this->expand($x,$base,$namespace);
|
||||
return $x;
|
||||
}
|
||||
|
||||
function expand($arr,$base = '',$namespace = '') {
|
||||
$ret = [];
|
||||
|
||||
// right now use a hardwired recursion depth of 5
|
||||
|
||||
for($z = 0; $z < 5; $z ++) {
|
||||
if(is_array($arr) && $arr) {
|
||||
foreach($arr as $a) {
|
||||
if(is_array($a)) {
|
||||
$ret[] = $a;
|
||||
}
|
||||
else {
|
||||
$x = $this->get_compound_property($a,$base,$namespace);
|
||||
if($x) {
|
||||
$ret = array_merge($ret,$x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @fixme de-duplicate
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param array $base
|
||||
* @param string $namespace if not set return empty string
|
||||
* @return string|NULL
|
||||
*/
|
||||
function get_namespace($base, $namespace) {
|
||||
|
||||
if(! $namespace)
|
||||
return '';
|
||||
|
||||
$key = null;
|
||||
|
||||
foreach( [ $this->data, $base ] as $b ) {
|
||||
if(! $b)
|
||||
continue;
|
||||
|
||||
if(array_key_exists('@context', $b)) {
|
||||
if(is_array($b['@context'])) {
|
||||
foreach($b['@context'] as $ns) {
|
||||
if(is_array($ns)) {
|
||||
foreach($ns as $k => $v) {
|
||||
if($namespace === $v)
|
||||
$key = $k;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($namespace === $ns) {
|
||||
$key = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($namespace === $b['@context']) {
|
||||
$key = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $property
|
||||
* @param array $base (optional)
|
||||
* @param string $namespace (optional) default empty
|
||||
* @return NULL|mixed
|
||||
*/
|
||||
function get_property_obj($property, $base = '', $namespace = '') {
|
||||
$prefix = $this->get_namespace($base, $namespace);
|
||||
if($prefix === null)
|
||||
return null;
|
||||
|
||||
$base = (($base) ? $base : $this->data);
|
||||
$propname = (($prefix) ? $prefix . ':' : '') . $property;
|
||||
|
||||
if(! is_array($base)) {
|
||||
btlogger('not an array: ' . print_r($base,true));
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((array_key_exists($propname, $base)) ? $base[$propname] : null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Fetches a property from an URL.
|
||||
*
|
||||
* @param string $url
|
||||
* @return NULL|mixed
|
||||
*/
|
||||
|
||||
function fetch_property($url) {
|
||||
return self::fetch($url);
|
||||
}
|
||||
|
||||
static function fetch($url,$channel = null) {
|
||||
return Activity::fetch($url,$channel);
|
||||
}
|
||||
|
||||
static function is_an_actor($s) {
|
||||
return(in_array($s,[ 'Application','Group','Organization','Person','Service' ]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $property
|
||||
* @param array $base
|
||||
* @param string $namespace (optional) default empty
|
||||
* @return NULL|mixed
|
||||
*/
|
||||
|
||||
function get_actor($property,$base='',$namespace = '') {
|
||||
$x = $this->get_property_obj($property, $base, $namespace);
|
||||
if($this->is_url($x)) {
|
||||
|
||||
// SECURITY: If we have already stored the actor profile, re-generate it
|
||||
// from cached data - don't refetch it from the network
|
||||
|
||||
$r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1",
|
||||
dbesc($x)
|
||||
);
|
||||
if($r) {
|
||||
$y = Activity::encode_person($r[0]);
|
||||
$y['cached'] = true;
|
||||
return $y;
|
||||
}
|
||||
}
|
||||
$actor = $this->get_compound_property($property,$base,$namespace,true);
|
||||
if(is_array($actor) && self::is_an_actor($actor['type'])) {
|
||||
if(array_key_exists('id',$actor) && (! array_key_exists('inbox',$actor))) {
|
||||
$actor = $this->fetch_property($actor['id']);
|
||||
}
|
||||
return $actor;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $property
|
||||
* @param array $base
|
||||
* @param string $namespace (optional) default empty
|
||||
* @param boolean $first (optional) default false, if true and result is a sequential array return only the first element
|
||||
* @return NULL|mixed
|
||||
*/
|
||||
function get_compound_property($property, $base = '', $namespace = '', $first = false) {
|
||||
$x = $this->get_property_obj($property, $base, $namespace);
|
||||
if($this->is_url($x)) {
|
||||
$y = $this->fetch_property($x);
|
||||
if (is_array($y)) {
|
||||
$x = $y;
|
||||
}
|
||||
}
|
||||
|
||||
// verify and unpack JSalmon signature if present
|
||||
|
||||
if(is_array($x) && array_key_exists('signed',$x)) {
|
||||
$ret = JSalmon::verify($x);
|
||||
$tmp = JSalmon::unpack($x['data']);
|
||||
if($ret && $ret['success']) {
|
||||
if($ret['signer']) {
|
||||
$saved = json_encode($x,JSON_UNESCAPED_SLASHES);
|
||||
$x = $tmp;
|
||||
$x['signer'] = $ret['signer'];
|
||||
$x['signed_data'] = $saved;
|
||||
if($ret['hubloc']) {
|
||||
$x['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($first && is_array($x) && array_key_exists(0,$x)) {
|
||||
return $x[0];
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if string starts with http.
|
||||
*
|
||||
* @param string $url
|
||||
* @return boolean
|
||||
*/
|
||||
function is_url($url) {
|
||||
if(($url) && (! is_array($url)) && (strpos($url, 'http') === 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the type property.
|
||||
*
|
||||
* @param array $base
|
||||
* @param string $namespace (optional) default empty
|
||||
* @return NULL|mixed
|
||||
*/
|
||||
function get_primary_type($base = '', $namespace = '') {
|
||||
if(! $base)
|
||||
$base = $this->data;
|
||||
|
||||
$x = $this->get_property_obj('type', $base, $namespace);
|
||||
if(is_array($x)) {
|
||||
foreach($x as $y) {
|
||||
if(strpos($y, ':') === false) {
|
||||
return $y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
function debug() {
|
||||
$x = var_export($this, true);
|
||||
return $x;
|
||||
}
|
||||
|
||||
|
||||
static function is_as_request() {
|
||||
|
||||
$x = getBestSupportedMimeType([
|
||||
'application/ld+json;profile="https://www.w3.org/ns/activitystreams"',
|
||||
'application/activity+json',
|
||||
'application/ld+json;profile="http://www.w3.org/ns/activitystreams"'
|
||||
]);
|
||||
|
||||
return(($x) ? true : false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
32
Zotlabs/Lib/Api_router.php
Normal file
32
Zotlabs/Lib/Api_router.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class Api_router {
|
||||
|
||||
static private $routes = array();
|
||||
|
||||
static function register($path,$fn,$auth_required) {
|
||||
self::$routes[$path] = [ 'func' => $fn, 'auth' => $auth_required ];
|
||||
}
|
||||
|
||||
static function find($path) {
|
||||
if (array_key_exists($path,self::$routes)) {
|
||||
return self::$routes[$path];
|
||||
}
|
||||
|
||||
$with_params = dirname($path) . '/[id]';
|
||||
|
||||
if (array_key_exists($with_params,self::$routes)) {
|
||||
return self::$routes[$with_params];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static function dbg() {
|
||||
return self::$routes;
|
||||
}
|
||||
|
||||
}
|
||||
1361
Zotlabs/Lib/Apps.php
Normal file
1361
Zotlabs/Lib/Apps.php
Normal file
File diff suppressed because it is too large
Load Diff
46
Zotlabs/Lib/Cache.php
Normal file
46
Zotlabs/Lib/Cache.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* cache api
|
||||
*/
|
||||
|
||||
class Cache {
|
||||
public static function get($key) {
|
||||
|
||||
$hash = hash('whirlpool',$key);
|
||||
|
||||
$r = q("SELECT v FROM cache WHERE k = '%s' AND updated > %s - INTERVAL %s LIMIT 1",
|
||||
dbesc($hash),
|
||||
db_utcnow(),
|
||||
db_quoteinterval(get_config('system','object_cache_days', '30') . ' DAY')
|
||||
);
|
||||
|
||||
if ($r)
|
||||
return $r[0]['v'];
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function set($key,$value) {
|
||||
|
||||
$hash = hash('whirlpool',$key);
|
||||
|
||||
$r = q("SELECT * FROM cache WHERE k = '%s' limit 1",
|
||||
dbesc($hash)
|
||||
);
|
||||
if($r) {
|
||||
q("UPDATE cache SET v = '%s', updated = '%s' WHERE k = '%s'",
|
||||
dbesc($value),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($hash));
|
||||
}
|
||||
else {
|
||||
q("INSERT INTO cache ( k, v, updated) VALUES ('%s','%s','%s')",
|
||||
dbesc($hash),
|
||||
dbesc($value),
|
||||
dbesc(datetime_convert()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
275
Zotlabs/Lib/Chatroom.php
Normal file
275
Zotlabs/Lib/Chatroom.php
Normal file
@@ -0,0 +1,275 @@
|
||||
<?php
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief A class with chatroom related static methods.
|
||||
*/
|
||||
class Chatroom {
|
||||
/**
|
||||
* @brief Creates a chatroom.
|
||||
*
|
||||
* @param array $channel
|
||||
* @param array $arr
|
||||
* @return array An associative array containing:
|
||||
* * \e boolean \b success - A boolean success status
|
||||
* * \e string \b message - (optional) A string
|
||||
*/
|
||||
static public function create($channel, $arr) {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
$name = trim($arr['name']);
|
||||
if(! $name) {
|
||||
$ret['message'] = t('Missing room name');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r = q("select cr_id from chatroom where cr_uid = %d and cr_name = '%s' limit 1",
|
||||
intval($channel['channel_id']),
|
||||
dbesc($name)
|
||||
);
|
||||
if($r) {
|
||||
$ret['message'] = t('Duplicate room name');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r = q("select count(cr_id) as total from chatroom where cr_aid = %d",
|
||||
intval($channel['channel_account_id'])
|
||||
);
|
||||
if($r)
|
||||
$limit = service_class_fetch($channel['channel_id'], 'chatrooms');
|
||||
|
||||
if(($r) && ($limit !== false) && ($r[0]['total'] >= $limit)) {
|
||||
$ret['message'] = upgrade_message();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(! array_key_exists('expire', $arr))
|
||||
$arr['expire'] = 120; // minutes, e.g. 2 hours
|
||||
|
||||
$created = datetime_convert();
|
||||
|
||||
$x = q("insert into chatroom ( cr_aid, cr_uid, cr_name, cr_created, cr_edited, cr_expire, allow_cid, allow_gid, deny_cid, deny_gid )
|
||||
values ( %d, %d , '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s' ) ",
|
||||
intval($channel['channel_account_id']),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($name),
|
||||
dbesc($created),
|
||||
dbesc($created),
|
||||
intval($arr['expire']),
|
||||
dbesc($arr['allow_cid']),
|
||||
dbesc($arr['allow_gid']),
|
||||
dbesc($arr['deny_cid']),
|
||||
dbesc($arr['deny_gid'])
|
||||
);
|
||||
|
||||
if($x)
|
||||
$ret['success'] = true;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static public function destroy($channel,$arr) {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
if(intval($arr['cr_id']))
|
||||
$sql_extra = " and cr_id = " . intval($arr['cr_id']) . " ";
|
||||
elseif(trim($arr['cr_name']))
|
||||
$sql_extra = " and cr_name = '" . protect_sprintf(dbesc(trim($arr['cr_name']))) . "' ";
|
||||
else {
|
||||
$ret['message'] = t('Invalid room specifier.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r = q("select * from chatroom where cr_uid = %d $sql_extra limit 1",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if(! $r) {
|
||||
$ret['message'] = t('Invalid room specifier.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
build_sync_packet($channel['channel_id'],array('chatroom' => $r));
|
||||
|
||||
q("delete from chatroom where cr_id = %d",
|
||||
intval($r[0]['cr_id'])
|
||||
);
|
||||
if($r[0]['cr_id']) {
|
||||
q("delete from chatpresence where cp_room = %d",
|
||||
intval($r[0]['cr_id'])
|
||||
);
|
||||
q("delete from chat where chat_room = %d",
|
||||
intval($r[0]['cr_id'])
|
||||
);
|
||||
}
|
||||
|
||||
$ret['success'] = true;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static public function enter($observer_xchan, $room_id, $status, $client) {
|
||||
|
||||
if(! $room_id || ! $observer_xchan)
|
||||
return;
|
||||
|
||||
$r = q("select * from chatroom where cr_id = %d limit 1",
|
||||
intval($room_id)
|
||||
);
|
||||
if(! $r) {
|
||||
notice( t('Room not found.') . EOL);
|
||||
return false;
|
||||
}
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($r[0]['cr_uid']);
|
||||
|
||||
$x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1",
|
||||
intval($room_id),
|
||||
intval($r[0]['cr_uid'])
|
||||
);
|
||||
if(! $x) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return false;
|
||||
}
|
||||
|
||||
$limit = service_class_fetch($r[0]['cr_uid'], 'chatters_inroom');
|
||||
if($limit !== false) {
|
||||
$y = q("select count(*) as total from chatpresence where cp_room = %d",
|
||||
intval($room_id)
|
||||
);
|
||||
if($y && $y[0]['total'] > $limit) {
|
||||
notice( t('Room is full') . EOL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(intval($x[0]['cr_expire'])) {
|
||||
$r = q("delete from chat where created < %s - INTERVAL %s and chat_room = %d",
|
||||
db_utcnow(),
|
||||
db_quoteinterval( intval($x[0]['cr_expire']) . ' MINUTE' ),
|
||||
intval($x[0]['cr_id'])
|
||||
);
|
||||
}
|
||||
|
||||
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1",
|
||||
dbesc($observer_xchan),
|
||||
intval($room_id)
|
||||
);
|
||||
if($r) {
|
||||
q("update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
intval($r[0]['cp_id']),
|
||||
dbesc($client)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
$r = q("insert into chatpresence ( cp_room, cp_xchan, cp_last, cp_status, cp_client )
|
||||
values ( %d, '%s', '%s', '%s', '%s' )",
|
||||
intval($room_id),
|
||||
dbesc($observer_xchan),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($status),
|
||||
dbesc($client)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
function leave($observer_xchan, $room_id, $client) {
|
||||
if(! $room_id || ! $observer_xchan)
|
||||
return;
|
||||
|
||||
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1",
|
||||
dbesc($observer_xchan),
|
||||
intval($room_id),
|
||||
dbesc($client)
|
||||
);
|
||||
if($r) {
|
||||
q("delete from chatpresence where cp_id = %d",
|
||||
intval($r[0]['cp_id'])
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static public function roomlist($uid) {
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($uid);
|
||||
|
||||
$r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
static public function list_count($uid) {
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($uid);
|
||||
|
||||
$r = q("select count(*) as total from chatroom where cr_uid = %d $sql_extra",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
return $r[0]['total'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a chat message via API.
|
||||
*
|
||||
* It is the caller's responsibility to enter the room.
|
||||
*
|
||||
* @param int $uid
|
||||
* @param int $room_id
|
||||
* @param string $xchan
|
||||
* @param string $text
|
||||
* @return array
|
||||
*/
|
||||
static public function message($uid, $room_id, $xchan, $text) {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
if(! $text)
|
||||
return;
|
||||
|
||||
$sql_extra = permissions_sql($uid);
|
||||
|
||||
$r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra",
|
||||
intval($uid),
|
||||
intval($room_id)
|
||||
);
|
||||
if(! $r)
|
||||
return $ret;
|
||||
|
||||
$arr = [
|
||||
'chat_room' => $room_id,
|
||||
'chat_xchan' => $xchan,
|
||||
'chat_text' => $text
|
||||
];
|
||||
/**
|
||||
* @hooks chat_message
|
||||
* Called to create a chat message.
|
||||
* * \e int \b chat_room
|
||||
* * \e string \b chat_xchan
|
||||
* * \e string \b chat_text
|
||||
*/
|
||||
call_hooks('chat_message', $arr);
|
||||
|
||||
$x = q("insert into chat ( chat_room, chat_xchan, created, chat_text )
|
||||
values( %d, '%s', '%s', '%s' )",
|
||||
intval($room_id),
|
||||
dbesc($xchan),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(str_rot47(base64url_encode($arr['chat_text'])))
|
||||
);
|
||||
|
||||
$ret['success'] = true;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
165
Zotlabs/Lib/Config.php
Normal file
165
Zotlabs/Lib/Config.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class Config {
|
||||
|
||||
/**
|
||||
* @brief Loads the hub's configuration from database to a cached storage.
|
||||
*
|
||||
* Retrieve a category ($family) of config variables from database to a cached
|
||||
* storage in the global App::$config[$family].
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
*/
|
||||
static public function Load($family) {
|
||||
if(! array_key_exists($family, \App::$config))
|
||||
\App::$config[$family] = array();
|
||||
|
||||
if(! array_key_exists('config_loaded', \App::$config[$family])) {
|
||||
$r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family));
|
||||
if($r !== false) {
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$k = $rr['k'];
|
||||
\App::$config[$family][$k] = $rr['v'];
|
||||
}
|
||||
}
|
||||
\App::$config[$family]['config_loaded'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a configuration value for the hub.
|
||||
*
|
||||
* Stores a config value ($value) in the category ($family) under the key ($key).
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to set
|
||||
* @param mixed $value
|
||||
* The value to store in the configuration
|
||||
* @return mixed
|
||||
* Return the set value, or false if the database update failed
|
||||
*/
|
||||
static public function Set($family, $key, $value) {
|
||||
// manage array value
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
if(self::Get($family, $key) === false || (! self::get_from_storage($family, $key))) {
|
||||
$ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue)
|
||||
);
|
||||
if($ret) {
|
||||
\App::$config[$family][$key] = $value;
|
||||
$ret = $value;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$ret = q("UPDATE config SET v = '%s' WHERE cat = '%s' AND k = '%s'",
|
||||
dbesc($dbvalue),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
if($ret) {
|
||||
\App::$config[$family][$key] = $value;
|
||||
$ret = $value;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a particular config variable given the category name ($family)
|
||||
* and a key.
|
||||
*
|
||||
* Get a particular config variable from the given category ($family) and the
|
||||
* $key from a cached storage in App::$config[$family]. If a key is found in the
|
||||
* DB but does not exist in local config cache, pull it into the cache so we
|
||||
* do not have to hit the DB again for this item.
|
||||
*
|
||||
* Returns false if not set.
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to query
|
||||
* @param string $default (optional) default false
|
||||
* @return mixed Return value or false on error or if not set
|
||||
*/
|
||||
static public function Get($family, $key, $default = false) {
|
||||
if((! array_key_exists($family, \App::$config)) || (! array_key_exists('config_loaded', \App::$config[$family])))
|
||||
self::Load($family);
|
||||
|
||||
if(array_key_exists('config_loaded', \App::$config[$family])) {
|
||||
if(! array_key_exists($key, \App::$config[$family])) {
|
||||
return $default;
|
||||
}
|
||||
return ((! is_array(\App::$config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$family][$key]))
|
||||
? unserialize(\App::$config[$family][$key])
|
||||
: \App::$config[$family][$key]
|
||||
);
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deletes the given key from the hub's configuration database.
|
||||
*
|
||||
* Removes the configured value from the stored cache in App::$config[$family]
|
||||
* and removes it from the database.
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to delete
|
||||
* @return mixed
|
||||
*/
|
||||
static public function Delete($family, $key) {
|
||||
|
||||
$ret = false;
|
||||
|
||||
if(array_key_exists($family, \App::$config) && array_key_exists($key, \App::$config[$family]))
|
||||
unset(\App::$config[$family][$key]);
|
||||
|
||||
$ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s'",
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns a record directly from the database configuration storage.
|
||||
*
|
||||
* This function queries directly the database and bypasses the cached storage
|
||||
* from get_config($family, $key).
|
||||
*
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to query
|
||||
* @return mixed
|
||||
*/
|
||||
static private function get_from_storage($family,$key) {
|
||||
$ret = q("SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1",
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
114
Zotlabs/Lib/DB_Upgrade.php
Normal file
114
Zotlabs/Lib/DB_Upgrade.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class DB_Upgrade {
|
||||
|
||||
public $config_name = '';
|
||||
public $func_prefix = '';
|
||||
|
||||
function __construct($db_revision) {
|
||||
|
||||
$this->config_name = 'db_version';
|
||||
$this->func_prefix = '_';
|
||||
|
||||
$build = get_config('system', 'db_version', 0);
|
||||
if(! intval($build))
|
||||
$build = set_config('system', 'db_version', $db_revision);
|
||||
|
||||
if($build == $db_revision) {
|
||||
// Nothing to be done.
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$stored = intval($build);
|
||||
if(! $stored) {
|
||||
logger('Critical: check_config unable to determine database schema version');
|
||||
return;
|
||||
}
|
||||
|
||||
$current = intval($db_revision);
|
||||
|
||||
if($stored < $current) {
|
||||
|
||||
// The last update we performed was $stored.
|
||||
// Start at $stored + 1 and continue until we have completed $current
|
||||
|
||||
for($x = $stored + 1; $x <= $current; $x ++) {
|
||||
$s = '_' . $x;
|
||||
$cls = '\\Zotlabs\Update\\' . $s ;
|
||||
if(! class_exists($cls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There could be a lot of processes running or about to run.
|
||||
// We want exactly one process to run the update command.
|
||||
// So store the fact that we're taking responsibility
|
||||
// after first checking to see if somebody else already has.
|
||||
|
||||
// If the update fails or times-out completely you may need to
|
||||
// delete the config entry to try again.
|
||||
|
||||
Config::Load('database');
|
||||
|
||||
if(get_config('database', $s))
|
||||
break;
|
||||
set_config('database',$s, '1');
|
||||
|
||||
|
||||
$c = new $cls();
|
||||
|
||||
$retval = $c->run();
|
||||
|
||||
if($retval != UPDATE_SUCCESS) {
|
||||
|
||||
|
||||
$source = t('Source code of failed update: ') . "\n\n" . @file_get_contents('Zotlabs/Update/' . $s . '.php');
|
||||
|
||||
|
||||
// Prevent sending hundreds of thousands of emails by creating
|
||||
// a lockfile.
|
||||
|
||||
$lockfile = 'store/[data]/mailsent';
|
||||
|
||||
if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 86400)))
|
||||
return;
|
||||
@unlink($lockfile);
|
||||
//send the administrator an e-mail
|
||||
file_put_contents($lockfile, $x);
|
||||
|
||||
$r = q("select account_language from account where account_email = '%s' limit 1",
|
||||
dbesc(\App::$config['system']['admin_email'])
|
||||
);
|
||||
push_lang(($r) ? $r[0]['account_language'] : 'en');
|
||||
z_mail(
|
||||
[
|
||||
'toEmail' => \App::$config['system']['admin_email'],
|
||||
'messageSubject' => sprintf( t('Update Error at %s'), z_root()),
|
||||
'textVersion' => replace_macros(get_intltext_template('update_fail_eml.tpl'),
|
||||
[
|
||||
'$sitename' => \App::$config['system']['sitename'],
|
||||
'$siteurl' => z_root(),
|
||||
'$update' => $x,
|
||||
'$error' => sprintf( t('Update %s failed. See error logs.'), $x),
|
||||
'$baseurl' => z_root(),
|
||||
'$source' => $source
|
||||
]
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
//try the logger
|
||||
logger('CRITICAL: Update Failed: ' . $x);
|
||||
pop_lang();
|
||||
}
|
||||
else {
|
||||
set_config('database',$s, 'success');
|
||||
}
|
||||
}
|
||||
}
|
||||
set_config('system', 'db_version', $db_revision);
|
||||
}
|
||||
}
|
||||
}
|
||||
147
Zotlabs/Lib/DReport.php
Normal file
147
Zotlabs/Lib/DReport.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
class DReport {
|
||||
|
||||
private $location;
|
||||
private $sender;
|
||||
private $recipient;
|
||||
private $message_id;
|
||||
private $status;
|
||||
private $date;
|
||||
|
||||
function __construct($location,$sender,$recipient,$message_id,$status = 'deliver') {
|
||||
$this->location = $location;
|
||||
$this->sender = $sender;
|
||||
$this->recipient = $recipient;
|
||||
$this->name = EMPTY_STR;
|
||||
$this->message_id = $message_id;
|
||||
$this->status = $status;
|
||||
$this->date = datetime_convert();
|
||||
}
|
||||
|
||||
function update($status) {
|
||||
$this->status = $status;
|
||||
$this->date = datetime_convert();
|
||||
}
|
||||
|
||||
function set_name($name) {
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
function addto_update($status) {
|
||||
$this->status = $this->status . ' ' . $status;
|
||||
}
|
||||
|
||||
|
||||
function set($arr) {
|
||||
$this->location = $arr['location'];
|
||||
$this->sender = $arr['sender'];
|
||||
$this->recipient = $arr['recipient'];
|
||||
$this->name = $arr['name'];
|
||||
$this->message_id = $arr['message_id'];
|
||||
$this->status = $arr['status'];
|
||||
$this->date = $arr['date'];
|
||||
}
|
||||
|
||||
function get() {
|
||||
return array(
|
||||
'location' => $this->location,
|
||||
'sender' => $this->sender,
|
||||
'recipient' => $this->recipient,
|
||||
'name' => $this->name,
|
||||
'message_id' => $this->message_id,
|
||||
'status' => $this->status,
|
||||
'date' => $this->date
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief decide whether to store a returned delivery report
|
||||
*
|
||||
* @param array $dr
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
static function is_storable($dr) {
|
||||
|
||||
if(get_config('system', 'disable_dreport'))
|
||||
return false;
|
||||
|
||||
/**
|
||||
* @hooks dreport_is_storable
|
||||
* Called before storing a dreport record to determine whether to store it.
|
||||
* * \e array
|
||||
*/
|
||||
|
||||
call_hooks('dreport_is_storable', $dr);
|
||||
|
||||
// let plugins accept or reject - if neither, continue on
|
||||
if(array_key_exists('accept',$dr) && intval($dr['accept']))
|
||||
return true;
|
||||
if(array_key_exists('reject',$dr) && intval($dr['reject']))
|
||||
return false;
|
||||
|
||||
if(! ($dr['sender']))
|
||||
return false;
|
||||
|
||||
// Is the sender one of our channels?
|
||||
|
||||
$c = q("select channel_id from channel where channel_hash = '%s' or channel_portable_id = '%s' limit 1",
|
||||
dbesc($dr['sender']),
|
||||
dbesc($dr['sender'])
|
||||
);
|
||||
|
||||
if(! $c)
|
||||
return false;
|
||||
|
||||
// legacy zot recipients add a space and their name to the xchan. remove it if true.
|
||||
|
||||
$legacy_recipient = strpos($dr['recipient'], ' ');
|
||||
if($legacy_recipient !== false) {
|
||||
$legacy_recipient_parts = explode(' ', $dr['recipient'], 2);
|
||||
$rxchan = $legacy_recipient_parts[0];
|
||||
}
|
||||
else {
|
||||
$rxchan = $dr['recipient'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// is the recipient one of our connections, or do we want to store every report?
|
||||
|
||||
$pcf = get_pconfig($c[0]['channel_id'],'system','dreport_store_all');
|
||||
if($pcf)
|
||||
return true;
|
||||
|
||||
// We always add ourself as a recipient to private and relayed posts
|
||||
// So if a remote site says they can't find us, that's no big surprise
|
||||
// and just creates a lot of extra report noise
|
||||
|
||||
if(($dr['location'] !== z_root()) && ($dr['sender'] === $rxchan) && ($dr['status'] === 'recipient not found'))
|
||||
return false;
|
||||
|
||||
// If you have a private post with a recipient list, every single site is going to report
|
||||
// back a failed delivery for anybody on that list that isn't local to them. We're only
|
||||
// concerned about this if we have a local hubloc record which says we expected them to
|
||||
// have a channel on that site.
|
||||
|
||||
$r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_url = '%s'",
|
||||
dbesc($rxchan),
|
||||
dbesc($dr['location'])
|
||||
);
|
||||
if((! $r) && ($dr['status'] === 'recipient_not_found'))
|
||||
return false;
|
||||
|
||||
$r = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||
dbesc($rxchan),
|
||||
intval($c[0]['channel_id'])
|
||||
);
|
||||
if($r)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
861
Zotlabs/Lib/Enotify.php
Normal file
861
Zotlabs/Lib/Enotify.php
Normal file
@@ -0,0 +1,861 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief File with functions and a class for generating system and email notifications.
|
||||
*/
|
||||
|
||||
|
||||
class Enotify {
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param array $params an assoziative array with:
|
||||
* * \e string \b from_xchan sender xchan hash
|
||||
* * \e string \b to_xchan recipient xchan hash
|
||||
* * \e array \b item an assoziative array
|
||||
* * \e int \b type one of the NOTIFY_* constants from boot.php
|
||||
* * \e string \b link
|
||||
* * \e string \b parent_mid
|
||||
* * \e string \b otype
|
||||
* * \e string \b verb
|
||||
* * \e string \b activity
|
||||
*/
|
||||
|
||||
|
||||
static public function submit($params) {
|
||||
|
||||
logger('notification: entry', LOGGER_DEBUG);
|
||||
|
||||
// throw a small amount of entropy into the system to breakup duplicates arriving at the same precise instant.
|
||||
usleep(mt_rand(0, 10000));
|
||||
|
||||
if ($params['from_xchan']) {
|
||||
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($params['from_xchan'])
|
||||
);
|
||||
}
|
||||
if ($params['to_xchan']) {
|
||||
$y = q("select channel.*, account.* from channel left join account on channel_account_id = account_id
|
||||
where channel_hash = '%s' and channel_removed = 0 limit 1",
|
||||
dbesc($params['to_xchan'])
|
||||
);
|
||||
}
|
||||
if ($x & $y) {
|
||||
$sender = $x[0];
|
||||
$recip = $y[0];
|
||||
} else {
|
||||
logger('notification: no sender or recipient.');
|
||||
logger('sender: ' . $params['from_xchan']);
|
||||
logger('recip: ' . $params['to_xchan']);
|
||||
return;
|
||||
}
|
||||
|
||||
// from here on everything is in the recipients language
|
||||
|
||||
push_lang($recip['account_language']); // should probably have a channel language
|
||||
|
||||
$banner = t('$Projectname Notification');
|
||||
$product = t('$projectname'); // PLATFORM_NAME;
|
||||
$siteurl = z_root();
|
||||
$thanks = t('Thank You,');
|
||||
$sitename = get_config('system','sitename');
|
||||
$site_admin = sprintf( t('%s Administrator'), $sitename);
|
||||
$opt_out1 = sprintf( t('This email was sent by %1$s at %2$s.'), t('$Projectname'), \App::get_hostname());
|
||||
$opt_out2 = sprintf( t('To stop receiving these messages, please adjust your Notification Settings at %s'), z_root() . '/settings');
|
||||
$hopt_out2 = sprintf( t('To stop receiving these messages, please adjust your %s.'), '<a href="' . z_root() . '/settings' . '">' . t('Notification Settings') . '</a>');
|
||||
$sender_name = $product;
|
||||
$hostname = \App::get_hostname();
|
||||
if(strpos($hostname,':'))
|
||||
$hostname = substr($hostname,0,strpos($hostname,':'));
|
||||
|
||||
// Do not translate 'noreply' as it must be a legal 7-bit email address
|
||||
|
||||
$reply_email = get_config('system','reply_address');
|
||||
if(! $reply_email)
|
||||
$reply_email = 'noreply' . '@' . $hostname;
|
||||
|
||||
$sender_email = get_config('system','from_email');
|
||||
if(! $sender_email)
|
||||
$sender_email = 'Administrator' . '@' . $hostname;
|
||||
|
||||
$sender_name = get_config('system','from_email_name');
|
||||
if(! $sender_name)
|
||||
$sender_name = \Zotlabs\Lib\System::get_site_name();
|
||||
|
||||
|
||||
$additional_mail_header = "";
|
||||
|
||||
if(array_key_exists('item', $params)) {
|
||||
require_once('include/conversation.php');
|
||||
// if it's a normal item...
|
||||
if (array_key_exists('verb', $params['item'])) {
|
||||
// localize_item() alters the original item so make a copy first
|
||||
$i = $params['item'];
|
||||
logger('calling localize');
|
||||
localize_item($i);
|
||||
$title = $i['title'];
|
||||
$body = $i['body'];
|
||||
$private = (($i['item_private']) || intval($i['item_obscured']));
|
||||
}
|
||||
else {
|
||||
$title = $params['item']['title'];
|
||||
$body = $params['item']['body'];
|
||||
}
|
||||
if($params['item']['created'] < datetime_convert('UTC','UTC','now - 1 month')) {
|
||||
logger('notification invoked for an old item which may have been refetched.',LOGGER_DEBUG,LOG_INFO);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$title = $body = '';
|
||||
}
|
||||
|
||||
|
||||
$always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices');
|
||||
$vnotify = get_pconfig($recip['channel_id'],'system','vnotify');
|
||||
|
||||
$salutation = $recip['channel_name'];
|
||||
|
||||
// e.g. "your post", "David's photo", etc.
|
||||
$possess_desc = t('%s <!item_type!>');
|
||||
|
||||
if ($params['type'] == NOTIFY_MAIL) {
|
||||
logger('notification: mail');
|
||||
$subject = sprintf( t('[$Projectname:Notify] New mail received at %s'),$sitename);
|
||||
|
||||
$preamble = sprintf( t('%1$s sent you a new private message at %2$s.'), $sender['xchan_name'],$sitename);
|
||||
$epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]');
|
||||
$sitelink = t('Please visit %s to view and/or reply to your private messages.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl . '/mail/' . $params['item']['id'] );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/mail/' . $params['item']['id'] . '">' . $sitename . '</a>');
|
||||
$itemlink = $siteurl . '/mail/' . $params['item']['id'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_COMMENT) {
|
||||
//logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
|
||||
|
||||
$moderated = (($params['item']['item_blocked'] == ITEM_MODERATED) ? true : false);
|
||||
|
||||
$itemlink = $params['link'];
|
||||
|
||||
$action = t('commented on');
|
||||
|
||||
if(array_key_exists('item',$params) && in_array($params['item']['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
|
||||
|
||||
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) {
|
||||
logger('notification: not a visible activity. Ignoring.');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
if(activity_match($params['verb'], ACTIVITY_LIKE))
|
||||
$action = t('liked');
|
||||
|
||||
if(activity_match($params['verb'], ACTIVITY_DISLIKE))
|
||||
$action = t('disliked');
|
||||
|
||||
}
|
||||
|
||||
$parent_mid = $params['parent_mid'];
|
||||
|
||||
// Check to see if there was already a notify for this post.
|
||||
// If so don't create a second notification
|
||||
|
||||
$p = null;
|
||||
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
|
||||
dbesc($params['link']),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
if ($p) {
|
||||
logger('notification: comment already notified');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if it's a post figure out who's post it is.
|
||||
|
||||
$p = null;
|
||||
|
||||
if($params['otype'] === 'item' && $parent_mid) {
|
||||
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($parent_mid),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
xchan_query($p);
|
||||
|
||||
$item_post_type = item_post_type($p[0]);
|
||||
// $private = $p[0]['item_private'];
|
||||
$parent_id = $p[0]['id'];
|
||||
|
||||
$parent_item = $p[0];
|
||||
|
||||
//$possess_desc = str_replace('<!item_type!>',$possess_desc);
|
||||
|
||||
// "a post"
|
||||
$dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]a %4$s[/zrl]'),
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$action,
|
||||
$itemlink,
|
||||
$item_post_type);
|
||||
|
||||
// "George Bull's post"
|
||||
if($p)
|
||||
$dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]%4$s\'s %5$s[/zrl]'),
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$action,
|
||||
$itemlink,
|
||||
$p[0]['author']['xchan_name'],
|
||||
$item_post_type);
|
||||
|
||||
// "your post"
|
||||
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
|
||||
$dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]your %4$s[/zrl]'),
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$action,
|
||||
$itemlink,
|
||||
$item_post_type);
|
||||
|
||||
// Some mail softwares relies on subject field for threading.
|
||||
// So, we cannot have different subjects for notifications of the same thread.
|
||||
// Before this we have the name of the replier on the subject rendering
|
||||
// differents subjects for messages on the same thread.
|
||||
|
||||
if($moderated)
|
||||
$subject = sprintf( t('[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
||||
else
|
||||
$subject = sprintf( t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s commented on an item/conversation you have been following.'), $sender['xchan_name']);
|
||||
$epreamble = $dest_str;
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
if($moderated) {
|
||||
$tsitelink .= "\n\n" . sprintf( t('Please visit %s to approve or reject this comment.'), z_root() . '/moderate' );
|
||||
$hsitelink .= "<br><br>" . sprintf( t('Please visit %s to approve or reject this comment.'), '<a href="' . z_root() . '/moderate">' . z_root() . '/moderate</a>' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_LIKE) {
|
||||
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
|
||||
|
||||
$itemlink = $params['link'];
|
||||
|
||||
if (array_key_exists('item',$params) && (! activity_match($params['item']['verb'],ACTIVITY_LIKE))) {
|
||||
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) {
|
||||
logger('notification: not a visible activity. Ignoring.');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$parent_mid = $params['parent_mid'];
|
||||
|
||||
// Check to see if there was already a notify for this post.
|
||||
// If so don't create a second notification
|
||||
|
||||
$p = null;
|
||||
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
|
||||
dbesc($params['link']),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
if ($p) {
|
||||
logger('notification: like already notified');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if it's a post figure out who's post it is.
|
||||
|
||||
$p = null;
|
||||
|
||||
if($params['otype'] === 'item' && $parent_mid) {
|
||||
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($parent_mid),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
xchan_query($p);
|
||||
|
||||
|
||||
$item_post_type = item_post_type($p[0]);
|
||||
// $private = $p[0]['item_private'];
|
||||
$parent_id = $p[0]['id'];
|
||||
|
||||
$parent_item = $p[0];
|
||||
|
||||
|
||||
// "your post"
|
||||
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
|
||||
$dest_str = sprintf(t('%1$s liked [zrl=%2$s]your %3$s[/zrl]'),
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$itemlink,
|
||||
$item_post_type);
|
||||
else {
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
// Some mail softwares relies on subject field for threading.
|
||||
// So, we cannot have different subjects for notifications of the same thread.
|
||||
// Before this we have the name of the replier on the subject rendering
|
||||
// differents subjects for messages on the same thread.
|
||||
|
||||
$subject = sprintf( t('[$Projectname:Notify] Like received to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s liked an item/conversation you created.'), $sender['xchan_name']);
|
||||
$epreamble = $dest_str;
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
}
|
||||
|
||||
|
||||
|
||||
if($params['type'] == NOTIFY_WALL) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']);
|
||||
|
||||
$preamble = sprintf( t('%1$s posted to your profile wall at %2$s') , $sender['xchan_name'], $sitename);
|
||||
|
||||
$epreamble = sprintf( t('%1$s posted to [zrl=%2$s]your wall[/zrl]') ,
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$params['link']);
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_TAGSELF) {
|
||||
|
||||
$p = null;
|
||||
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
|
||||
dbesc($params['link']),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
if ($p) {
|
||||
logger('enotify: tag: already notified about this post');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
$subject = sprintf( t('[$Projectname:Notify] %s tagged you') , $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s tagged you at %2$s') , $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s [zrl=%2$s]tagged you[/zrl].') ,
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$params['link']);
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_POKE) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] %1$s poked you') , $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s poked you at %2$s') , $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s [zrl=%2$s]poked you[/zrl].') ,
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$params['link']);
|
||||
|
||||
$subject = str_replace('poked', t($params['activity']), $subject);
|
||||
$preamble = str_replace('poked', t($params['activity']), $preamble);
|
||||
$epreamble = str_replace('poked', t($params['activity']), $epreamble);
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_TAGSHARE) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] %s tagged your post') , $sender['xchan_name']);
|
||||
$preamble = sprintf( t('%1$s tagged your post at %2$s'),$sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('%1$s tagged [zrl=%2$s]your post[/zrl]') ,
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
|
||||
$itemlink);
|
||||
|
||||
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_INTRO) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] Introduction received'));
|
||||
$preamble = sprintf( t('You\'ve received an new connection request from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('You\'ve received [zrl=%1$s]a new connection request[/zrl] from %2$s.'),
|
||||
$siteurl . '/connections/ifpending',
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
|
||||
$body = sprintf( t('You may visit their profile at %s'),$sender['xchan_url']);
|
||||
|
||||
$sitelink = t('Please visit %s to approve or reject the connection request.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl . '/connections/ifpending');
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/connections/ifpending">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_SUGGEST) {
|
||||
$subject = sprintf( t('[$Projectname:Notify] Friend suggestion received'));
|
||||
$preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename);
|
||||
$epreamble = sprintf( t('You\'ve received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s.'),
|
||||
$itemlink,
|
||||
'[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]',
|
||||
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
|
||||
|
||||
$body = t('Name:') . ' ' . $params['item']['name'] . "\n";
|
||||
$body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n";
|
||||
$body .= sprintf( t('You may visit their profile at %s'),$params['item']['url']);
|
||||
|
||||
$sitelink = t('Please visit %s to approve or reject the suggestion.');
|
||||
$tsitelink = sprintf( $sitelink, $siteurl );
|
||||
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||
$itemlink = $params['link'];
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_CONFIRM) {
|
||||
// ?
|
||||
}
|
||||
|
||||
if ($params['type'] == NOTIFY_SYSTEM) {
|
||||
// ?
|
||||
}
|
||||
|
||||
$h = array(
|
||||
'params' => $params,
|
||||
'subject' => $subject,
|
||||
'preamble' => $preamble,
|
||||
'epreamble' => $epreamble,
|
||||
'body' => $body,
|
||||
'sitelink' => $sitelink,
|
||||
'sitename' => $sitename,
|
||||
'tsitelink' => $tsitelink,
|
||||
'hsitelink' => $hsitelink,
|
||||
'itemlink' => $itemlink,
|
||||
'sender' => $sender,
|
||||
'recipient' => $recip
|
||||
);
|
||||
|
||||
call_hooks('enotify', $h);
|
||||
|
||||
$subject = $h['subject'];
|
||||
$preamble = $h['preamble'];
|
||||
$epreamble = $h['epreamble'];
|
||||
$body = $h['body'];
|
||||
$sitelink = $h['sitelink'];
|
||||
$tsitelink = $h['tsitelink'];
|
||||
$hsitelink = $h['hsitelink'];
|
||||
$itemlink = $h['itemlink'];
|
||||
|
||||
|
||||
require_once('include/html2bbcode.php');
|
||||
|
||||
do {
|
||||
$dups = false;
|
||||
$hash = random_string();
|
||||
$r = q("SELECT id FROM notify WHERE hash = '%s' LIMIT 1",
|
||||
dbesc($hash));
|
||||
if ($r)
|
||||
$dups = true;
|
||||
} while ($dups === true);
|
||||
|
||||
|
||||
$datarray = array();
|
||||
$datarray['hash'] = $hash;
|
||||
$datarray['sender_hash'] = $sender['xchan_hash'];
|
||||
$datarray['xname'] = $sender['xchan_name'];
|
||||
$datarray['url'] = $sender['xchan_url'];
|
||||
$datarray['photo'] = $sender['xchan_photo_s'];
|
||||
$datarray['created'] = datetime_convert();
|
||||
$datarray['aid'] = $recip['channel_account_id'];
|
||||
$datarray['uid'] = $recip['channel_id'];
|
||||
$datarray['link'] = $itemlink;
|
||||
$datarray['parent'] = $parent_mid;
|
||||
$datarray['parent_item'] = $parent_item;
|
||||
$datarray['ntype'] = $params['type'];
|
||||
$datarray['verb'] = $params['verb'];
|
||||
$datarray['otype'] = $params['otype'];
|
||||
$datarray['abort'] = false;
|
||||
|
||||
$datarray['item'] = $params['item'];
|
||||
|
||||
call_hooks('enotify_store', $datarray);
|
||||
|
||||
if ($datarray['abort']) {
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// create notification entry in DB
|
||||
$seen = 0;
|
||||
|
||||
// Mark some notifications as seen right away
|
||||
// Note! The notification have to be created, because they are used to send emails
|
||||
// So easiest solution to hide them from Notices is to mark them as seen right away.
|
||||
// Another option would be to not add them to the DB, and change how emails are handled
|
||||
// (probably would be better that way)
|
||||
|
||||
if (!$always_show_in_notices) {
|
||||
if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_MAIL) || ($params['type'] == NOTIFY_INTRO)) {
|
||||
$seen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("insert into notify (hash,xname,url,photo,created,msg,aid,uid,link,parent,seen,ntype,verb,otype)
|
||||
values('%s','%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')",
|
||||
dbesc($datarray['hash']),
|
||||
dbesc($datarray['xname']),
|
||||
dbesc($datarray['url']),
|
||||
dbesc($datarray['photo']),
|
||||
dbesc($datarray['created']),
|
||||
dbesc(''), // will fill this in below after the record is created
|
||||
intval($datarray['aid']),
|
||||
intval($datarray['uid']),
|
||||
dbesc($datarray['link']),
|
||||
dbesc($datarray['parent']),
|
||||
intval($seen),
|
||||
intval($datarray['ntype']),
|
||||
dbesc($datarray['verb']),
|
||||
dbesc($datarray['otype'])
|
||||
);
|
||||
|
||||
$r = q("select id from notify where hash = '%s' and uid = %d limit 1",
|
||||
dbesc($hash),
|
||||
intval($recip['channel_id'])
|
||||
);
|
||||
if ($r) {
|
||||
$notify_id = $r[0]['id'];
|
||||
} else {
|
||||
logger('notification not found.');
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
$itemlink = z_root() . '/notify/view/' . $notify_id;
|
||||
$msg = str_replace('$itemlink',$itemlink,$epreamble);
|
||||
|
||||
// wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation
|
||||
|
||||
if ((\App::$language === 'en' || (! \App::$language)) && strpos($msg,', '))
|
||||
$msg = substr($msg,strpos($msg,', ')+1);
|
||||
|
||||
$r = q("update notify set msg = '%s' where id = %d and uid = %d",
|
||||
dbesc($msg),
|
||||
intval($notify_id),
|
||||
intval($datarray['uid'])
|
||||
);
|
||||
|
||||
// send email notification if notification preferences permit
|
||||
|
||||
require_once('bbcode.php');
|
||||
if ((intval($recip['channel_notifyflags']) & intval($params['type'])) || $params['type'] == NOTIFY_SYSTEM) {
|
||||
|
||||
logger('notification: sending notification email');
|
||||
|
||||
$hn = get_pconfig($recip['channel_id'],'system','email_notify_host');
|
||||
if($hn && (! stristr(\App::get_hostname(),$hn))) {
|
||||
// this isn't the email notification host
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
$textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array( "", "\n"), $body))),ENT_QUOTES,'UTF-8'));
|
||||
|
||||
$htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array("","<br />\n"),$body)));
|
||||
|
||||
|
||||
// use $_SESSION['zid_override'] to force zid() to use
|
||||
// the recipient address instead of the current observer
|
||||
|
||||
$_SESSION['zid_override'] = channel_reddress($recip);
|
||||
$_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address'];
|
||||
|
||||
$textversion = zidify_links($textversion);
|
||||
$htmlversion = zidify_links($htmlversion);
|
||||
|
||||
// unset when done to revert to normal behaviour
|
||||
|
||||
unset($_SESSION['zid_override']);
|
||||
unset($_SESSION['zrl_override']);
|
||||
|
||||
$datarray = array();
|
||||
$datarray['banner'] = $banner;
|
||||
$datarray['product'] = $product;
|
||||
$datarray['preamble'] = $preamble;
|
||||
$datarray['sitename'] = $sitename;
|
||||
$datarray['siteurl'] = $siteurl;
|
||||
$datarray['type'] = $params['type'];
|
||||
$datarray['parent'] = $params['parent_mid'];
|
||||
$datarray['source_name'] = $sender['xchan_name'];
|
||||
$datarray['source_link'] = $sender['xchan_url'];
|
||||
$datarray['source_photo'] = $sender['xchan_photo_s'];
|
||||
$datarray['uid'] = $recip['channel_id'];
|
||||
$datarray['username'] = $recip['channel_name'];
|
||||
$datarray['hsitelink'] = $hsitelink;
|
||||
$datarray['tsitelink'] = $tsitelink;
|
||||
$datarray['hitemlink'] = '<a href="' . $itemlink . '">' . $itemlink . '</a>';
|
||||
$datarray['titemlink'] = $itemlink;
|
||||
$datarray['thanks'] = $thanks;
|
||||
$datarray['site_admin'] = $site_admin;
|
||||
$datarray['opt_out1'] = $opt_out1;
|
||||
$datarray['opt_out2'] = $opt_out2;
|
||||
$datarray['hopt_out2'] = $hopt_out2;
|
||||
$datarray['title'] = stripslashes($title);
|
||||
$datarray['htmlversion'] = $htmlversion;
|
||||
$datarray['textversion'] = $textversion;
|
||||
$datarray['subject'] = $subject;
|
||||
$datarray['headers'] = $additional_mail_header;
|
||||
$datarray['email_secure'] = false;
|
||||
|
||||
call_hooks('enotify_mail', $datarray);
|
||||
|
||||
// Default to private - don't disclose message contents over insecure channels (such as email)
|
||||
// Might be interesting to use GPG,PGP,S/MIME encryption instead
|
||||
// but we'll save that for a clever plugin developer to implement
|
||||
|
||||
$private_activity = false;
|
||||
|
||||
if (! $datarray['email_secure']) {
|
||||
switch ($params['type']) {
|
||||
case NOTIFY_WALL:
|
||||
case NOTIFY_TAGSELF:
|
||||
case NOTIFY_POKE:
|
||||
case NOTIFY_COMMENT:
|
||||
if (! $private)
|
||||
break;
|
||||
$private_activity = true;
|
||||
case NOTIFY_MAIL:
|
||||
$datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = '';
|
||||
$datarray['subject'] = preg_replace('/' . preg_quote(t('[$Projectname:Notify]')) . '/','$0*',$datarray['subject']);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($private_activity
|
||||
&& intval(get_pconfig($datarray['uid'], 'system', 'ignore_private_notifications'))) {
|
||||
|
||||
pop_lang();
|
||||
return;
|
||||
}
|
||||
|
||||
// load the template for private message notifications
|
||||
$tpl = get_markup_template('email_notify_html.tpl');
|
||||
$email_html_body = replace_macros($tpl,array(
|
||||
'$banner' => $datarray['banner'],
|
||||
'$notify_icon' => \Zotlabs\Lib\System::get_notify_icon(),
|
||||
'$product' => $datarray['product'],
|
||||
'$preamble' => $salutation . '<br><br>' . $datarray['preamble'],
|
||||
'$sitename' => $datarray['sitename'],
|
||||
'$siteurl' => $datarray['siteurl'],
|
||||
'$source_name' => $datarray['source_name'],
|
||||
'$source_link' => $datarray['source_link'],
|
||||
'$source_photo' => $datarray['source_photo'],
|
||||
'$username' => $datarray['to_name'],
|
||||
'$hsitelink' => $datarray['hsitelink'],
|
||||
'$hitemlink' => $datarray['hitemlink'],
|
||||
'$thanks' => $datarray['thanks'],
|
||||
'$site_admin' => $datarray['site_admin'],
|
||||
'$opt_out1' => $datarray['opt_out1'],
|
||||
'$opt_out2' => $datarray['hopt_out2'],
|
||||
'$title' => $datarray['title'],
|
||||
'$htmlversion' => $datarray['htmlversion'],
|
||||
));
|
||||
|
||||
// load the template for private message notifications
|
||||
$tpl = get_markup_template('email_notify_text.tpl');
|
||||
$email_text_body = replace_macros($tpl, array(
|
||||
'$banner' => $datarray['banner'],
|
||||
'$product' => $datarray['product'],
|
||||
'$preamble' => $salutation . "\n\n" . $datarray['preamble'],
|
||||
'$sitename' => $datarray['sitename'],
|
||||
'$siteurl' => $datarray['siteurl'],
|
||||
'$source_name' => $datarray['source_name'],
|
||||
'$source_link' => $datarray['source_link'],
|
||||
'$source_photo' => $datarray['source_photo'],
|
||||
'$username' => $datarray['to_name'],
|
||||
'$tsitelink' => $datarray['tsitelink'],
|
||||
'$titemlink' => $datarray['titemlink'],
|
||||
'$thanks' => $datarray['thanks'],
|
||||
'$site_admin' => $datarray['site_admin'],
|
||||
'$opt_out1' => $datarray['opt_out1'],
|
||||
'$opt_out2' => $datarray['opt_out2'],
|
||||
'$title' => $datarray['title'],
|
||||
'$textversion' => $datarray['textversion'],
|
||||
));
|
||||
|
||||
// logger('text: ' . $email_text_body);
|
||||
|
||||
// use the EmailNotification library to send the message
|
||||
|
||||
self::send(array(
|
||||
'fromName' => $sender_name,
|
||||
'fromEmail' => $sender_email,
|
||||
'replyTo' => $reply_email,
|
||||
'toEmail' => $recip['account_email'],
|
||||
'messageSubject' => $datarray['subject'],
|
||||
'htmlVersion' => $email_html_body,
|
||||
'textVersion' => $email_text_body,
|
||||
'additionalMailHeader' => $datarray['headers'],
|
||||
));
|
||||
}
|
||||
|
||||
pop_lang();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a multipart/alternative message with Text and HTML versions.
|
||||
*
|
||||
* @param array $params an assoziative array with:
|
||||
* * \e string \b fromName name of the sender
|
||||
* * \e string \b fromEmail email of the sender
|
||||
* * \e string \b replyTo replyTo address to direct responses
|
||||
* * \e string \b toEmail destination email address
|
||||
* * \e string \b messageSubject subject of the message
|
||||
* * \e string \b htmlVersion html version of the message
|
||||
* * \e string \b textVersion text only version of the message
|
||||
* * \e string \b additionalMailHeader additions to the smtp mail header
|
||||
*/
|
||||
static public function send($params) {
|
||||
|
||||
$params['sent'] = false;
|
||||
$params['result'] = false;
|
||||
|
||||
call_hooks('email_send', $params);
|
||||
|
||||
if($params['sent']) {
|
||||
logger("notification: enotify::send (addon) returns " . (($params['result']) ? 'success' : 'failure'), LOGGER_DEBUG);
|
||||
return $params['result'];
|
||||
}
|
||||
|
||||
$fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
|
||||
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
|
||||
|
||||
// generate a mime boundary
|
||||
$mimeBoundary = rand(0, 9) . "-"
|
||||
.rand(100000000, 999999999) . "-"
|
||||
.rand(100000000, 999999999) . "=:"
|
||||
.rand(10000, 99999);
|
||||
|
||||
// generate a multipart/alternative message header
|
||||
$messageHeader =
|
||||
$params['additionalMailHeader'] .
|
||||
"From: $fromName <{$params['fromEmail']}>" . PHP_EOL .
|
||||
"Reply-To: $fromName <{$params['replyTo']}>" . PHP_EOL .
|
||||
"MIME-Version: 1.0" . PHP_EOL .
|
||||
"Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
|
||||
|
||||
// assemble the final multipart message body with the text and html types included
|
||||
$textBody = chunk_split(base64_encode($params['textVersion']));
|
||||
$htmlBody = chunk_split(base64_encode($params['htmlVersion']));
|
||||
|
||||
$multipartMessageBody =
|
||||
"--" . $mimeBoundary . PHP_EOL . // plain text section
|
||||
"Content-Type: text/plain; charset=UTF-8" . PHP_EOL .
|
||||
"Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL .
|
||||
$textBody . PHP_EOL .
|
||||
"--" . $mimeBoundary . PHP_EOL . // text/html section
|
||||
"Content-Type: text/html; charset=UTF-8" . PHP_EOL .
|
||||
"Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL .
|
||||
$htmlBody . PHP_EOL .
|
||||
"--" . $mimeBoundary . "--" . PHP_EOL; // message ending
|
||||
|
||||
// send the message
|
||||
$res = mail(
|
||||
$params['toEmail'], // send to address
|
||||
$messageSubject, // subject
|
||||
$multipartMessageBody, // message body
|
||||
$messageHeader // message headers
|
||||
);
|
||||
logger("notification: enotify::send returns " . (($res) ? 'success' : 'failure'), LOGGER_DEBUG);
|
||||
return $res;
|
||||
}
|
||||
|
||||
static public function format($item) {
|
||||
|
||||
$ret = '';
|
||||
|
||||
require_once('include/conversation.php');
|
||||
|
||||
// Call localize_item to get a one line status for activities.
|
||||
// This should set $item['localized'] to indicate we have a brief summary.
|
||||
// and perhaps $item['shortlocalized'] for an even briefer summary
|
||||
|
||||
localize_item($item);
|
||||
|
||||
if($item['shortlocalize']) {
|
||||
$itemem_text = $item['shortlocalize'];
|
||||
}
|
||||
elseif($item['localize']) {
|
||||
$itemem_text = $item['localize'];
|
||||
}
|
||||
else {
|
||||
$itemem_text = (($item['item_thread_top'])
|
||||
? t('created a new post')
|
||||
: sprintf( t('commented on %s\'s post'), $item['owner']['xchan_name']));
|
||||
|
||||
if($item['verb'] === ACTIVITY_SHARE) {
|
||||
$itemem_text = sprintf( t('repeated %s\'s post'), $item['author']['xchan_name']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$edit = false;
|
||||
|
||||
if($item['edited'] > $item['created']) {
|
||||
if($item['item_thread_top']) {
|
||||
$itemem_text = sprintf( t('edited a post dated %s'), relative_date($item['created']));
|
||||
$edit = true;
|
||||
}
|
||||
else {
|
||||
$itemem_text = sprintf( t('edited a comment dated %s'), relative_date($item['created']));
|
||||
$edit = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// convert this logic into a json array just like the system notifications
|
||||
|
||||
$who = (($item['verb'] === ACTIVITY_SHARE) ? 'owner' : 'author');
|
||||
|
||||
$x = array(
|
||||
'notify_link' => $item['llink'],
|
||||
'name' => $item[$who]['xchan_name'],
|
||||
'addr' => (($item[$who]['xchan_addr']) ? $item[$who]['xchan_addr'] : $item[$who]['xchan_url']),
|
||||
'url' => $item[$who]['xchan_url'],
|
||||
'photo' => $item[$who]['xchan_photo_s'],
|
||||
'when' => relative_date(($edit)? $item['edited'] : $item['created']),
|
||||
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
|
||||
'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])),
|
||||
'notify_id' => 'undefined',
|
||||
'thread_top' => (($item['item_thread_top']) ? true : false),
|
||||
'message' => strip_tags(bbcode($itemem_text)),
|
||||
// these are for the superblock addon
|
||||
'hash' => $item[$who]['xchan_hash'],
|
||||
'uid' => local_channel(),
|
||||
'display' => true
|
||||
);
|
||||
|
||||
call_hooks('enotify_format',$x);
|
||||
if(! $x['display']) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
}
|
||||
57
Zotlabs/Lib/ExtendedZip.php
Normal file
57
Zotlabs/Lib/ExtendedZip.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* Description of ExtendedZip
|
||||
*
|
||||
* @author andrew
|
||||
*/
|
||||
class ExtendedZip extends \ZipArchive {
|
||||
|
||||
// Member function to add a whole file system subtree to the archive
|
||||
public function addTree($dirname, $localname = '') {
|
||||
if ($localname)
|
||||
$this->addEmptyDir($localname);
|
||||
$this->_addTree($dirname, $localname);
|
||||
}
|
||||
|
||||
// Internal function, to recurse
|
||||
protected function _addTree($dirname, $localname) {
|
||||
$dir = opendir($dirname);
|
||||
while ($filename = readdir($dir)) {
|
||||
// Discard . and ..
|
||||
if ($filename == '.' || $filename == '..')
|
||||
continue;
|
||||
|
||||
// Proceed according to type
|
||||
$path = $dirname . '/' . $filename;
|
||||
$localpath = $localname ? ($localname . '/' . $filename) : $filename;
|
||||
if (is_dir($path)) {
|
||||
// Directory: add & recurse
|
||||
$this->addEmptyDir($localpath);
|
||||
$this->_addTree($path, $localpath);
|
||||
}
|
||||
else if (is_file($path)) {
|
||||
// File: just add
|
||||
$this->addFile($path, $localpath);
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
}
|
||||
|
||||
// Helper function
|
||||
public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '') {
|
||||
$zip = new self();
|
||||
$zip->open($zipFilename, $flags);
|
||||
$zip->addTree($dirname, $localname);
|
||||
$zip->close();
|
||||
}
|
||||
|
||||
}
|
||||
405
Zotlabs/Lib/Group.php
Normal file
405
Zotlabs/Lib/Group.php
Normal file
@@ -0,0 +1,405 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
|
||||
class Group {
|
||||
|
||||
static function add($uid,$name,$public = 0) {
|
||||
|
||||
$ret = false;
|
||||
if(x($uid) && x($name)) {
|
||||
$r = self::byname($uid,$name); // check for dups
|
||||
if($r !== false) {
|
||||
|
||||
// This could be a problem.
|
||||
// Let's assume we've just created a group which we once deleted
|
||||
// all the old members are gone, but the group remains so we don't break any security
|
||||
// access lists. What we're doing here is reviving the dead group, but old content which
|
||||
// was restricted to this group may now be seen by the new group members.
|
||||
|
||||
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
|
||||
intval($r)
|
||||
);
|
||||
if(($z) && $z[0]['deleted']) {
|
||||
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
|
||||
notice( t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
do {
|
||||
$dups = false;
|
||||
$hash = random_string(32) . str_replace(['<','>'],['.','.'], $name);
|
||||
|
||||
$r = q("SELECT id FROM pgrp WHERE hash = '%s' LIMIT 1", dbesc($hash));
|
||||
if($r)
|
||||
$dups = true;
|
||||
} while($dups == true);
|
||||
|
||||
|
||||
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
|
||||
VALUES( '%s', %d, %d, '%s' ) ",
|
||||
dbesc($hash),
|
||||
intval($uid),
|
||||
intval($public),
|
||||
dbesc($name)
|
||||
);
|
||||
$ret = $r;
|
||||
}
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function remove($uid,$name) {
|
||||
$ret = false;
|
||||
if(x($uid) && x($name)) {
|
||||
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
if($r) {
|
||||
$group_id = $r[0]['id'];
|
||||
$group_hash = $r[0]['hash'];
|
||||
}
|
||||
|
||||
if(! $group_id)
|
||||
return false;
|
||||
|
||||
// remove group from default posting lists
|
||||
$r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
if($r) {
|
||||
$user_info = $r[0];
|
||||
$change = false;
|
||||
|
||||
if($user_info['channel_default_group'] == $group_hash) {
|
||||
$user_info['channel_default_group'] = '';
|
||||
$change = true;
|
||||
}
|
||||
if(strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) {
|
||||
$user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']);
|
||||
$change = true;
|
||||
}
|
||||
if(strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) {
|
||||
$user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']);
|
||||
$change = true;
|
||||
}
|
||||
|
||||
if($change) {
|
||||
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
|
||||
WHERE channel_id = %d",
|
||||
intval($user_info['channel_default_group']),
|
||||
dbesc($user_info['channel_allow_gid']),
|
||||
dbesc($user_info['channel_deny_gid']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// remove all members
|
||||
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d ",
|
||||
intval($uid),
|
||||
intval($group_id)
|
||||
);
|
||||
|
||||
// remove group
|
||||
$r = q("UPDATE pgrp SET deleted = 1 WHERE uid = %d AND gname = '%s'",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
|
||||
$ret = $r;
|
||||
|
||||
}
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function byname($uid,$name) {
|
||||
if((! $uid) || (! strlen($name)))
|
||||
return false;
|
||||
$r = q("SELECT * FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
if($r)
|
||||
return $r[0]['id'];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static function rec_byhash($uid,$hash) {
|
||||
if((! $uid) || (! strlen($hash)))
|
||||
return false;
|
||||
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($hash)
|
||||
);
|
||||
if($r)
|
||||
return $r[0];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static function member_remove($uid,$name,$member) {
|
||||
$gid = self::byname($uid,$name);
|
||||
if(! $gid)
|
||||
return false;
|
||||
if(! ( $uid && $gid && $member))
|
||||
return false;
|
||||
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
);
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
static function member_add($uid,$name,$member,$gid = 0) {
|
||||
if(! $gid)
|
||||
$gid = self::byname($uid,$name);
|
||||
if((! $gid) || (! $uid) || (! $member))
|
||||
return false;
|
||||
|
||||
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
);
|
||||
if($r)
|
||||
return true; // You might question this, but
|
||||
// we indicate success because the group member was in fact created
|
||||
// -- It was just created at another time
|
||||
if(! $r)
|
||||
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
|
||||
VALUES( %d, %d, '%s' ) ",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
);
|
||||
|
||||
Libsync::build_sync_packet($uid,null,true);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
static function members($gid) {
|
||||
$ret = array();
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT * FROM pgrp_member
|
||||
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
|
||||
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
|
||||
intval($gid),
|
||||
intval(local_channel()),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r)
|
||||
$ret = $r;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function members_xchan($gid) {
|
||||
$ret = [];
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
|
||||
intval($gid),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$ret[] = $rr['xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function members_profile_xchan($uid,$gid) {
|
||||
$ret = [];
|
||||
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d",
|
||||
intval($gid),
|
||||
intval($uid)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$ret[] = $rr['xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static function select($uid,$group = '') {
|
||||
|
||||
$grps = [];
|
||||
$o = '';
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($uid)
|
||||
);
|
||||
$grps[] = array('name' => '', 'hash' => '0', 'selected' => '');
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$grps[] = array('name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : ''));
|
||||
}
|
||||
|
||||
}
|
||||
logger('select: ' . print_r($grps,true), LOGGER_DATA);
|
||||
|
||||
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
|
||||
'$label' => t('Add new connections to this privacy group'),
|
||||
'$groups' => $grps
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static function widget($every="connections",$each="group",$edit = false, $group_id = 0, $cid = '',$mode = 1) {
|
||||
|
||||
$o = '';
|
||||
|
||||
if(! (local_channel() && feature_enabled(local_channel(),'groups'))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
$member_of = array();
|
||||
if($cid) {
|
||||
$member_of = self::containing(local_channel(),$cid);
|
||||
}
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
|
||||
|
||||
if ($edit) {
|
||||
$groupedit = [ 'href' => "group/".$rr['id'], 'title' => t('edit') ];
|
||||
}
|
||||
else {
|
||||
$groupedit = null;
|
||||
}
|
||||
|
||||
$groups[] = [
|
||||
'id' => $rr['id'],
|
||||
'enc_cid' => base64url_encode($cid),
|
||||
'cid' => $cid,
|
||||
'text' => $rr['gname'],
|
||||
'selected' => $selected,
|
||||
'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''),
|
||||
'edit' => $groupedit,
|
||||
'ismember' => in_array($rr['id'],$member_of),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$tpl = get_markup_template("group_side.tpl");
|
||||
$o = replace_macros($tpl, array(
|
||||
'$title' => t('Privacy Groups'),
|
||||
'$edittext' => t('Edit group'),
|
||||
'$createtext' => t('Add privacy group'),
|
||||
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''),
|
||||
'$groups' => $groups,
|
||||
'$add' => t('add'),
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
static function expand($g) {
|
||||
if(! (is_array($g) && count($g)))
|
||||
return array();
|
||||
|
||||
$ret = [];
|
||||
$x = [];
|
||||
|
||||
// private profile linked virtual groups
|
||||
|
||||
foreach($g as $gv) {
|
||||
if(substr($gv,0,3) === 'vp.') {
|
||||
$profile_hash = substr($gv,3);
|
||||
if($profile_hash) {
|
||||
$r = q("select abook_xchan from abook where abook_profile = '%s'",
|
||||
dbesc($profile_hash)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rv) {
|
||||
$ret[] = $rv['abook_xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$x[] = $gv;
|
||||
}
|
||||
}
|
||||
|
||||
if($x) {
|
||||
stringify_array_elms($x,true);
|
||||
$groups = implode(',', $x);
|
||||
if($groups) {
|
||||
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$ret[] = $rr['xchan'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function member_of($c) {
|
||||
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ",
|
||||
dbesc($c)
|
||||
);
|
||||
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
static function containing($uid,$c) {
|
||||
|
||||
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
|
||||
intval($uid),
|
||||
dbesc($c)
|
||||
);
|
||||
|
||||
$ret = array();
|
||||
if($r) {
|
||||
foreach($r as $rr)
|
||||
$ret[] = $rr['gid'];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
165
Zotlabs/Lib/IConfig.php
Normal file
165
Zotlabs/Lib/IConfig.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
|
||||
class IConfig {
|
||||
|
||||
static public function Load(&$item) {
|
||||
return;
|
||||
}
|
||||
|
||||
static public function Get(&$item, $family, $key, $default = false) {
|
||||
|
||||
$is_item = false;
|
||||
|
||||
if(is_array($item)) {
|
||||
$is_item = true;
|
||||
if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
|
||||
$item['iconfig'] = array();
|
||||
|
||||
if(array_key_exists('item_id',$item))
|
||||
$iid = $item['item_id'];
|
||||
else
|
||||
$iid = $item['id'];
|
||||
}
|
||||
elseif(intval($item))
|
||||
$iid = $item;
|
||||
|
||||
if(! $iid)
|
||||
return $default;
|
||||
|
||||
if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) {
|
||||
foreach($item['iconfig'] as $c) {
|
||||
if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key)
|
||||
return $c['v'];
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1",
|
||||
intval($iid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
if($r) {
|
||||
$r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
|
||||
if($is_item)
|
||||
$item['iconfig'][] = $r[0];
|
||||
return $r[0]['v'];
|
||||
}
|
||||
return $default;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* IConfig::Set(&$item, $family, $key, $value, $sharing = false);
|
||||
*
|
||||
* $item - item array or item id. If passed an array the iconfig meta information is
|
||||
* added to the item structure (which will need to be saved with item_store eventually).
|
||||
* If passed an id, the DB is updated, but may not be federated and/or cloned.
|
||||
* $family - namespace of meta variable
|
||||
* $key - key of meta variable
|
||||
* $value - value of meta variable
|
||||
* $sharing - boolean (default false); if true the meta information is propagated with the item
|
||||
* to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered.
|
||||
* If the meta information is added after delivery and you wish it to be shared, it may be necessary to
|
||||
* alter the item edited timestamp and invoke the delivery process on the updated item. The edited
|
||||
* timestamp needs to be altered in order to trigger an item_store_update() at the receiving end.
|
||||
*/
|
||||
|
||||
|
||||
static public function Set(&$item, $family, $key, $value, $sharing = false) {
|
||||
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
$is_item = false;
|
||||
$idx = null;
|
||||
|
||||
if(is_array($item)) {
|
||||
$is_item = true;
|
||||
if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
|
||||
$item['iconfig'] = array();
|
||||
elseif($item['iconfig']) {
|
||||
for($x = 0; $x < count($item['iconfig']); $x ++) {
|
||||
if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
|
||||
$idx = $x;
|
||||
}
|
||||
}
|
||||
}
|
||||
$entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing);
|
||||
|
||||
if(is_null($idx))
|
||||
$item['iconfig'][] = $entry;
|
||||
else
|
||||
$item['iconfig'][$idx] = $entry;
|
||||
return $value;
|
||||
}
|
||||
|
||||
if(intval($item))
|
||||
$iid = intval($item);
|
||||
|
||||
if(! $iid)
|
||||
return false;
|
||||
|
||||
if(self::Get($item, $family, $key) === false) {
|
||||
$r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ",
|
||||
intval($iid),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue),
|
||||
intval($sharing)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ",
|
||||
dbesc($dbvalue),
|
||||
intval($sharing),
|
||||
intval($iid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
}
|
||||
|
||||
if(! $r)
|
||||
return false;
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static public function Delete(&$item, $family, $key) {
|
||||
|
||||
|
||||
$is_item = false;
|
||||
$idx = null;
|
||||
|
||||
if(is_array($item)) {
|
||||
$is_item = true;
|
||||
if(is_array($item['iconfig'])) {
|
||||
for($x = 0; $x < count($item['iconfig']); $x ++) {
|
||||
if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
|
||||
unset($item['iconfig'][$x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(intval($item))
|
||||
$iid = intval($item);
|
||||
|
||||
if(! $iid)
|
||||
return false;
|
||||
|
||||
return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ",
|
||||
intval($iid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
122
Zotlabs/Lib/Img_filesize.php
Normal file
122
Zotlabs/Lib/Img_filesize.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
class Img_filesize {
|
||||
|
||||
private $url;
|
||||
|
||||
function __construct($url) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
function getSize() {
|
||||
$size = null;
|
||||
|
||||
if(stripos($this->url,z_root() . '/photo') !== false) {
|
||||
$size = self::getLocalFileSize($this->url);
|
||||
}
|
||||
if(! $size) {
|
||||
$size = getRemoteFileSize($this->url);
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
|
||||
static function getLocalFileSize($url) {
|
||||
|
||||
$fname = basename($url);
|
||||
$resolution = 0;
|
||||
|
||||
if(strpos($fname,'.') !== false)
|
||||
$fname = substr($fname,0,strpos($fname,'.'));
|
||||
|
||||
if(substr($fname,-2,1) == '-') {
|
||||
$resolution = intval(substr($fname,-1,1));
|
||||
$fname = substr($fname,0,-2);
|
||||
}
|
||||
|
||||
$r = q("SELECT filesize FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
|
||||
dbesc($fname),
|
||||
intval($resolution)
|
||||
);
|
||||
if($r) {
|
||||
return $r[0]['filesize'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to determine the size of a remote file by making an HTTP request for
|
||||
* a byte range, or look for the content-length header in the response.
|
||||
* The function aborts the transfer as soon as the size is found, or if no
|
||||
* length headers are returned, it aborts the transfer.
|
||||
*
|
||||
* @return int|null null if size could not be determined, or length of content
|
||||
*/
|
||||
function getRemoteFileSize($url)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
|
||||
$headers = array(
|
||||
'Range: bytes=0-1',
|
||||
'Connection: close',
|
||||
);
|
||||
|
||||
$in_headers = true;
|
||||
$size = null;
|
||||
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2450.0 Iron/46.0.2450.0');
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, 0); // set to 1 to debug
|
||||
curl_setopt($ch, CURLOPT_STDERR, fopen('php://output', 'r'));
|
||||
|
||||
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $line) use (&$in_headers, &$size) {
|
||||
$length = strlen($line);
|
||||
|
||||
if (trim($line) == '') {
|
||||
$in_headers = false;
|
||||
}
|
||||
|
||||
list($header, $content) = explode(':', $line, 2);
|
||||
$header = strtolower(trim($header));
|
||||
|
||||
if ($header == 'content-range') {
|
||||
// found a content-range header
|
||||
list($rng, $s) = explode('/', $content, 2);
|
||||
$size = (int)$s;
|
||||
return 0; // aborts transfer
|
||||
} else if ($header == 'content-length' && 206 != curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
|
||||
// found content-length header and this is not a 206 Partial Content response (range response)
|
||||
$size = (int)$content;
|
||||
return 0;
|
||||
} else {
|
||||
// continue
|
||||
return $length;
|
||||
}
|
||||
});
|
||||
|
||||
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) use ($in_headers) {
|
||||
if (!$in_headers) {
|
||||
// shouldn't be here unless we couldn't determine file size
|
||||
// abort transfer
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write function is also called when reading headers
|
||||
return strlen($data);
|
||||
});
|
||||
|
||||
curl_exec($ch);
|
||||
curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $size;
|
||||
}
|
||||
72
Zotlabs/Lib/JSalmon.php
Normal file
72
Zotlabs/Lib/JSalmon.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Web\HTTPSig;
|
||||
|
||||
class JSalmon {
|
||||
|
||||
static function sign($data,$key_id,$key,$data_type = 'application/x-zot+json') {
|
||||
|
||||
$data = base64url_encode(json_encode($data,true),true); // strip padding
|
||||
$encoding = 'base64url';
|
||||
$algorithm = 'RSA-SHA256';
|
||||
|
||||
$data = preg_replace('/\s+/','',$data);
|
||||
|
||||
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
|
||||
|
||||
$precomputed = '.' . base64url_encode($data_type,true) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng';
|
||||
|
||||
$signature = base64url_encode(rsa_sign($data . $precomputed, $key), true);
|
||||
|
||||
return ([
|
||||
'signed' => true,
|
||||
'data' => $data,
|
||||
'data_type' => $data_type,
|
||||
'encoding' => $encoding,
|
||||
'alg' => $algorithm,
|
||||
'sigs' => [
|
||||
'value' => $signature,
|
||||
'key_id' => base64url_encode($key_id, true)
|
||||
]
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
static function verify($x) {
|
||||
|
||||
logger('verify');
|
||||
$ret = [ 'results' => [] ];
|
||||
|
||||
if(! is_array($x)) {
|
||||
return $false;
|
||||
}
|
||||
if(! ( array_key_exists('signed',$x) && $x['signed'])) {
|
||||
return $false;
|
||||
}
|
||||
|
||||
$signed_data = preg_replace('/\s+/','',$x['data']) . '.'
|
||||
. base64url_encode($x['data_type'],true) . '.'
|
||||
. base64url_encode($x['encoding'],true) . '.'
|
||||
. base64url_encode($x['alg'],true);
|
||||
|
||||
$key = HTTPSig::get_key(EMPTY_STR,base64url_decode($x['sigs']['key_id']));
|
||||
logger('key: ' . print_r($key,true));
|
||||
if($key['portable_id'] && $key['public_key']) {
|
||||
if(rsa_verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) {
|
||||
logger('verified');
|
||||
$ret = [ 'success' => true, 'signer' => $key['portable_id'], 'hubloc' => $key['hubloc'] ];
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
static function unpack($data) {
|
||||
return json_decode(base64url_decode($data),true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
135
Zotlabs/Lib/LDSignatures.php
Normal file
135
Zotlabs/Lib/LDSignatures.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
require_once('library/jsonld/jsonld.php');
|
||||
|
||||
class LDSignatures {
|
||||
|
||||
|
||||
static function verify($data,$pubkey) {
|
||||
|
||||
$ohash = self::hash(self::signable_options($data['signature']));
|
||||
$dhash = self::hash(self::signable_data($data));
|
||||
|
||||
$x = rsa_verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey);
|
||||
logger('LD-verify: ' . intval($x));
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
static function dopplesign(&$data,$channel) {
|
||||
// remove for the time being - performance issues
|
||||
// $data['magicEnv'] = self::salmon_sign($data,$channel);
|
||||
return self::sign($data,$channel);
|
||||
}
|
||||
|
||||
static function sign($data,$channel) {
|
||||
|
||||
$options = [
|
||||
'type' => 'RsaSignature2017',
|
||||
'nonce' => random_string(64),
|
||||
'creator' => z_root() . '/channel/' . $channel['channel_address'],
|
||||
'created' => datetime_convert('UTC','UTC', 'now', 'Y-m-d\TH:i:s\Z')
|
||||
];
|
||||
|
||||
$ohash = self::hash(self::signable_options($options));
|
||||
$dhash = self::hash(self::signable_data($data));
|
||||
$options['signatureValue'] = base64_encode(rsa_sign($ohash . $dhash,$channel['channel_prvkey']));
|
||||
|
||||
$signed = array_merge([
|
||||
'@context' => [
|
||||
ACTIVITYSTREAMS_JSONLD_REV,
|
||||
'https://w3id.org/security/v1' ],
|
||||
],$options);
|
||||
|
||||
return $signed;
|
||||
}
|
||||
|
||||
|
||||
static function signable_data($data) {
|
||||
|
||||
$newdata = [];
|
||||
if($data) {
|
||||
foreach($data as $k => $v) {
|
||||
if(! in_array($k,[ 'signature' ])) {
|
||||
$newdata[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return json_encode($newdata,JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
|
||||
static function signable_options($options) {
|
||||
|
||||
$newopts = [ '@context' => 'https://w3id.org/identity/v1' ];
|
||||
if($options) {
|
||||
foreach($options as $k => $v) {
|
||||
if(! in_array($k,[ 'type','id','signatureValue' ])) {
|
||||
$newopts[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return json_encode($newopts,JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
static function hash($obj) {
|
||||
|
||||
return hash('sha256',self::normalise($obj));
|
||||
}
|
||||
|
||||
static function normalise($data) {
|
||||
if(is_string($data)) {
|
||||
$data = json_decode($data);
|
||||
}
|
||||
|
||||
if(! is_object($data))
|
||||
return '';
|
||||
|
||||
jsonld_set_document_loader('jsonld_document_loader');
|
||||
|
||||
try {
|
||||
$d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
logger('normalise error:' . print_r($e,true));
|
||||
logger('normalise error: ' . print_r($data,true));
|
||||
}
|
||||
|
||||
return $d;
|
||||
}
|
||||
|
||||
static function salmon_sign($data,$channel) {
|
||||
|
||||
$arr = $data;
|
||||
$data = json_encode($data,JSON_UNESCAPED_SLASHES);
|
||||
$data = base64url_encode($data, false); // do not strip padding
|
||||
$data_type = 'application/activity+json';
|
||||
$encoding = 'base64url';
|
||||
$algorithm = 'RSA-SHA256';
|
||||
$keyhash = base64url_encode(z_root() . '/channel/' . $channel['channel_address']);
|
||||
|
||||
$data = str_replace(array(" ","\t","\r","\n"),array("","","",""),$data);
|
||||
|
||||
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
|
||||
|
||||
$precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
|
||||
|
||||
$signature = base64url_encode(rsa_sign($data . $precomputed,$channel['channel_prvkey']));
|
||||
|
||||
return ([
|
||||
'id' => $arr['id'],
|
||||
'meData' => $data,
|
||||
'meDataType' => $data_type,
|
||||
'meEncoding' => $encoding,
|
||||
'meAlgorithm' => $algorithm,
|
||||
'meCreator' => z_root() . '/channel/' . $channel['channel_address'],
|
||||
'meSignatureValue' => $signature
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
1019
Zotlabs/Lib/Libsync.php
Normal file
1019
Zotlabs/Lib/Libsync.php
Normal file
File diff suppressed because it is too large
Load Diff
3195
Zotlabs/Lib/Libzot.php
Normal file
3195
Zotlabs/Lib/Libzot.php
Normal file
File diff suppressed because it is too large
Load Diff
654
Zotlabs/Lib/Libzotdir.php
Normal file
654
Zotlabs/Lib/Libzotdir.php
Normal file
@@ -0,0 +1,654 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libzot;
|
||||
|
||||
require_once('include/permissions.php');
|
||||
|
||||
|
||||
class Libzotdir {
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param int $dirmode
|
||||
* @return array
|
||||
*/
|
||||
|
||||
static function find_upstream_directory($dirmode) {
|
||||
global $DIRECTORY_FALLBACK_SERVERS;
|
||||
|
||||
$preferred = get_config('system','directory_server');
|
||||
|
||||
// Thwart attempts to use a private directory
|
||||
|
||||
if(($preferred) && ($preferred != z_root())) {
|
||||
$r = q("select * from site where site_url = '%s' limit 1",
|
||||
dbesc($preferred)
|
||||
);
|
||||
if(($r) && ($r[0]['site_flags'] & DIRECTORY_MODE_STANDALONE)) {
|
||||
$preferred = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (! $preferred) {
|
||||
|
||||
/*
|
||||
* No directory has yet been set. For most sites, pick one at random
|
||||
* from our list of directory servers. However, if we're a directory
|
||||
* server ourself, point at the local instance
|
||||
* We will then set this value so this should only ever happen once.
|
||||
* Ideally there will be an admin setting to change to a different
|
||||
* directory server if you don't like our choice or if circumstances change.
|
||||
*/
|
||||
|
||||
$dirmode = intval(get_config('system','directory_mode'));
|
||||
if ($dirmode == DIRECTORY_MODE_NORMAL) {
|
||||
$toss = mt_rand(0,count($DIRECTORY_FALLBACK_SERVERS));
|
||||
$preferred = $DIRECTORY_FALLBACK_SERVERS[$toss];
|
||||
if(! $preferred) {
|
||||
$preferred = DIRECTORY_FALLBACK_MASTER;
|
||||
}
|
||||
set_config('system','directory_server',$preferred);
|
||||
}
|
||||
else {
|
||||
set_config('system','directory_server',z_root());
|
||||
}
|
||||
}
|
||||
if($preferred) {
|
||||
return [ 'url' => $preferred ];
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Directories may come and go over time. We will need to check that our
|
||||
* directory server is still valid occasionally, and reset to something that
|
||||
* is if our directory has gone offline for any reason
|
||||
*/
|
||||
|
||||
static function check_upstream_directory() {
|
||||
|
||||
$directory = get_config('system', 'directory_server');
|
||||
|
||||
// it's possible there is no directory server configured and the local hub is being used.
|
||||
// If so, default to preserving the absence of a specific server setting.
|
||||
|
||||
$isadir = true;
|
||||
|
||||
if ($directory) {
|
||||
$j = Zotfinger::exec($directory);
|
||||
if(array_path_exists('data/directory_mode',$j)) {
|
||||
if ($j['data']['directory_mode'] === 'normal') {
|
||||
$isadir = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! $isadir)
|
||||
set_config('system', 'directory_server', '');
|
||||
}
|
||||
|
||||
|
||||
static function get_directory_setting($observer, $setting) {
|
||||
|
||||
if ($observer)
|
||||
$ret = get_xconfig($observer, 'directory', $setting);
|
||||
else
|
||||
$ret = ((array_key_exists($setting,$_SESSION)) ? intval($_SESSION[$setting]) : false);
|
||||
|
||||
if($ret === false)
|
||||
$ret = get_config('directory', $setting);
|
||||
|
||||
|
||||
// 'safemode' is the default if there is no observer or no established preference.
|
||||
|
||||
if($setting === 'safemode' && $ret === false)
|
||||
$ret = 1;
|
||||
|
||||
if($setting === 'globaldir' && intval(get_config('system','localdir_hide')))
|
||||
$ret = 1;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called by the directory_sort widget.
|
||||
*/
|
||||
static function dir_sort_links() {
|
||||
|
||||
$safe_mode = 1;
|
||||
|
||||
$observer = get_observer_hash();
|
||||
|
||||
$safe_mode = self::get_directory_setting($observer, 'safemode');
|
||||
$globaldir = self::get_directory_setting($observer, 'globaldir');
|
||||
$pubforums = self::get_directory_setting($observer, 'pubforums');
|
||||
|
||||
$hide_local = intval(get_config('system','localdir_hide'));
|
||||
if($hide_local)
|
||||
$globaldir = 1;
|
||||
|
||||
|
||||
// Build urls without order and pubforums so it's easy to tack on the changed value
|
||||
// Probably there's an easier way to do this
|
||||
|
||||
$directory_sort_order = get_config('system','directory_sort_order');
|
||||
if(! $directory_sort_order)
|
||||
$directory_sort_order = 'date';
|
||||
|
||||
$current_order = (($_REQUEST['order']) ? $_REQUEST['order'] : $directory_sort_order);
|
||||
$suggest = (($_REQUEST['suggest']) ? '&suggest=' . $_REQUEST['suggest'] : '');
|
||||
|
||||
$url = 'directory?f=';
|
||||
|
||||
$tmp = array_merge($_GET,$_POST);
|
||||
unset($tmp['suggest']);
|
||||
unset($tmp['pubforums']);
|
||||
unset($tmp['global']);
|
||||
unset($tmp['safe']);
|
||||
unset($tmp['q']);
|
||||
unset($tmp['f']);
|
||||
$forumsurl = $url . http_build_query($tmp) . $suggest;
|
||||
|
||||
$o = replace_macros(get_markup_template('dir_sort_links.tpl'), [
|
||||
'$header' => t('Directory Options'),
|
||||
'$forumsurl' => $forumsurl,
|
||||
'$safemode' => array('safemode', t('Safe Mode'),$safe_mode,'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&safe="+(this.checked ? 1 : 0)\''),
|
||||
'$pubforums' => array('pubforums', t('Public Forums Only'),$pubforums,'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&pubforums="+(this.checked ? 1 : 0)\''),
|
||||
'$hide_local' => $hide_local,
|
||||
'$globaldir' => array('globaldir', t('This Website Only'), 1-intval($globaldir),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&global="+(this.checked ? 0 : 1)\''),
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks the directory mode of this hub.
|
||||
*
|
||||
* Checks the directory mode of this hub to see if it is some form of directory server. If it is,
|
||||
* get the directory realm of this hub. Fetch a list of all other directory servers in this realm and request
|
||||
* a directory sync packet. This will contain both directory updates and new ratings. Store these all in the DB.
|
||||
* In the case of updates, we will query each of them asynchronously from a poller task. Ratings are stored
|
||||
* directly if the rater's signature matches.
|
||||
*
|
||||
* @param int $dirmode;
|
||||
*/
|
||||
|
||||
static function sync_directories($dirmode) {
|
||||
|
||||
if ($dirmode == DIRECTORY_MODE_STANDALONE || $dirmode == DIRECTORY_MODE_NORMAL)
|
||||
return;
|
||||
|
||||
$realm = get_directory_realm();
|
||||
if ($realm == DIRECTORY_REALM) {
|
||||
$r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_type = %d and ( site_realm = '%s' or site_realm = '') ",
|
||||
intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY),
|
||||
dbesc(z_root()),
|
||||
intval(SITE_TYPE_ZOT),
|
||||
dbesc($realm)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_realm like '%s' and site_type = %d ",
|
||||
intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY),
|
||||
dbesc(z_root()),
|
||||
dbesc(protect_sprintf('%' . $realm . '%')),
|
||||
intval(SITE_TYPE_ZOT)
|
||||
);
|
||||
}
|
||||
|
||||
// If there are no directory servers, setup the fallback master
|
||||
/** @FIXME What to do if we're in a different realm? */
|
||||
|
||||
if ((! $r) && (z_root() != DIRECTORY_FALLBACK_MASTER)) {
|
||||
|
||||
$x = site_store_lowlevel(
|
||||
[
|
||||
'site_url' => DIRECTORY_FALLBACK_MASTER,
|
||||
'site_flags' => DIRECTORY_MODE_PRIMARY,
|
||||
'site_update' => NULL_DATE,
|
||||
'site_directory' => DIRECTORY_FALLBACK_MASTER . '/dirsearch',
|
||||
'site_realm' => DIRECTORY_REALM,
|
||||
'site_valid' => 1,
|
||||
]
|
||||
);
|
||||
|
||||
$r = q("select * from site where site_flags in (%d, %d) and site_url != '%s' and site_type = %d ",
|
||||
intval(DIRECTORY_MODE_PRIMARY),
|
||||
intval(DIRECTORY_MODE_SECONDARY),
|
||||
dbesc(z_root()),
|
||||
intval(SITE_TYPE_ZOT)
|
||||
);
|
||||
}
|
||||
if (! $r)
|
||||
return;
|
||||
|
||||
foreach ($r as $rr) {
|
||||
if (! $rr['site_directory'])
|
||||
continue;
|
||||
|
||||
logger('sync directories: ' . $rr['site_directory']);
|
||||
|
||||
// for brand new directory servers, only load the last couple of days.
|
||||
// It will take about a month for a new directory to obtain the full current repertoire of channels.
|
||||
/** @FIXME Go back and pick up earlier ratings if this is a new directory server. These do not get refreshed. */
|
||||
|
||||
$token = get_config('system','realm_token');
|
||||
|
||||
$syncdate = (($rr['site_sync'] <= NULL_DATE) ? datetime_convert('UTC','UTC','now - 2 days') : $rr['site_sync']);
|
||||
$x = z_fetch_url($rr['site_directory'] . '?f=&sync=' . urlencode($syncdate) . (($token) ? '&t=' . $token : ''));
|
||||
|
||||
if (! $x['success'])
|
||||
continue;
|
||||
|
||||
$j = json_decode($x['body'],true);
|
||||
if (!($j['transactions']) || ($j['ratings']))
|
||||
continue;
|
||||
|
||||
q("update site set site_sync = '%s' where site_url = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($rr['site_url'])
|
||||
);
|
||||
|
||||
logger('sync_directories: ' . $rr['site_url'] . ': ' . print_r($j,true), LOGGER_DATA);
|
||||
|
||||
if (is_array($j['transactions']) && count($j['transactions'])) {
|
||||
foreach ($j['transactions'] as $t) {
|
||||
$r = q("select * from updates where ud_guid = '%s' limit 1",
|
||||
dbesc($t['transaction_id'])
|
||||
);
|
||||
if($r)
|
||||
continue;
|
||||
|
||||
$ud_flags = 0;
|
||||
if (is_array($t['flags']) && in_array('deleted',$t['flags']))
|
||||
$ud_flags |= UPDATE_FLAGS_DELETED;
|
||||
if (is_array($t['flags']) && in_array('forced',$t['flags']))
|
||||
$ud_flags |= UPDATE_FLAGS_FORCED;
|
||||
|
||||
$z = q("insert into updates ( ud_hash, ud_guid, ud_date, ud_flags, ud_addr )
|
||||
values ( '%s', '%s', '%s', %d, '%s' ) ",
|
||||
dbesc($t['hash']),
|
||||
dbesc($t['transaction_id']),
|
||||
dbesc($t['timestamp']),
|
||||
intval($ud_flags),
|
||||
dbesc($t['address'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* Given an update record, probe the channel, grab a zot-info packet and refresh/sync the data.
|
||||
*
|
||||
* Ignore updating records marked as deleted.
|
||||
*
|
||||
* If successful, sets ud_last in the DB to the current datetime for this
|
||||
* reddress/webbie.
|
||||
*
|
||||
* @param array $ud Entry from update table
|
||||
*/
|
||||
|
||||
static function update_directory_entry($ud) {
|
||||
|
||||
logger('update_directory_entry: ' . print_r($ud,true), LOGGER_DATA);
|
||||
|
||||
if ($ud['ud_addr'] && (! ($ud['ud_flags'] & UPDATE_FLAGS_DELETED))) {
|
||||
$success = false;
|
||||
|
||||
$href = \Zotlabs\Lib\Webfinger::zot_url(punify($ud['ud_addr']));
|
||||
if($href) {
|
||||
$zf = \Zotlabs\Lib\Zotfinger::exec($href);
|
||||
}
|
||||
if(is_array($zf) && array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
|
||||
$xc = Libzot::import_xchan($zf['data'], 0, $ud);
|
||||
}
|
||||
else {
|
||||
q("update updates set ud_last = '%s' where ud_addr = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($ud['ud_addr'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Push local channel updates to a local directory server.
|
||||
*
|
||||
* This is called from include/directory.php if a profile is to be pushed to the
|
||||
* directory and the local hub in this case is any kind of directory server.
|
||||
*
|
||||
* @param int $uid
|
||||
* @param boolean $force
|
||||
*/
|
||||
|
||||
static function local_dir_update($uid, $force) {
|
||||
|
||||
|
||||
logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG);
|
||||
|
||||
$p = q("select channel.channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
$profile = array();
|
||||
$profile['encoding'] = 'zot';
|
||||
|
||||
if ($p) {
|
||||
$hash = $p[0]['channel_hash'];
|
||||
|
||||
$profile['description'] = $p[0]['pdesc'];
|
||||
$profile['birthday'] = $p[0]['dob'];
|
||||
if ($age = age($p[0]['dob'],$p[0]['channel_timezone'],''))
|
||||
$profile['age'] = $age;
|
||||
|
||||
$profile['gender'] = $p[0]['gender'];
|
||||
$profile['marital'] = $p[0]['marital'];
|
||||
$profile['sexual'] = $p[0]['sexual'];
|
||||
$profile['locale'] = $p[0]['locality'];
|
||||
$profile['region'] = $p[0]['region'];
|
||||
$profile['postcode'] = $p[0]['postal_code'];
|
||||
$profile['country'] = $p[0]['country_name'];
|
||||
$profile['about'] = $p[0]['about'];
|
||||
$profile['homepage'] = $p[0]['homepage'];
|
||||
$profile['hometown'] = $p[0]['hometown'];
|
||||
|
||||
if ($p[0]['keywords']) {
|
||||
$tags = array();
|
||||
$k = explode(' ', $p[0]['keywords']);
|
||||
if ($k)
|
||||
foreach ($k as $kk)
|
||||
if (trim($kk))
|
||||
$tags[] = trim($kk);
|
||||
|
||||
if ($tags)
|
||||
$profile['keywords'] = $tags;
|
||||
}
|
||||
|
||||
$hidden = (1 - intval($p[0]['publish']));
|
||||
|
||||
logger('hidden: ' . $hidden);
|
||||
|
||||
$r = q("select xchan_hidden from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($p[0]['channel_hash'])
|
||||
);
|
||||
|
||||
if(intval($r[0]['xchan_hidden']) != $hidden) {
|
||||
$r = q("update xchan set xchan_hidden = %d where xchan_hash = '%s'",
|
||||
intval($hidden),
|
||||
dbesc($p[0]['channel_hash'])
|
||||
);
|
||||
}
|
||||
|
||||
$arr = [ 'channel_id' => $uid, 'hash' => $hash, 'profile' => $profile ];
|
||||
call_hooks('local_dir_update', $arr);
|
||||
|
||||
$address = channel_reddress($p[0]);
|
||||
|
||||
if (perm_is_allowed($uid, '', 'view_profile')) {
|
||||
self::import_directory_profile($hash, $arr['profile'], $address, 0);
|
||||
}
|
||||
else {
|
||||
// they may have made it private
|
||||
$r = q("delete from xprof where xprof_hash = '%s'",
|
||||
dbesc($hash)
|
||||
);
|
||||
$r = q("delete from xtag where xtag_hash = '%s'",
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$ud_hash = random_string() . '@' . \App::get_hostname();
|
||||
self::update_modtime($hash, $ud_hash, channel_reddress($p[0]),(($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Imports a directory profile.
|
||||
*
|
||||
* @param string $hash
|
||||
* @param array $profile
|
||||
* @param string $addr
|
||||
* @param number $ud_flags (optional) UPDATE_FLAGS_UPDATED
|
||||
* @param number $suppress_update (optional) default 0
|
||||
* @return boolean $updated if something changed
|
||||
*/
|
||||
|
||||
static function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLAGS_UPDATED, $suppress_update = 0) {
|
||||
|
||||
logger('import_directory_profile', LOGGER_DEBUG);
|
||||
if (! $hash)
|
||||
return false;
|
||||
|
||||
$arr = array();
|
||||
|
||||
$arr['xprof_hash'] = $hash;
|
||||
$arr['xprof_dob'] = (($profile['birthday'] === '0000-00-00') ? $profile['birthday'] : datetime_convert('','',$profile['birthday'],'Y-m-d')); // !!!! check this for 0000 year
|
||||
$arr['xprof_age'] = (($profile['age']) ? intval($profile['age']) : 0);
|
||||
$arr['xprof_desc'] = (($profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_gender'] = (($profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_marital'] = (($profile['marital']) ? htmlspecialchars($profile['marital'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_sexual'] = (($profile['sexual']) ? htmlspecialchars($profile['sexual'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_locale'] = (($profile['locale']) ? htmlspecialchars($profile['locale'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_region'] = (($profile['region']) ? htmlspecialchars($profile['region'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_postcode'] = (($profile['postcode']) ? htmlspecialchars($profile['postcode'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_country'] = (($profile['country']) ? htmlspecialchars($profile['country'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_about'] = (($profile['about']) ? htmlspecialchars($profile['about'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_homepage'] = (($profile['homepage']) ? htmlspecialchars($profile['homepage'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
$arr['xprof_hometown'] = (($profile['hometown']) ? htmlspecialchars($profile['hometown'], ENT_COMPAT,'UTF-8',false) : '');
|
||||
|
||||
$clean = array();
|
||||
if (array_key_exists('keywords', $profile) and is_array($profile['keywords'])) {
|
||||
self::import_directory_keywords($hash,$profile['keywords']);
|
||||
foreach ($profile['keywords'] as $kw) {
|
||||
$kw = trim(htmlspecialchars($kw,ENT_COMPAT, 'UTF-8', false));
|
||||
$kw = trim($kw, ',');
|
||||
$clean[] = $kw;
|
||||
}
|
||||
}
|
||||
|
||||
$arr['xprof_keywords'] = implode(' ',$clean);
|
||||
|
||||
// Self censored, make it so
|
||||
// These are not translated, so the German "erwachsenen" keyword will not censor the directory profile. Only the English form - "adult".
|
||||
|
||||
|
||||
if(in_arrayi('nsfw',$clean) || in_arrayi('adult',$clean)) {
|
||||
q("update xchan set xchan_selfcensored = 1 where xchan_hash = '%s'",
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
|
||||
$r = q("select * from xprof where xprof_hash = '%s' limit 1",
|
||||
dbesc($hash)
|
||||
);
|
||||
|
||||
if ($arr['xprof_age'] > 150)
|
||||
$arr['xprof_age'] = 150;
|
||||
if ($arr['xprof_age'] < 0)
|
||||
$arr['xprof_age'] = 0;
|
||||
|
||||
if ($r) {
|
||||
$update = false;
|
||||
foreach ($r[0] as $k => $v) {
|
||||
if ((array_key_exists($k,$arr)) && ($arr[$k] != $v)) {
|
||||
logger('import_directory_profile: update ' . $k . ' => ' . $arr[$k]);
|
||||
$update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($update) {
|
||||
q("update xprof set
|
||||
xprof_desc = '%s',
|
||||
xprof_dob = '%s',
|
||||
xprof_age = %d,
|
||||
xprof_gender = '%s',
|
||||
xprof_marital = '%s',
|
||||
xprof_sexual = '%s',
|
||||
xprof_locale = '%s',
|
||||
xprof_region = '%s',
|
||||
xprof_postcode = '%s',
|
||||
xprof_country = '%s',
|
||||
xprof_about = '%s',
|
||||
xprof_homepage = '%s',
|
||||
xprof_hometown = '%s',
|
||||
xprof_keywords = '%s'
|
||||
where xprof_hash = '%s'",
|
||||
dbesc($arr['xprof_desc']),
|
||||
dbesc($arr['xprof_dob']),
|
||||
intval($arr['xprof_age']),
|
||||
dbesc($arr['xprof_gender']),
|
||||
dbesc($arr['xprof_marital']),
|
||||
dbesc($arr['xprof_sexual']),
|
||||
dbesc($arr['xprof_locale']),
|
||||
dbesc($arr['xprof_region']),
|
||||
dbesc($arr['xprof_postcode']),
|
||||
dbesc($arr['xprof_country']),
|
||||
dbesc($arr['xprof_about']),
|
||||
dbesc($arr['xprof_homepage']),
|
||||
dbesc($arr['xprof_hometown']),
|
||||
dbesc($arr['xprof_keywords']),
|
||||
dbesc($arr['xprof_hash'])
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$update = true;
|
||||
logger('New profile');
|
||||
q("insert into xprof (xprof_hash, xprof_desc, xprof_dob, xprof_age, xprof_gender, xprof_marital, xprof_sexual, xprof_locale, xprof_region, xprof_postcode, xprof_country, xprof_about, xprof_homepage, xprof_hometown, xprof_keywords) values ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
|
||||
dbesc($arr['xprof_hash']),
|
||||
dbesc($arr['xprof_desc']),
|
||||
dbesc($arr['xprof_dob']),
|
||||
intval($arr['xprof_age']),
|
||||
dbesc($arr['xprof_gender']),
|
||||
dbesc($arr['xprof_marital']),
|
||||
dbesc($arr['xprof_sexual']),
|
||||
dbesc($arr['xprof_locale']),
|
||||
dbesc($arr['xprof_region']),
|
||||
dbesc($arr['xprof_postcode']),
|
||||
dbesc($arr['xprof_country']),
|
||||
dbesc($arr['xprof_about']),
|
||||
dbesc($arr['xprof_homepage']),
|
||||
dbesc($arr['xprof_hometown']),
|
||||
dbesc($arr['xprof_keywords'])
|
||||
);
|
||||
}
|
||||
|
||||
$d = [
|
||||
'xprof' => $arr,
|
||||
'profile' => $profile,
|
||||
'update' => $update
|
||||
];
|
||||
/**
|
||||
* @hooks import_directory_profile
|
||||
* Called when processing delivery of a profile structure from an external source (usually for directory storage).
|
||||
* * \e array \b xprof
|
||||
* * \e array \b profile
|
||||
* * \e boolean \b update
|
||||
*/
|
||||
call_hooks('import_directory_profile', $d);
|
||||
|
||||
if (($d['update']) && (! $suppress_update))
|
||||
self::update_modtime($arr['xprof_hash'],random_string() . '@' . \App::get_hostname(), $addr, $ud_flags);
|
||||
|
||||
return $d['update'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $hash An xtag_hash
|
||||
* @param array $keywords
|
||||
*/
|
||||
|
||||
static function import_directory_keywords($hash, $keywords) {
|
||||
|
||||
$existing = array();
|
||||
$r = q("select * from xtag where xtag_hash = '%s' and xtag_flags = 0",
|
||||
dbesc($hash)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr)
|
||||
$existing[] = $rr['xtag_term'];
|
||||
}
|
||||
|
||||
$clean = array();
|
||||
foreach($keywords as $kw) {
|
||||
$kw = trim(htmlspecialchars($kw,ENT_COMPAT, 'UTF-8', false));
|
||||
$kw = trim($kw, ',');
|
||||
$clean[] = $kw;
|
||||
}
|
||||
|
||||
foreach($existing as $x) {
|
||||
if(! in_array($x, $clean))
|
||||
$r = q("delete from xtag where xtag_hash = '%s' and xtag_term = '%s' and xtag_flags = 0",
|
||||
dbesc($hash),
|
||||
dbesc($x)
|
||||
);
|
||||
}
|
||||
foreach($clean as $x) {
|
||||
if(! in_array($x, $existing)) {
|
||||
$r = q("insert into xtag ( xtag_hash, xtag_term, xtag_flags) values ( '%s' ,'%s', 0 )",
|
||||
dbesc($hash),
|
||||
dbesc($x)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $hash
|
||||
* @param string $guid
|
||||
* @param string $addr
|
||||
* @param int $flags (optional) default 0
|
||||
*/
|
||||
|
||||
static function update_modtime($hash, $guid, $addr, $flags = 0) {
|
||||
|
||||
$dirmode = intval(get_config('system', 'directory_mode'));
|
||||
|
||||
if($dirmode == DIRECTORY_MODE_NORMAL)
|
||||
return;
|
||||
|
||||
if($flags) {
|
||||
q("insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' )",
|
||||
dbesc($hash),
|
||||
dbesc($guid),
|
||||
dbesc(datetime_convert()),
|
||||
intval($flags),
|
||||
dbesc($addr)
|
||||
);
|
||||
}
|
||||
else {
|
||||
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d)>0 ",
|
||||
intval(UPDATE_FLAGS_UPDATED),
|
||||
dbesc($addr),
|
||||
intval(UPDATE_FLAGS_UPDATED)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
132
Zotlabs/Lib/MarkdownSoap.php
Normal file
132
Zotlabs/Lib/MarkdownSoap.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief MarkdownSoap class.
|
||||
*
|
||||
* Purify Markdown for storage
|
||||
* @code{.php}
|
||||
* $x = new MarkdownSoap($string_to_be_cleansed);
|
||||
* $text = $x->clean();
|
||||
* @endcode
|
||||
* What this does:
|
||||
* 1. extracts code blocks and privately escapes them from processing
|
||||
* 2. Run html purifier on the content
|
||||
* 3. put back the code blocks
|
||||
* 4. run htmlspecialchars on the entire content for safe storage
|
||||
*
|
||||
* At render time:
|
||||
* @code{.php}
|
||||
* $markdown = \Zotlabs\Lib\MarkdownSoap::unescape($text);
|
||||
* $html = \Michelf\MarkdownExtra::DefaultTransform($markdown);
|
||||
* @endcode
|
||||
*/
|
||||
class MarkdownSoap {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $str;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $token;
|
||||
|
||||
|
||||
function __construct($s) {
|
||||
$this->str = $s;
|
||||
$this->token = random_string(20);
|
||||
}
|
||||
|
||||
function clean() {
|
||||
|
||||
$x = $this->extract_code($this->str);
|
||||
|
||||
$x = $this->purify($x);
|
||||
|
||||
$x = $this->putback_code($x);
|
||||
|
||||
$x = $this->escape($x);
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Extracts code blocks and privately escapes them from processing.
|
||||
*
|
||||
* @see encode_code()
|
||||
* @see putback_code()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
function extract_code($s) {
|
||||
|
||||
$text = preg_replace_callback('{
|
||||
(?:\n\n|\A\n?)
|
||||
( # $1 = the code block -- one or more lines, starting with a space/tab
|
||||
(?>
|
||||
[ ]{'.'4'.'} # Lines must start with a tab or a tab-width of spaces
|
||||
.*\n+
|
||||
)+
|
||||
)
|
||||
((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
|
||||
}xm',
|
||||
[ $this , 'encode_code' ], $s);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
function encode_code($matches) {
|
||||
return $this->token . ';' . base64_encode($matches[0]) . ';' ;
|
||||
}
|
||||
|
||||
function decode_code($matches) {
|
||||
return base64_decode($matches[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put back the code blocks.
|
||||
*
|
||||
* @see extract_code()
|
||||
* @see decode_code()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
function putback_code($s) {
|
||||
$text = preg_replace_callback('{' . $this->token . '\;(.*?)\;}xm', [ $this, 'decode_code' ], $s);
|
||||
return $text;
|
||||
}
|
||||
|
||||
function purify($s) {
|
||||
$s = $this->protect_autolinks($s);
|
||||
$s = purify_html($s);
|
||||
$s = $this->unprotect_autolinks($s);
|
||||
return $s;
|
||||
}
|
||||
|
||||
function protect_autolinks($s) {
|
||||
$s = preg_replace('/\<(https?\:\/\/)(.*?)\>/', '[$1$2]($1$2)', $s);
|
||||
return $s;
|
||||
}
|
||||
|
||||
function unprotect_autolinks($s) {
|
||||
return $s;
|
||||
}
|
||||
|
||||
function escape($s) {
|
||||
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts special HTML entities back to characters.
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
static public function unescape($s) {
|
||||
return htmlspecialchars_decode($s, ENT_QUOTES);
|
||||
}
|
||||
}
|
||||
93
Zotlabs/Lib/MessageFilter.php
Normal file
93
Zotlabs/Lib/MessageFilter.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
|
||||
class MessageFilter {
|
||||
|
||||
|
||||
static public function evaluate($item,$incl,$excl) {
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
unobscure($item);
|
||||
|
||||
$text = prepare_text($item['body'],$item['mimetype']);
|
||||
$text = html2plain(($item['title']) ? $item['title'] . ' ' . $text : $text);
|
||||
|
||||
|
||||
$lang = null;
|
||||
|
||||
if((strpos($incl,'lang=') !== false) || (strpos($excl,'lang=') !== false) || (strpos($incl,'lang!=') !== false) || (strpos($excl,'lang!=') !== false)) {
|
||||
$lang = detect_language($text);
|
||||
}
|
||||
|
||||
$tags = ((is_array($item['term']) && count($item['term'])) ? $item['term'] : false);
|
||||
|
||||
// exclude always has priority
|
||||
|
||||
$exclude = (($excl) ? explode("\n",$excl) : null);
|
||||
|
||||
if($exclude) {
|
||||
foreach($exclude as $word) {
|
||||
$word = trim($word);
|
||||
if(! $word)
|
||||
continue;
|
||||
if(substr($word,0,1) === '#' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return false;
|
||||
}
|
||||
elseif(substr($word,0,1) === '$' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return false;
|
||||
}
|
||||
elseif((strpos($word,'/') === 0) && preg_match($word,$text))
|
||||
return false;
|
||||
elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0))
|
||||
return false;
|
||||
elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0))
|
||||
return false;
|
||||
elseif(stristr($text,$word) !== false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$include = (($incl) ? explode("\n",$incl) : null);
|
||||
|
||||
if($include) {
|
||||
foreach($include as $word) {
|
||||
$word = trim($word);
|
||||
if(! $word)
|
||||
continue;
|
||||
if(substr($word,0,1) === '#' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return true;
|
||||
}
|
||||
elseif(substr($word,0,1) === '$' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if(($t['ttype'] == TERM_CATEGORY) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
return true;
|
||||
}
|
||||
elseif((strpos($word,'/') === 0) && preg_match($word,$text))
|
||||
return true;
|
||||
elseif((strpos($word,'lang=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,5))) == 0))
|
||||
return true;
|
||||
elseif((strpos($word,'lang!=') === 0) && ($lang) && (strcasecmp($lang,trim(substr($word,6))) != 0))
|
||||
return true;
|
||||
elseif(stristr($text,$word) !== false)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
311
Zotlabs/Lib/NativeWiki.php
Normal file
311
Zotlabs/Lib/NativeWiki.php
Normal file
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
define ( 'NWIKI_ITEM_RESOURCE_TYPE', 'nwiki' );
|
||||
|
||||
class NativeWiki {
|
||||
|
||||
|
||||
static public function listwikis($channel, $observer_hash) {
|
||||
|
||||
$sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash);
|
||||
$wikis = q("SELECT * FROM item
|
||||
WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra",
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if($wikis) {
|
||||
foreach($wikis as &$w) {
|
||||
|
||||
$w['json_allow_cid'] = acl2json($w['allow_cid']);
|
||||
$w['json_allow_gid'] = acl2json($w['allow_gid']);
|
||||
$w['json_deny_cid'] = acl2json($w['deny_cid']);
|
||||
$w['json_deny_gid'] = acl2json($w['deny_gid']);
|
||||
|
||||
$w['rawName'] = get_iconfig($w, 'wiki', 'rawName');
|
||||
$w['htmlName'] = escape_tags($w['rawName']);
|
||||
//$w['urlName'] = urlencode(urlencode($w['rawName']));
|
||||
$w['urlName'] = self::name_encode($w['rawName']);
|
||||
$w['mimeType'] = get_iconfig($w, 'wiki', 'mimeType');
|
||||
$w['typelock'] = get_iconfig($w, 'wiki', 'typelock');
|
||||
$w['lockstate'] = (($w['allow_cid'] || $w['allow_gid'] || $w['deny_cid'] || $w['deny_gid']) ? 'lock' : 'unlock');
|
||||
}
|
||||
}
|
||||
// TODO: query db for wikis the observer can access. Return with two lists, for read and write access
|
||||
return array('wikis' => $wikis);
|
||||
}
|
||||
|
||||
|
||||
function create_wiki($channel, $observer_hash, $wiki, $acl) {
|
||||
|
||||
$resource_id = new_uuid();
|
||||
$uuid = new_uuid();
|
||||
|
||||
$ac = $acl->get();
|
||||
$mid = z_root() . '/item/' . $uuid;
|
||||
|
||||
$arr = array(); // Initialize the array of parameters for the post
|
||||
$item_hidden = ((intval($wiki['postVisible']) === 0) ? 1 : 0);
|
||||
$wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName'];
|
||||
$arr['aid'] = $channel['channel_account_id'];
|
||||
$arr['uuid'] = $uuid;
|
||||
$arr['uid'] = $channel['channel_id'];
|
||||
$arr['mid'] = $mid;
|
||||
$arr['parent_mid'] = $mid;
|
||||
$arr['item_hidden'] = $item_hidden;
|
||||
$arr['resource_type'] = NWIKI_ITEM_RESOURCE_TYPE;
|
||||
$arr['resource_id'] = $resource_id;
|
||||
$arr['owner_xchan'] = $channel['channel_hash'];
|
||||
$arr['author_xchan'] = $observer_hash;
|
||||
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
|
||||
$arr['llink'] = $arr['plink'];
|
||||
$arr['title'] = $wiki['htmlName']; // name of new wiki;
|
||||
$arr['allow_cid'] = $ac['allow_cid'];
|
||||
$arr['allow_gid'] = $ac['allow_gid'];
|
||||
$arr['deny_cid'] = $ac['deny_cid'];
|
||||
$arr['deny_gid'] = $ac['deny_gid'];
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_thread_top'] = 1;
|
||||
$arr['item_private'] = intval($acl->is_private());
|
||||
$arr['verb'] = ACTIVITY_CREATE;
|
||||
$arr['obj_type'] = ACTIVITY_OBJ_WIKI;
|
||||
$arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]';
|
||||
|
||||
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_wiki'),true);
|
||||
|
||||
// Save the wiki name information using iconfig. This is shareable.
|
||||
if(! set_iconfig($arr, 'wiki', 'rawName', $wiki['rawName'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
if(! set_iconfig($arr, 'wiki', 'mimeType', $wiki['mimeType'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
|
||||
set_iconfig($arr,'wiki','typelock',$wiki['typelock'],true);
|
||||
|
||||
$post = item_store($arr);
|
||||
|
||||
$item_id = $post['item_id'];
|
||||
|
||||
if($item_id) {
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'activity', $item_id));
|
||||
return array('item' => $post['item'], 'item_id' => $item_id, 'success' => true);
|
||||
}
|
||||
else {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
|
||||
function update_wiki($channel_id, $observer_hash, $arr, $acl) {
|
||||
|
||||
$w = self::get_wiki($channel_id, $observer_hash, $arr['resource_id']);
|
||||
$item = $w['wiki'];
|
||||
|
||||
if(! $item) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
|
||||
$x = $acl->get();
|
||||
|
||||
$item['allow_cid'] = $x['allow_cid'];
|
||||
$item['allow_gid'] = $x['allow_gid'];
|
||||
$item['deny_cid'] = $x['deny_cid'];
|
||||
$item['deny_gid'] = $x['deny_gid'];
|
||||
$item['item_private'] = intval($acl->is_private());
|
||||
|
||||
$update_title = false;
|
||||
|
||||
if($item['title'] !== $arr['updateRawName']) {
|
||||
$update_title = true;
|
||||
$item['title'] = $arr['updateRawName'];
|
||||
}
|
||||
|
||||
$update = item_store_update($item);
|
||||
|
||||
$item_id = $update['item_id'];
|
||||
|
||||
// update acl for any existing wiki pages
|
||||
|
||||
q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d where resource_type = 'nwikipage' and resource_id = '%s'",
|
||||
dbesc($item['allow_cid']),
|
||||
dbesc($item['allow_gid']),
|
||||
dbesc($item['deny_cid']),
|
||||
dbesc($item['deny_gid']),
|
||||
dbesc($item['item_private']),
|
||||
dbesc($arr['resource_id'])
|
||||
);
|
||||
|
||||
|
||||
if($update['item_id']) {
|
||||
info( t('Wiki updated successfully'));
|
||||
if($update_title) {
|
||||
// Update the wiki name information using iconfig.
|
||||
if(! set_iconfig($update['item_id'], 'wiki', 'rawName', $arr['updateRawName'], true)) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
return array('item' => $update['item'], 'item_id' => $update['item_id'], 'success' => $update['success']);
|
||||
}
|
||||
else {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
}
|
||||
|
||||
static public function sync_a_wiki_item($uid,$id,$resource_id) {
|
||||
|
||||
|
||||
$r = q("SELECT * from item WHERE uid = %d AND ( id = %d OR ( resource_type = '%s' and resource_id = '%s' )) ",
|
||||
intval($uid),
|
||||
intval($id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$q = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s'",
|
||||
dbesc($r[0]['resource_id'])
|
||||
);
|
||||
if($q) {
|
||||
$r = array_merge($r,$q);
|
||||
}
|
||||
xchan_query($r);
|
||||
$sync_item = fetch_post_tags($r);
|
||||
if($sync_item) {
|
||||
$pkt = [];
|
||||
foreach($sync_item as $w) {
|
||||
$pkt[] = encode_item($w,true);
|
||||
}
|
||||
build_sync_packet($uid,array('wiki' => $pkt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function delete_wiki($channel_id,$observer_hash,$resource_id) {
|
||||
|
||||
$w = self::get_wiki($channel_id,$observer_hash,$resource_id);
|
||||
$item = $w['wiki'];
|
||||
if(! $item) {
|
||||
return array('item' => null, 'success' => false);
|
||||
}
|
||||
else {
|
||||
$drop = drop_item($item['id'], false, DROPITEM_NORMAL);
|
||||
}
|
||||
|
||||
info( t('Wiki files deleted successfully'));
|
||||
|
||||
return array('item' => $item, 'item_id' => $item['id'], 'success' => (($drop === 1) ? true : false));
|
||||
}
|
||||
|
||||
|
||||
static public function get_wiki($channel_id, $observer_hash, $resource_id) {
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
$item = q("SELECT * FROM item WHERE uid = %d AND resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0
|
||||
$sql_extra limit 1",
|
||||
intval($channel_id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if(! $item) {
|
||||
return array('wiki' => null);
|
||||
}
|
||||
else {
|
||||
|
||||
$w = $item[0]; // wiki item table record
|
||||
// Get wiki metadata
|
||||
$rawName = get_iconfig($w, 'wiki', 'rawName');
|
||||
$mimeType = get_iconfig($w, 'wiki', 'mimeType');
|
||||
$typelock = get_iconfig($w, 'wiki', 'typelock');
|
||||
|
||||
return array(
|
||||
'wiki' => $w,
|
||||
'rawName' => $rawName,
|
||||
'htmlName' => escape_tags($rawName),
|
||||
//'urlName' => urlencode(urlencode($rawName)),
|
||||
'urlName' => self::name_encode($rawName),
|
||||
'mimeType' => $mimeType,
|
||||
'typelock' => $typelock
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public function exists_by_name($uid, $urlName) {
|
||||
|
||||
$sql_extra = item_permissions_sql($uid);
|
||||
|
||||
$item = q("SELECT item.id, resource_id FROM item left join iconfig on iconfig.iid = item.id
|
||||
WHERE resource_type = '%s' AND iconfig.v = '%s' AND uid = %d
|
||||
AND item_deleted = 0 $sql_extra limit 1",
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
//dbesc(urldecode($urlName)),
|
||||
dbesc(self::name_decode($urlName)),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if($item) {
|
||||
return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']);
|
||||
}
|
||||
else {
|
||||
return array('id' => null, 'resource_id' => null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public function get_permissions($resource_id, $owner_id, $observer_hash) {
|
||||
// TODO: For now, only the owner can edit
|
||||
$sql_extra = item_permissions_sql($owner_id, $observer_hash);
|
||||
|
||||
if(local_channel() && local_channel() == $owner_id) {
|
||||
return [ 'read' => true, 'write' => true, 'success' => true ];
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM item WHERE uid = %d and resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
|
||||
intval($owner_id),
|
||||
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
return array('read' => false, 'write' => false, 'success' => true);
|
||||
}
|
||||
else {
|
||||
// TODO: Create a new permission setting for wiki analogous to webpages. Until
|
||||
// then, use webpage permissions
|
||||
$write = perm_is_allowed($owner_id, $observer_hash,'write_wiki');
|
||||
return array('read' => true, 'write' => $write, 'success' => true);
|
||||
}
|
||||
}
|
||||
|
||||
public static function name_encode ($string) {
|
||||
|
||||
$string = html_entity_decode($string);
|
||||
$encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$ret = mb_ereg_replace_callback ('[^A-Za-z0-9\-\_\.\~]',function ($char) {
|
||||
$charhex = unpack('H*',$char[0]);
|
||||
$ret = '('.$charhex[1].')';
|
||||
return $ret;
|
||||
}
|
||||
,$string);
|
||||
mb_internal_encoding($encoding);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function name_decode ($string) {
|
||||
|
||||
$encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$ret = mb_ereg_replace_callback ('(\(([0-9a-f]+)\))',function ($chars) {
|
||||
return pack('H*',$chars[2]);
|
||||
}
|
||||
,$string);
|
||||
mb_internal_encoding($encoding);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
701
Zotlabs/Lib/NativeWikiPage.php
Normal file
701
Zotlabs/Lib/NativeWikiPage.php
Normal file
@@ -0,0 +1,701 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
|
||||
class NativeWikiPage {
|
||||
|
||||
static public function page_list($channel_id,$observer_hash, $resource_id) {
|
||||
|
||||
// TODO: Create item table records for pages so that metadata like title can be applied
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id,$observer_hash,$resource_id);
|
||||
|
||||
$pages[] = [
|
||||
'resource_id' => '',
|
||||
'title' => 'Home',
|
||||
'url' => 'Home',
|
||||
'link_id' => 'id_wiki_home_0'
|
||||
];
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and item_deleted = 0
|
||||
$sql_extra order by title asc",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
$x = [];
|
||||
$y = [];
|
||||
|
||||
foreach($r as $rv) {
|
||||
if(! in_array($rv['mid'],$x)) {
|
||||
$y[] = $rv;
|
||||
$x[] = $rv['mid'];
|
||||
}
|
||||
}
|
||||
|
||||
$items = fetch_post_tags($y,true);
|
||||
|
||||
foreach($items as $page_item) {
|
||||
$title = get_iconfig($page_item['id'],'nwikipage','pagetitle',t('(No Title)'));
|
||||
if(urldecode($title) !== 'Home') {
|
||||
$pages[] = [
|
||||
'resource_id' => $resource_id,
|
||||
'title' => escape_tags($title),
|
||||
//'url' => str_replace('%2F','/',urlencode(str_replace('%2F','/',urlencode($title)))),
|
||||
'url' => Zlib\NativeWiki::name_encode($title),
|
||||
'link_id' => 'id_' . substr($resource_id, 0, 10) . '_' . $page_item['id']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array('pages' => $pages, 'wiki' => $w);
|
||||
}
|
||||
|
||||
|
||||
static public function create_page($channel_id, $observer_hash, $name, $resource_id, $mimetype = 'text/bbcode') {
|
||||
|
||||
logger('mimetype: ' . $mimetype);
|
||||
|
||||
if(! in_array($mimetype,[ 'text/markdown','text/bbcode','text/plain','text/html' ]))
|
||||
$mimetype = 'text/markdown';
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (! $w['wiki']) {
|
||||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
// backslashes won't work well in the javascript functions
|
||||
$name = str_replace('\\','',$name);
|
||||
|
||||
// create an empty activity
|
||||
|
||||
$arr = [];
|
||||
$arr['uid'] = $channel_id;
|
||||
$arr['author_xchan'] = $observer_hash;
|
||||
$arr['mimetype'] = $mimetype;
|
||||
$arr['title'] = $name;
|
||||
$arr['resource_type'] = 'nwikipage';
|
||||
$arr['resource_id'] = $resource_id;
|
||||
$arr['allow_cid'] = $w['wiki']['allow_cid'];
|
||||
$arr['allow_gid'] = $w['wiki']['allow_gid'];
|
||||
$arr['deny_cid'] = $w['wiki']['deny_cid'];
|
||||
$arr['deny_gid'] = $w['wiki']['deny_gid'];
|
||||
|
||||
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel_id,'view_wiki'),true);
|
||||
|
||||
// We may wish to change this some day.
|
||||
$arr['item_unpublished'] = 1;
|
||||
|
||||
set_iconfig($arr,'nwikipage','pagetitle',(($name) ? $name : t('(No Title)')),true);
|
||||
|
||||
$p = post_activity_item($arr, false, false);
|
||||
|
||||
if($p['item_id']) {
|
||||
$page = [
|
||||
'rawName' => $name,
|
||||
'htmlName' => escape_tags($name),
|
||||
//'urlName' => urlencode($name),
|
||||
'urlName' => Zlib\NativeWiki::name_encode($name)
|
||||
|
||||
];
|
||||
|
||||
return array('page' => $page, 'item_id' => $p['item_id'], 'item' => $p['activity'], 'wiki' => $w, 'message' => '', 'success' => true);
|
||||
}
|
||||
return [ 'success' => false, 'message' => t('Wiki page create failed.') ];
|
||||
}
|
||||
|
||||
static public function rename_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$pageNewName = ((array_key_exists('pageNewName',$arr)) ? $arr['pageNewName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if(! $w['wiki']) {
|
||||
return array('message' => t('Wiki not found.'), 'success' => false);
|
||||
}
|
||||
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageNewName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
return [ 'success' => false, 'message' => t('Destination name already exists') ];
|
||||
}
|
||||
|
||||
|
||||
$ids = [];
|
||||
|
||||
$ic = q("select *, item.id as item_id from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
foreach($ic as $c) {
|
||||
set_iconfig($c['item_id'],'nwikipage','pagetitle',$pageNewName);
|
||||
$ids[] = $c['item_id'];
|
||||
}
|
||||
|
||||
$str_ids = implode(',', $ids);
|
||||
q("update item set title = '%s' where id in ($str_ids)",
|
||||
dbesc($pageNewName)
|
||||
);
|
||||
|
||||
$page = [
|
||||
'rawName' => $pageNewName,
|
||||
'htmlName' => escape_tags($pageNewName),
|
||||
//'urlName' => urlencode(escape_tags($pageNewName))
|
||||
'urlName' => Zlib\NativeWiki::name_encode($pageNewName)
|
||||
];
|
||||
|
||||
return [ 'success' => true, 'page' => $page ];
|
||||
}
|
||||
|
||||
return [ 'success' => false, 'item_id' => $c['item_id'], 'message' => t('Page not found') ];
|
||||
|
||||
}
|
||||
|
||||
static public function get_page_content($arr) {
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? intval($arr['channel_id']) : 0);
|
||||
$revision = ((array_key_exists('revision',$arr)) ? intval($arr['revision']) : (-1));
|
||||
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (! $w['wiki']) {
|
||||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$item = self::load_page($arr);
|
||||
|
||||
if($item) {
|
||||
$content = $item['body'];
|
||||
|
||||
return [
|
||||
'content' => $content,
|
||||
'mimeType' => $w['mimeType'],
|
||||
'pageMimeType' => $item['mimetype'],
|
||||
'message' => '',
|
||||
'success' => true
|
||||
];
|
||||
}
|
||||
|
||||
return array('content' => null, 'message' => t('Error reading page content'), 'success' => false);
|
||||
|
||||
}
|
||||
|
||||
static public function page_history($arr) {
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return array('history' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$items = self::load_page_history($arr);
|
||||
|
||||
$history = [];
|
||||
|
||||
if($items) {
|
||||
$processed = 0;
|
||||
foreach($items as $item) {
|
||||
if($processed > 1000)
|
||||
break;
|
||||
$processed ++;
|
||||
$history[] = [
|
||||
'revision' => $item['revision'],
|
||||
'date' => datetime_convert('UTC',date_default_timezone_get(),$item['edited']),
|
||||
'name' => $item['author']['xchan_name'],
|
||||
'title' => get_iconfig($item,'nwikipage','commit_msg')
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return [ 'success' => true, 'history' => $history ];
|
||||
}
|
||||
|
||||
return [ 'success' => false ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static public function load_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (! $w['wiki']) {
|
||||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$ids = '';
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
foreach($ic as $c) {
|
||||
if($ids)
|
||||
$ids .= ',';
|
||||
$ids .= intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
if($revision == (-1))
|
||||
$sql_extra .= " order by revision desc ";
|
||||
elseif($revision)
|
||||
$sql_extra .= " and revision = " . intval($revision) . " ";
|
||||
|
||||
$r = null;
|
||||
|
||||
|
||||
if($ids) {
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) $sql_extra limit 1",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$items = fetch_post_tags($r,true);
|
||||
return $items[0];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static public function load_page_history($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (! $w['wiki']) {
|
||||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$ids = '';
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
foreach($ic as $c) {
|
||||
if($ids)
|
||||
$ids .= ',';
|
||||
$ids .= intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
|
||||
|
||||
$sql_extra .= " order by revision desc ";
|
||||
|
||||
$r = null;
|
||||
if($ids) {
|
||||
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) and item_deleted = 0 $sql_extra",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$items = fetch_post_tags($r,true);
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static public function save_page($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$content = ((array_key_exists('content',$arr)) ? $arr['content'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (!$w['wiki']) {
|
||||
return array('message' => t('Error reading wiki'), 'success' => false);
|
||||
}
|
||||
|
||||
|
||||
// fetch the most recently saved revision.
|
||||
|
||||
$item = self::load_page($arr);
|
||||
|
||||
if(! $item) {
|
||||
return array('message' => t('Page not found'), 'success' => false);
|
||||
}
|
||||
|
||||
$mimetype = $item['mimetype'];
|
||||
|
||||
// change just the fields we need to change to create a revision;
|
||||
|
||||
unset($item['id']);
|
||||
unset($item['author']);
|
||||
$item['parent'] = 0;
|
||||
$item['body'] = $content;
|
||||
$item['author_xchan'] = $observer_hash;
|
||||
$item['revision'] = (($arr['revision']) ? intval($arr['revision']) + 1 : intval($item['revision']) + 1);
|
||||
$item['edited'] = datetime_convert();
|
||||
$item['mimetype'] = $mimetype;
|
||||
|
||||
if($item['iconfig'] && is_array($item['iconfig']) && count($item['iconfig'])) {
|
||||
for($x = 0; $x < count($item['iconfig']); $x ++) {
|
||||
unset($item['iconfig'][$x]['id']);
|
||||
unset($item['iconfig'][$x]['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
$ret = item_store($item, false, false);
|
||||
|
||||
if($ret['item_id'])
|
||||
return array('message' => '', 'item_id' => $ret['item_id'], 'filename' => $filename, 'success' => true);
|
||||
else
|
||||
return array('message' => t('Page update failed.'), 'success' => false);
|
||||
}
|
||||
|
||||
static public function delete_page($arr) {
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if(! $w['wiki']) {
|
||||
return [ 'success' => false, 'message' => t('Error reading wiki') ];
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
|
||||
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
|
||||
intval($channel_id),
|
||||
dbesc($pageUrlName)
|
||||
);
|
||||
|
||||
if($ic) {
|
||||
foreach($ic as $c) {
|
||||
$ids[] = intval($c['iid']);
|
||||
}
|
||||
}
|
||||
|
||||
if($ids) {
|
||||
drop_items($ids);
|
||||
return [ 'success' => true ];
|
||||
}
|
||||
|
||||
return [ 'success' => false, 'message' => t('Nothing deleted') ];
|
||||
}
|
||||
|
||||
static public function revert_page($arr) {
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null);
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
if (! $commitHash) {
|
||||
return array('content' => $content, 'message' => 'No commit was provided', 'success' => false);
|
||||
}
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (!$w['wiki']) {
|
||||
return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
$x = $arr;
|
||||
|
||||
if(intval($commitHash) > 0) {
|
||||
unset($x['commitHash']);
|
||||
$x['revision'] = intval($commitHash) - 1;
|
||||
$loaded = self::load_page($x);
|
||||
|
||||
if($loaded) {
|
||||
$content = $loaded['body'];
|
||||
return [ 'content' => $content, 'success' => true ];
|
||||
}
|
||||
return [ 'content' => $content, 'success' => false ];
|
||||
}
|
||||
}
|
||||
|
||||
static public function compare_page($arr) {
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
|
||||
$currentCommit = ((array_key_exists('currentCommit',$arr)) ? $arr['currentCommit'] : (-1));
|
||||
$compareCommit = ((array_key_exists('compareCommit',$arr)) ? $arr['compareCommit'] : 0);
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
|
||||
if (!$w['wiki']) {
|
||||
return array('message' => t('Error reading wiki'), 'success' => false);
|
||||
}
|
||||
|
||||
$x = $arr;
|
||||
$x['revision'] = (-1);
|
||||
|
||||
$currpage = self::load_page($x);
|
||||
if($currpage)
|
||||
$currentContent = $currpage['body'];
|
||||
|
||||
$x['revision'] = $compareCommit;
|
||||
$comppage = self::load_page($x);
|
||||
if($comppage)
|
||||
$compareContent = $comppage['body'];
|
||||
|
||||
if($currpage && $comppage) {
|
||||
require_once('library/class.Diff.php');
|
||||
$diff = \Diff::toTable(\Diff::compare($currentContent, $compareContent));
|
||||
|
||||
return [ 'success' => true, 'diff' => $diff ];
|
||||
}
|
||||
return [ 'success' => false, 'message' => t('Compare: object not found.') ];
|
||||
|
||||
}
|
||||
|
||||
static public function commit($arr) {
|
||||
|
||||
$commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : t('Page updated'));
|
||||
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
|
||||
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
|
||||
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : t('Untitled'));
|
||||
|
||||
if(array_key_exists('resource_id', $arr)) {
|
||||
$resource_id = $arr['resource_id'];
|
||||
}
|
||||
else {
|
||||
return array('message' => t('Wiki resource_id required for git commit'), 'success' => false);
|
||||
}
|
||||
|
||||
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
|
||||
if (! $w['wiki']) {
|
||||
return array('message' => t('Error reading wiki'), 'success' => false);
|
||||
}
|
||||
|
||||
|
||||
$page = self::load_page($arr);
|
||||
|
||||
if($page) {
|
||||
set_iconfig($page['id'],'nwikipage','commit_msg',escape_tags($commit_msg),true);
|
||||
return [ 'success' => true, 'item_id' => $page['id'], 'page' => $page ];
|
||||
}
|
||||
|
||||
return [ 'success' => false, 'message' => t('Page not found.') ];
|
||||
|
||||
}
|
||||
|
||||
static public function convert_links($s, $wikiURL) {
|
||||
|
||||
if (strpos($s,'[[') !== false) {
|
||||
preg_match_all("/\[\[(.*?)\]\]/", $s, $match);
|
||||
$pages = $pageURLs = array();
|
||||
foreach ($match[1] as $m) {
|
||||
// TODO: Why do we need to double urlencode for this to work?
|
||||
//$pageURLs[] = urlencode(urlencode(escape_tags($m)));
|
||||
$pageURLs[] = Zlib\NativeWiki::name_encode(escape_tags($m));
|
||||
$pages[] = $m;
|
||||
}
|
||||
$idx = 0;
|
||||
while(strpos($s,'[[') !== false) {
|
||||
$replace = '<a href="'.$wikiURL.'/'.$pageURLs[$idx].'">'.$pages[$idx].'</a>';
|
||||
$s = preg_replace("/\[\[(.*?)\]\]/", $replace, $s, 1);
|
||||
$idx++;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
static public function render_page_history($arr) {
|
||||
|
||||
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
|
||||
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
|
||||
|
||||
$pageHistory = self::page_history([
|
||||
'channel_id' => \App::$profile_uid,
|
||||
'observer_hash' => get_observer_hash(),
|
||||
'resource_id' => $resource_id,
|
||||
'pageUrlName' => $pageUrlName
|
||||
]);
|
||||
|
||||
return replace_macros(get_markup_template('nwiki_page_history.tpl'), array(
|
||||
'$pageHistory' => $pageHistory['history'],
|
||||
'$permsWrite' => $arr['permsWrite'],
|
||||
'$name_lbl' => t('Name'),
|
||||
'$msg_label' => t('Message','wiki_history'),
|
||||
'$date_lbl' => t('Date'),
|
||||
'$revert_btn' => t('Revert'),
|
||||
'$compare_btn' => t('Compare')
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Replace the instances of the string [toc] with a list element that will be populated by
|
||||
* a table of contents by the JavaScript library
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
static public function generate_toc($s) {
|
||||
if (strpos($s,'[toc]') !== false) {
|
||||
//$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
|
||||
$toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
|
||||
$s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a select set of bbcode tags. Much of the code is copied from include/bbcode.php
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
static public function bbcode($s) {
|
||||
|
||||
$s = str_replace(array('[baseurl]', '[sitename]'), array(z_root(), get_config('system', 'sitename')), $s);
|
||||
|
||||
$s = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $s);
|
||||
|
||||
$s = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $s);
|
||||
|
||||
|
||||
$observer = \App::get_observer();
|
||||
if ($observer) {
|
||||
$s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
|
||||
$s2 = '</span>';
|
||||
$obsBaseURL = $observer['xchan_connurl'];
|
||||
$obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
|
||||
$s = str_replace('[observer.baseurl]', $obsBaseURL, $s);
|
||||
$s = str_replace('[observer.url]', $observer['xchan_url'], $s);
|
||||
$s = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $s);
|
||||
$s = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $s);
|
||||
$s = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $s);
|
||||
$s = str_replace('[observer.photo]', '', $s);
|
||||
}
|
||||
else {
|
||||
$s = str_replace('[observer.baseurl]', '', $s);
|
||||
$s = str_replace('[observer.url]', '', $s);
|
||||
$s = str_replace('[observer.name]', '', $s);
|
||||
$s = str_replace('[observer.address]', '', $s);
|
||||
$s = str_replace('[observer.webname]', '', $s);
|
||||
$s = str_replace('[observer.photo]', '', $s);
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
static public function get_file_ext($arr) {
|
||||
if($arr['mimetype'] === 'text/bbcode')
|
||||
return '.bb';
|
||||
elseif($arr['mimetype'] === 'text/markdown')
|
||||
return '.md';
|
||||
elseif($arr['mimetype'] === 'text/plain')
|
||||
return '.txt';
|
||||
|
||||
}
|
||||
|
||||
// This function is derived from
|
||||
// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
|
||||
static public function toc($content) {
|
||||
// ensure using only "\n" as line-break
|
||||
$source = str_replace(["\r\n", "\r"], "\n", $content);
|
||||
|
||||
// look for markdown TOC items
|
||||
preg_match_all(
|
||||
'/^(?:=|-|#).*$/m',
|
||||
$source,
|
||||
$matches,
|
||||
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
|
||||
);
|
||||
|
||||
// preprocess: iterate matched lines to create an array of items
|
||||
// where each item is an array(level, text)
|
||||
$file_size = strlen($source);
|
||||
foreach ($matches[0] as $item) {
|
||||
$found_mark = substr($item[0], 0, 1);
|
||||
if ($found_mark == '#') {
|
||||
// text is the found item
|
||||
$item_text = $item[0];
|
||||
$item_level = strrpos($item_text, '#') + 1;
|
||||
$item_text = substr($item_text, $item_level);
|
||||
} else {
|
||||
// text is the previous line (empty if <hr>)
|
||||
$item_offset = $item[1];
|
||||
$prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
|
||||
$item_text =
|
||||
substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
|
||||
$item_text = trim($item_text);
|
||||
$item_level = $found_mark == '=' ? 1 : 2;
|
||||
}
|
||||
if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
|
||||
// item is an horizontal separator or a table header, don't mind
|
||||
continue;
|
||||
}
|
||||
$raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
|
||||
}
|
||||
$o = '';
|
||||
foreach($raw_toc as $t) {
|
||||
$level = intval($t['level']);
|
||||
$text = $t['text'];
|
||||
switch ($level) {
|
||||
case 1:
|
||||
$li = '* ';
|
||||
break;
|
||||
case 2:
|
||||
$li = ' * ';
|
||||
break;
|
||||
case 3:
|
||||
$li = ' * ';
|
||||
break;
|
||||
case 4:
|
||||
$li = ' * ';
|
||||
break;
|
||||
default:
|
||||
$li = '* ';
|
||||
break;
|
||||
}
|
||||
$o .= $li . $text . "\n";
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
288
Zotlabs/Lib/PConfig.php
Normal file
288
Zotlabs/Lib/PConfig.php
Normal file
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief Class for handling channel specific configurations.
|
||||
*
|
||||
* <b>PConfig</b> is used for channel specific configurations and takes a
|
||||
* <i>channel_id</i> as identifier. It stores for example which features are
|
||||
* enabled per channel. The storage is of size MEDIUMTEXT.
|
||||
*
|
||||
* @code{.php}$var = Zotlabs\Lib\PConfig::Get('uid', 'category', 'key');
|
||||
* // with default value for non existent key
|
||||
* $var = Zotlabs\Lib\PConfig::Get('uid', 'category', 'unsetkey', 'defaultvalue');@endcode
|
||||
*
|
||||
* The old (deprecated?) way to access a PConfig value is:
|
||||
* @code{.php}$var = get_pconfig(local_channel(), 'category', 'key');@endcode
|
||||
*/
|
||||
class PConfig {
|
||||
|
||||
/**
|
||||
* @brief Loads all configuration values of a channel into a cached storage.
|
||||
*
|
||||
* All configuration values of the given channel are stored in global cache
|
||||
* which is available under the global variable App::$config[$uid].
|
||||
*
|
||||
* @param string $uid
|
||||
* The channel_id
|
||||
* @return void|false Nothing or false if $uid is null or false
|
||||
*/
|
||||
static public function Load($uid) {
|
||||
if(is_null($uid) || $uid === false)
|
||||
return false;
|
||||
|
||||
if(! is_array(\App::$config)) {
|
||||
btlogger('App::$config not an array');
|
||||
}
|
||||
|
||||
if(! array_key_exists($uid, \App::$config)) {
|
||||
\App::$config[$uid] = array();
|
||||
}
|
||||
|
||||
if(! is_array(\App::$config[$uid])) {
|
||||
btlogger('App::$config[$uid] not an array: ' . $uid);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM pconfig WHERE uid = %d",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$k = $rr['k'];
|
||||
$c = $rr['cat'];
|
||||
if(! array_key_exists($c, \App::$config[$uid])) {
|
||||
\App::$config[$uid][$c] = array();
|
||||
\App::$config[$uid][$c]['config_loaded'] = true;
|
||||
}
|
||||
\App::$config[$uid][$c][$k] = $rr['v'];
|
||||
\App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a particular channel's config variable given the category name
|
||||
* ($family) and a key.
|
||||
*
|
||||
* Get a particular channel's config value from the given category ($family)
|
||||
* and the $key from a cached storage in App::$config[$uid].
|
||||
*
|
||||
* Returns false if not set.
|
||||
*
|
||||
* @param string $uid
|
||||
* The channel_id
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to query
|
||||
* @param mixed $default (optional, default false)
|
||||
* Default value to return if key does not exist
|
||||
* @return mixed Stored value or false if it does not exist
|
||||
*/
|
||||
static public function Get($uid, $family, $key, $default = false) {
|
||||
|
||||
if(is_null($uid) || $uid === false)
|
||||
return $default;
|
||||
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
self::Load($uid);
|
||||
|
||||
if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family])))
|
||||
return $default;
|
||||
|
||||
return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$uid][$family][$key]))
|
||||
? unserialize(\App::$config[$uid][$family][$key])
|
||||
: \App::$config[$uid][$family][$key]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a configuration value for a channel.
|
||||
*
|
||||
* Stores a config value ($value) in the category ($family) under the key ($key)
|
||||
* for the channel_id $uid.
|
||||
*
|
||||
* @param string $uid
|
||||
* The channel_id
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to set
|
||||
* @param string $value
|
||||
* The value to store
|
||||
* @param string $updated (optional)
|
||||
* The datetime to store
|
||||
* @return mixed Stored $value or false
|
||||
*/
|
||||
static public function Set($uid, $family, $key, $value, $updated = NULL) {
|
||||
|
||||
// this catches subtle errors where this function has been called
|
||||
// with local_channel() when not logged in (which returns false)
|
||||
// and throws an error in array_key_exists below.
|
||||
// we provide a function backtrace in the logs so that we can find
|
||||
// and fix the calling function.
|
||||
|
||||
if(is_null($uid) || $uid === false) {
|
||||
btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// manage array value
|
||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||
|
||||
$now = datetime_convert();
|
||||
if (! $updated) {
|
||||
//Sometimes things happen fast... very fast.
|
||||
//To make sure legitimate updates aren't rejected
|
||||
//because not enough time has passed. We say our updates
|
||||
//happened just a short time in the past rather than right now.
|
||||
$updated = datetime_convert('UTC','UTC','-2 seconds');
|
||||
}
|
||||
|
||||
$hash = hash('sha256',$family.':'.$key);
|
||||
|
||||
if (self::Get($uid, 'hz_delpconfig', $hash) !== false) {
|
||||
if (self::Get($uid, 'hz_delpconfig', $hash) > $now) {
|
||||
logger('Refusing to update pconfig with outdated info (Item deleted more recently).', LOGGER_NORMAL, LOG_ERR);
|
||||
return self::Get($uid,$family,$key);
|
||||
} else {
|
||||
self::Delete($uid,'hz_delpconfig',$hash);
|
||||
}
|
||||
}
|
||||
|
||||
if(self::Get($uid, $family, $key) === false) {
|
||||
if(! array_key_exists($uid, \App::$config))
|
||||
\App::$config[$uid] = array();
|
||||
if(! array_key_exists($family, \App::$config[$uid]))
|
||||
\App::$config[$uid][$family] = array();
|
||||
|
||||
|
||||
$ret = q("INSERT INTO pconfig ( uid, cat, k, v, updated ) VALUES ( %d, '%s', '%s', '%s', '%s' ) ",
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key),
|
||||
dbesc($dbvalue),
|
||||
dbesc($updated)
|
||||
);
|
||||
|
||||
// There is a possible race condition if another process happens
|
||||
// to insert something after this thread has Loaded and now. We should
|
||||
// at least make a note of it if it happens.
|
||||
|
||||
if (!$ret) {
|
||||
logger("Error: Insert to pconfig failed.",LOGGER_NORMAL, LOG_ERR);
|
||||
}
|
||||
|
||||
\App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
|
||||
|
||||
}
|
||||
else {
|
||||
$new = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now);
|
||||
|
||||
if ($new) {
|
||||
|
||||
// @NOTE There is still a possible race condition under limited circumstances
|
||||
// where a value will be updated by another thread with more current data than
|
||||
// we have. At this point there is no easy way to test for it, so we update
|
||||
// and hope for the best.
|
||||
|
||||
$ret = q("UPDATE pconfig SET v = '%s', updated = '%s' WHERE uid = %d and cat = '%s' AND k = '%s' ",
|
||||
dbesc($dbvalue),
|
||||
dbesc($updated),
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
\App::$config[$uid][$family]['pcfgud:'.$key] = $updated;
|
||||
|
||||
} else {
|
||||
logger('Refusing to update pconfig with outdated info.', LOGGER_NORMAL, LOG_ERR);
|
||||
return self::Get($uid, $family, $key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// keep a separate copy for all variables which were
|
||||
// set in the life of this page. We need this to
|
||||
// synchronise channel clones.
|
||||
|
||||
if(! array_key_exists('transient', \App::$config[$uid]))
|
||||
\App::$config[$uid]['transient'] = array();
|
||||
if(! array_key_exists($family, \App::$config[$uid]['transient']))
|
||||
\App::$config[$uid]['transient'][$family] = array();
|
||||
|
||||
\App::$config[$uid][$family][$key] = $value;
|
||||
|
||||
if ($new) {
|
||||
\App::$config[$uid]['transient'][$family][$key] = $value;
|
||||
\App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated;
|
||||
}
|
||||
|
||||
if($ret)
|
||||
return $value;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Deletes the given key from the channel's configuration.
|
||||
*
|
||||
* Removes the configured value from the stored cache in App::$config[$uid]
|
||||
* and removes it from the database.
|
||||
*
|
||||
* @param string $uid
|
||||
* The channel_id
|
||||
* @param string $family
|
||||
* The category of the configuration value
|
||||
* @param string $key
|
||||
* The configuration key to delete
|
||||
* @param string $updated (optional)
|
||||
* The datetime to store
|
||||
* @return boolean
|
||||
*/
|
||||
static public function Delete($uid, $family, $key, $updated = NULL) {
|
||||
|
||||
if(is_null($uid) || $uid === false)
|
||||
return false;
|
||||
|
||||
$updated = ($updated) ? $updated : datetime_convert('UTC','UTC','-2 seconds');
|
||||
$now = datetime_convert();
|
||||
$newer = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now);
|
||||
|
||||
if (! $newer) {
|
||||
logger('Refusing to delete pconfig with outdated delete request.', LOGGER_NORMAL, LOG_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
$ret = false;
|
||||
|
||||
if (isset(\App::$config[$uid][$family][$key])) {
|
||||
unset(\App::$config[$uid][$family][$key]);
|
||||
}
|
||||
|
||||
if (isset(\App::$config[$uid][$family]['pcfgud:'.$key])) {
|
||||
unset(\App::$config[$uid][$family]['pcfgud:'.$key]);
|
||||
}
|
||||
|
||||
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
|
||||
intval($uid),
|
||||
dbesc($family),
|
||||
dbesc($key)
|
||||
);
|
||||
|
||||
// Synchronize delete with clones.
|
||||
|
||||
if ($family != 'hz_delpconfig') {
|
||||
$hash = hash('sha256',$family.':'.$key);
|
||||
set_pconfig($uid,'hz_delpconfig',$hash,$updated);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
186
Zotlabs/Lib/Permcat.php
Normal file
186
Zotlabs/Lib/Permcat.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Access\PermissionRoles;
|
||||
use Zotlabs\Access\Permissions;
|
||||
|
||||
/**
|
||||
* @brief Permission Categories. Permission rules for various classes of connections.
|
||||
*
|
||||
* Connection permissions answer the question "Can Joe view my photos?"
|
||||
*
|
||||
* Some permissions may be inherited from the channel's "privacy settings"
|
||||
* (@ref ::Zotlabs::Access::PermissionLimits "PermissionLimits") "Who can view my
|
||||
* photos (at all)?" which have higher priority than individual connection settings.
|
||||
* We evaluate permission limits first, and then fall through to connection
|
||||
* permissions if the permission limits didn't already make a definitive decision.
|
||||
*
|
||||
* After PermissionLimits and connection permissions are evaluated, individual
|
||||
* content ACLs are evaluated (@ref ::Zotlabs::Access::AccessList "AccessList").
|
||||
* These answer the question "Can Joe view *this* album/photo?".
|
||||
*/
|
||||
class Permcat {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $permcats = [];
|
||||
|
||||
/**
|
||||
* @brief Permcat constructor.
|
||||
*
|
||||
* @param int $channel_id
|
||||
*/
|
||||
public function __construct($channel_id) {
|
||||
|
||||
$perms = [];
|
||||
|
||||
// first check role perms for a perms_connect setting
|
||||
|
||||
$role = get_pconfig($channel_id,'system','permissions_role');
|
||||
if($role) {
|
||||
$x = PermissionRoles::role_perms($role);
|
||||
if($x['perms_connect']) {
|
||||
$perms = Permissions::FilledPerms($x['perms_connect']);
|
||||
}
|
||||
}
|
||||
|
||||
// if no role perms it may be a custom role, see if there any autoperms
|
||||
|
||||
if(! $perms) {
|
||||
$perms = Permissions::FilledAutoPerms($channel_id);
|
||||
}
|
||||
|
||||
// if no autoperms it may be a custom role with manual perms
|
||||
|
||||
if(! $perms) {
|
||||
$r = q("select channel_hash from channel where channel_id = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
$x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
|
||||
intval($channel_id),
|
||||
dbesc($r[0]['channel_hash'])
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
$perms[$xv['k']] = intval($xv['v']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nothing was found - create a filled permission array where all permissions are 0
|
||||
|
||||
if(! $perms) {
|
||||
$perms = Permissions::FilledPerms([]);
|
||||
}
|
||||
|
||||
$this->permcats[] = [
|
||||
'name' => 'default',
|
||||
'localname' => t('default','permcat'),
|
||||
'perms' => Permissions::Operms($perms),
|
||||
'system' => 1
|
||||
];
|
||||
|
||||
|
||||
$p = $this->load_permcats($channel_id);
|
||||
if($p) {
|
||||
for($x = 0; $x < count($p); $x++) {
|
||||
$this->permcats[] = [
|
||||
'name' => $p[$x][0],
|
||||
'localname' => $p[$x][1],
|
||||
'perms' => Permissions::Operms(Permissions::FilledPerms($p[$x][2])),
|
||||
'system' => intval($p[$x][3])
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return array with permcats.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listing() {
|
||||
return $this->permcats;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
* * \e array with permcats
|
||||
* * \e bool \b error if $name not found in permcats true
|
||||
*/
|
||||
public function fetch($name) {
|
||||
if($name && $this->permcats) {
|
||||
foreach($this->permcats as $permcat) {
|
||||
if(strcasecmp($permcat['name'], $name) === 0) {
|
||||
return $permcat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ['error' => true];
|
||||
}
|
||||
|
||||
public function load_permcats($uid) {
|
||||
|
||||
$permcats = [
|
||||
[ 'follower', t('follower','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
|
||||
'post_like' ], 1
|
||||
],
|
||||
[ 'contributor', t('contributor','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
|
||||
'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1
|
||||
],
|
||||
[ 'publisher', t('publisher','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages',
|
||||
'write_storage','post_wall','write_pages','write_wiki','post_comments','post_like','tag_deliver',
|
||||
'chat', 'republish' ], 1
|
||||
]
|
||||
];
|
||||
|
||||
if($uid) {
|
||||
$x = q("select * from pconfig where uid = %d and cat = 'permcat'",
|
||||
intval($uid)
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
$value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
|
||||
$permcats[] = [ $xv['k'], $xv['k'], $value, 0 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hooks permcats
|
||||
* * \e array
|
||||
*/
|
||||
call_hooks('permcats', $permcats);
|
||||
|
||||
return $permcats;
|
||||
}
|
||||
|
||||
static public function find_permcat($arr, $name) {
|
||||
if((! $arr) || (! $name))
|
||||
return false;
|
||||
|
||||
foreach($arr as $p)
|
||||
if($p['name'] == $name)
|
||||
return $p['value'];
|
||||
}
|
||||
|
||||
static public function update($channel_id, $name, $permarr) {
|
||||
PConfig::Set($channel_id, 'permcat', $name, $permarr);
|
||||
}
|
||||
|
||||
static public function delete($channel_id, $name) {
|
||||
PConfig::Delete($channel_id, 'permcat', $name);
|
||||
}
|
||||
|
||||
}
|
||||
159
Zotlabs/Lib/PermissionDescription.php
Normal file
159
Zotlabs/Lib/PermissionDescription.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
require_once("include/permissions.php");
|
||||
require_once("include/language.php");
|
||||
require_once("include/text.php");
|
||||
|
||||
|
||||
/**
|
||||
* Encapsulates information the ACL dialog requires to describe
|
||||
* permission settings for an item with an empty ACL.
|
||||
* i.e the caption, icon, and tooltip for the no-ACL option in the ACL dialog.
|
||||
*/
|
||||
class PermissionDescription {
|
||||
|
||||
private $global_perm;
|
||||
private $channel_perm;
|
||||
private $fallback_description;
|
||||
|
||||
/**
|
||||
* Constructor is private.
|
||||
* Use static methods fromGlobalPermission(), fromStandalonePermission(),
|
||||
* or fromDescription() to create instances.
|
||||
*
|
||||
* @internal
|
||||
* @param int $global_perm
|
||||
* @param int $channel_perm
|
||||
* @param string $description (optional) default empty
|
||||
*/
|
||||
private function __construct($global_perm, $channel_perm, $description = '') {
|
||||
$this->global_perm = $global_perm;
|
||||
$this->channel_perm = $channel_perm;
|
||||
$this->fallback_description = ($description == '') ? t('Visible to your default audience') : $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the interpretation of an empty ACL can't be summarised with a global default permission
|
||||
* or a specific permission setting then use this method and describe what it means instead.
|
||||
* Remember to localize the description first.
|
||||
*
|
||||
* @param string $description - the localized caption for the no-ACL option in the ACL dialog.
|
||||
* @return a new instance of PermissionDescription
|
||||
*/
|
||||
public static function fromDescription($description) {
|
||||
return new PermissionDescription('', 0x80000, $description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method only if the interpretation of an empty ACL doesn't fall back to a global
|
||||
* default permission. You should pass one of the constants from boot.php - PERMS_PUBLIC,
|
||||
* PERMS_NETWORK etc.
|
||||
*
|
||||
* @param integer $perm - a single enumerated constant permission - PERMS_PUBLIC, PERMS_NETWORK etc.
|
||||
* @return a new instance of PermissionDescription
|
||||
*/
|
||||
public static function fromStandalonePermission($perm) {
|
||||
|
||||
$result = new PermissionDescription('', $perm);
|
||||
|
||||
$checkPerm = $result->get_permission_description();
|
||||
if($checkPerm == $result->fallback_description) {
|
||||
$result = null;
|
||||
logger('null PermissionDescription from unknown standalone permission: ' . $perm, LOGGER_DEBUG, LOG_ERR);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the preferred way to create a PermissionDescription, as it provides the most details.
|
||||
* Use this method if you know an empty ACL will result in one of the global default permissions
|
||||
* being used, such as channel_r_stream (for which you would pass 'view_stream').
|
||||
*
|
||||
* @param string $permname - a key for the global perms array from get_perms() in permissions.php,
|
||||
* e.g. 'view_stream', 'view_profile', etc.
|
||||
* @return a new instance of PermissionDescription
|
||||
*/
|
||||
public static function fromGlobalPermission($permname) {
|
||||
|
||||
$result = null;
|
||||
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
if(array_key_exists($permname, $global_perms)) {
|
||||
|
||||
$channelPerm = \Zotlabs\Access\PermissionLimits::Get(\App::$channel['channel_id'], $permname);
|
||||
|
||||
$result = new PermissionDescription('', $channelPerm);
|
||||
} else {
|
||||
// The acl dialog can handle null arguments, but it shouldn't happen
|
||||
logger('null PermissionDescription from unknown global permission: ' . $permname, LOGGER_DEBUG, LOG_ERR);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a localized description of the permission, or a generic message if the permission
|
||||
* is unknown.
|
||||
*
|
||||
* @return string description
|
||||
*/
|
||||
public function get_permission_description() {
|
||||
|
||||
switch($this->channel_perm) {
|
||||
case 0: return t('Only me');
|
||||
case PERMS_PUBLIC: return t('Public');
|
||||
case PERMS_NETWORK: return t('Anybody in the $Projectname network');
|
||||
case PERMS_SITE: return sprintf(t('Any account on %s'), \App::get_hostname());
|
||||
case PERMS_CONTACTS: return t('Any of my connections');
|
||||
case PERMS_SPECIFIC: return t('Only connections I specifically allow');
|
||||
case PERMS_AUTHED: return t('Anybody authenticated (could include visitors from other networks)');
|
||||
case PERMS_PENDING: return t('Any connections including those who haven\'t yet been approved');
|
||||
default: return $this->fallback_description;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an icon css class name if an appropriate one is available, e.g. "fa-globe" for Public,
|
||||
* otherwise returns empty string.
|
||||
*
|
||||
* @return string icon css class name (often FontAwesome)
|
||||
*/
|
||||
public function get_permission_icon() {
|
||||
|
||||
switch($this->channel_perm) {
|
||||
case 0:/* only me */ return 'fa-eye-slash';
|
||||
case PERMS_PUBLIC: return 'fa-globe';
|
||||
case PERMS_NETWORK: return 'fa-share-alt-square'; // fa-share-alt-square is very similiar to the hubzilla logo, but we should create our own logo class to use
|
||||
case PERMS_SITE: return 'fa-sitemap';
|
||||
case PERMS_CONTACTS: return 'fa-group';
|
||||
case PERMS_SPECIFIC: return 'fa-list';
|
||||
case PERMS_AUTHED: return '';
|
||||
case PERMS_PENDING: return '';
|
||||
default: return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a localized description of where the permission came from, if this is known.
|
||||
* If it's not know, or if the permission is standalone and didn't come from a default
|
||||
* permission setting, then empty string is returned.
|
||||
*
|
||||
* @return string description or empty string
|
||||
*/
|
||||
public function get_permission_origin_description() {
|
||||
|
||||
switch($this->global_perm) {
|
||||
case PERMS_R_STREAM: return t('This is your default setting for the audience of your normal stream, and posts.');
|
||||
case PERMS_R_PROFILE: return t('This is your default setting for who can view your default channel profile');
|
||||
case PERMS_R_ABOOK: return t('This is your default setting for who can view your connections');
|
||||
case PERMS_R_STORAGE: return t('This is your default setting for who can view your file storage and photos');
|
||||
case PERMS_R_PAGES: return t('This is your default setting for the audience of your webpages');
|
||||
default: return '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
278
Zotlabs/Lib/Queue.php
Normal file
278
Zotlabs/Lib/Queue.php
Normal file
@@ -0,0 +1,278 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libzot;
|
||||
|
||||
|
||||
class Queue {
|
||||
|
||||
static function update($id, $add_priority = 0) {
|
||||
|
||||
logger('queue: requeue item ' . $id,LOGGER_DEBUG);
|
||||
$x = q("select outq_created, outq_posturl from outq where outq_hash = '%s' limit 1",
|
||||
dbesc($id)
|
||||
);
|
||||
if(! $x)
|
||||
return;
|
||||
|
||||
|
||||
$y = q("select min(outq_created) as earliest from outq where outq_posturl = '%s'",
|
||||
dbesc($x[0]['outq_posturl'])
|
||||
);
|
||||
|
||||
// look for the oldest queue entry with this destination URL. If it's older than a couple of days,
|
||||
// the destination is considered to be down and only scheduled once an hour, regardless of the
|
||||
// age of the current queue item.
|
||||
|
||||
$might_be_down = false;
|
||||
|
||||
if($y)
|
||||
$might_be_down = ((datetime_convert('UTC','UTC',$y[0]['earliest']) < datetime_convert('UTC','UTC','now - 2 days')) ? true : false);
|
||||
|
||||
|
||||
// Set all other records for this destination way into the future.
|
||||
// The queue delivers by destination. We'll keep one queue item for
|
||||
// this destination (this one) with a shorter delivery. If we succeed
|
||||
// once, we'll try to deliver everything for that destination.
|
||||
// The delivery will be set to at most once per hour, and if the
|
||||
// queue item is less than 12 hours old, we'll schedule for fifteen
|
||||
// minutes.
|
||||
|
||||
$r = q("UPDATE outq SET outq_scheduled = '%s' WHERE outq_posturl = '%s'",
|
||||
dbesc(datetime_convert('UTC','UTC','now + 5 days')),
|
||||
dbesc($x[0]['outq_posturl'])
|
||||
);
|
||||
|
||||
$since = datetime_convert('UTC','UTC',$x[0]['outq_created']);
|
||||
|
||||
if(($might_be_down) || ($since < datetime_convert('UTC','UTC','now - 12 hour'))) {
|
||||
$next = datetime_convert('UTC','UTC','now + 1 hour');
|
||||
}
|
||||
else {
|
||||
$next = datetime_convert('UTC','UTC','now + ' . intval($add_priority) . ' minutes');
|
||||
}
|
||||
|
||||
q("UPDATE outq SET outq_updated = '%s',
|
||||
outq_priority = outq_priority + %d,
|
||||
outq_scheduled = '%s'
|
||||
WHERE outq_hash = '%s'",
|
||||
|
||||
dbesc(datetime_convert()),
|
||||
intval($add_priority),
|
||||
dbesc($next),
|
||||
dbesc($id)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static function remove($id,$channel_id = 0) {
|
||||
logger('queue: remove queue item ' . $id,LOGGER_DEBUG);
|
||||
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
|
||||
|
||||
q("DELETE FROM outq WHERE outq_hash = '%s' $sql_extra",
|
||||
dbesc($id)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static function remove_by_posturl($posturl) {
|
||||
logger('queue: remove queue posturl ' . $posturl,LOGGER_DEBUG);
|
||||
|
||||
q("DELETE FROM outq WHERE outq_posturl = '%s' ",
|
||||
dbesc($posturl)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static function set_delivered($id,$channel = 0) {
|
||||
logger('queue: set delivered ' . $id,LOGGER_DEBUG);
|
||||
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
|
||||
|
||||
// Set the next scheduled run date so far in the future that it will be expired
|
||||
// long before it ever makes it back into the delivery chain.
|
||||
|
||||
q("update outq set outq_delivered = 1, outq_updated = '%s', outq_scheduled = '%s' where outq_hash = '%s' $sql_extra ",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert('UTC','UTC','now + 5 days')),
|
||||
dbesc($id)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static function insert($arr) {
|
||||
|
||||
// do not queue anything with no destination
|
||||
|
||||
if(! (array_key_exists('posturl',$arr) && trim($arr['posturl']))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
|
||||
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
|
||||
values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s' )",
|
||||
dbesc($arr['hash']),
|
||||
intval($arr['account_id']),
|
||||
intval($arr['channel_id']),
|
||||
dbesc(($arr['driver']) ? $arr['driver'] : 'zot'),
|
||||
dbesc($arr['posturl']),
|
||||
intval(1),
|
||||
intval(($arr['priority']) ? $arr['priority'] : 0),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($arr['notify']),
|
||||
dbesc(($arr['msg']) ? $arr['msg'] : '')
|
||||
);
|
||||
return $x;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static function deliver($outq, $immediate = false) {
|
||||
|
||||
$base = null;
|
||||
$h = parse_url($outq['outq_posturl']);
|
||||
if($h !== false)
|
||||
$base = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
|
||||
|
||||
if(($base) && ($base !== z_root()) && ($immediate)) {
|
||||
$y = q("select site_update, site_dead from site where site_url = '%s' ",
|
||||
dbesc($base)
|
||||
);
|
||||
if($y) {
|
||||
if(intval($y[0]['site_dead'])) {
|
||||
self::remove_by_posturl($outq['outq_posturl']);
|
||||
logger('dead site ignored ' . $base);
|
||||
return;
|
||||
}
|
||||
if($y[0]['site_update'] < datetime_convert('UTC','UTC','now - 1 month')) {
|
||||
self::update($outq['outq_hash'],10);
|
||||
logger('immediate delivery deferred for site ' . $base);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// zot sites should all have a site record, unless they've been dead for as long as
|
||||
// your site has existed. Since we don't know for sure what these sites are,
|
||||
// call them unknown
|
||||
|
||||
site_store_lowlevel(
|
||||
[
|
||||
'site_url' => $base,
|
||||
'site_update' => datetime_convert(),
|
||||
'site_dead' => 0,
|
||||
'site_type' => intval(($outq['outq_driver'] === 'post') ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN),
|
||||
'site_crypto' => ''
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$arr = array('outq' => $outq, 'base' => $base, 'handled' => false, 'immediate' => $immediate);
|
||||
call_hooks('queue_deliver',$arr);
|
||||
if($arr['handled'])
|
||||
return;
|
||||
|
||||
// "post" queue driver - used for diaspora and friendica-over-diaspora communications.
|
||||
|
||||
if($outq['outq_driver'] === 'post') {
|
||||
$result = z_post_url($outq['outq_posturl'],$outq['outq_msg']);
|
||||
if($result['success'] && $result['return_code'] < 300) {
|
||||
logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG);
|
||||
if($base) {
|
||||
q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($base)
|
||||
);
|
||||
}
|
||||
q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
|
||||
dbesc('accepted for delivery'),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($outq['outq_hash'])
|
||||
);
|
||||
self::remove($outq['outq_hash']);
|
||||
|
||||
// server is responding - see if anything else is going to this destination and is piled up
|
||||
// and try to send some more. We're relying on the fact that do_delivery() results in an
|
||||
// immediate delivery otherwise we could get into a queue loop.
|
||||
|
||||
if(! $immediate) {
|
||||
$x = q("select outq_hash from outq where outq_posturl = '%s' and outq_delivered = 0",
|
||||
dbesc($outq['outq_posturl'])
|
||||
);
|
||||
|
||||
$piled_up = array();
|
||||
if($x) {
|
||||
foreach($x as $xx) {
|
||||
$piled_up[] = $xx['outq_hash'];
|
||||
}
|
||||
}
|
||||
if($piled_up) {
|
||||
// call do_delivery() with the force flag
|
||||
do_delivery($piled_up, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger('deliver: queue post returned ' . $result['return_code']
|
||||
. ' from ' . $outq['outq_posturl'],LOGGER_DEBUG);
|
||||
self::update($outq['outq_hash'],10);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// normal zot delivery
|
||||
|
||||
logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
|
||||
|
||||
|
||||
if($outq['outq_posturl'] === z_root() . '/zot') {
|
||||
// local delivery
|
||||
$zot = new \Zotlabs\Zot6\Receiver(new \Zotlabs\Zot6\Zot6Handler(),$outq['outq_notify']);
|
||||
$result = $zot->run(true);
|
||||
logger('returned_json: ' . json_encode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOGGER_DATA);
|
||||
logger('deliver: local zot delivery succeeded to ' . $outq['outq_posturl']);
|
||||
Libzot::process_response($outq['outq_posturl'],[ 'success' => true, 'body' => json_encode($result) ], $outq);
|
||||
}
|
||||
else {
|
||||
logger('remote');
|
||||
$channel = null;
|
||||
|
||||
if($outq['outq_channel']) {
|
||||
$channel = channelx_by_n($outq['outq_channel']);
|
||||
}
|
||||
|
||||
$host_crypto = null;
|
||||
|
||||
if($channel && $base) {
|
||||
$h = q("select hubloc_sitekey, site_crypto from hubloc left join site on hubloc_url = site_url where site_url = '%s' and hubloc_sitekey != '' order by hubloc_id desc limit 1",
|
||||
dbesc($base)
|
||||
);
|
||||
if($h) {
|
||||
$host_crypto = $h[0];
|
||||
}
|
||||
}
|
||||
|
||||
$msg = $outq['outq_notify'];
|
||||
|
||||
$result = Libzot::zot($outq['outq_posturl'],$msg,$channel,$host_crypto);
|
||||
|
||||
if($result['success']) {
|
||||
logger('deliver: remote zot delivery succeeded to ' . $outq['outq_posturl']);
|
||||
Libzot::process_response($outq['outq_posturl'],$result, $outq);
|
||||
}
|
||||
else {
|
||||
logger('deliver: remote zot delivery failed to ' . $outq['outq_posturl']);
|
||||
logger('deliver: remote zot delivery fail data: ' . print_r($result,true), LOGGER_DATA);
|
||||
self::update($outq['outq_hash'],10);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
28
Zotlabs/Lib/SConfig.php
Normal file
28
Zotlabs/Lib/SConfig.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief Account configuration storage is built on top of the under-utilised xconfig.
|
||||
*
|
||||
* @see XConfig
|
||||
*/
|
||||
class SConfig {
|
||||
|
||||
static public function Load($server_id) {
|
||||
return XConfig::Load('s_' . $server_id);
|
||||
}
|
||||
|
||||
static public function Get($server_id,$family,$key,$default = false) {
|
||||
return XConfig::Get('s_' . $server_id,$family,$key, $default);
|
||||
}
|
||||
|
||||
static public function Set($server_id,$family,$key,$value) {
|
||||
return XConfig::Set('s_' . $server_id,$family,$key,$value);
|
||||
}
|
||||
|
||||
static public function Delete($server_id,$family,$key) {
|
||||
return XConfig::Delete('s_' . $server_id,$family,$key);
|
||||
}
|
||||
|
||||
}
|
||||
144
Zotlabs/Lib/Share.php
Normal file
144
Zotlabs/Lib/Share.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class Share {
|
||||
|
||||
private $item = null;
|
||||
|
||||
|
||||
public function __construct($post_id) {
|
||||
|
||||
if(! $post_id)
|
||||
return;
|
||||
|
||||
if(! (local_channel() || remote_channel()))
|
||||
return;
|
||||
|
||||
$r = q("SELECT * from item left join xchan on author_xchan = xchan_hash WHERE id = %d LIMIT 1",
|
||||
intval($post_id)
|
||||
);
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
if(($r[0]['item_private']) && ($r[0]['xchan_network'] !== 'rss'))
|
||||
return;
|
||||
|
||||
$sql_extra = item_permissions_sql($r[0]['uid']);
|
||||
|
||||
$r = q("select * from item where id = %d $sql_extra",
|
||||
intval($post_id)
|
||||
);
|
||||
if(! $r)
|
||||
return;
|
||||
|
||||
if($r[0]['mimetype'] !== 'text/bbcode')
|
||||
return;
|
||||
|
||||
/** @FIXME eventually we want to post remotely via rpost on your home site */
|
||||
// When that works remove this next bit:
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
xchan_query($r);
|
||||
|
||||
$this->item = $r[0];
|
||||
return;
|
||||
}
|
||||
|
||||
public function obj() {
|
||||
$obj = [];
|
||||
|
||||
if(! $this->item)
|
||||
return $obj;
|
||||
|
||||
$obj['asld'] = $this->item['mid'];
|
||||
$obj['type'] = $this->item['obj_type'];
|
||||
$obj['id'] = $this->item['mid'];
|
||||
$obj['content'] = $this->item['body'];
|
||||
$obj['content_type'] = $this->item['mimetype'];
|
||||
$obj['title'] = $this->item['title'];
|
||||
$obj['created'] = $this->item['created'];
|
||||
$obj['edited'] = $this->item['edited'];
|
||||
$obj['author'] = [
|
||||
'name' => $this->item['author']['xchan_name'],
|
||||
'address' => $this->item['author']['xchan_addr'],
|
||||
'network' => $this->item['author']['xchan_network'],
|
||||
'link' => [
|
||||
[
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => $this->item['author']['xchan_url']
|
||||
],
|
||||
[
|
||||
'rel' => 'photo',
|
||||
'type' => $this->item['author']['xchan_photo_mimetype'],
|
||||
'href' => $this->item['author']['xchan_photo_m']
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$obj['owner'] = [
|
||||
'name' => $this->item['owner']['xchan_name'],
|
||||
'address' => $this->item['owner']['xchan_addr'],
|
||||
'network' => $this->item['owner']['xchan_network'],
|
||||
'link' => [
|
||||
[
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => $this->item['owner']['xchan_url']
|
||||
],
|
||||
[
|
||||
'rel' => 'photo',
|
||||
'type' => $this->item['owner']['xchan_photo_mimetype'],
|
||||
'href' => $this->item['owner']['xchan_photo_m']
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$obj['link'] = [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => $this->item['plink']
|
||||
];
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public function bbcode() {
|
||||
$bb = EMPTY_STR;
|
||||
|
||||
if(! $this->item)
|
||||
return $bb;
|
||||
|
||||
$is_photo = (($this->item['obj_type'] === ACTIVITY_OBJ_PHOTO) ? true : false);
|
||||
if($is_photo) {
|
||||
$object = json_decode($this->item['obj'],true);
|
||||
$photo_bb = $object['body'];
|
||||
}
|
||||
|
||||
if (strpos($this->item['body'], "[/share]") !== false) {
|
||||
$pos = strpos($this->item['body'], "[share");
|
||||
$bb = substr($this->item['body'], $pos);
|
||||
} else {
|
||||
$bb = "[share author='".urlencode($this->item['author']['xchan_name']).
|
||||
"' profile='" . $this->item['author']['xchan_url'] .
|
||||
"' avatar='" . $this->item['author']['xchan_photo_s'] .
|
||||
"' link='" . $this->item['plink'] .
|
||||
"' auth='" . (($this->item['author']['network'] === 'zot') ? 'true' : 'false') .
|
||||
"' posted='" . $this->item['created'] .
|
||||
"' message_id='" . $this->item['mid'] .
|
||||
"']";
|
||||
if($this->item['title'])
|
||||
$bb .= '[b]'.$this->item['title'].'[/b]'."\r\n";
|
||||
$bb .= (($is_photo) ? $photo_bb . "\r\n" . $this->item['body'] : $this->item['body']);
|
||||
$bb .= "[/share]";
|
||||
}
|
||||
|
||||
return $bb;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
127
Zotlabs/Lib/SuperCurl.php
Normal file
127
Zotlabs/Lib/SuperCurl.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* @brief wrapper for z_fetch_url() which can be instantiated with several built-in parameters and
|
||||
* these can be modified and re-used. Useful for CalDAV and other processes which need to authenticate
|
||||
* and set lots of CURL options (many of which stay the same from one call to the next).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
class SuperCurl {
|
||||
|
||||
|
||||
private $auth;
|
||||
private $url;
|
||||
|
||||
private $curlopt = array();
|
||||
|
||||
private $headers = null;
|
||||
public $filepos = 0;
|
||||
public $filehandle = 0;
|
||||
public $request_data = '';
|
||||
|
||||
private $request_method = 'GET';
|
||||
private $upload = false;
|
||||
private $cookies = false;
|
||||
|
||||
|
||||
private function set_data($s) {
|
||||
$this->request_data = $s;
|
||||
$this->filepos = 0;
|
||||
}
|
||||
|
||||
public function curl_read($ch,$fh,$size) {
|
||||
|
||||
if($this->filepos < 0) {
|
||||
unset($fh);
|
||||
return '';
|
||||
}
|
||||
|
||||
$s = substr($this->request_data,$this->filepos,$size);
|
||||
|
||||
if(strlen($s) < $size)
|
||||
$this->filepos = (-1);
|
||||
else
|
||||
$this->filepos = $this->filepos + $size;
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
public function __construct($opts = array()) {
|
||||
$this->set($opts);
|
||||
}
|
||||
|
||||
private function set($opts = array()) {
|
||||
if($opts) {
|
||||
foreach($opts as $k => $v) {
|
||||
switch($k) {
|
||||
case 'http_auth':
|
||||
$this->auth = $v;
|
||||
break;
|
||||
case 'magicauth':
|
||||
// currently experimental
|
||||
$this->magicauth = $v;
|
||||
\Zotlabs\Daemon\Master::Summon([ 'CurlAuth', $v ]);
|
||||
break;
|
||||
case 'custom':
|
||||
$this->request_method = $v;
|
||||
break;
|
||||
case 'url':
|
||||
$this->url = $v;
|
||||
break;
|
||||
case 'data':
|
||||
$this->set_data($v);
|
||||
if($v) {
|
||||
$this->upload = true;
|
||||
}
|
||||
else {
|
||||
$this->upload = false;
|
||||
}
|
||||
break;
|
||||
case 'headers':
|
||||
$this->headers = $v;
|
||||
break;
|
||||
default:
|
||||
$this->curlopts[$k] = $v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function exec() {
|
||||
$opts = $this->curlopts;
|
||||
$url = $this->url;
|
||||
if($this->auth)
|
||||
$opts['http_auth'] = $this->auth;
|
||||
if($this->magicauth) {
|
||||
$opts['cookiejar'] = 'store/[data]/cookie_' . $this->magicauth;
|
||||
$opts['cookiefile'] = 'store/[data]/cookie_' . $this->magicauth;
|
||||
$opts['cookie'] = 'PHPSESSID=' . trim(file_get_contents('store/[data]/cookien_' . $this->magicauth));
|
||||
$c = channelx_by_n($this->magicauth);
|
||||
if($c)
|
||||
$url = zid($this->url,channel_reddress($c));
|
||||
}
|
||||
if($this->custom)
|
||||
$opts['custom'] = $this->custom;
|
||||
if($this->headers)
|
||||
$opts['headers'] = $this->headers;
|
||||
if($this->upload) {
|
||||
$opts['upload'] = true;
|
||||
$opts['infile'] = $this->filehandle;
|
||||
$opts['infilesize'] = strlen($this->request_data);
|
||||
$opts['readfunc'] = [ $this, 'curl_read' ] ;
|
||||
}
|
||||
|
||||
$recurse = 0;
|
||||
return z_fetch_url($this->url,true,$recurse,(($opts) ? $opts : null));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
150
Zotlabs/Lib/SvgSanitizer.php
Normal file
150
Zotlabs/Lib/SvgSanitizer.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
use DomDocument;
|
||||
|
||||
/**
|
||||
* SVGSantiizer
|
||||
*
|
||||
* Whitelist-based PHP SVG sanitizer.
|
||||
*
|
||||
* @link https://github.com/alister-/SVG-Sanitizer}
|
||||
* @author Alister Norris
|
||||
* @copyright Copyright (c) 2013 Alister Norris
|
||||
* @license http://opensource.org/licenses/mit-license.php The MIT License
|
||||
* @package svgsanitizer
|
||||
*/
|
||||
|
||||
class SvgSanitizer {
|
||||
|
||||
private $xmlDoc; // PHP XML DOMDocument
|
||||
|
||||
private $removedattrs = [];
|
||||
|
||||
private static $allowed_functions = [ 'matrix', 'url', 'translate', 'rgb' ];
|
||||
|
||||
// defines the whitelist of elements and attributes allowed.
|
||||
private static $whitelist = [
|
||||
'a' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'href', 'xlink:href', 'xlink:title' ],
|
||||
'circle' => [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
||||
'clipPath' => [ 'class', 'clipPathUnits', 'id' ],
|
||||
'defs' => [ ],
|
||||
'style' => [ 'type' ],
|
||||
'desc' => [ ],
|
||||
'ellipse' => [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
||||
'feGaussianBlur' => [ 'class', 'color-interpolation-filters', 'id', 'requiredFeatures', 'stdDeviation' ],
|
||||
'filter' => [ 'class', 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'requiredFeatures', 'width', 'x', 'xlink:href', 'y' ],
|
||||
'foreignObject' => [ 'class', 'font-size', 'height', 'id', 'opacity', 'requiredFeatures', 'style', 'transform', 'width', 'x', 'y' ],
|
||||
'g' => [ 'class', 'clip-path', 'clip-rule', 'id', 'display', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor' ],
|
||||
'image' => [ 'class', 'clip-path', 'clip-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:href', 'xlink:title', 'y' ],
|
||||
'line' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'x1', 'x2', 'y1', 'y2' ],
|
||||
'linearGradient' => [ 'class', 'id', 'gradientTransform', 'gradientUnits', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'x1', 'x2', 'xlink:href', 'y1', 'y2' ],
|
||||
'marker' => [ 'id', 'class', 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'systemLanguage', 'viewBox' ],
|
||||
'mask' => [ 'class', 'height', 'id', 'maskContentUnits', 'maskUnits', 'width', 'x', 'y' ],
|
||||
'metadata' => [ 'class', 'id' ],
|
||||
'path' => [ 'class', 'clip-path', 'clip-rule', 'd', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
||||
'pattern' => [ 'class', 'height', 'id', 'patternContentUnits', 'patternTransform', 'patternUnits', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xlink:href', 'y' ],
|
||||
'polygon' => [ 'class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'class', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
||||
'polyline' => [ 'class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
||||
'radialGradient' => [ 'class', 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href' ],
|
||||
'rect' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'width', 'x', 'y' ],
|
||||
'stop' => [ 'class', 'id', 'offset', 'requiredFeatures', 'stop-color', 'stop-opacity', 'style', 'systemLanguage' ],
|
||||
'svg' => [ 'class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'y' ],
|
||||
'switch' => [ 'class', 'id', 'requiredFeatures', 'systemLanguage' ],
|
||||
'symbol' => [ 'class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox' ],
|
||||
'text' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y' ],
|
||||
'textPath' => [ 'class', 'id', 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'transform', 'xlink:href' ],
|
||||
'title' => [ ],
|
||||
'tspan' => [ 'class', 'clip-path', 'clip-rule', 'dx', 'dy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'rotate', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'textLength', 'transform', 'x', 'xml:space', 'y' ],
|
||||
'use' => [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'transform', 'width', 'x', 'xlink:href', 'y' ],
|
||||
];
|
||||
|
||||
function __construct() {
|
||||
$this->xmlDoc = new DOMDocument('1.0','UTF-8');
|
||||
$this->xmlDoc->preserveWhiteSpace = false;
|
||||
libxml_use_internal_errors(true);
|
||||
}
|
||||
|
||||
// load XML SVG
|
||||
function load($file) {
|
||||
$this->xmlDoc->load($file);
|
||||
}
|
||||
|
||||
function loadXML($str) {
|
||||
if (! $this->xmlDoc->loadXML($str)) {
|
||||
logger('loadxml: ' . print_r(libxml_get_errors(),true), LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function sanitize()
|
||||
{
|
||||
// all elements in xml doc
|
||||
$allElements = $this->xmlDoc->getElementsByTagName('*');
|
||||
|
||||
// loop through all elements
|
||||
for($i = 0; $i < $allElements->length; $i++)
|
||||
{
|
||||
$this->removedattrs = [];
|
||||
|
||||
$currentNode = $allElements->item($i);
|
||||
|
||||
// logger('current_node: ' . print_r($currentNode,true));
|
||||
|
||||
// array of allowed attributes in specific element
|
||||
$whitelist_attr_arr = self::$whitelist[$currentNode->tagName];
|
||||
|
||||
// does element exist in whitelist?
|
||||
if(isset($whitelist_attr_arr)) {
|
||||
$total = $currentNode->attributes->length;
|
||||
|
||||
for($x = 0; $x < $total; $x++) {
|
||||
|
||||
// get attributes name
|
||||
$attrName = $currentNode->attributes->item($x)->nodeName;
|
||||
|
||||
// logger('checking: ' . print_r($currentNode->attributes->item($x),true));
|
||||
$matches = false;
|
||||
|
||||
// check if attribute isn't in whitelist
|
||||
if(! in_array($attrName, $whitelist_attr_arr)) {
|
||||
$this->removedattrs[] = $attrName;
|
||||
}
|
||||
// check for disallowed functions
|
||||
elseif (preg_match_all('/([a-zA-Z0-9]+)[\s]*\(/',
|
||||
$currentNode->attributes->item($x)->textContent,$matches,PREG_SET_ORDER)) {
|
||||
if ($attrName === 'text') {
|
||||
continue;
|
||||
}
|
||||
foreach ($matches as $match) {
|
||||
if(! in_array($match[1],self::$allowed_functions)) {
|
||||
logger('queue_remove_function: ' . $match[1],LOGGER_DEBUG);
|
||||
$this->removedattrs[] = $attrName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->removedattrs) {
|
||||
foreach ($this->removedattrs as $attr) {
|
||||
$currentNode->removeAttribute($attr);
|
||||
logger('removed: ' . $attr, LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// else remove element
|
||||
else {
|
||||
logger('remove_node: ' . print_r($currentNode,true));
|
||||
$currentNode->parentNode->removeChild($currentNode);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function saveSVG() {
|
||||
$this->xmlDoc->formatOutput = true;
|
||||
return($this->xmlDoc->saveXML());
|
||||
}
|
||||
}
|
||||
85
Zotlabs/Lib/System.php
Normal file
85
Zotlabs/Lib/System.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
class System {
|
||||
|
||||
static public function get_platform_name() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && array_key_exists('platform_name',\App::$config['system']))
|
||||
return \App::$config['system']['platform_name'];
|
||||
return PLATFORM_NAME;
|
||||
}
|
||||
|
||||
static public function get_site_name() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['sitename'])
|
||||
return \App::$config['system']['sitename'];
|
||||
return '';
|
||||
}
|
||||
|
||||
static public function get_project_version() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
|
||||
return '';
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && array_key_exists('std_version',\App::$config['system']))
|
||||
return \App::$config['system']['std_version'];
|
||||
|
||||
return self::get_std_version();
|
||||
}
|
||||
|
||||
static public function get_update_version() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
|
||||
return '';
|
||||
return DB_UPDATE_VERSION;
|
||||
}
|
||||
|
||||
|
||||
static public function get_notify_icon() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['email_notify_icon_url'])
|
||||
return \App::$config['system']['email_notify_icon_url'];
|
||||
return z_root() . DEFAULT_NOTIFY_ICON;
|
||||
}
|
||||
|
||||
static public function get_site_icon() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['site_icon_url'])
|
||||
return \App::$config['system']['site_icon_url'];
|
||||
return z_root() . DEFAULT_PLATFORM_ICON ;
|
||||
}
|
||||
|
||||
|
||||
static public function get_project_link() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['project_link'])
|
||||
return \App::$config['system']['project_link'];
|
||||
return 'https://hubzilla.org';
|
||||
}
|
||||
|
||||
static public function get_project_srclink() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['project_srclink'])
|
||||
return \App::$config['system']['project_srclink'];
|
||||
return 'https://framagit.org/hubzilla/core.git';
|
||||
}
|
||||
|
||||
static public function get_server_role() {
|
||||
return 'pro';
|
||||
}
|
||||
|
||||
|
||||
static public function get_zot_revision() {
|
||||
$x = [ 'revision' => ZOT_REVISION ];
|
||||
call_hooks('zot_revision',$x);
|
||||
return $x['revision'];
|
||||
}
|
||||
|
||||
static public function get_std_version() {
|
||||
if(defined('STD_VERSION'))
|
||||
return STD_VERSION;
|
||||
return '0.0.0';
|
||||
}
|
||||
|
||||
static public function compatible_project($p) {
|
||||
|
||||
if(get_directory_realm() != DIRECTORY_REALM)
|
||||
return true;
|
||||
if(in_array(strtolower($p),['hubzilla','zap','red']))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
21
Zotlabs/Lib/Techlevels.php
Normal file
21
Zotlabs/Lib/Techlevels.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
|
||||
class Techlevels {
|
||||
|
||||
static public function levels() {
|
||||
$techlevels = [
|
||||
'0' => t('0. Beginner/Basic'),
|
||||
'1' => t('1. Novice - not skilled but willing to learn'),
|
||||
'2' => t('2. Intermediate - somewhat comfortable'),
|
||||
'3' => t('3. Advanced - very comfortable'),
|
||||
'4' => t('4. Expert - I can write computer code'),
|
||||
'5' => t('5. Wizard - I probably know more than you do')
|
||||
];
|
||||
return $techlevels;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
869
Zotlabs/Lib/ThreadItem.php
Normal file
869
Zotlabs/Lib/ThreadItem.php
Normal file
@@ -0,0 +1,869 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Apps;
|
||||
|
||||
require_once('include/text.php');
|
||||
|
||||
/**
|
||||
* A thread item
|
||||
*/
|
||||
|
||||
class ThreadItem {
|
||||
|
||||
public $data = array();
|
||||
private $template = 'conv_item.tpl';
|
||||
private $comment_box_template = 'comment_item.tpl';
|
||||
private $commentable = false;
|
||||
// list of supported reaction emojis - a site can over-ride this via config system.reactions
|
||||
private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f606','1f62e','1f634','1f61c','1f607','1f608'];
|
||||
private $toplevel = false;
|
||||
private $children = array();
|
||||
private $parent = null;
|
||||
private $conversation = null;
|
||||
private $redirect_url = null;
|
||||
private $owner_url = '';
|
||||
private $owner_photo = '';
|
||||
private $owner_name = '';
|
||||
private $wall_to_wall = false;
|
||||
private $threaded = false;
|
||||
private $visiting = false;
|
||||
private $channel = null;
|
||||
private $display_mode = 'normal';
|
||||
private $reload = '';
|
||||
|
||||
|
||||
public function __construct($data) {
|
||||
|
||||
$this->data = $data;
|
||||
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
|
||||
$this->threaded = get_config('system','thread_allow');
|
||||
|
||||
$observer = \App::get_observer();
|
||||
|
||||
// Prepare the children
|
||||
if($data['children']) {
|
||||
foreach($data['children'] as $item) {
|
||||
|
||||
/*
|
||||
* Only add those that will be displayed
|
||||
*/
|
||||
|
||||
if((! visible_activity($item)) || array_key_exists('blocked',$item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$child = new ThreadItem($item);
|
||||
$this->add_child($child);
|
||||
}
|
||||
}
|
||||
|
||||
// allow a site to configure the order and content of the reaction emoji list
|
||||
if($this->toplevel) {
|
||||
$x = get_config('system','reactions');
|
||||
if($x && is_array($x) && count($x)) {
|
||||
$this->reactions = $x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data in a form usable by a conversation template
|
||||
*
|
||||
* Returns:
|
||||
* _ The data requested on success
|
||||
* _ false on failure
|
||||
*/
|
||||
|
||||
public function get_template_data($conv_responses, $thread_level=1, $conv_flags = []) {
|
||||
|
||||
$result = array();
|
||||
|
||||
$item = $this->get_data();
|
||||
|
||||
$commentww = '';
|
||||
$sparkle = '';
|
||||
$buttons = '';
|
||||
$dropping = false;
|
||||
$star = false;
|
||||
$isstarred = "unstarred fa-star-o";
|
||||
$is_comment = false;
|
||||
$is_item = false;
|
||||
$osparkle = '';
|
||||
$total_children = $this->count_descendants();
|
||||
$unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants());
|
||||
|
||||
$conv = $this->get_conversation();
|
||||
$observer = $conv->get_observer();
|
||||
|
||||
$lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|
||||
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
|
||||
? t('Private Message')
|
||||
: false);
|
||||
|
||||
$shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false);
|
||||
|
||||
// allow an exemption for sharing stuff from your private feeds
|
||||
if($item['author']['xchan_network'] === 'rss')
|
||||
$shareable = true;
|
||||
|
||||
$privacy_warning = false;
|
||||
if(intval($item['item_private']) && ($item['owner']['xchan_network'] === 'activitypub')) {
|
||||
$recips = get_iconfig($item['parent'], 'activitypub', 'recips');
|
||||
|
||||
if(! in_array($observer['xchan_url'], $recips['to']))
|
||||
$privacy_warning = true;
|
||||
}
|
||||
|
||||
if ($lock) {
|
||||
if (($item['mid'] == $item['parent_mid']) && count(get_terms_oftype($item['term'],TERM_FORUM))) {
|
||||
$privacy_warning = true;
|
||||
$conv_flags['parent_privacy_warning'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$privacy_warning = (isset($conv_flags['parent_privacy_warning'])) ? $conv_flags['parent_privacy_warning'] : $privacy_warning;
|
||||
|
||||
if ($lock && $privacy_warning) {
|
||||
$lock = t('Privacy conflict. Discretion advised.');
|
||||
}
|
||||
|
||||
$mode = $conv->get_mode();
|
||||
|
||||
switch($item['item_type']) {
|
||||
case ITEM_TYPE_CARD:
|
||||
$edlink = 'card_edit';
|
||||
break;
|
||||
case ITEM_TYPE_ARTICLE:
|
||||
$edlink = 'article_edit';
|
||||
break;
|
||||
default:
|
||||
$edlink = 'editpost';
|
||||
break;
|
||||
}
|
||||
|
||||
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
|
||||
$edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit'));
|
||||
else
|
||||
$edpost = false;
|
||||
|
||||
|
||||
if($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|
||||
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
|
||||
|| $this->get_data_value('uid') == local_channel())
|
||||
$dropping = true;
|
||||
|
||||
|
||||
if(array_key_exists('real_uid',$item)) {
|
||||
$edpost = false;
|
||||
$dropping = false;
|
||||
}
|
||||
|
||||
|
||||
if($dropping) {
|
||||
$drop = array(
|
||||
'dropping' => $dropping,
|
||||
'delete' => t('Delete'),
|
||||
);
|
||||
}
|
||||
elseif(is_site_admin()) {
|
||||
$drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ];
|
||||
}
|
||||
|
||||
// FIXME
|
||||
if($observer_is_pageowner) {
|
||||
$multidrop = array(
|
||||
'select' => t('Select'),
|
||||
);
|
||||
}
|
||||
|
||||
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
|
||||
|
||||
$profile_avatar = $item['author']['xchan_photo_m'];
|
||||
$profile_link = chanlink_hash($item['author_xchan']);
|
||||
$profile_name = $item['author']['xchan_name'];
|
||||
|
||||
$location = format_location($item);
|
||||
$isevent = false;
|
||||
$attend = null;
|
||||
$canvote = false;
|
||||
|
||||
// process action responses - e.g. like/dislike/attend/agree/whatever
|
||||
$response_verbs = array('like');
|
||||
if(feature_enabled($conv->get_profile_owner(),'dislike'))
|
||||
$response_verbs[] = 'dislike';
|
||||
if($item['obj_type'] === ACTIVITY_OBJ_EVENT) {
|
||||
$response_verbs[] = 'attendyes';
|
||||
$response_verbs[] = 'attendno';
|
||||
$response_verbs[] = 'attendmaybe';
|
||||
if($this->is_commentable() && $observer) {
|
||||
$isevent = true;
|
||||
$attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
|
||||
}
|
||||
}
|
||||
|
||||
$consensus = (intval($item['item_consensus']) ? true : false);
|
||||
if($consensus) {
|
||||
$response_verbs[] = 'agree';
|
||||
$response_verbs[] = 'disagree';
|
||||
$response_verbs[] = 'abstain';
|
||||
if($this->is_commentable() && $observer) {
|
||||
$conlabels = array( t('I agree'), t('I disagree'), t('I abstain'));
|
||||
$canvote = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(! feature_enabled($conv->get_profile_owner(),'dislike'))
|
||||
unset($conv_responses['dislike']);
|
||||
|
||||
$responses = get_responses($conv_responses,$response_verbs,$this,$item);
|
||||
|
||||
$my_responses = [];
|
||||
foreach($response_verbs as $v) {
|
||||
$my_responses[$v] = (($conv_responses[$v][$item['mid'] . '-m']) ? 1 : 0);
|
||||
}
|
||||
|
||||
$like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
|
||||
$like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : '');
|
||||
if (($like_list) && (count($like_list) > MAX_LIKERS)) {
|
||||
$like_list_part = array_slice($like_list, 0, MAX_LIKERS);
|
||||
array_push($like_list_part, '<a class="dropdown-item" href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
||||
} else {
|
||||
$like_list_part = '';
|
||||
}
|
||||
$like_button_label = tt('Like','Likes',$like_count,'noun');
|
||||
|
||||
if (feature_enabled($conv->get_profile_owner(),'dislike')) {
|
||||
$dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : '');
|
||||
$dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : '');
|
||||
$dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun');
|
||||
if (($dislike_list) && (count($dislike_list) > MAX_LIKERS)) {
|
||||
$dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS);
|
||||
array_push($dislike_list_part, '<a class="dropdown-item" href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
||||
} else {
|
||||
$dislike_list_part = '';
|
||||
}
|
||||
}
|
||||
|
||||
$showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : '');
|
||||
$showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike'))
|
||||
? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : '');
|
||||
|
||||
/*
|
||||
* We should avoid doing this all the time, but it depends on the conversation mode
|
||||
* And the conv mode may change when we change the conv, or it changes its mode
|
||||
* Maybe we should establish a way to be notified about conversation changes
|
||||
*/
|
||||
|
||||
$this->check_wall_to_wall();
|
||||
|
||||
if($this->is_toplevel()) {
|
||||
// FIXME check this permission
|
||||
if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) {
|
||||
|
||||
$star = array(
|
||||
'toggle' => t("Toggle Star Status"),
|
||||
'isstarred' => ((intval($item['item_starred'])) ? true : false),
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
$is_comment = true;
|
||||
}
|
||||
|
||||
|
||||
$verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
|
||||
$forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : '');
|
||||
$unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : '');
|
||||
|
||||
$settings = '';
|
||||
|
||||
// FIXME - check this permission
|
||||
if($conv->get_profile_owner() == local_channel()) {
|
||||
$tagger = array(
|
||||
'tagit' => t("Add Tag"),
|
||||
'classtagger' => "",
|
||||
);
|
||||
|
||||
$settings = t('Conversation Tools');
|
||||
}
|
||||
|
||||
$has_bookmarks = false;
|
||||
if(Apps::system_app_installed(local_channel(), 'Bookmarks') && is_array($item['term'])) {
|
||||
foreach($item['term'] as $t) {
|
||||
if(($t['ttype'] == TERM_BOOKMARK))
|
||||
$has_bookmarks = true;
|
||||
}
|
||||
}
|
||||
|
||||
$has_event = false;
|
||||
if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel())
|
||||
$has_event = true;
|
||||
|
||||
if($this->is_commentable() && $observer) {
|
||||
$like = array( t("I like this \x28toggle\x29"), t("like"));
|
||||
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
|
||||
$reply_to = array( t("Reply on this comment"), t("reply"), t("Reply to"));
|
||||
}
|
||||
|
||||
if ($shareable) {
|
||||
// This actually turns out not to be possible in some protocol stacks without opening up hundreds of new issues.
|
||||
// Will allow it only for uri resolvable sources.
|
||||
if(strpos($item['mid'],'http') === 0) {
|
||||
$share = []; //Not yet ready for primetime
|
||||
//$share = array( t('Repeat This'), t('repeat'));
|
||||
}
|
||||
$embed = array( t('Share This'), t('share'));
|
||||
}
|
||||
|
||||
$dreport = '';
|
||||
|
||||
$keep_reports = intval(get_config('system','expire_delivery_reports'));
|
||||
if($keep_reports === 0)
|
||||
$keep_reports = 10;
|
||||
|
||||
if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0) {
|
||||
$dreport = t('Delivery Report');
|
||||
$dreport_link = gen_link_id($item['mid']);
|
||||
}
|
||||
|
||||
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
|
||||
$is_new = true;
|
||||
|
||||
localize_item($item);
|
||||
|
||||
$body = prepare_body($item,true);
|
||||
|
||||
// $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link
|
||||
// since we can't depend on llink or plink pointing to the right local location.
|
||||
|
||||
$owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@'));
|
||||
$viewthread = $item['llink'];
|
||||
if($conv->get_mode() === 'channel')
|
||||
$viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . urlencode(gen_link_id($item['mid']));
|
||||
|
||||
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
|
||||
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
|
||||
|
||||
$children = $this->get_children();
|
||||
|
||||
$has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
|
||||
|
||||
$dropdown_extras_arr = [ 'item' => $item , 'dropdown_extras' => '' ];
|
||||
call_hooks('dropdown_extras',$dropdown_extras_arr);
|
||||
$dropdown_extras = $dropdown_extras_arr['dropdown_extras'];
|
||||
|
||||
$tmp_item = array(
|
||||
'template' => $this->get_template(),
|
||||
'mode' => $mode,
|
||||
'item_type' => intval($item['item_type']),
|
||||
'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
|
||||
'body' => $body['html'],
|
||||
'tags' => $body['tags'],
|
||||
'categories' => $body['categories'],
|
||||
'mentions' => $body['mentions'],
|
||||
'attachments' => $body['attachments'],
|
||||
'folders' => $body['folders'],
|
||||
'text' => strip_tags($body['html']),
|
||||
'id' => $this->get_id(),
|
||||
'mid' => $item['mid'],
|
||||
'parent' => $item['parent'],
|
||||
'author_id' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
|
||||
'isevent' => $isevent,
|
||||
'attend' => $attend,
|
||||
'consensus' => $consensus,
|
||||
'conlabels' => $conlabels,
|
||||
'canvote' => $canvote,
|
||||
'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url'])),
|
||||
'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), (($item['owner']['xchan_addr']) ? $item['owner']['xchan_addr'] : $item['owner']['xchan_url'])),
|
||||
'llink' => $item['llink'],
|
||||
'viewthread' => $viewthread,
|
||||
'to' => t('to'),
|
||||
'via' => t('via'),
|
||||
'wall' => t('Wall-to-Wall'),
|
||||
'vwall' => t('via Wall-To-Wall:'),
|
||||
'profile_url' => $profile_link,
|
||||
'thread_action_menu' => thread_action_menu($item,$conv->get_mode()),
|
||||
'thread_author_menu' => thread_author_menu($item,$conv->get_mode()),
|
||||
'dreport' => $dreport,
|
||||
'dreport_link' => $dreport_link,
|
||||
'name' => $profile_name,
|
||||
'thumb' => $profile_avatar,
|
||||
'osparkle' => $osparkle,
|
||||
'sparkle' => $sparkle,
|
||||
'title' => $item['title'],
|
||||
'title_tosource' => get_pconfig($conv->get_profile_owner(),'system','title_tosource'),
|
||||
'ago' => relative_date($item['created']),
|
||||
'app' => $item['app'],
|
||||
'str_app' => sprintf( t('from %s'), $item['app']),
|
||||
'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'),
|
||||
'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'),
|
||||
'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''),
|
||||
'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''),
|
||||
'lock' => $lock,
|
||||
'privacy_warning' => $privacy_warning,
|
||||
'verified' => $verified,
|
||||
'unverified' => $unverified,
|
||||
'forged' => $forged,
|
||||
'location' => $location,
|
||||
'divider' => get_pconfig($conv->get_profile_owner(),'system','item_divider'),
|
||||
'attend_label' => t('Attend'),
|
||||
'attend_title' => t('Attendance Options'),
|
||||
'vote_label' => t('Vote'),
|
||||
'vote_title' => t('Voting Options'),
|
||||
'is_comment' => $is_comment,
|
||||
'is_new' => $is_new,
|
||||
'owner_url' => $this->get_owner_url(),
|
||||
'owner_photo' => $this->get_owner_photo(),
|
||||
'owner_name' => $this->get_owner_name(),
|
||||
'photo' => $body['photo'],
|
||||
'event' => $body['event'],
|
||||
'has_tags' => $has_tags,
|
||||
'reactions' => $this->reactions,
|
||||
// Item toolbar buttons
|
||||
'emojis' => (($this->is_toplevel() && $this->is_commentable() && $observer && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''),
|
||||
'like' => $like,
|
||||
'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''),
|
||||
'reply_to' => (((! $this->is_toplevel()) && feature_enabled($conv->get_profile_owner(),'reply_to')) ? $reply_to : ''),
|
||||
'top_hint' => t("Go to previous comment"),
|
||||
'share' => $share,
|
||||
'embed' => $embed,
|
||||
'rawmid' => $item['mid'],
|
||||
'plink' => get_plink($item),
|
||||
'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''),
|
||||
'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts') && ($item['item_type'] == ITEM_TYPE_POST)) ? $star : ''),
|
||||
'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''),
|
||||
'filer' => ((feature_enabled($conv->get_profile_owner(),'filing') && ($item['item_type'] == ITEM_TYPE_POST)) ? $filer : ''),
|
||||
'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''),
|
||||
'addtocal' => (($has_event) ? t('Add to Calendar') : ''),
|
||||
'drop' => $drop,
|
||||
'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''),
|
||||
'dropdown_extras' => $dropdown_extras,
|
||||
// end toolbar buttons
|
||||
'unseen_comments' => $unseen_comments,
|
||||
'comment_count' => $total_children,
|
||||
'comment_count_txt' => $comment_count_txt,
|
||||
'list_unseen_txt' => $list_unseen_txt,
|
||||
'markseen' => t('Mark all seen'),
|
||||
'responses' => $responses,
|
||||
'my_responses' => $my_responses,
|
||||
'like_count' => $like_count,
|
||||
'like_list' => $like_list,
|
||||
'like_list_part' => $like_list_part,
|
||||
'like_button_label' => $like_button_label,
|
||||
'like_modal_title' => t('Likes','noun'),
|
||||
'dislike_modal_title' => t('Dislikes','noun'),
|
||||
'dislike_count' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_count : ''),
|
||||
'dislike_list' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list : ''),
|
||||
'dislike_list_part' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list_part : ''),
|
||||
'dislike_button_label' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_button_label : ''),
|
||||
'modal_dismiss' => t('Close'),
|
||||
'showlike' => $showlike,
|
||||
'showdislike' => $showdislike,
|
||||
'comment' => $this->get_comment_box($indent),
|
||||
'previewing' => ($conv->is_preview() ? true : false ),
|
||||
'preview_lbl' => t('This is an unsaved preview'),
|
||||
'wait' => t('Please wait'),
|
||||
'submid' => str_replace(['+','='], ['',''], base64_encode($item['mid'])),
|
||||
'thread_level' => $thread_level,
|
||||
'settings' => $settings,
|
||||
'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? $item['thr_parent'] : '')
|
||||
);
|
||||
|
||||
$arr = array('item' => $item, 'output' => $tmp_item);
|
||||
call_hooks('display_item', $arr);
|
||||
|
||||
$result = $arr['output'];
|
||||
|
||||
$result['children'] = array();
|
||||
$nb_children = count($children);
|
||||
|
||||
$visible_comments = get_config('system','expanded_comments');
|
||||
if($visible_comments === false)
|
||||
$visible_comments = 3;
|
||||
|
||||
// needed for scroll to comment from notification but needs more work
|
||||
// as we do not want to open all comments unless there is actually an #item_xx anchor
|
||||
// and the url fragment is not sent to the server.
|
||||
// if(in_array(\App::$module,['display','update_display']))
|
||||
// $visible_comments = 99999;
|
||||
|
||||
if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) {
|
||||
foreach($children as $child) {
|
||||
$result['children'][] = $child->get_template_data($conv_responses, $thread_level + 1,$conv_flags);
|
||||
}
|
||||
// Collapse
|
||||
if(($nb_children > $visible_comments) || ($thread_level > 1)) {
|
||||
$result['children'][0]['comment_firstcollapsed'] = true;
|
||||
$result['children'][0]['num_comments'] = $comment_count_txt;
|
||||
$result['children'][0]['hide_text'] = sprintf( t('%s show all'), '<i class="fa fa-chevron-down"></i>');
|
||||
if($thread_level > 1) {
|
||||
$result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
|
||||
}
|
||||
else {
|
||||
$result['children'][$nb_children - ($visible_comments + 1)]['comment_lastcollapsed'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result['private'] = $item['item_private'];
|
||||
$result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : '');
|
||||
|
||||
if($this->is_threaded()) {
|
||||
$result['flatten'] = false;
|
||||
$result['threaded'] = true;
|
||||
}
|
||||
else {
|
||||
$result['flatten'] = true;
|
||||
$result['threaded'] = false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->get_data_value('id');
|
||||
}
|
||||
|
||||
public function get_display_mode() {
|
||||
return $this->display_mode;
|
||||
}
|
||||
|
||||
public function set_display_mode($mode) {
|
||||
$this->display_mode = $mode;
|
||||
}
|
||||
|
||||
public function is_threaded() {
|
||||
return $this->threaded;
|
||||
}
|
||||
|
||||
public function set_reload($val) {
|
||||
$this->reload = $val;
|
||||
}
|
||||
|
||||
public function get_reload() {
|
||||
return $this->reload;
|
||||
}
|
||||
|
||||
public function set_commentable($val) {
|
||||
$this->commentable = $val;
|
||||
foreach($this->get_children() as $child)
|
||||
$child->set_commentable($val);
|
||||
}
|
||||
|
||||
public function is_commentable() {
|
||||
return $this->commentable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child item
|
||||
*/
|
||||
public function add_child($item) {
|
||||
$item_id = $item->get_id();
|
||||
if(!$item_id) {
|
||||
logger('[ERROR] Item::add_child : Item has no ID!!', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
if($this->get_child($item->get_id())) {
|
||||
logger('[WARN] Item::add_child : Item already exists ('. $item->get_id() .').', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* Only add what will be displayed
|
||||
*/
|
||||
|
||||
if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$item->set_parent($this);
|
||||
$this->children[] = $item;
|
||||
return end($this->children);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a child by its ID
|
||||
*/
|
||||
public function get_child($id) {
|
||||
foreach($this->get_children() as $child) {
|
||||
if($child->get_id() == $id)
|
||||
return $child;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all our children
|
||||
*/
|
||||
public function get_children() {
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set our parent
|
||||
*/
|
||||
protected function set_parent($item) {
|
||||
$parent = $this->get_parent();
|
||||
if($parent) {
|
||||
$parent->remove_child($this);
|
||||
}
|
||||
$this->parent = $item;
|
||||
$this->set_conversation($item->get_conversation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove our parent
|
||||
*/
|
||||
protected function remove_parent() {
|
||||
$this->parent = null;
|
||||
$this->conversation = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a child
|
||||
*/
|
||||
public function remove_child($item) {
|
||||
$id = $item->get_id();
|
||||
foreach($this->get_children() as $key => $child) {
|
||||
if($child->get_id() == $id) {
|
||||
$child->remove_parent();
|
||||
unset($this->children[$key]);
|
||||
// Reindex the array, in order to make sure there won't be any trouble on loops using count()
|
||||
$this->children = array_values($this->children);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
logger('[WARN] Item::remove_child : Item is not a child ('. $id .').', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent item
|
||||
*/
|
||||
protected function get_parent() {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* set conversation
|
||||
*/
|
||||
public function set_conversation($conv) {
|
||||
$previous_mode = ($this->conversation ? $this->conversation->get_mode() : '');
|
||||
|
||||
$this->conversation = $conv;
|
||||
|
||||
// Set it on our children too
|
||||
foreach($this->get_children() as $child)
|
||||
$child->set_conversation($conv);
|
||||
}
|
||||
|
||||
/**
|
||||
* get conversation
|
||||
*/
|
||||
public function get_conversation() {
|
||||
return $this->conversation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw data
|
||||
*
|
||||
* We shouldn't need this
|
||||
*/
|
||||
public function get_data() {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a data value
|
||||
*
|
||||
* Returns:
|
||||
* _ value on success
|
||||
* _ false on failure
|
||||
*/
|
||||
public function get_data_value($name) {
|
||||
if(!isset($this->data[$name])) {
|
||||
// logger('[ERROR] Item::get_data_value : Item has no value name "'. $name .'".', LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->data[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template
|
||||
*/
|
||||
public function get_template() {
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
|
||||
public function set_template($t) {
|
||||
$this->template = $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a toplevel post
|
||||
*/
|
||||
private function is_toplevel() {
|
||||
return $this->toplevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the total of our descendants
|
||||
*/
|
||||
private function count_descendants() {
|
||||
$children = $this->get_children();
|
||||
$total = count($children);
|
||||
if($total > 0) {
|
||||
foreach($children as $child) {
|
||||
$total += $child->count_descendants();
|
||||
}
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
|
||||
private function count_unseen_descendants() {
|
||||
$children = $this->get_children();
|
||||
$total = count($children);
|
||||
if($total > 0) {
|
||||
$total = 0;
|
||||
foreach($children as $child) {
|
||||
if((! visible_activity($child->data)) || array_key_exists('author_blocked',$child->data)) {
|
||||
continue;
|
||||
}
|
||||
if(intval($child->data['item_unseen']))
|
||||
$total ++;
|
||||
}
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the template for the comment box
|
||||
*/
|
||||
private function get_comment_box_template() {
|
||||
return $this->comment_box_template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the comment box
|
||||
*
|
||||
* Returns:
|
||||
* _ The comment box string (empty if no comment box)
|
||||
* _ false on failure
|
||||
*/
|
||||
private function get_comment_box($indent) {
|
||||
|
||||
if(!$this->is_toplevel() && !get_config('system','thread_allow')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$comment_box = '';
|
||||
$conv = $this->get_conversation();
|
||||
|
||||
// logger('Commentable conv: ' . $conv->is_commentable());
|
||||
|
||||
if(! $this->is_commentable())
|
||||
return;
|
||||
|
||||
$template = get_markup_template($this->get_comment_box_template());
|
||||
|
||||
$observer = $conv->get_observer();
|
||||
|
||||
$arr = array('comment_buttons' => '','id' => $this->get_id());
|
||||
call_hooks('comment_buttons',$arr);
|
||||
$comment_buttons = $arr['comment_buttons'];
|
||||
|
||||
$comment_box = replace_macros($template,array(
|
||||
'$return_path' => '',
|
||||
'$threaded' => $this->is_threaded(),
|
||||
'$jsreload' => $conv->reload,
|
||||
'$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
|
||||
'$id' => $this->get_id(),
|
||||
'$parent' => $this->get_id(),
|
||||
'$comment_buttons' => $comment_buttons,
|
||||
'$profile_uid' => $conv->get_profile_owner(),
|
||||
'$mylink' => $observer['xchan_url'],
|
||||
'$mytitle' => t('This is you'),
|
||||
'$myphoto' => $observer['xchan_photo_s'],
|
||||
'$comment' => t('Comment'),
|
||||
'$submit' => t('Submit'),
|
||||
'$edbold' => t('Bold'),
|
||||
'$editalic' => t('Italic'),
|
||||
'$eduline' => t('Underline'),
|
||||
'$edquote' => t('Quote'),
|
||||
'$edcode' => t('Code'),
|
||||
'$edimg' => t('Image'),
|
||||
'$edatt' => t('Attach/Upload file'),
|
||||
'$edurl' => t('Insert Link'),
|
||||
'$edvideo' => t('Video'),
|
||||
'$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
|
||||
'$indent' => $indent,
|
||||
'$can_upload' => (perm_is_allowed($conv->get_profile_owner(),get_observer_hash(),'write_storage') && $conv->is_uploadable()),
|
||||
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
|
||||
'$encrypt' => t('Encrypt text'),
|
||||
'$cipher' => $conv->get_cipher(),
|
||||
'$sourceapp' => \App::$sourcename,
|
||||
'$observer' => get_observer_hash(),
|
||||
'$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
|
||||
'$anonname' => [ 'anonname', t('Your full name (required)') ],
|
||||
'$anonmail' => [ 'anonmail', t('Your email address (required)') ],
|
||||
'$anonurl' => [ 'anonurl', t('Your website URL (optional)') ]
|
||||
));
|
||||
|
||||
return $comment_box;
|
||||
}
|
||||
|
||||
private function get_redirect_url() {
|
||||
return $this->redirect_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we are a wall to wall item and set the relevant properties
|
||||
*/
|
||||
protected function check_wall_to_wall() {
|
||||
$conv = $this->get_conversation();
|
||||
$this->wall_to_wall = false;
|
||||
$this->owner_url = '';
|
||||
$this->owner_photo = '';
|
||||
$this->owner_name = '';
|
||||
|
||||
if($conv->get_mode() === 'channel')
|
||||
return;
|
||||
|
||||
if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) {
|
||||
$this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']);
|
||||
$this->owner_photo = $this->data['owner']['xchan_photo_m'];
|
||||
$this->owner_name = $this->data['owner']['xchan_name'];
|
||||
$this->wall_to_wall = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function is_wall_to_wall() {
|
||||
return $this->wall_to_wall;
|
||||
}
|
||||
|
||||
private function get_owner_url() {
|
||||
return $this->owner_url;
|
||||
}
|
||||
|
||||
private function get_owner_photo() {
|
||||
return $this->owner_photo;
|
||||
}
|
||||
|
||||
private function get_owner_name() {
|
||||
return $this->owner_name;
|
||||
}
|
||||
|
||||
private function is_visiting() {
|
||||
return $this->visiting;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
53
Zotlabs/Lib/ThreadListener.php
Normal file
53
Zotlabs/Lib/ThreadListener.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
class ThreadListener {
|
||||
|
||||
static public function store($target_id,$portable_id,$ltype = 0) {
|
||||
$x = self::fetch($target_id,$portable_id,$ltype = 0);
|
||||
if(! $x) {
|
||||
$r = q("insert into listeners ( target_id, portable_id, ltype ) values ( '%s', '%s' , %d ) ",
|
||||
dbesc($target_id),
|
||||
dbesc($portable_id),
|
||||
intval($ltype)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static public function fetch($target_id,$portable_id,$ltype = 0) {
|
||||
$x = q("select * from listeners where target_id = '%s' and portable_id = '%s' and ltype = %d limit 1",
|
||||
dbesc($target_id),
|
||||
dbesc($portable_id),
|
||||
intval($ltype)
|
||||
);
|
||||
if($x) {
|
||||
return $x[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function fetch_by_target($target_id,$ltype = 0) {
|
||||
$x = q("select * from listeners where target_id = '%s' and ltype = %d",
|
||||
dbesc($target_id),
|
||||
intval($ltype)
|
||||
);
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
static public function delete_by_target($target_id, $ltype = 0) {
|
||||
return q("delete from listeners where target_id = '%s' and ltype = %d",
|
||||
dbesc($target_id),
|
||||
intval($ltype)
|
||||
);
|
||||
}
|
||||
|
||||
static public function delete_by_pid($portable_id, $ltype = 0) {
|
||||
return q("delete from listeners where portable_id = '%s' and ltype = %d",
|
||||
dbesc($portable_id),
|
||||
intval($ltype)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user