1358 Commits

Author SHA1 Message Date
9897dcfa04 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:14 +00:00
01b7ffd8d3 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:13 +00:00
0ed1b40384 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:13 +00:00
0a1b6e156a Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:12 +00:00
f09ad65b7a Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:12 +00:00
92b30574c7 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:11 +00:00
f5eb897143 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:10 +00:00
8ed74a3aed Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:10 +00:00
7158e9210f Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:09 +00:00
9444f8805a Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:09 +00:00
2095fde1f4 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:08 +00:00
922c8a49d5 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:07 +00:00
7acf00fc4d Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:07 +00:00
86b416cb47 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:06 +00:00
09ed1d8731 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:05 +00:00
022f0cb891 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:05 +00:00
8e4a3d8d4a Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:04 +00:00
97f60c2aa5 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:03 +00:00
7fb3d0a77d Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:03 +00:00
82d2d1eff6 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:02 +00:00
1ed5e88c7c Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:01 +00:00
a1f473b8a3 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:01 +00:00
0ed968a17b Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:45:00 +00:00
1a3e7389fa Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:59 +00:00
8199d0022d Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:59 +00:00
8eb03de70b Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:58 +00:00
1a43c797c3 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:58 +00:00
668ff3da60 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:57 +00:00
a3d8b01582 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:56 +00:00
380afede5e Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:56 +00:00
bf85022852 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:55 +00:00
76f3b5cd0d Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:54 +00:00
818c86a758 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:54 +00:00
a718da84af Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:53 +00:00
c7b7860fd6 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:53 +00:00
31da31ec45 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:52 +00:00
2fd5aa0787 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:51 +00:00
d47e45ae64 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:51 +00:00
1fea3621f5 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 08:44:50 +00:00
6855e3711a Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:49 +00:00
26f2040905 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:48 +00:00
a52b141017 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:48 +00:00
5d988b1cb8 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:47 +00:00
4fc18d865b Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:46 +00:00
262a6e4b84 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:46 +00:00
e450738fd7 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:45 +00:00
83ec459ca5 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:44 +00:00
4de853d788 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:44 +00:00
ad6cbac1f8 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:43 +00:00
2fcd451339 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:43 +00:00
762547c1f5 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:42 +00:00
25cc185aee Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:41 +00:00
0fc6a1d6f3 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:41 +00:00
76991aecae Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:40 +00:00
f7c03a7122 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:39 +00:00
dc0fa2dff7 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:39 +00:00
99043f1c52 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:38 +00:00
73a89f15e6 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:38 +00:00
b4a3b13ee0 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:37 +00:00
3d30491875 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:36 +00:00
dda64246c5 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:36 +00:00
a0d1d19687 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:35 +00:00
66c81b2a91 Tower: upload cetmix_tower_server_queue 16.0.1.2.2 (via marketplace) 2026-04-27 08:44:35 +00:00
c945b52671 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:34 +00:00
146d71319e Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:33 +00:00
d6d2136df6 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:33 +00:00
9c9cc898a4 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:32 +00:00
be07a3b18d Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:31 +00:00
9f312687b1 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:31 +00:00
eadb83779e Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:30 +00:00
e244e8279b Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:30 +00:00
47fe5ea7a5 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:29 +00:00
05724afff0 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:28 +00:00
5578fb365a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:28 +00:00
30a3b0dc4e Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:27 +00:00
51c5cb3bdb Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:27 +00:00
0849ae6161 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:26 +00:00
81ee76ce21 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:26 +00:00
dc76af271e Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:25 +00:00
5f868f7610 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:24 +00:00
cf31963487 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:24 +00:00
f1b923ae7f Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:23 +00:00
0484142dd5 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:23 +00:00
806c7ce8b8 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:22 +00:00
424742714d Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:21 +00:00
87b5247726 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:21 +00:00
e225e7b2a2 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:20 +00:00
1877e3c1ae Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:20 +00:00
3ea304cb45 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:19 +00:00
d49b02938a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:18 +00:00
8db12c649f Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:18 +00:00
9c16569b69 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:17 +00:00
c2813bc9b3 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:17 +00:00
5111caa738 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:16 +00:00
2f302772e3 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:16 +00:00
0deb721477 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:15 +00:00
178f8e137e Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:14 +00:00
0769cb0756 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:14 +00:00
95485e2558 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:13 +00:00
ab144b1350 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:13 +00:00
4c6fd5e470 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:12 +00:00
05e045267a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:11 +00:00
f5a9261856 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:11 +00:00
764642fbf1 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:10 +00:00
9170934142 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:10 +00:00
a0877d3ba4 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:09 +00:00
d236c96001 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:08 +00:00
5f76fc4ad5 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:08 +00:00
db4e11225b Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:07 +00:00
28987afc7d Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:07 +00:00
eff6288a42 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:06 +00:00
af344b5014 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:05 +00:00
e97a22516c Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:05 +00:00
d99c2f23a9 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:04 +00:00
49b0220cc1 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:04 +00:00
8f87c713f3 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:03 +00:00
eb2ad30e64 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:03 +00:00
1ebf77f1aa Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:02 +00:00
32e517b5ec Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:01 +00:00
fe243328a0 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:00 +00:00
070314632d Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:44:00 +00:00
b9c4a621dc Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:59 +00:00
5f9fb1597b Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:58 +00:00
62edb14057 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:58 +00:00
2b1c121be9 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:57 +00:00
51efac175a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:57 +00:00
7e737b5877 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:56 +00:00
2beb85437a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:56 +00:00
cfdd00e264 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:55 +00:00
034ea5c0bd Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:54 +00:00
8621fac655 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:54 +00:00
8a5b68926c Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:53 +00:00
22885f7fdd Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:53 +00:00
e3e51b8367 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:52 +00:00
019224ba4c Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:51 +00:00
833346a1a8 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:51 +00:00
c501af7d45 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:50 +00:00
aa1b8801ce Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:49 +00:00
b48081c8e2 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:49 +00:00
a366d1b52c Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:48 +00:00
5cb28ea01a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:48 +00:00
30f1f2df49 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:47 +00:00
c416aabc44 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:47 +00:00
17d150a45f Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:46 +00:00
6211de488b Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:46 +00:00
5fd192356f Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:45 +00:00
929448f1ca Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:44 +00:00
8733b3cb61 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:44 +00:00
c5fa399627 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:43 +00:00
4ce9f94318 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:43 +00:00
281c0167b1 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:42 +00:00
96d4ad7ef7 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:42 +00:00
6ce7c48b2d Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:41 +00:00
c3bdb2c14d Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:40 +00:00
898b423feb Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:40 +00:00
7264942e8d Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:39 +00:00
3f23cfecf3 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:39 +00:00
23e386b526 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:38 +00:00
f0193a9307 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:38 +00:00
bbddf942a2 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:37 +00:00
f7d3a429a5 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:36 +00:00
89bba86349 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:36 +00:00
0a2076df37 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:35 +00:00
7da0bc5c93 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:34 +00:00
2c7bea7e69 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:34 +00:00
cc4bde613b Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:33 +00:00
a3e7e80ffb Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:33 +00:00
3d2174b4e8 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:32 +00:00
436bc160e3 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:31 +00:00
693821eb53 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:31 +00:00
495bb536f1 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:30 +00:00
a81ee9d711 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:30 +00:00
13f88ed1ed Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:29 +00:00
9c92bd8a2d Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:28 +00:00
9815bfd407 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:28 +00:00
42256b6283 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:27 +00:00
4d4b874ee0 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:27 +00:00
e741fd3d1c Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:26 +00:00
23db6fae45 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:26 +00:00
0cac17c395 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:25 +00:00
9bea4833ca Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:24 +00:00
d70d24cb7a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:24 +00:00
ab129128b3 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:23 +00:00
8c292c2217 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:23 +00:00
0b504afdca Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:22 +00:00
fa76207199 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:22 +00:00
a6d3222ffc Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:21 +00:00
e7b8c1fc11 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:21 +00:00
226ecfa11e Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:20 +00:00
92a34a2292 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:19 +00:00
19b6b2caca Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:19 +00:00
448f814aae Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:18 +00:00
2537f4e58c Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:18 +00:00
d0059616aa Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:17 +00:00
8c8199abbd Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:17 +00:00
64825c8e84 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:16 +00:00
62cd370099 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:16 +00:00
9b528e38fc Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:15 +00:00
c45450ed87 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:14 +00:00
cc53a55c96 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:14 +00:00
9573216bfd Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:13 +00:00
2839e110fe Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:13 +00:00
ba9ce2ad88 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:12 +00:00
eb4d7a5477 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:11 +00:00
42d21b989a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:11 +00:00
23cf3ad81b Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:10 +00:00
cce324dbfb Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:10 +00:00
9e1dcd02dd Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:09 +00:00
bfbe68ff88 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:09 +00:00
e07234573c Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:08 +00:00
5b2f53b33a Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:08 +00:00
14e7468ca7 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:07 +00:00
7df06465a8 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:07 +00:00
cb2eb054eb Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:06 +00:00
3ef2cc50fe Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:05 +00:00
d12d454c70 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:05 +00:00
9a17bcd25e Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:04 +00:00
73ebe069f6 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:03 +00:00
2755e373fd Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:03 +00:00
9e43910cc8 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:02 +00:00
1646ace09b Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:02 +00:00
c6c6570800 Tower: upload cetmix_tower_server 16.0.2.2.9 (via marketplace) 2026-04-27 08:43:01 +00:00
21576ec28f Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:43:00 +00:00
a5b60a5d3b Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:59 +00:00
abcb71d469 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:58 +00:00
4fdf6333f2 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:58 +00:00
c18aba668b Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:57 +00:00
0a8333e1e2 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:57 +00:00
3d19db5049 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:56 +00:00
62e7767925 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:56 +00:00
070c89e75e Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:55 +00:00
cf0d897dfa Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:54 +00:00
9fc1c6bd65 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:54 +00:00
342e616963 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:53 +00:00
a4c6f5c561 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:53 +00:00
811d32c5be Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:52 +00:00
135074c040 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:51 +00:00
af55099d83 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:51 +00:00
2d9f32fc2f Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:50 +00:00
d361711043 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:50 +00:00
426c0e0792 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:49 +00:00
ae451e5911 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:48 +00:00
31bcb48704 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:48 +00:00
25703173fb Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:47 +00:00
eab2080115 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:47 +00:00
5f99227e6c Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:46 +00:00
4a547632ac Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:45 +00:00
8cd9bae8ea Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:45 +00:00
ddadefa9a6 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:44 +00:00
7276688114 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:43 +00:00
66450d4d02 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:43 +00:00
2d0bda98b1 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:42 +00:00
89943c26eb Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:42 +00:00
0ac25c7405 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:41 +00:00
b54c955847 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:41 +00:00
857ec4fceb Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:40 +00:00
83ff1a0ec5 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:39 +00:00
ef85be3808 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:39 +00:00
25b80d98ce Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:38 +00:00
1871e1ffe9 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:38 +00:00
4440daa0a4 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:37 +00:00
6e018447b2 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:37 +00:00
5c4949bf5b Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:36 +00:00
90cb176847 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:36 +00:00
bdf8278b7f Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:35 +00:00
da1f2fd426 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:34 +00:00
4b1cbbc86b Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:34 +00:00
0957e4d55b Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:33 +00:00
6509c2136f Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:33 +00:00
52877f9b2c Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:32 +00:00
6176d27861 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:31 +00:00
37a160148d Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:31 +00:00
ee1501034b Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:30 +00:00
92e62ae21b Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:30 +00:00
7a5d6aa254 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:29 +00:00
42a4abb176 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:29 +00:00
440324c078 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:28 +00:00
7e9e92a179 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:27 +00:00
ad62d49f3d Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:27 +00:00
a562808d99 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:26 +00:00
7f6a00a8f7 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:26 +00:00
f04db1b076 Tower: upload cetmix_tower_git 16.0.2.0.2 (via marketplace) 2026-04-27 08:42:25 +00:00
236b4a6227 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:15 +00:00
93be36fb52 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:14 +00:00
412f99f6a1 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:14 +00:00
a00f32e12f Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:13 +00:00
155436e103 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:12 +00:00
c43c7035a7 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:12 +00:00
a68656e1d5 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:11 +00:00
65a7419e30 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:11 +00:00
d334b0c87b Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:10 +00:00
4826cd422e Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:10 +00:00
0f8a0bddba Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:09 +00:00
155faf8f8b Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:08 +00:00
b8e8b0d989 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:08 +00:00
8f8eec47a9 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:07 +00:00
c0767d1041 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:07 +00:00
4bb470d291 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:06 +00:00
7f4f78e750 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:05 +00:00
6640a61437 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:05 +00:00
0e7e46d0bb Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:04 +00:00
367f45a9b3 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:04 +00:00
1d4e56cbd9 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:03 +00:00
4e07525d10 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:03 +00:00
f5d6ad46c4 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:02 +00:00
cc8804103b Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:01 +00:00
f7f24085cd Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:01 +00:00
097cf223ec Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:00 +00:00
8c3381f41b Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:42:00 +00:00
05a553a8fb Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:59 +00:00
e71e1e04f4 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:58 +00:00
cc614c3ecf Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:58 +00:00
49feadbeb9 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:57 +00:00
66d1bf5e47 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:57 +00:00
7d39b690ec Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:56 +00:00
48c79615fe Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:56 +00:00
55dac4ca23 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:55 +00:00
a861002926 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:54 +00:00
462f134278 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:54 +00:00
1a42ca3cb1 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:53 +00:00
f5574ed238 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:53 +00:00
3f00653bb2 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:52 +00:00
505f69fb27 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:52 +00:00
85ff0c5741 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:51 +00:00
b91b95bccd Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:41:51 +00:00
984be00635 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:05 +00:00
01fd85aec0 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:05 +00:00
6aa60f1bc3 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:04 +00:00
55bad508da Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:04 +00:00
99ec962ca3 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:03 +00:00
d4b094937a Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:02 +00:00
19e36c1a35 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:02 +00:00
ce15caaa45 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:01 +00:00
315e1bd1e7 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:01 +00:00
ff8d274a38 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:00 +00:00
ab2c9cddae Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:33:00 +00:00
16dc380c53 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:59 +00:00
4b5170e8b7 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:58 +00:00
c7912ec5a6 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:58 +00:00
090f0099c0 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:58 +00:00
ed7a1d93ba Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:57 +00:00
cbf850a987 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:56 +00:00
877cbcdd6b Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:56 +00:00
44e10c9212 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:55 +00:00
a2742e95ec Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:55 +00:00
9105818e3a Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:54 +00:00
f06a374569 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:54 +00:00
1c38931430 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:53 +00:00
fa92ab9ba8 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:53 +00:00
4b56acc480 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:52 +00:00
f3cb0587f5 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 08:32:52 +00:00
3e756c774f Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:44 +00:00
e8fe926dbb Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:43 +00:00
b2a168bd06 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:43 +00:00
4628821451 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:42 +00:00
ab108c0437 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:42 +00:00
5d9fe7b1f3 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:41 +00:00
1b3bf2d301 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:41 +00:00
017d7883d3 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:40 +00:00
00439eac6e Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:39 +00:00
d5b31de87e Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:39 +00:00
f9a6b56c81 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:38 +00:00
123239031f Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:38 +00:00
7f65dc9a92 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:38 +00:00
25c345f665 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:37 +00:00
2c2058e07b Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:36 +00:00
f628de0c15 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:36 +00:00
998d97da45 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:35 +00:00
7a6f12082b Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 08:32:35 +00:00
Tower Deploy
9bb80002c8 Wipe addons/: full reset for clean re-upload 2026-04-27 11:20:53 +03:00
2cf3b5185d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:40 +00:00
9214b650ae Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:39 +00:00
e6027c710b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:39 +00:00
7a40f423d4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:38 +00:00
9966aa4ffa Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:38 +00:00
7c90e7bee2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:37 +00:00
be3a699471 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:37 +00:00
a68f5ed5da Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:36 +00:00
3a4d546c10 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:36 +00:00
386893e751 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:35 +00:00
e8cd94cc98 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:34 +00:00
bbf383a59f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:34 +00:00
eb41cf2557 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:33 +00:00
7d71cd87fe Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:33 +00:00
886affc442 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:32 +00:00
236c25028c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:32 +00:00
ca0996089d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:31 +00:00
326bbe4eb1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:31 +00:00
bd2de68a13 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:30 +00:00
241485ada6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:30 +00:00
93925e7edb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:29 +00:00
8be03b6213 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:28 +00:00
f8be9708f2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:28 +00:00
43f1d3a460 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:27 +00:00
95ab9b7b07 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:27 +00:00
c4dec5820f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:26 +00:00
cf8020a374 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:26 +00:00
8b2b00309b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:25 +00:00
43c386dd0f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:24 +00:00
94e68bf101 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:24 +00:00
c6fcbd4e88 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:24 +00:00
95ec10c4cd Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:23 +00:00
8cde5f5b85 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:22 +00:00
92daedbcfe Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:22 +00:00
59af83f001 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:21 +00:00
68ca5feaec Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:21 +00:00
d379066f8d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:20 +00:00
50f45a25f6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:20 +00:00
4f1b44f859 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:19 +00:00
63cb075ebe Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:18 +00:00
3bc89980fb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:18 +00:00
a30f10f463 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:18 +00:00
a3f387f59d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:17 +00:00
0496b94742 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:16 +00:00
eeea0bde1d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:16 +00:00
19a63eac0c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:15 +00:00
ff42b73982 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:15 +00:00
ac9207b0c6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:14 +00:00
7dadc5938a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:14 +00:00
88fb907a24 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:13 +00:00
a349d97184 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:12 +00:00
2eee80609f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:12 +00:00
fcb747f2c9 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:11 +00:00
826194b88f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:11 +00:00
303d179c1a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:10 +00:00
b309b6f244 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:09 +00:00
ee0ef6b69d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:09 +00:00
121fcd2639 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:08 +00:00
5cecb3364e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:08 +00:00
1e2909808a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:07 +00:00
b8658d0fed Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:06 +00:00
ea586f0019 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:06 +00:00
4219a55576 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:05 +00:00
2d6197c181 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:05 +00:00
049d8dc461 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:04 +00:00
8f7afa25fc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:04 +00:00
7c0c8cf62a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:03 +00:00
e0c9e3817f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:02 +00:00
95894e0965 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:02 +00:00
0fd426db38 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:01 +00:00
7f38305cda Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:01 +00:00
9eb03938ba Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:00 +00:00
38b16543da Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:18:00 +00:00
3a6e036b1d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:59 +00:00
c28baccca8 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:58 +00:00
2352fdfaab Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:58 +00:00
fd93d95ef0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:57 +00:00
1ad508d029 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:57 +00:00
80e2953742 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:56 +00:00
8f2214eb37 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:55 +00:00
105434392b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:55 +00:00
d77c0ec323 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:54 +00:00
ebc9c2da81 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:54 +00:00
b706079a96 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:54 +00:00
1a3fb88ff0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:53 +00:00
fe73ec564d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:52 +00:00
38becb2347 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:52 +00:00
9cc237dfcd Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:51 +00:00
59a0a18068 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:51 +00:00
3cdcbd70c3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:50 +00:00
36f48cb3ef Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:49 +00:00
6e40ceba46 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:48 +00:00
9ed9312f52 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:48 +00:00
3bf88a3db2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:47 +00:00
cd835868a4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:47 +00:00
3adbefa88a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:46 +00:00
6192b3aff5 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:45 +00:00
b504a42afc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:45 +00:00
60532fda2e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:44 +00:00
4604622231 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:43 +00:00
f4e43a2f84 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:43 +00:00
c5c3887d97 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:42 +00:00
8ce3697a6e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:41 +00:00
bbe37b34d9 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:41 +00:00
ae8c208c59 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:40 +00:00
3811a9d7cd Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:39 +00:00
3eed4a9224 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:38 +00:00
68b713a69a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:37 +00:00
af1be38c68 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:37 +00:00
3780eaf1f2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:36 +00:00
1f23472908 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:35 +00:00
5e71e0a98a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:35 +00:00
5e665079f3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:34 +00:00
b67d86ef4b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:33 +00:00
cf83815785 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:33 +00:00
255a06a789 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:32 +00:00
3153e06601 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:31 +00:00
7e4c9dcd99 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:31 +00:00
8e92de0c4e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:30 +00:00
eb58ac434c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:29 +00:00
5aed68117b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:29 +00:00
b6c3a855a4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:28 +00:00
cd4b7cd2e6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:27 +00:00
cb1e060ebb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:27 +00:00
ccc9ef0644 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:26 +00:00
03b1d2bd59 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:25 +00:00
565ef8f0cc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:25 +00:00
ae52efe220 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:24 +00:00
09576d37b4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:23 +00:00
3b556e385d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:23 +00:00
d24677fc8e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:22 +00:00
bc9c9bf125 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:21 +00:00
953db1c18e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:21 +00:00
bb6408e1bb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:20 +00:00
f5ee80a075 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:19 +00:00
e2a1ef97cf Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:19 +00:00
f7aa151993 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:18 +00:00
c8461e648d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:17 +00:00
78f57a52e8 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:17 +00:00
645bbb9e1f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:16 +00:00
1c5b8f78e8 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:15 +00:00
b06be61868 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:15 +00:00
22635fd1db Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:14 +00:00
502f3c276f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:13 +00:00
a29e7d3701 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:12 +00:00
90a6de998c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:12 +00:00
309834e218 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:11 +00:00
36548b07b3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:11 +00:00
a647db524a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:10 +00:00
96392d7cab Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:09 +00:00
3c73cf7286 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:08 +00:00
5128d56863 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:08 +00:00
ec366ca548 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:07 +00:00
eaaf033cd5 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:06 +00:00
899eefb2b1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:06 +00:00
35c152c073 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:05 +00:00
4db61b7221 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:04 +00:00
56faad93d6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:03 +00:00
b02021eeab Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:03 +00:00
0f8d4c52be Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:02 +00:00
f6b23b2697 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:01 +00:00
9c162c8c40 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:01 +00:00
9ee9d2dc06 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:17:00 +00:00
f88873226d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:59 +00:00
e6ef101e11 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:58 +00:00
ace82b83f0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:58 +00:00
c3b5ebd7bc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:57 +00:00
f52001bffa Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:56 +00:00
8289f0ec93 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:56 +00:00
4c85b5da81 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:55 +00:00
7bddb74ba7 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:54 +00:00
b088c69c2b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:54 +00:00
ffc66cfaa1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:53 +00:00
50705d8a20 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:52 +00:00
eb85e1f034 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:52 +00:00
c104fc8c43 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:51 +00:00
12aaeebb69 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:50 +00:00
b8accd5199 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:50 +00:00
36e718ae36 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:49 +00:00
fc67cb263f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:48 +00:00
d6bec900fe Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:48 +00:00
db967ff6e3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:47 +00:00
9d6d07b2e1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:46 +00:00
1444a3064e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:46 +00:00
0a2e334aee Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:45 +00:00
15d21d3ab5 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:45 +00:00
a4f565087c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:44 +00:00
6a11883c7c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:43 +00:00
1202892973 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:42 +00:00
d3e1cc28bc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:42 +00:00
151246c614 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:41 +00:00
5049ba6907 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:40 +00:00
f8b593bec4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:35 +00:00
682e48bb2b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:34 +00:00
c4ddcb8e92 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:34 +00:00
d992b45cdd Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:33 +00:00
f89637d6e8 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:33 +00:00
a493701b6e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:32 +00:00
77b6a4b2fc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:32 +00:00
9d595b2565 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:31 +00:00
812b64b18d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:31 +00:00
a6d4d64192 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:30 +00:00
0f52520ee3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:30 +00:00
8a996f5083 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:29 +00:00
b4e0d93c28 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:29 +00:00
f54217e713 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:28 +00:00
ebb1399951 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:28 +00:00
f9d33713ab Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:27 +00:00
4af3a1e647 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:26 +00:00
af44da007b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:26 +00:00
1d5a2ceed0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:25 +00:00
4f9d558cf4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:25 +00:00
8bdd6064ab Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:24 +00:00
76b43e0b65 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:24 +00:00
3b80e2101c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:23 +00:00
42653be822 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:23 +00:00
717ce4756a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:22 +00:00
5ac0c18619 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:22 +00:00
79dd86e13f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:21 +00:00
05b6f98a82 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:21 +00:00
098ce63b26 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:20 +00:00
254f6312b4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:20 +00:00
5dc4447ff3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:19 +00:00
d77978d0c9 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:19 +00:00
c4df067894 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:18 +00:00
c210efa9a2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:18 +00:00
3dbf0baeb2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:17 +00:00
5903af189c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:17 +00:00
507eab7847 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:16 +00:00
0f5b16febc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:16 +00:00
1b5342da13 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:15 +00:00
9d2776f6ce Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:15 +00:00
716a6d735c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:14 +00:00
5362b526e7 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:14 +00:00
0586c40667 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:13 +00:00
9e48c4e0dc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:12 +00:00
569a853b3a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:12 +00:00
74a3f434a4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:12 +00:00
a6af9583df Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:11 +00:00
326900b3a7 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:10 +00:00
c4dfb0a886 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:09 +00:00
a5efdebe15 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:09 +00:00
cb84ce69be Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:08 +00:00
7e5354d5ad Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:07 +00:00
521d765b35 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:06 +00:00
7fbaaf189b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:06 +00:00
6a9182c820 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:05 +00:00
90f7afa720 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:05 +00:00
90c893ae66 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:04 +00:00
8d55a7ee70 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:04 +00:00
f6e32ece58 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:03 +00:00
162ad41852 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:02 +00:00
8b89083a51 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:02 +00:00
68c5b015e0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:01 +00:00
61e360ae9e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:00 +00:00
50663c7700 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:16:00 +00:00
4da1291a50 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:59 +00:00
94df75a9bf Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:59 +00:00
5ea3184c5e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:58 +00:00
099bb0dfd5 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:58 +00:00
e318c89788 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:57 +00:00
1174604b05 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:57 +00:00
364f37aa5a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:56 +00:00
bbb71840c1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:56 +00:00
c2923e01e6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:55 +00:00
4131ae0adb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:54 +00:00
f16e0abf03 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:54 +00:00
07adc2628c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:53 +00:00
a682b818d3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:53 +00:00
b2a8c2dcde Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:52 +00:00
2314a8f6c2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:52 +00:00
f2033e0408 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:51 +00:00
38d4a641f1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:51 +00:00
8ca3561c1a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:50 +00:00
bf7158a6e8 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:50 +00:00
6a92d586a4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:49 +00:00
2a93942be1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:48 +00:00
e81e6f4ff1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:48 +00:00
5e4cf9723b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:48 +00:00
a6fb93b231 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:47 +00:00
a3022f8332 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:47 +00:00
af0b27d762 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:46 +00:00
d2a8d537f6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:45 +00:00
52d65dabba Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:44 +00:00
cbd499b88f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:44 +00:00
d59aa0179a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:43 +00:00
bf61f4eb4f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:43 +00:00
97352ac44d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:42 +00:00
eb0687da36 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:42 +00:00
ceea23aaaf Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:41 +00:00
802a5a8a1c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:40 +00:00
2d24db2b08 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:40 +00:00
bfb1edac54 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:39 +00:00
b12ac35b65 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:39 +00:00
8b881eba5b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:38 +00:00
b2317325e2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:38 +00:00
a8e845cb8b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:37 +00:00
14bd70a67c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 08:15:36 +00:00
82cfb22c03 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:27 +00:00
50cd192fd8 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:26 +00:00
62a0a9b1bd Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:26 +00:00
88b9f087a1 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:25 +00:00
55b5ad56c8 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:25 +00:00
00d5145aa0 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:24 +00:00
6161522a04 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:24 +00:00
abaabc4cc0 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:23 +00:00
2686884335 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:23 +00:00
f41c8d4c6f Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:22 +00:00
a9496bdbd2 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:21 +00:00
5e634580c2 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:21 +00:00
37b4590851 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:20 +00:00
81e565fdec Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:20 +00:00
b912c85da7 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:19 +00:00
7ef63fa72d Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:18 +00:00
627c3e9ffa Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:18 +00:00
876b3f4a7d Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:17 +00:00
f323562bbd Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:17 +00:00
f98711ec66 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:16 +00:00
8db97cf776 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:16 +00:00
f38452a52a Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:15 +00:00
03d392803f Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:15 +00:00
8b40cf2659 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 08:15:14 +00:00
86cf1847f4 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:15:00 +00:00
45d7ed8b73 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:59 +00:00
0b7b196159 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:59 +00:00
33ad700d61 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:58 +00:00
7f8552981b Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:57 +00:00
5cc9d2512b Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:57 +00:00
6ab789e36d Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:56 +00:00
f8109af6ce Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:56 +00:00
1bfc6ac3af Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:55 +00:00
548817116a Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:55 +00:00
b2f712e6b6 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:54 +00:00
93739ddaff Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:54 +00:00
1373305638 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:53 +00:00
70a54d0787 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:53 +00:00
40a164b1b0 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:52 +00:00
bc966d56b0 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:51 +00:00
61e7953827 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:51 +00:00
192e1a9dbc Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:50 +00:00
2fe3c98c53 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:49 +00:00
5f3cca665d Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 08:14:48 +00:00
88d5b049ff Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:40 +00:00
4614cb31fb Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:40 +00:00
44d76bc4a1 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:39 +00:00
353350476d Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:39 +00:00
76d63a2fe8 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:38 +00:00
cce75a5895 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:37 +00:00
2409adec5e Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:37 +00:00
f75a5247b5 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:36 +00:00
8cfa1310d1 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:36 +00:00
086b96cc39 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:35 +00:00
908aa7e1da Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:35 +00:00
b6218e6b07 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:34 +00:00
3d868855ca Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:34 +00:00
7e7213f67b Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:33 +00:00
f5afc7d31c Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:33 +00:00
72737afb61 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:32 +00:00
b39e81512e Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:32 +00:00
62fad98a12 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:31 +00:00
98c4aa7358 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:30 +00:00
1a3ee1d4de Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:30 +00:00
be2facb1f1 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:29 +00:00
97b4731ca6 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:29 +00:00
83326bcaed Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:28 +00:00
09eda63698 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:28 +00:00
d0aaff2135 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:27 +00:00
7bd0bd0989 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:26 +00:00
94bd98ab65 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:26 +00:00
25fa4c853b Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:26 +00:00
4b4581ff2e Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:25 +00:00
e1ea01e59e Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:24 +00:00
da4d5c2494 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:24 +00:00
3713992eb3 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:23 +00:00
e1c8337464 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:23 +00:00
6c81ab18c8 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:22 +00:00
f0085588b9 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:22 +00:00
8fdb330a6c Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:21 +00:00
fb7a94f8ae Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:21 +00:00
e71e3822e0 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:20 +00:00
e289fb9145 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:19 +00:00
bf2a8c4010 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:19 +00:00
5cc34775f3 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:18 +00:00
7f75afbdba Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:18 +00:00
1390ec0c15 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:17 +00:00
4e84600e7e Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:17 +00:00
c0ea49872c Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:16 +00:00
0685e4cabe Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:16 +00:00
875a590978 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:15 +00:00
98d8aeb011 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:14 +00:00
2f9905210a Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:14 +00:00
41d56a304a Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:13 +00:00
55da1da7f3 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:13 +00:00
a65d315cda Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:12 +00:00
16e6c57a3f Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:12 +00:00
638a2df7c6 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:11 +00:00
9b53282444 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:11 +00:00
89d02b353b Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:10 +00:00
c968cca4de Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:10 +00:00
e163b0d99b Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:09 +00:00
4426a5abb6 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:09 +00:00
8c8e527249 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 08:14:08 +00:00
f50c1865d5 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:07:03 +00:00
f5257dc7ab Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:07:02 +00:00
14315e0035 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:07:01 +00:00
e2fe62b379 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:07:01 +00:00
1f9bea1264 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:07:00 +00:00
08f1a4d3cb Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:07:00 +00:00
be8a0ac9c3 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:59 +00:00
a383f11d2a Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:58 +00:00
91618edeec Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:58 +00:00
b64f6da230 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:57 +00:00
ba4b26b175 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:57 +00:00
525c919b3a Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:56 +00:00
d7f6de08e9 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:56 +00:00
0d20ab7aa8 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:55 +00:00
231d59da7f Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:54 +00:00
4fef277751 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:54 +00:00
7032e64dcb Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:53 +00:00
15481c11c0 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:53 +00:00
5930f771e5 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:52 +00:00
2290c90089 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:51 +00:00
eb28ba0f78 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:51 +00:00
7df203efe8 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:50 +00:00
766b1dd779 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:50 +00:00
e992a8ea3f Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:49 +00:00
e3863de129 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:48 +00:00
bfed6bdcf4 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:48 +00:00
f4834218ce Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:47 +00:00
e3e001ac5b Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:47 +00:00
afc1985114 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:46 +00:00
f0c0fa15ac Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:45 +00:00
3bb17aa74a Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:45 +00:00
3887d3afd3 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:44 +00:00
ccf1ac8e77 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:44 +00:00
df84150f14 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:43 +00:00
fd4f3c89cf Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:43 +00:00
46fa14692c Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:42 +00:00
2d26b672bf Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:42 +00:00
f908dd5acd Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:41 +00:00
f50135b5c6 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:40 +00:00
2be8fc95b7 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:40 +00:00
736d4b40e0 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:39 +00:00
7fa0a4c79a Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:39 +00:00
8881aeb2ca Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 08:06:38 +00:00
8fa1c29c59 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:32 +00:00
318ef00817 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:31 +00:00
3fcdf69f56 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:31 +00:00
e2785fff55 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:30 +00:00
e5adc46d44 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:29 +00:00
6052fcbe7e Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:29 +00:00
268e7e9b23 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:28 +00:00
53f93fe01b Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:28 +00:00
202cb09e2b Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:27 +00:00
c29df047d2 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:27 +00:00
8dc8a3d39b Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:26 +00:00
34a4c17e9b Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:26 +00:00
ccb61bd1d9 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:25 +00:00
be89574d27 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:25 +00:00
e8a12c08d8 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:24 +00:00
16a5812db0 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:23 +00:00
366eeab65d Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:23 +00:00
ce185f92e3 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:22 +00:00
276dccf5fd Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:22 +00:00
4fc6c80352 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:21 +00:00
016afe19f8 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:21 +00:00
7295ad401c Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:20 +00:00
1eed0fbda0 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:19 +00:00
da449b9852 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 08:06:19 +00:00
Tower Deploy
9a499aced7 Wipe addons/: corrupt source from old double-base64 upload bug + test artifacts; ready for clean re-upload 2026-04-27 10:59:54 +03:00
c3f2c4f522 Tower: upload probe_addon 16.0.1.0.0 (via marketplace) 2026-04-27 07:53:52 +00:00
a356f71745 Tower: upload probe_addon 16.0.1.0.0 (via marketplace) 2026-04-27 07:53:51 +00:00
0a76509365 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:23 +00:00
9083833444 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:22 +00:00
ed9dc11c4b Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:22 +00:00
1c2d483a46 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:21 +00:00
1f073938d7 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:21 +00:00
e12133fff0 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:20 +00:00
61d95f53d6 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:20 +00:00
ebd9d7c16f Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:19 +00:00
455a7192d3 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:18 +00:00
4c8ec8ffa3 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:18 +00:00
2beca515ca Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:17 +00:00
e1c3544f09 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:17 +00:00
242fc36fd0 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:16 +00:00
4754df89b7 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:16 +00:00
e050040bae Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:15 +00:00
30deb10c27 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:14 +00:00
f2791efa4f Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:14 +00:00
acc9748aa2 Tower: upload cx_web_refresh_from_backend 16.0.1.0.0 (via marketplace) 2026-04-27 06:59:13 +00:00
b36fe277c0 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:53 +00:00
0b07e80ecb Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:53 +00:00
b448019f93 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:52 +00:00
a108daebd0 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:52 +00:00
2c950b5a0a Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:51 +00:00
0ded373257 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:51 +00:00
4ad6ffce26 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:50 +00:00
265f8092e5 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:49 +00:00
6735056551 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:49 +00:00
a70aae6404 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:48 +00:00
f7c2027d17 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:48 +00:00
8f9c4f4ed9 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:47 +00:00
cd4fa9df4d Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:47 +00:00
b776dea93e Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:46 +00:00
2d655e9822 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:46 +00:00
f1aef07115 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:45 +00:00
ceac54f2a8 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:45 +00:00
8cd2d73dd1 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:44 +00:00
4c8a85091e Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:44 +00:00
1d8e306a5b Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:43 +00:00
ff76148774 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:42 +00:00
263616cf66 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:42 +00:00
5d8563cf5e Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:41 +00:00
3a8e7bb486 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:41 +00:00
dac924d260 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:40 +00:00
2fec9bae57 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:40 +00:00
a3a0e7f1a9 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:39 +00:00
57e4922aa4 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:39 +00:00
5a86e951c9 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:38 +00:00
07a2292b98 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:38 +00:00
498ebf5b5e Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:37 +00:00
0c0a53fb80 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:37 +00:00
f13d08283f Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:36 +00:00
6776b72adf Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:36 +00:00
fc0111f9af Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:35 +00:00
58ecb0871a Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:34 +00:00
5ab36dc181 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:34 +00:00
9eb4e7eb59 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:33 +00:00
b73d178751 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:33 +00:00
aeb5997303 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:32 +00:00
b6be8f1f51 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:32 +00:00
6e4ec0f188 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:31 +00:00
d84a9d95e3 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:31 +00:00
e85ead856e Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:30 +00:00
d640f69b64 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:30 +00:00
3a855c6905 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:29 +00:00
e5bc9f79bc Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:29 +00:00
e4a9a645a1 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:28 +00:00
7be7fc0d06 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:28 +00:00
639c21ee64 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:27 +00:00
83463f08fd Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:27 +00:00
d62c41a4c0 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:26 +00:00
5bc32a7b39 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:26 +00:00
b87f9f2f0f Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:25 +00:00
ecb8f48fc7 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:25 +00:00
453e861eb1 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:24 +00:00
9d9ba90f65 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:24 +00:00
c0ec43dc15 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:23 +00:00
8bf0f53a1f Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:23 +00:00
b9935804d8 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:22 +00:00
e3cd173cae Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:22 +00:00
0b171536bd Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:21 +00:00
4df5459abb Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:21 +00:00
99c360c739 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:20 +00:00
238f3a123f Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:19 +00:00
7635f192bc Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:19 +00:00
4be4c95126 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:19 +00:00
c7174e1aa0 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:18 +00:00
038f113176 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:18 +00:00
e640b7dc00 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:17 +00:00
69ee0e8a79 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:16 +00:00
44f9bf1d9d Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:16 +00:00
528d049505 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:16 +00:00
d38fff270d Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:15 +00:00
f47e6d77df Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:14 +00:00
bcdb9f7100 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:14 +00:00
79c3511ced Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:13 +00:00
77163b4017 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:13 +00:00
52512ff961 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:12 +00:00
8e37d624ff Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:11 +00:00
2b845fa110 Tower: upload cetmix_tower_yaml 16.0.3.1.0 (via marketplace) 2026-04-27 06:58:11 +00:00
09c730c852 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:56 +00:00
9ea0b5ca1e Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:55 +00:00
3f7c12c4cb Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:55 +00:00
52212a4234 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:54 +00:00
aad83a6e45 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:54 +00:00
b15249a7cc Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:53 +00:00
971c0b6bb1 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:53 +00:00
c8259d3fae Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:52 +00:00
c1c1591ffd Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:52 +00:00
1ceae80007 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:51 +00:00
711c240058 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:51 +00:00
ed906caf54 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:50 +00:00
fa316c0948 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:50 +00:00
64da73b835 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:49 +00:00
51d27b362c Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:49 +00:00
11bf6134ec Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:48 +00:00
e6fd3d1594 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:48 +00:00
6c440b46d0 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:47 +00:00
6f5049ff54 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:46 +00:00
785da91996 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:46 +00:00
a59be21d5c Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:45 +00:00
dcd8d31c0b Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:45 +00:00
bbff9cd347 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:44 +00:00
c5433c7b44 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:44 +00:00
52e3ae85ef Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:43 +00:00
6ee8d34a08 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:43 +00:00
fc845bf79a Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:42 +00:00
aa3ea16a1b Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:42 +00:00
5d72ad53fb Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:41 +00:00
d5a16b3baa Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:41 +00:00
4300c11cb1 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:40 +00:00
611bf9a530 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:40 +00:00
f665a077cb Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:39 +00:00
62c2411818 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:39 +00:00
1aeff8903c Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:38 +00:00
7a0fe4f363 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:38 +00:00
6ebe68c8fc Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:37 +00:00
075a340056 Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:37 +00:00
d764da736d Tower: upload cetmix_tower_webhook 16.0.1.0.5 (via marketplace) 2026-04-27 06:57:36 +00:00
b9ee75209a Tower: upload cetmix_dup_test 16.0.1.0.0 (via marketplace) (force-overwrite) 2026-04-27 06:56:35 +00:00
389ffcbadb Tower: upload cetmix_dup_test 16.0.1.0.0 (via marketplace) (force-overwrite) 2026-04-27 06:56:35 +00:00
37ec61eab2 Tower: upload cetmix_dup_test 16.0.1.0.0 (via marketplace) 2026-04-27 06:56:34 +00:00
a901150981 Tower: upload cetmix_dup_test 16.0.1.0.0 (via marketplace) 2026-04-27 06:56:33 +00:00
d7e623d816 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:12 +00:00
45e7dd2c6c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:11 +00:00
25ca66a86b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:11 +00:00
a78cbd6583 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:10 +00:00
09283bba61 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:10 +00:00
e738070b24 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:09 +00:00
0c67e0d798 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:09 +00:00
9e7f379923 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:08 +00:00
93426fbae5 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:08 +00:00
f1b9101b13 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:07 +00:00
33d3b02763 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:06 +00:00
2a169afa62 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:06 +00:00
a2fc7b47c1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:05 +00:00
c717460cea Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:04 +00:00
a8f57858d8 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:04 +00:00
3ab0e79386 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:03 +00:00
236b78c33b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:02 +00:00
18138fd178 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:02 +00:00
fa34dcb44e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:01 +00:00
f8a7e22755 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:00 +00:00
5e7a05b949 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:54:00 +00:00
676d1fd8c1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:59 +00:00
9a569b9af1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:59 +00:00
bfda22756e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:58 +00:00
237d692cd1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:58 +00:00
31b57b24f5 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:57 +00:00
ff8cc52e41 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:56 +00:00
f6d8bab742 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:56 +00:00
1bd0a301dd Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:55 +00:00
d7ac3f27e0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:55 +00:00
adf18c04a9 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:54 +00:00
150023c203 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:54 +00:00
21bf17da38 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:53 +00:00
54c3d037a0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:53 +00:00
cc7c59f4fa Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:52 +00:00
491c5fa696 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:52 +00:00
cb1c08a52d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:51 +00:00
7c414a48de Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:51 +00:00
0d03d8d956 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:50 +00:00
ee974eb8d1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:50 +00:00
5e17847c10 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:49 +00:00
753ee2e4e3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:49 +00:00
2c73095fd6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:48 +00:00
c31875dc95 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:48 +00:00
39ac32de74 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:47 +00:00
3a6f76212d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:47 +00:00
89c5d6195a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:46 +00:00
a6c0f93af0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:46 +00:00
f52cdfe12d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:45 +00:00
fe91357505 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:44 +00:00
e4c578f20a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:44 +00:00
d9734e17fb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:43 +00:00
4cc3f94635 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:43 +00:00
8ff4dd5b3c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:42 +00:00
423b6acfde Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:42 +00:00
ccf2ec0804 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:41 +00:00
002f0bda6f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:41 +00:00
753aee7fc5 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:40 +00:00
c96b8b5c64 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:40 +00:00
821e088b8e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:39 +00:00
3ea5965a99 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:38 +00:00
5ce2821634 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:38 +00:00
5d4b6ee4fc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:37 +00:00
7399e63d70 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:37 +00:00
fc27945b4e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:36 +00:00
2b98a8ca57 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:36 +00:00
d50103ca24 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:35 +00:00
52a3aaec81 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:35 +00:00
48d9f3af80 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:34 +00:00
7575ca93ad Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:33 +00:00
dcf7f0daa9 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:33 +00:00
ffe3f45168 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:32 +00:00
bd17bdabf9 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:32 +00:00
118c993e31 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:31 +00:00
33707afaaf Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:31 +00:00
5fc79cb304 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:30 +00:00
b595872bb3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:29 +00:00
e50e55444c Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:29 +00:00
0f68d7e8f9 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:28 +00:00
f161ba7728 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:28 +00:00
fb2479c6fe Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:27 +00:00
f8f75587c3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:27 +00:00
3cbf6b5144 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:26 +00:00
48cf579779 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:26 +00:00
5c5edd2106 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:25 +00:00
4a4b2f7206 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:25 +00:00
e84cdd1a54 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:24 +00:00
410eaab039 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:24 +00:00
8b8dd4758f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:23 +00:00
16dfa61d3d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:23 +00:00
cd0dcdb06b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:22 +00:00
0bc76ebcfb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:22 +00:00
b86383444b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:21 +00:00
e788902689 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:21 +00:00
2d0d90ba7e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:20 +00:00
c56cba7257 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:19 +00:00
63623d0dc3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:19 +00:00
1a409eab82 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:18 +00:00
135242d577 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:18 +00:00
aec96c5193 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:17 +00:00
a68eef6627 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:17 +00:00
0ed1ee7bb0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:16 +00:00
ccdde704c7 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:16 +00:00
f2803833a6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:15 +00:00
884df448f0 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:14 +00:00
a1cba28258 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:14 +00:00
eddb6db49e Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:13 +00:00
67267c20a3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:13 +00:00
547da816ad Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:12 +00:00
ecf57118ba Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:12 +00:00
3681255837 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:11 +00:00
f97595108f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:11 +00:00
7bf6c0aa4b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:10 +00:00
9fb24cad21 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:10 +00:00
b036b9f480 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:09 +00:00
2d677619f3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:08 +00:00
576e6edecc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:08 +00:00
0819ee5593 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:08 +00:00
7ca45462cf Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:07 +00:00
0e8399ae71 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:07 +00:00
cf42f5455d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:06 +00:00
50536e5867 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:05 +00:00
e3c584c560 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:05 +00:00
c48e67db97 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:04 +00:00
fd8c6f50f2 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:04 +00:00
e09e6074c8 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:03 +00:00
c470e9603f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:03 +00:00
faf0882b3a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:02 +00:00
e96209ad14 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:02 +00:00
1912047142 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:01 +00:00
8011416ceb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:01 +00:00
2d3f527e24 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:53:00 +00:00
aed221fa34 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:59 +00:00
425d46b0ef Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:59 +00:00
b3d43ad682 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:58 +00:00
65af6a8437 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:58 +00:00
ac07f2e7df Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:57 +00:00
4d1c88b43b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:57 +00:00
465720ccdd Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:56 +00:00
21fe8ed322 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:56 +00:00
01d440de88 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:55 +00:00
aba0ce3a6d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:55 +00:00
906217822f Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:54 +00:00
9e81d94e5d Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:54 +00:00
092f3b1026 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:53 +00:00
6739cac57b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:53 +00:00
2d69ab84ce Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:52 +00:00
af3a8d4dbc Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:52 +00:00
0792585612 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:51 +00:00
ee798802e6 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:51 +00:00
3f44bf0577 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:50 +00:00
eaedae0565 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:50 +00:00
9c068d07c9 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:49 +00:00
8abe88b2d3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:49 +00:00
ece70df8fe Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:48 +00:00
ecc375cf63 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:48 +00:00
d89a5b2e4b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:47 +00:00
d041586baf Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:47 +00:00
49472d32a1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:46 +00:00
aa83b5c270 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:46 +00:00
24bd37cd38 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:45 +00:00
a4e24baeb5 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:45 +00:00
f0512fdce3 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:44 +00:00
101b6c9b74 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:44 +00:00
9db3f91c28 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:43 +00:00
94de4c07da Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:43 +00:00
67eedfddc4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:42 +00:00
829ec15b5b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:42 +00:00
e8bc314cfb Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:41 +00:00
85328a6e96 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:41 +00:00
3af743ed1b Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:40 +00:00
b3b67e7abf Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:39 +00:00
f2d4464209 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:39 +00:00
3fa52b6f32 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:38 +00:00
01ad3e8a8a Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:38 +00:00
fc4bbe2568 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:37 +00:00
d1a407c6b8 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:37 +00:00
a210ca3e17 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:36 +00:00
276f4a5aa4 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:36 +00:00
56b5e117f1 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:35 +00:00
00c5630072 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:35 +00:00
f3a4594386 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:34 +00:00
ed335e5010 Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) 2026-04-27 06:52:34 +00:00
cdd5dbb5ea Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:24 +00:00
0e51ca5bce Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:24 +00:00
0f24587641 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:23 +00:00
5b1f74e263 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:23 +00:00
0a2171ae91 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:22 +00:00
09573a7cfc Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:22 +00:00
686c4f2698 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:21 +00:00
9273950afc Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:21 +00:00
add6fe3994 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:20 +00:00
581efc0235 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:20 +00:00
b1d9b4810f Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:19 +00:00
a868059124 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:18 +00:00
2ceb788c2e Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:18 +00:00
3ca93dfc54 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:18 +00:00
e8315b207d Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:17 +00:00
3090536fc7 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:17 +00:00
c5034b43ab Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:16 +00:00
6b4b7939b0 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:16 +00:00
99be7c765a Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:15 +00:00
a018275ebf Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:14 +00:00
fb9777247a Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:14 +00:00
1e8239c7e2 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:13 +00:00
81b127648b Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:13 +00:00
4c5e3f2f28 Tower: upload cetmix_tower_server_queue1 16.0.2.0.0 (via marketplace) 2026-04-27 06:47:12 +00:00
9fb7d3ff42 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:56 +00:00
ac3093b5dc Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:55 +00:00
975d29fa31 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:55 +00:00
94adb5f348 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:54 +00:00
fba8cc9acd Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:54 +00:00
0fb75fa95f Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:53 +00:00
840c4ac3a9 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:52 +00:00
16613c86a7 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:52 +00:00
0c43591378 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:51 +00:00
9ea6ac8d24 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:51 +00:00
394210c99b Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:50 +00:00
0a7c8c70b0 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:50 +00:00
50cfffdb19 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:49 +00:00
262f2ceef5 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:49 +00:00
5377ca3d57 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:48 +00:00
2fc48951c8 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:48 +00:00
b5308c583c Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:47 +00:00
ffc4690cf5 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:47 +00:00
aace3488c5 Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:46 +00:00
9782ca679d Tower: upload cetmix_tower_aws 16.0.1.1.1 (via marketplace) 2026-04-27 06:46:46 +00:00
258500d3f7 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:37 +00:00
20a3a2d33d Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:37 +00:00
09b6d24303 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:36 +00:00
244569004b Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:36 +00:00
773928cf47 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:35 +00:00
0b60b46a40 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:35 +00:00
4a4797e49d Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:34 +00:00
a26a507d31 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:34 +00:00
151578461e Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:33 +00:00
c219e1c5e6 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:33 +00:00
701190a853 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:32 +00:00
4a5d224e26 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:32 +00:00
c948ed897f Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:31 +00:00
9f83c4003a Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:31 +00:00
60ad89af8d Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:30 +00:00
f59c3ac6e4 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:30 +00:00
25aae80175 Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:29 +00:00
8a784023df Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:29 +00:00
d105b3086e Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:28 +00:00
e68734af4d Tower: upload cetmix_tower_ovh 16.0.1.0.1 (via marketplace) 2026-04-27 06:46:28 +00:00
80aca5c42e Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:35 +00:00
91cc351b9f Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:34 +00:00
3727eff0a1 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:34 +00:00
98e8f2c77f Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:33 +00:00
d9cc0ef9d3 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:33 +00:00
20e5e555f1 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:32 +00:00
156a6a6cb6 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:32 +00:00
2c57c4598c Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:31 +00:00
130678682c Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:31 +00:00
ca706b0281 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:30 +00:00
9ff2b454fb Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:30 +00:00
5362042060 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:29 +00:00
59c05047e6 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:29 +00:00
dabc32defa Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:28 +00:00
d0ba4497b8 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:28 +00:00
cbdbb2cb4f Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:27 +00:00
8090db41fd Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:27 +00:00
e4b8bf49c6 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:26 +00:00
f91e4f7f47 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:26 +00:00
2185ab4d96 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:25 +00:00
8b55326dbd Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:25 +00:00
29de3846b7 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:24 +00:00
781f6703f2 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:24 +00:00
7901b11a6d Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:23 +00:00
136351e574 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:22 +00:00
004fe34221 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:22 +00:00
dc15afe84c Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:21 +00:00
298b4baeae Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:21 +00:00
efa72f8d96 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:21 +00:00
d5d8cca96e Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:20 +00:00
34676028f9 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:20 +00:00
6639a57225 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:19 +00:00
e084da09e7 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:18 +00:00
8afc6b5c10 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:18 +00:00
28b558e0eb Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:18 +00:00
18d55d8ef9 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:17 +00:00
ded62cb3f1 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:17 +00:00
da00ab06c2 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:16 +00:00
4021aeef49 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:15 +00:00
3cf5653f0d Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:15 +00:00
779e44f63a Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:14 +00:00
17f8d7bb98 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:14 +00:00
47e0d157a2 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:13 +00:00
bcfaf764a4 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:13 +00:00
cd38fe180c Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:12 +00:00
51b54d0dc6 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:12 +00:00
a452163d96 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:11 +00:00
1457492697 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:11 +00:00
c7ce387900 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:10 +00:00
7131dbd052 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:10 +00:00
1a2c8df31e Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:09 +00:00
d2d280c2e3 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:09 +00:00
7480c912b5 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:08 +00:00
307fb2c8a3 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:08 +00:00
85dcab4226 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:07 +00:00
da7bb49726 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:07 +00:00
17c5b9b811 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:06 +00:00
458ca8b40c Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:06 +00:00
9bf906a371 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:05 +00:00
b1e7ce7277 Tower: upload cetmix_tower_git 16.0.2.0.4 (via marketplace) 2026-04-27 06:45:05 +00:00
0fb461e3df Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:43 +00:00
fdb9083e95 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:42 +00:00
ab645f0fe9 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:42 +00:00
290ce48514 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:41 +00:00
b6c35b9f76 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:41 +00:00
5c90e911b0 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:40 +00:00
b63181ae6b Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:39 +00:00
bc72822fe4 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:39 +00:00
29d6e2157c Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:38 +00:00
6b851b5033 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:38 +00:00
cad2a32394 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:38 +00:00
b251ba9709 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:37 +00:00
812fb1ff32 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:36 +00:00
0e299769bb Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:36 +00:00
956fed6616 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:35 +00:00
ef982e5d22 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:35 +00:00
fe589090d7 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:34 +00:00
6100570511 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:34 +00:00
c25370304e Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:33 +00:00
203d561a5d Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:33 +00:00
987367d1ca Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:32 +00:00
f7523e073f Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:32 +00:00
f42fd8a333 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:31 +00:00
bf39b6c79e Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:30 +00:00
33dbbb5178 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:30 +00:00
db79948886 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:29 +00:00
cf09b40b4a Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:29 +00:00
fbc5aedf35 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:28 +00:00
31c0f1566b Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:28 +00:00
16786404e1 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:27 +00:00
050d68c0d1 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:27 +00:00
9f807e8e1d Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:26 +00:00
851c2d0239 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:26 +00:00
f9ab417fdf Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:25 +00:00
6702e0714f Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:25 +00:00
fa16558cda Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:24 +00:00
5328e0be5d Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:24 +00:00
1bd02406d4 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:23 +00:00
a4c34fb326 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:23 +00:00
80a70b758d Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:22 +00:00
0a333efddb Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:22 +00:00
a4cf1a2957 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:21 +00:00
59e5709f28 Tower: upload cetmix_tower 16.0.2.1.0 (via marketplace) 2026-04-27 06:44:21 +00:00
1195eb23b1 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:13 +00:00
69f00977ae Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:12 +00:00
fc8b8b8a9a Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:12 +00:00
07a3160ed5 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:11 +00:00
1496fbfa53 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:11 +00:00
780593c0b6 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:10 +00:00
db891f43ce Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:10 +00:00
3357d9a86b Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:09 +00:00
43a7ca4b5e Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:09 +00:00
c764a356ce Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:08 +00:00
4a881b9eaf Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:08 +00:00
76d70ea861 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:07 +00:00
959a04e1cc Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:07 +00:00
bf8fbcc9e3 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:06 +00:00
f9fe46154a Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:06 +00:00
c97921b2ea Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:05 +00:00
95967f2f45 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:05 +00:00
552c05599f Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:04 +00:00
837d110796 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:04 +00:00
fcc7e84300 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:03 +00:00
9080bc85f2 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:03 +00:00
512f1a8f4d Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:02 +00:00
4faa6b9af4 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:02 +00:00
019ee02912 Tower: upload cetmix_tower_server_queue 16.0.2.0.0 (via marketplace) 2026-04-27 06:44:01 +00:00
369 changed files with 93699 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
============
Cetmix Tower
============
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:ec1914ccdcdfd8bfa539b1c131e8b2c41946b9bf978d2a32d13ee89ab655cd65
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-cetmix%2Fcetmix--tower-lightgray.png?logo=github
:target: https://github.com/cetmix/cetmix-tower/tree/16.0/cetmix_tower
:alt: cetmix/cetmix-tower
|badge1| |badge2| |badge3|
This is a technical module that allows to get `Cetmix
Tower <https://cetmix.com/tower>`__ modules from the `Odoo App
Store <https://apps.odoo.com>`__.
It's designed to install all the `Cetmix
Tower <https://cetmix.com/tower>`__ modules at once.
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/cetmix/cetmix-tower/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/cetmix/cetmix-tower/issues/new?body=module:%20cetmix_tower%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Cetmix
Maintainers
-----------
This module is part of the `cetmix/cetmix-tower <https://github.com/cetmix/cetmix-tower/tree/16.0/cetmix_tower>`_ project on GitHub.
You are welcome to contribute.

View File

View File

@@ -0,0 +1,22 @@
# Copyright Cetmix OU
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Cetmix Tower",
"summary": "Odoo SAAS Server Application Management",
"version": "16.0.2.1.0",
"development_status": "Beta",
"category": "Productivity",
"website": "https://tower.cetmix.com",
"live_test_url": "https://tower.cetmix.com/download",
"images": ["static/description/banner.png"],
"author": "Cetmix",
"license": "AGPL-3",
"application": True,
"installable": True,
"depends": [
"cetmix_tower_server",
"cetmix_tower_server_queue",
"cetmix_tower_git",
"cetmix_tower_webhook",
],
}

View File

@@ -0,0 +1,13 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1,3 @@
This is a technical module that allows to get [Cetmix Tower](https://cetmix.com/tower) modules from the [Odoo App Store](https://apps.odoo.com).
It's designed to install all the [Cetmix Tower](https://cetmix.com/tower) modules at once.

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@@ -0,0 +1,435 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 756 322.5" style="enable-background:new 0 0 756 322.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#FFFFFF;stroke:#FFFFFF;stroke-width:0.75;stroke-miterlimit:10;}
</style>
<g>
<g>
<g>
<path class="st0" d="M447.2,121.7c-2,1.6-4.7,2.9-8.3,3.9c-3.6,1-6.8,1.6-9.6,1.6c-10.9,0-19.5-2.8-25.8-8.3s-9.4-13.3-9.4-23.5
V53.7h-11.8V35.6H394V14.7l23.5-4.2v25.1h16l0.2,18l-16.2,0.1v37.4c0,4.6,1.1,8.4,3.3,11.3c2.2,3,5.4,4.5,9.7,4.5
c1.6,0,3.2-0.2,4.8-0.5c1.6-0.4,3.2-1,4.9-1.8L447.2,121.7z"/>
</g>
<g>
<path class="st0" d="M536.3,49.4c3.8-4.3,8.8-7.6,15-10.1c6.3-2.5,11.8-3.7,16.8-3.7c12,0,20.6,3.5,25.6,10.5
c5.1,7.1,7.6,15.6,7.6,25.8v55.2h-23.9v-54c0-5.6-1.3-9.9-4-12.8s-6.6-4.5-11.6-4.5c-3.4,0-7,0.9-10.7,2.7s-7.2,3.9-10.3,6.2
c0.1,1.2,0.2,2.4,0.4,3.7c0.1,1.2,0.2,2.4,0.2,3.7v55.2h-23.9V73.1c0-5.6-1.3-9.9-4-12.8s-6.5-4.5-11.4-4.5
c-3.1,0-6.1,0.6-9.2,1.9c-3.1,1.3-6.1,2.9-8.9,4.8v64.7h-23.7V39l23.3-3v7c3-2,5-3,9.4-4.5c5.7-1.9,10.7-3,15.2-3
c7,0,12.7,1.2,17.3,3.7C530.1,41.8,533.7,45.2,536.3,49.4z"/>
</g>
<g>
<path class="st0" d="M634.8,0c3.8,0,7,1.3,9.6,3.8c2.6,2.6,3.9,5.7,3.9,9.5s-1.3,6.9-3.9,9.5c-2.6,2.6-5.8,3.8-9.6,3.8
c-3.7,0-6.8-1.3-9.3-3.8c-2.6-2.6-3.8-5.7-3.8-9.5s1.3-6.9,3.8-9.5C628.1,1.3,631.2,0,634.8,0z M646.9,36l-0.2,91.1H623L622.9,36
H646.9z"/>
</g>
<g>
<path class="st0" d="M659.4,127.2l34.1-45.3l-32.8-45.8h25.8l21,29.9l21.9-29.9H756l-34.5,45.8l31.6,45.3H727l-20.5-28.4
l-20.9,28.4H659.4z"/>
</g>
<g>
<path class="st0" d="M198.4,81.5c0-26.6,19.5-45.5,46.7-45.5c18,0,29,7.8,34.8,15.6l-15.1,14c-4.2-6.1-10.5-9.4-18.6-9.4
c-14,0-23.9,10.1-23.9,25.2s9.9,25.4,23.9,25.4c8.1,0,14.4-3.6,18.6-9.4l15.1,13.8c-5.9,8.1-16.7,15.8-34.8,15.8
C217.9,127.2,198.4,108.3,198.4,81.5z"/>
</g>
<g>
<path class="st0" d="M289.4,81.5c0-25.2,18.8-45.5,45.6-45.5c26.3,0,44.1,19.4,44.1,47.8v5.1h-65.5c1.5,10.9,10.4,20.1,25.3,20.1
c7.5,0,17.8-3.2,23.5-8.7l10.3,14.7c-8.8,7.9-22.6,12-36.2,12C309.6,127.2,289.4,109.4,289.4,81.5z M334.8,54.2
c-14.4,0-20.6,10.6-21.7,19.2h43.4C356,65.2,350.2,54.2,334.8,54.2z"/>
</g>
</g>
<g>
<g>
<path class="st0" d="M92.3,91.5c0.6,0.3,0.7,1,0.2,1.5c-3.1,2.8-6.6,5.2-10.3,7.1c-6.6,3.2-13.7,4.8-20.9,4.7
c-7.2-0.3-14.2-2.2-20.3-5.7s-11.2-8.5-14.9-14.3s-5.8-12.5-6.4-19.3c-0.4-6.8,0.8-13.6,3.5-19.7c1.4-3,3.1-5.9,5.2-8.5
s4.5-4.9,7.1-7c5.2-4,11.3-6.7,17.7-7.8C46.9,24,41,27.1,36.4,31.4c-2.4,2.1-4.5,4.5-6.2,7.1c-1.8,2.6-3.1,5.5-4.3,8.4
c-2.1,5.8-2.7,12-1.9,18.1c0.9,6.1,3.3,11.7,6.8,16.6c3.6,4.8,8.3,8.7,13.6,11.2s11.1,3.6,16.9,3.4c5.8-0.3,11.3-2,16.2-4.9
c1.9-1.2,3.7-2.5,5.4-4c0.3-0.2,0.7-0.3,1-0.1L92.3,91.5z"/>
</g>
<g>
<path class="st0" d="M110.3,107.7c0.4,0.4,0.3,1.1-0.1,1.5c-0.2,0.2-0.4,0.4-0.6,0.6c-2.6,2.3-5.4,4.5-8.3,6.4s-6,3.6-9.2,5
s-6.5,2.6-9.8,3.5c-13.3,3.7-27.7,2.9-40.4-1.9s-23.8-13.5-31.3-24.7C3.2,86.8-0.4,73.5,0,60.3c0.5-13.1,5.2-26,13.1-36.1
C21.2,14,32.3,6.5,44.5,3C56.8-0.6,70-0.2,81.8,4c5.9,2.1,11.4,5.1,16.3,8.9c5,3.7,9.3,8.3,12.7,13.2c-3.8-4.8-8.3-9.1-13.3-12.4
S87,7.7,81.1,6c-11.5-3.4-24-2.9-35.3,1S24.9,18.4,18.3,28c-6.7,9.6-10.2,21.1-9.9,32.4c0.2,11.3,4.1,22.5,10.8,31.5
c6.7,8.9,16.2,15.5,26.7,18.8s21.9,3.1,32-0.3c8.2-2.7,15.4-7.5,21.2-13.5c0.4-0.4,1.1-0.5,1.5-0.1c0.6,0.6,1.3,1.3,1.8,2
C102.6,98.6,108.3,105.4,110.3,107.7z"/>
</g>
<g>
<path class="st0" d="M149.8,41l-35.6,43.5l2,4.1l4.1,8.6c0.7,1.5,0.4,3.3-0.8,4.5l-2.9,2.7c-0.2,0.2-0.4,0.2-0.7,0.2
c-0.1,0-0.2-0.1-0.3-0.2c0,0-0.1,0-0.1-0.1l-7.9-9.4c-0.8-0.9-1.6-1.8-2.5-2.6c-0.7-0.6-1.3-1.2-2.1-1.8c-1.4-1.1-3-2.2-4.6-3
c-0.2-0.2-0.5-0.3-0.8-0.4l-9.1-4.8l-1.7-0.9c-0.4-0.2-0.5-0.6-0.3-1l2-3.4c0.9-1.5,2.6-2.2,4.2-1.8l13.7,3.1l13.9-18L91.8,47.8
c-0.4-0.2-0.5-0.7-0.3-1l4.5-5.6c1.8-2.3,4.8-3.4,7.7-3l30.2,5.1l7.5-9.6c1.7-2.2,3.9-3.9,6.4-5l3.5-1.5c0.5-0.2,1-0.2,1.4-0.1
c0.3,0.1,0.5,0.2,0.7,0.3l0,0c0.5,0.4,0.9,1.2,0.7,2l-0.6,3.7C152.9,36,151.7,38.7,149.8,41z"/>
</g>
<g>
<g>
<path class="st0" d="M155.2,85.4l-4.5,5.6c-0.2,0.2-0.5,0.3-0.7,0.2c-0.1,0-0.3-0.1-0.4-0.2l-17.2-23.3l13.3-16.1l10.5,25.7
C157.5,79.9,157,83,155.2,85.4z"/>
</g>
</g>
</g>
</g>
<g>
<path class="st0" d="M397.4,241.7c-15.1,0-27.3-12.3-27.3-27.3s12.3-27.3,27.3-27.3c15.1,0,27.3,12.3,27.3,27.3l0,0
C424.7,229.5,412.4,241.7,397.4,241.7z M397.4,230.4c8.9,0,16-7.2,16-16c0-8.8-7.2-16-16-16c-8.9,0-16,7.2-16,16
C381.4,223.2,388.5,230.4,397.4,230.4z M340.2,241.7c-15.1,0-27.3-12.3-27.3-27.3s12.3-27.3,27.3-27.3c15.1,0,27.3,12.3,27.3,27.3
l0,0C367.5,229.5,355.3,241.7,340.2,241.7z M340.2,230.4c8.9,0,16-7.2,16-16c0-8.8-7.2-16-16-16c-8.9,0-16,7.2-16,16
C324.2,223.2,331.3,230.4,340.2,230.4z M310.3,214.1c0,15.3-12.3,27.7-27.3,27.7s-27.3-12.4-27.3-27.7s11.1-27,27.3-27
c6,0,11.5,1.2,16,4.6v-15.8c0-3,2.7-5.5,5.7-5.5s5.7,2.5,5.7,5.5V214.1z M282.9,230.4c8.9,0,16-7.2,16-16c0-8.8-7.2-16-16-16
c-8.9,0-16,7.2-16,16C266.9,223.2,274.1,230.4,282.9,230.4z"/>
</g>
<g>
<path class="st0" d="M225.7,241.7c-15.1,0-27.3-12.3-27.3-27.3s12.3-27.3,27.3-27.3s27.3,12.3,27.3,27.3l0,0
C253.1,229.5,240.9,241.7,225.7,241.7z M225.7,230.4c8.9,0,16-7.2,16-16c0-8.8-7.2-16-16-16c-8.9,0-16,7.2-16,16
C209.7,223.2,216.9,230.4,225.7,230.4z"/>
</g>
<g>
<g>
<path class="st0" d="M547.4,229.9c0.1,0,0.2,0,0.4,0c0.1,0,0.2,0.1,0.1,0.1v0.1c0,3.8,0,7.6,0,11.4c0,0.1,0,0.1,0,0.1
c-0.9,0-1.8,0-2.7,0c0-0.1,0-0.2,0-0.2c0-3.7,0-7.4,0-11.1c0-0.3-0.1-0.2,0.2-0.2c0.1,0,0.2,0,0.4,0
C546.4,229.9,546.9,229.9,547.4,229.9z"/>
</g>
<g>
<path class="st0" d="M520.6,200.7c-0.1,0.2-0.1,0.5-0.1,0.8c0,0.1-0.1,0.2-0.2,0.2c-0.4-0.1-0.9-0.1-1.3-0.2
c-1.5-0.2-3.2-0.4-4.7-0.6c-1.4-0.2-2.7-0.4-4.1-0.5c-0.4-0.1-0.8-0.1-1.2-0.2c-0.1-0.1-0.1-0.1-0.1-0.2c0.2-1.2,0.3-2.4,0.4-3.6
c0-0.1,0.1-0.2,0.2-0.2c1.1,0.1,2.1,0.2,3.2,0.4c1.2,0.2,2.6,0.4,3.7,0.5c1.4,0.2,2.7,0.4,4.1,0.5c0.4,0.1,0.4,0.1,0.3,0.4
c-0.1,0.3-0.1,0.6-0.1,1c-0.1,0-0.1,0.1-0.1,0.1c-0.1,0.4-0.1,0.9-0.2,1.4C520.6,200.7,520.6,200.7,520.6,200.7z"/>
</g>
<g>
<path class="st0" d="M572.9,206.4c0.1-0.2,0.1-0.6,0.1-0.8c0-0.1,0.1-0.1,0.2-0.1c1,0.1,2,0.2,3,0.4c1.1,0.1,2.1,0.2,3.2,0.4
c1.2,0.1,2.3,0.3,3.5,0.5c0.5,0.1,1.1,0.1,1.5,0.2c0.1,0,0.2,0.1,0.2,0.2c0.1,0.6-0.1,1.2-0.2,1.8c-0.1,0.6-0.2,1.2-0.2,1.7
c0,0.1-0.1,0.2-0.2,0.1c-1.4-0.2-2.8-0.4-4.2-0.6c-1.4-0.2-2.7-0.4-4-0.5c-1.1-0.1-2.1-0.2-3.1-0.4c-0.1,0-0.1-0.1-0.1-0.2
c0.1-0.4,0.1-0.7,0.1-1.1c0.1,0,0.1-0.1,0.1-0.1c0.1-0.4,0.1-0.9,0.2-1.3C573,206.6,573,206.5,572.9,206.4z"/>
</g>
<g>
<path class="st0" d="M571.1,213.7c0.1-0.2,0.2-0.4,0.3-0.7c0.1-0.1,0.1-0.1,0.2-0.1c2.2,1,4.4,2,6.6,3c1.2,0.6,2.4,1.1,3.7,1.7
c0.2,0.1,0.2,0.1,0.1,0.3c-0.5,1-0.9,2-1.4,3c-0.1,0.1-0.1,0.1-0.2,0.1c-2.3-1.1-4.6-2.1-7-3.2c-1.1-0.5-2.2-1-3.3-1.5
c-0.2-0.1-0.2-0.1-0.1-0.3c0.2-0.3,0.2-0.6,0.4-0.9c0.2-0.3,0.3-0.6,0.4-0.9C571,214.1,571.1,213.9,571.1,213.7z"/>
</g>
<g>
<path class="st0" d="M522.6,193.4c-0.1,0.2-0.2,0.5-0.4,0.7c-0.1,0.1-0.1,0.1-0.2,0.1c-1.2-0.6-2.6-1.1-3.8-1.7
c-1.5-0.7-3.2-1.4-4.8-2.2c-0.6-0.2-1.1-0.5-1.7-0.8c-0.1-0.1-0.1-0.1-0.1-0.2c0.5-1,1-2.1,1.4-3c0.1-0.1,0.1-0.1,0.2-0.1
c1,0.5,2.1,0.9,3,1.4c2.4,1.1,4.8,2.2,7.2,3.3c0.1,0.1,0.2,0.1,0.1,0.3c-0.1,0.2-0.2,0.5-0.4,0.8c-0.1,0.2-0.2,0.4-0.2,0.6
C522.8,192.7,522.6,193,522.6,193.4z"/>
</g>
<g>
<path class="st0" d="M567.2,220.1c0.1-0.2,0.2-0.3,0.4-0.5c0.1-0.1,0.1-0.1,0.2,0c2.1,1.9,4.3,3.7,6.5,5.6
c0.7,0.6,1.4,1.2,2.1,1.8c0.1,0.1,0.1,0.2,0.1,0.3c-0.7,0.8-1.4,1.5-2,2.4c-0.1,0.1-0.1,0.1-0.2,0c-1.9-1.7-3.9-3.3-5.8-5
c-0.9-0.8-1.8-1.6-2.8-2.4c-0.1-0.1-0.1-0.1,0-0.2c0.2-0.2,0.4-0.4,0.6-0.7"/>
</g>
<g>
<path class="st0" d="M526.4,186.9c-0.2,0.2-0.4,0.4-0.5,0.6c-0.1,0.1-0.1,0.1-0.2,0c-1.2-1-2.4-2-3.5-3c-1.4-1.2-2.7-2.4-4.1-3.6
c-0.3-0.2-0.6-0.5-1-0.8c-0.1-0.1-0.1-0.1-0.1-0.2c0.7-0.8,1.4-1.5,2-2.3c0.1-0.1,0.2-0.1,0.2-0.1c1.4,1.2,2.7,2.4,4.1,3.6
c1.5,1.2,3,2.6,4.5,3.9c0.1,0.1,0.1,0.1,0.1,0.2c-0.2,0.2-0.3,0.4-0.4,0.5c-0.1,0-0.1,0-0.1,0.1
C527.1,186.1,526.8,186.5,526.4,186.9C526.4,186.8,526.4,186.9,526.4,186.9z"/>
</g>
<g>
<path class="st0" d="M531.8,181.9c-0.1,0.1-0.2,0.2-0.4,0.2c-0.1,0.1-0.2,0.1-0.3-0.1c-0.7-1.1-1.4-2.1-2-3.2
c-1.4-2.1-2.7-4.2-4-6.3c-0.1-0.1-0.1-0.2,0.1-0.2c0.8-0.5,1.6-1,2.4-1.5c0.1-0.1,0.2-0.1,0.2,0.1c1,1.5,2,3.1,3,4.7
c1,1.6,2.1,3.2,3,4.8c0.2,0.2,0.2,0.2-0.1,0.4c-0.1,0.1-0.2,0.1-0.3,0.2c-0.1,0-0.1,0.1-0.2,0.1c-0.4,0.2-0.8,0.5-1.1,0.7
C532,181.8,531.9,181.8,531.8,181.9z"/>
</g>
<g>
<path class="st0" d="M561.7,225.3c0.2-0.1,0.4-0.2,0.5-0.4c0.1-0.1,0.2-0.1,0.2,0.1c0.8,1.2,1.5,2.4,2.3,3.6
c1.1,1.7,2.2,3.4,3.3,5.1c0.2,0.2,0.4,0.5,0.5,0.8c0.1,0.1,0.1,0.2-0.1,0.2c-0.8,0.5-1.6,1.1-2.4,1.5c-0.1,0.1-0.2,0.1-0.2-0.1
c-1.7-2.7-3.4-5.3-5.1-8c-0.4-0.5-0.7-1.1-1-1.5c-0.1-0.1-0.1-0.1,0.1-0.2c0.2-0.1,0.4-0.2,0.6-0.4"/>
</g>
<g>
<path class="st0" d="M554.9,228.6c0.2-0.1,0.4-0.1,0.5-0.1c0.1-0.1,0.2-0.1,0.2,0.1c0.4,1.4,0.8,2.9,1.2,4.3
c0.6,2.1,1.2,4.3,1.9,6.5c0.1,0.2,0.1,0.2-0.2,0.3c-0.8,0.2-1.6,0.5-2.4,0.7c-0.2,0.1-0.2,0-0.3-0.2c-0.4-1.2-0.7-2.4-1.1-3.6
c-0.7-2.4-1.4-4.8-2.1-7.1c-0.1-0.2-0.1-0.2,0.2-0.2c0.2-0.1,0.3-0.1,0.4-0.1C553.9,228.9,554.4,228.8,554.9,228.6z"/>
</g>
<g>
<path class="st0" d="M538.7,178.5c-0.2,0.1-0.4,0.1-0.5,0.1c-0.1,0.1-0.2,0-0.2-0.1c-0.2-0.8-0.5-1.6-0.7-2.4
c-0.8-2.6-1.5-5.2-2.3-7.9c-0.1-0.2-0.1-0.3-0.1-0.5c-0.1-0.1-0.1-0.2,0.1-0.2c0.7-0.2,1.5-0.4,2.2-0.7c0.5-0.1,0.4-0.1,0.6,0.3
c0.6,2,1.2,4,1.7,6c0.4,1.5,0.9,3,1.4,4.5c0.1,0.1,0,0.2-0.1,0.2c-0.2,0.1-0.3,0.1-0.4,0.1c-0.1-0.1-0.1,0-0.1,0
c-0.4,0.1-0.7,0.2-1.1,0.4C538.9,178.5,538.8,178.5,538.7,178.5z"/>
</g>
<g>
<path class="st0" d="M546.1,177.3c-0.5,0-0.5,0-0.5-0.5c0-3.6,0-7.3,0-11c0-0.2,0.1-0.2,0.2-0.2c0.8,0,1.5,0,2.4,0
c0.1,0,0.2,0.1,0.2,0.2c0,3.7,0,7.6,0,11.3c0,0.1-0.1,0.2-0.2,0.2c-0.1,0-0.3,0-0.4,0C547.2,177.2,546.7,177.2,546.1,177.3z"/>
</g>
<g>
<path class="st0" d="M540.1,229.1c0.4,0.1,0.4,0.1,0.2,0.4c-1,3.6-2.1,7.1-3,10.7c-0.1,0.2-0.1,0.2-0.2,0.1
c-0.7-0.2-1.4-0.4-2.1-0.6c-0.2-0.1-0.2-0.1-0.1-0.2c0.5-1.8,1.1-3.6,1.5-5.4c0.5-1.8,1.1-3.6,1.5-5.5c0.1-0.2,0.1-0.2,0.2-0.1
c0.1,0.1,0.2,0.1,0.4,0.1C539,228.8,539.6,228.9,540.1,229.1z"/>
</g>
<g>
<path class="st0" d="M553.6,178.2c-0.4-0.1-0.4-0.1-0.3-0.5c0.8-2.9,1.7-5.9,2.5-8.9c0.2-0.6,0.4-1.2,0.5-1.8
c0.1-0.1,0.1-0.2,0.2-0.1c0.7,0.2,1.4,0.4,2.2,0.6c0.2,0.1,0.1,0.1,0.1,0.2c-0.4,1.6-0.9,3.2-1.4,4.9c-0.6,2-1.1,4-1.7,6
c-0.1,0.2-0.1,0.2-0.3,0.2c-0.1-0.1-0.1-0.1-0.2-0.1c-0.3-0.1-0.7-0.2-1-0.3C554,178.2,553.8,178.2,553.6,178.2z"/>
</g>
<g>
<path class="st0" d="M560.3,181.2c-0.3-0.2-0.2-0.2-0.1-0.5c1.7-2.6,3.3-5.2,4.9-7.8c0.4-0.5,0.7-1.1,1-1.6
c0.1-0.1,0.1-0.1,0.2-0.1c0.6,0.4,1.1,0.7,1.7,1.1c0.1,0.1,0.1,0.1,0.1,0.2c-1,1.5-2,3-2.9,4.6c-1.1,1.6-2.1,3.2-3.1,4.9
c-0.1,0.2-0.2,0.2-0.4,0.1"/>
</g>
<g>
<path class="st0" d="M533.1,226.1c0.2,0.2,0.2,0.2,0.1,0.5c-1.2,1.9-2.4,3.7-3.6,5.6c-0.8,1.2-1.6,2.5-2.4,3.7
c-0.1,0.1-0.2,0.2-0.3,0.1c-0.5-0.4-1.1-0.7-1.6-1.1c-0.1-0.1-0.1-0.1-0.1-0.2c1.4-2.1,2.7-4.3,4.1-6.4c0.7-1,1.2-2,1.9-3
c0.1-0.2,0.1-0.2,0.4-0.1c0,0,0.1,0,0.1,0.1C532.3,225.5,532.7,225.8,533.1,226.1z"/>
</g>
<g>
<path class="st0" d="M527.4,221.4c0.1,0.1,0.1,0.2-0.1,0.3c-2.7,2.4-5.4,4.7-8.2,7c-0.1,0.1-0.2,0.2-0.4,0.4
c-0.1,0.1-0.1,0.1-0.2,0c-0.4-0.5-0.8-0.9-1.2-1.4c-0.1-0.1-0.1-0.1,0.1-0.2c0.7-0.6,1.4-1.2,2.1-1.8c1.4-1.2,2.7-2.4,4.1-3.6
c0.8-0.7,1.6-1.4,2.4-2.1c0.2-0.1,0.2-0.1,0.3,0.1C526.7,220.6,527.1,221,527.4,221.4z"/>
</g>
<g>
<path class="st0" d="M566.2,185.8c-0.1-0.1-0.1-0.2,0.1-0.4c2.1-1.8,4.2-3.7,6.4-5.5c0.7-0.6,1.4-1.2,2.1-1.8
c0.1-0.1,0.2-0.1,0.2,0c0.4,0.4,0.7,0.9,1.1,1.3c0.1,0.1,0.1,0.2-0.1,0.2c-2.1,1.8-4.2,3.6-6.2,5.4c-0.7,0.7-1.5,1.2-2.2,1.9
c-0.1,0.1-0.2,0.1-0.4,0C566.9,186.6,566.6,186.2,566.2,185.8z"/>
</g>
<g>
<path class="st0" d="M570.3,191.9c-0.1-0.1,0.1-0.1,0.1-0.2c0.9-0.4,1.8-0.8,2.7-1.2c1.2-0.5,2.3-1.1,3.5-1.6
c1.4-0.6,2.7-1.2,4-1.9c0.1-0.1,0.2-0.1,0.3,0.1c0.2,0.4,0.4,0.9,0.6,1.3c0.1,0.1,0.1,0.2-0.1,0.2c-1.8,0.8-3.6,1.7-5.5,2.5
c-1.6,0.7-3.2,1.5-4.9,2.2c-0.1,0.1-0.2,0.1-0.2-0.1C570.8,192.9,570.6,192.4,570.3,191.9z"/>
</g>
<g>
<path class="st0" d="M523.2,215.2c0.1,0.1-0.1,0.1-0.1,0.2c-1,0.4-1.9,0.9-2.9,1.4c-1.2,0.6-2.4,1.1-3.6,1.7
c-1.3,0.6-2.6,1.2-3.9,1.8c-0.1,0.1-0.1,0.1-0.2-0.1c-0.2-0.5-0.4-1-0.7-1.4c-0.1-0.1-0.1-0.2,0.1-0.2c2.7-1.2,5.4-2.4,8-3.7
c0.7-0.4,1.5-0.7,2.3-1.1c0.1-0.1,0.2-0.1,0.2,0C522.7,214.2,523,214.8,523.2,215.2z"/>
</g>
<g>
<path class="st0" d="M531.8,181.9c0.1-0.1,0.1-0.1,0.2-0.2c0.4-0.2,0.7-0.5,1.1-0.7c0.1-0.1,0.1-0.1,0.2-0.1
c0.4,0.7,0.8,1.4,1.2,2c1,1.7,2,3.3,3,4.9c0.5,0.9,1.1,1.7,1.5,2.6c0.1,0.1,0.1,0.2-0.1,0.2c-0.4,0.2-0.9,0.5-1.2,0.8
c-0.1,0.1-0.1,0.1-0.2-0.1c-1-1.6-1.9-3.2-2.9-4.8c-0.7-1.1-1.4-2.2-2.1-3.4c-0.2-0.4-0.5-0.8-0.7-1.2
C532,182,531.9,182,531.8,181.9z"/>
</g>
<g>
<path class="st0" d="M514.2,209c-1.6,0.2-3.2,0.4-4.8,0.7c-0.1,0-0.2,0-0.2-0.1c-0.1-0.4-0.1-0.9-0.2-1.3c0-0.1,0.1-0.2,0.1-0.2
c1.3-0.2,2.6-0.4,3.9-0.5c1.5-0.2,3-0.4,4.5-0.6c1-0.1,2-0.2,3-0.4c0.1,0.6,0.2,1.1,0.2,1.6"/>
</g>
<g>
<path class="st0" d="M572.8,199c1.4-0.2,2.9-0.4,4.4-0.6c1.3-0.2,2.7-0.4,4-0.5c1-0.1,2-0.2,3-0.4c0.2-0.1,0.2,0,0.2,0.2
c0.1,0.4,0.1,0.8,0.2,1.2c0,0.1,0,0.2-0.1,0.2c-1,0.1-1.9,0.2-2.9,0.4c-1.6,0.2-3.2,0.4-4.9,0.7c-1.2,0.2-2.4,0.3-3.6,0.5
c-0.1,0-0.1,0-0.1,0C572.9,200.1,572.8,199.5,572.8,199z"/>
</g>
<g>
<path class="st0" d="M546.1,177.3c0.5-0.1,1.1-0.1,1.6,0c0,3.7,0,7.4,0,11.1c0,0.2,0,0.2-0.2,0.2c-0.4,0-0.7,0-1.1,0
c-0.2,0-0.2-0.1-0.2-0.2c0-3.6,0-7.2,0-10.8C546.1,177.5,546.1,177.3,546.1,177.3z"/>
</g>
<g>
<path class="st0" d="M547.4,229.9c-0.5,0-1.1,0-1.6,0c0-3.7,0-7.4,0-11.1c0-0.2,0.1-0.2,0.2-0.2c0.4,0,0.8,0,1.2,0
c0.1,0,0.2,0.1,0.2,0.2c0,0.8,0,1.6,0,2.4C547.4,224.1,547.4,227,547.4,229.9z"/>
</g>
<g>
<path class="st0" d="M553.6,178.2c0.2,0,0.4,0.1,0.6,0.1c0.4,0.1,0.7,0.2,1,0.3c-0.1,0.2-0.2,0.5-0.2,0.8c-0.5,1.6-1,3.3-1.4,4.9
c-0.5,1.7-1,3.3-1.5,5c-0.1,0.1-0.1,0.2-0.2,0.1c-0.4-0.1-0.8-0.2-1.2-0.4c-0.1-0.1-0.1-0.1-0.1-0.2c0.4-1.2,0.7-2.4,1.1-3.7
c0.5-1.7,1-3.4,1.5-5.1C553.1,179.5,553.4,178.8,553.6,178.2z"/>
</g>
<g>
<path class="st0" d="M526.4,186.9c0-0.1,0-0.1,0.1-0.1c0.3-0.4,0.6-0.7,1-1.1c0.1-0.1,0.1-0.1,0.1-0.1c0.4,0.3,0.7,0.6,1,0.9
c0.5,0.5,1.1,1,1.5,1.4c1,0.9,2,1.8,3,2.7c0.6,0.6,1.2,1.1,1.8,1.7c0.2,0.2,0.5,0.5,0.8,0.7c0.1,0.1,0.1,0.1,0,0.2
c-0.3,0.3-0.6,0.7-0.8,1c-0.1,0.1-0.1,0.1-0.2,0.1c-0.3-0.3-0.6-0.6-1-0.8c-1.2-1.1-2.4-2.1-3.6-3.2c-1-0.9-1.9-1.7-2.9-2.6
C527.1,187.5,526.8,187.2,526.4,186.9z"/>
</g>
<g>
<path class="st0" d="M540.1,229.1c-0.5-0.1-1.1-0.2-1.5-0.4c0.4-1.1,0.7-2.3,1-3.4c0.4-1.4,0.8-2.7,1.2-4.1
c0.3-1.1,0.6-2.1,0.9-3.2c0.1-0.2,0.1-0.2,0.2-0.2c0.4,0.1,0.8,0.2,1.2,0.4c0.1,0.1,0.2,0.1,0.1,0.2c-0.5,1.7-1,3.4-1.5,5.1
c-0.5,1.7-1,3.5-1.5,5.2C540.1,228.8,540.1,228.9,540.1,229.1z"/>
</g>
<g>
<path class="st0" d="M522.6,193.4c0.1-0.3,0.2-0.6,0.4-0.9c0.1-0.2,0.1-0.4,0.2-0.6c0.7,0.3,1.3,0.6,2,0.9c1.5,0.7,3,1.4,4.5,2.1
c0.9,0.4,1.7,0.8,2.6,1.2c0.3,0.2,0.7,0.3,1,0.4c0.1,0.1,0.1,0.1,0.1,0.2c-0.2,0.4-0.4,0.8-0.5,1.2c-0.1,0.1-0.1,0.2-0.2,0.1
c-0.7-0.4-1.4-0.7-2.1-1c-1.9-0.9-3.9-1.8-5.8-2.7C524,194.1,523.3,193.7,522.6,193.4z"/>
</g>
<g>
<path class="st0" d="M571.1,213.7c-0.1,0.2-0.1,0.4-0.2,0.6c-0.1,0.3-0.2,0.6-0.4,0.9c-0.7-0.3-1.4-0.6-2.1-1
c-1.6-0.7-3.2-1.5-4.8-2.2c-0.8-0.4-1.6-0.7-2.4-1.1c-0.2-0.1-0.6-0.2-0.8-0.4c-0.1-0.1-0.1-0.1-0.1-0.2c0.2-0.4,0.4-0.8,0.6-1.2
c0.1-0.1,0.1-0.1,0.2-0.1c1.4,0.7,2.7,1.2,4.2,1.9C567.2,211.8,569.2,212.7,571.1,213.7C571.1,213.7,571.1,213.7,571.1,213.7z"/>
</g>
<g>
<path class="st0" d="M538.7,178.5c0.1-0.1,0.2-0.1,0.2-0.1c0.4-0.1,0.7-0.2,1.1-0.4c0.1,0,0.1-0.1,0.1,0c0.5,1.6,1,3.2,1.4,4.8
c0.4,1.2,0.7,2.4,1.1,3.6c0.2,0.7,0.4,1.5,0.7,2.2c0.1,0.1,0,0.2-0.1,0.2c-0.4,0.1-0.8,0.2-1.2,0.4c-0.2,0.1-0.2,0-0.2-0.2
c-0.3-1-0.6-2-0.9-3c-0.4-1.2-0.7-2.5-1.1-3.7C539.5,181.1,539.1,179.8,538.7,178.5z"/>
</g>
<g>
<path class="st0" d="M520.6,200.7c-0.1,0-0.1-0.1-0.1-0.1c0.1-0.4,0.1-0.9,0.2-1.4c0-0.1,0.1-0.1,0.1-0.1c0.9,0.1,1.7,0.2,2.6,0.4
c1,0.1,2.1,0.2,3,0.4c1,0.2,2,0.2,3,0.4c0.7,0.1,1.4,0.2,2.2,0.2c0.2,0,0.2,0.1,0.2,0.2c-0.1,0.4-0.1,0.8-0.2,1.2
c0,0.1-0.1,0.1-0.2,0.1c-0.9-0.1-1.8-0.2-2.7-0.4c-1-0.1-1.9-0.2-2.9-0.4c-0.9-0.1-1.8-0.2-2.7-0.4
C522.4,200.9,521.6,200.8,520.6,200.7C520.8,200.8,520.8,200.8,520.6,200.7z"/>
</g>
<g>
<path class="st0" d="M533.1,226.1c-0.4-0.3-0.9-0.6-1.4-0.9c0.3-0.4,0.5-0.8,0.8-1.2c0.7-1.1,1.4-2.1,2.1-3.2
c1.1-1.7,2.1-3.3,3.2-5c0.1-0.1,0.1-0.1,0.2-0.1c0.4,0.2,0.7,0.5,1.1,0.7c0.1,0.1,0.1,0.1,0.1,0.2c-0.5,0.7-0.9,1.4-1.4,2.2
c-1.5,2.4-3,4.7-4.5,7.1C533.2,226,533.2,226.1,533.1,226.1z"/>
</g>
<g>
<path class="st0" d="M560.4,181.1c0.5,0.2,0.9,0.6,1.4,0.9c-0.5,0.7-0.9,1.4-1.4,2.2c-1.5,2.4-3,4.8-4.6,7.2
c-0.1,0.1-0.1,0.1-0.2,0.1c-0.4-0.2-0.7-0.4-1.1-0.7c-0.1-0.1-0.2-0.1-0.1-0.2c0.8-1.2,1.5-2.4,2.3-3.6c1.2-1.9,2.4-3.8,3.6-5.7
C560.4,181.1,560.4,181.1,560.4,181.1z"/>
</g>
<g>
<path class="st0" d="M527.4,221.4c-0.4-0.4-0.7-0.8-1.1-1.2c1-0.9,2-1.7,3-2.6c1-0.9,2-1.7,3-2.6c0.8-0.7,1.7-1.4,2.5-2.1
c0.1-0.1,0.2-0.1,0.2,0.1c0.2,0.3,0.5,0.7,0.8,1c0.1,0.1,0.1,0.2,0,0.2c-0.6,0.5-1.2,1.1-1.8,1.6c-0.6,0.5-1.2,1.1-1.9,1.6
c-0.9,0.8-1.8,1.5-2.7,2.4C528.7,220.3,528,220.8,527.4,221.4z"/>
</g>
<g>
<path class="st0" d="M572.8,199c0.1,0.5,0.1,1.1,0.2,1.5c-0.4,0.1-0.7,0.1-1.1,0.2c-0.7,0.1-1.5,0.2-2.2,0.3
c-0.8,0.1-1.7,0.2-2.5,0.4c-0.8,0.1-1.7,0.2-2.5,0.4c-0.7,0.1-1.4,0.2-2.2,0.3c-0.2,0.1-0.4,0.1-0.7,0.1c-0.1,0.1-0.2-0.1-0.2-0.1
c-0.1-0.3-0.1-0.6-0.1-0.9c0-0.2-0.1-0.4,0-0.5c0.1-0.1,0.3-0.1,0.4-0.1c1.4-0.2,2.8-0.4,4.2-0.6c1.4-0.2,2.7-0.4,4-0.6
C571.2,199.2,571.9,199.2,572.8,199z"/>
</g>
<g>
<path class="st0" d="M554.9,228.8c-0.5,0.2-1,0.4-1.5,0.5c-0.2-1-0.6-2.2-0.9-3.2c-0.4-1.4-0.8-2.9-1.2-4.3
c-0.3-1.1-0.6-2.3-0.9-3.4c-0.1-0.1-0.1-0.2,0.1-0.2c0.4-0.1,0.8-0.2,1.2-0.4c0.1-0.1,0.2,0,0.2,0.1c0.4,1.5,0.8,3,1.2,4.5
c0.6,2,1.1,4,1.7,6.1C554.9,228.6,554.9,228.8,554.9,228.8z"/>
</g>
<g>
<path class="st0" d="M520.8,208.1c-0.1-0.5-0.1-1.1-0.2-1.5c1.2-0.2,2.4-0.4,3.6-0.5c1.1-0.1,2.2-0.3,3.3-0.5
c1.2-0.2,2.4-0.3,3.7-0.5c0.1,0,0.3-0.1,0.4-0.1c0.1,0,0.2,0,0.2,0.1c0.1,0.4,0.1,0.9,0.2,1.2c0,0.1-0.1,0.2-0.1,0.2
c-0.4,0.1-0.9,0.1-1.2,0.2c-0.7,0.1-1.4,0.2-2.2,0.3c-0.7,0.1-1.5,0.2-2.2,0.3c-0.7,0.1-1.4,0.2-2.1,0.3"/>
</g>
<g>
<path class="st0" d="M566.3,221.4c-1.4-1.2-2.9-2.5-4.3-3.7c-1.1-1-2.2-1.9-3.4-2.9c-0.2-0.2-0.5-0.5-0.8-0.7
c-0.1-0.1-0.1-0.1,0-0.2c0.2-0.3,0.5-0.6,0.8-0.9c0.1-0.1,0.2-0.1,0.3,0c0.4,0.4,0.9,0.8,1.4,1.2c0.9,0.7,1.7,1.5,2.6,2.3
c0.7,0.6,1.4,1.2,2,1.7c0.8,0.8,1.5,1.4,2.3,2.1c0,0.1-0.1,0.2-0.2,0.2"/>
</g>
<g>
<path class="st0" d="M572.9,206.4c0.1,0.1,0.1,0.1,0.1,0.2c-0.1,0.4-0.1,0.9-0.2,1.3c0,0.1,0,0.1-0.1,0.1
c-0.4-0.1-0.9-0.1-1.4-0.2c-0.8-0.1-1.7-0.2-2.6-0.4c-0.7-0.1-1.4-0.2-2.2-0.3c-0.7-0.1-1.4-0.2-2.2-0.3c-0.7-0.1-1.2-0.2-1.9-0.2
c-0.2-0.1-0.6-0.1-0.8-0.1c-0.1,0-0.1-0.1-0.1-0.2c0.1-0.4,0.1-0.9,0.2-1.3c0-0.1,0.1-0.1,0.2-0.1c0.4,0.1,0.7,0.1,1.1,0.1
c0.8,0.1,1.6,0.2,2.4,0.4c0.7,0.1,1.5,0.2,2.3,0.3c0.8,0.1,1.7,0.2,2.5,0.4c0.8,0.1,1.6,0.2,2.4,0.4
C572.7,206.4,572.8,206.4,572.9,206.4z"/>
</g>
<g>
<path class="st0" d="M566.2,185.8c0.4,0.4,0.7,0.8,1.1,1.2c-0.4,0.3-0.7,0.6-1.1,0.9c-0.9,0.8-1.8,1.5-2.8,2.4
c-0.8,0.7-1.7,1.4-2.4,2.1c-0.7,0.6-1.4,1.2-2.1,1.8c-0.1,0.1-0.2,0.1-0.4-0.1c-0.2-0.3-0.5-0.6-0.8-0.9c-0.1-0.1-0.1-0.2,0-0.2
c0.5-0.4,1-0.9,1.5-1.3c0.6-0.5,1.2-1.1,1.8-1.5c0.9-0.8,1.9-1.6,2.8-2.4C564.7,187.1,565.5,186.4,566.2,185.8z"/>
</g>
<g>
<path class="st0" d="M561.7,225.3c-0.1,0.2-0.4,0.2-0.6,0.4c-0.2,0.1-0.4,0.2-0.6,0.4c-0.1,0.1-0.1,0.1-0.2,0.1
c-0.2-0.5-0.6-1-0.9-1.5c-1.1-1.7-2.1-3.5-3.2-5.2c-0.6-0.9-1.1-1.8-1.7-2.7c-0.1-0.1-0.1-0.2,0.1-0.2c0.4-0.2,0.7-0.4,1.1-0.7
c0.1-0.1,0.2-0.1,0.2,0.1c1.5,2.4,3,4.9,4.5,7.4C560.8,223.9,561.2,224.6,561.7,225.3z"/>
</g>
<g>
<path class="st0" d="M523.2,215.2c-0.2-0.5-0.5-1-0.7-1.4c0.7-0.4,1.4-0.7,2.2-1c2-0.9,4-1.8,6-2.7c0.6-0.3,1.2-0.6,1.9-0.9
c0.1-0.1,0.2-0.1,0.2,0.1c0.2,0.4,0.4,0.8,0.5,1.2c0.1,0.1,0.1,0.1-0.1,0.2c-2.1,0.9-4,1.9-6.1,2.8c-1.1,0.5-2.3,1.1-3.4,1.5
C523.6,215.1,523.4,215.2,523.2,215.2z"/>
</g>
<g>
<path class="st0" d="M570.3,191.9c0.2,0.5,0.5,1,0.7,1.4c-0.4,0.2-0.7,0.4-1.1,0.5c-1,0.5-2,0.9-3,1.4c-1.5,0.7-3,1.4-4.6,2.1
c-0.5,0.2-1,0.4-1.5,0.7c-0.1,0.1-0.2,0.1-0.2-0.1c-0.2-0.4-0.4-0.8-0.6-1.2c-0.1-0.1,0-0.1,0.1-0.2c1.6-0.7,3.2-1.5,4.9-2.2
c1.2-0.5,2.3-1.1,3.5-1.6c0.6-0.2,1.1-0.5,1.7-0.7C570.3,192,570.3,192,570.3,191.9z"/>
</g>
</g>
<g>
<g>
<g>
<path class="st0" d="M599.3,214.7c0-8.1,2.2-14.5,6.5-19c4.3-4.6,9.9-6.8,16.8-6.8c4.5,0,8.6,1.1,12.2,3.2c3.6,2.1,6.4,5.2,8.3,9
c1.9,3.9,2.9,8.2,2.9,13.1c0,4.9-1,9.3-3,13.3c-2,3.9-4.8,6.8-8.5,8.9c-3.6,2-7.6,3-11.8,3c-4.6,0-8.7-1.1-12.3-3.3
c-3.6-2.2-6.4-5.2-8.2-9.1C600.2,223,599.3,219,599.3,214.7z M605.9,214.8c0,5.9,1.6,10.5,4.8,13.9c3.2,3.4,7.1,5.1,11.9,5.1
c4.9,0,8.9-1.7,12-5.1c3.2-3.4,4.7-8.3,4.7-14.5c0-4-0.7-7.4-2-10.4s-3.3-5.2-5.9-6.9c-2.6-1.6-5.5-2.4-8.7-2.4
c-4.6,0-8.5,1.5-11.8,4.7C607.6,202.2,605.9,207.4,605.9,214.8z"/>
</g>
<g>
<path class="st0" d="M622.7,241.4c-4.9,0-9.4-1.2-13.4-3.6s-7-5.8-9-10c-2-4-3-8.3-3-13.1c0-8.6,2.4-15.5,7.1-20.4
c4.7-4.9,10.9-7.5,18.3-7.5c4.9,0,9.3,1.2,13.3,3.5c3.9,2.3,7,5.6,9.1,9.8c2,4.2,3.1,8.9,3.1,14s-1.1,9.9-3.2,14.2
c-2.3,4.3-5.3,7.6-9.3,9.8C631.6,240.3,627.3,241.4,622.7,241.4z M622.7,191c-6.4,0-11.4,2-15.4,6.2c-4,4.1-6,10.1-6,17.6
c0,4.1,0.8,7.8,2.6,11.2c1.7,3.5,4.2,6.3,7.4,8.3c3.3,2,7.1,3,11.2,3c3.9,0,7.6-1,10.8-2.8c3.3-1.8,5.8-4.5,7.7-8
c1.8-3.6,2.7-7.8,2.7-12.3c0-4.6-0.9-8.6-2.6-12.2c-1.7-3.5-4.3-6.2-7.4-8.1C630.5,191.9,626.9,191,622.7,191z M622.6,235.8
c-5.4,0-9.9-1.9-13.5-5.7c-3.5-3.7-5.3-8.9-5.3-15.3c0-7.9,1.9-13.7,5.7-17.3c3.6-3.5,8.1-5.3,13.2-5.3c3.6,0,6.9,1,9.8,2.7
c2.9,1.9,5.2,4.5,6.7,7.8c1.5,3.2,2.2,6.9,2.2,11.3c0,6.8-1.8,12.2-5.2,16C632.6,233.8,628,235.8,622.6,235.8z M622.7,196.4
c-4.1,0-7.4,1.4-10.4,4.1c-2.9,2.8-4.3,7.6-4.3,14.3c0,5.3,1.4,9.5,4.2,12.4c2.7,3,6.1,4.4,10.4,4.4s7.7-1.4,10.5-4.5
c2.7-3,4.2-7.4,4.2-13.1c0-3.7-0.6-6.8-1.8-9.5c-1.2-2.6-2.9-4.5-5.1-6C628.1,197.1,625.5,196.4,622.7,196.4z"/>
</g>
</g>
<g>
<g>
<path class="st0" d="M693.7,221.3l6.4,1.6c-1.4,5.3-3.8,9.3-7.3,12.1s-7.8,4.2-12.9,4.2c-5.2,0-9.5-1.1-12.8-3.2
c-3.3-2.1-5.8-5.2-7.5-9.3c-1.7-4-2.6-8.4-2.6-13.1c0-5.1,1-9.5,2.9-13.3c2-3.8,4.7-6.7,8.3-8.6s7.5-2.9,11.8-2.9
c4.9,0,9,1.2,12.3,3.7c3.3,2.5,5.7,6,7,10.5l-6.4,1.5c-1.1-3.6-2.8-6.1-4.9-7.7c-2.1-1.6-4.9-2.4-8.1-2.4c-3.7,0-6.9,0.9-9.4,2.7
c-2.5,1.8-4.3,4.2-5.3,7.3c-1,3-1.5,6.1-1.5,9.3c0,4.2,0.6,7.8,1.8,10.9c1.2,3.1,3.1,5.4,5.7,7c2.6,1.5,5.3,2.3,8.3,2.3
c3.6,0,6.7-1.1,9.2-3.2C691,228.5,692.8,225.4,693.7,221.3z"/>
</g>
<g>
<path class="st0" d="M679.9,241.3c-5.7,0-10.4-1.2-13.9-3.6c-3.6-2.4-6.4-5.8-8.3-10.2c-1.8-4.2-2.7-8.9-2.7-13.9
c0-5.5,1.1-10.2,3.2-14.2c2.1-4.2,5.2-7.3,9.1-9.5c3.8-2.1,8.2-3.2,12.9-3.2c5.3,0,9.9,1.4,13.6,4.2c3.7,2.8,6.3,6.7,7.7,11.5
l0.6,2.1l-10.4,2.4l-0.6-1.8c-1-3.1-2.4-5.4-4.2-6.7c-1.8-1.4-4.1-2-6.8-2c-3.3,0-6.1,0.8-8.2,2.3c-2.1,1.5-3.7,3.6-4.5,6.2
c-1,2.9-1.4,5.8-1.4,8.7c0,3.9,0.5,7.3,1.7,10.1c1,2.6,2.6,4.6,4.8,6c2.3,1.4,4.6,2,7.2,2c3.1,0,5.7-0.9,7.9-2.7
c2.1-1.8,3.6-4.6,4.4-8.2l0.5-2.1l10.5,2.6l-0.5,2c-1.5,5.7-4.2,10.2-8,13.3C690.2,239.8,685.4,241.3,679.9,241.3z M680,190.9
c-4,0-7.6,0.9-10.8,2.7c-3.2,1.8-5.7,4.3-7.4,7.7c-1.8,3.4-2.7,7.6-2.7,12.3c0,4.5,0.8,8.5,2.4,12.3c1.5,3.6,3.8,6.4,6.7,8.3
s6.8,2.9,11.7,2.9c4.7,0,8.5-1.2,11.6-3.7c2.7-2.1,4.7-5.2,6-9l-2.3-0.6c-1.1,3.5-2.9,6.3-5.2,8.4c-2.9,2.4-6.4,3.6-10.5,3.6
c-3.3,0-6.5-0.9-9.3-2.6c-3-1.8-5.2-4.5-6.5-8c-1.2-3.3-1.9-7.3-1.9-11.7c0-3.4,0.5-6.7,1.7-10c1.1-3.5,3.2-6.2,6.1-8.3
c2.9-2,6.4-3.1,10.6-3.1c3.7,0,6.8,1,9.3,2.9c2.1,1.6,3.8,3.9,5,7l2.3-0.5c-1.2-3-3-5.5-5.5-7.3C688.1,192,684.4,190.9,680,190.9
z"/>
</g>
</g>
<g>
<g>
<path class="st0" d="M707.2,238.5l18.7-48.8h7l19.9,48.8h-7.4l-5.7-14.8h-20.4l-5.4,14.8H707.2z M721.3,218.4h16.5l-5.1-13.5
c-1.5-4.1-2.7-7.5-3.5-10.1c-0.6,3.2-1.5,6.2-2.6,9.3L721.3,218.4z"/>
</g>
<g>
<path class="st0" d="M729.4,187.6h5l21.7,53h-11.9l-5.7-14.8h-17.5l-5.4,14.8h-11.2l20.2-53h4 M746.9,236.4h2.9l-18.2-44.6h-1
l0.7,2.4c0.8,2.9,2,6.3,3.4,10l6.2,16.3h-22.6l6.4-17.1c1.1-3.2,2-6.1,2.5-9l0.5-2.7h-0.4l-17.1,44.6h2.3l5.4-14.8h23.3
L746.9,236.4z M724.4,216.3h10.5l-4-10.7c-0.4-1.2-0.8-2.3-1.2-3.5c-0.3,0.9-0.6,1.7-0.9,2.6L724.4,216.3z"/>
</g>
</g>
</g>
<g>
<path class="st1" d="M327.3,257c1.3-0.2,3-0.4,5.3-0.4c2.7,0,4.7,0.7,6,1.8c1.2,1,1.8,2.6,1.8,4.5c0,1.9-0.6,3.5-1.7,4.5
c-1.4,1.5-3.8,2.3-6.5,2.3c-0.8,0-1.5-0.1-2.2-0.2v8.5h-2.7V257z M330,267.3c0.6,0.2,1.4,0.2,2.3,0.2c3.3,0,5.4-1.6,5.4-4.5
c0-2.8-2-4.2-5-4.2c-1.2,0-2.1,0.1-2.6,0.2L330,267.3L330,267.3z"/>
<path class="st1" d="M352,278l-0.2-1.9h-0.1c-0.8,1.2-2.5,2.3-4.6,2.3c-3.1,0-4.6-2.2-4.6-4.4c0-3.7,3.3-5.7,9.2-5.7V268
c0-1.2-0.4-3.5-3.5-3.5c-1.4,0-2.9,0.4-4,1.1l-0.7-1.8c1.2-0.8,3.1-1.4,5-1.4c4.6,0,5.8,3.2,5.8,6.2v5.7c0,1.3,0.1,2.6,0.2,3.6H352
L352,278z M351.6,270.2c-3-0.1-6.5,0.5-6.5,3.5c0,1.8,1.2,2.7,2.6,2.7c2,0,3.3-1.2,3.7-2.6c0.1-0.3,0.2-0.6,0.2-0.9V270.2z"/>
<path class="st1" d="M359.2,267.6c0-1.8-0.1-3.3-0.1-4.8h2.4l0.1,3h0.1c0.7-2,2.4-3.3,4.2-3.3c0.3,0,0.5,0.1,0.8,0.1v2.6
c-0.3-0.1-0.6-0.1-1-0.1c-2,0-3.3,1.5-3.7,3.6c-0.1,0.4-0.1,0.8-0.1,1.3v8.1h-2.7V267.6z"/>
<path class="st1" d="M374.1,258.4v4.4h4v2.1h-4v8.2c0,1.9,0.5,3,2.1,3c0.7,0,1.2-0.1,1.6-0.2l0.1,2.1c-0.5,0.2-1.4,0.4-2.4,0.4
c-1.3,0-2.3-0.4-3-1.2c-0.8-0.8-1.1-2.2-1.1-4v-8.3H369v-2.1h2.4v-3.6L374.1,258.4z"/>
<path class="st1" d="M381.6,266.9c0-1.5-0.1-2.9-0.1-4.1h2.4l0.2,2.5h0.1c0.8-1.4,2.5-2.9,5.1-2.9c2.1,0,5.4,1.2,5.4,6.5v9.1h-2.8
v-8.8c0-2.4-0.9-4.5-3.5-4.5c-1.8,0-3.3,1.3-3.7,2.9c-0.1,0.4-0.2,0.8-0.2,1.3v9.2h-2.8L381.6,266.9L381.6,266.9z"/>
<path class="st1" d="M401.1,270.9c0.1,3.7,2.4,5.3,5.2,5.3c2,0,3.2-0.4,4.2-0.8l0.5,2c-1,0.4-2.7,1-5.1,1c-4.7,0-7.5-3.1-7.5-7.7
c0-4.6,2.7-8.2,7.1-8.2c5,0,6.3,4.4,6.3,7.2c0,0.6-0.1,1-0.1,1.3L401.1,270.9L401.1,270.9L401.1,270.9z M409.2,268.9
c0.1-1.8-0.7-4.5-3.9-4.5c-2.8,0-4,2.6-4.3,4.5H409.2z"/>
<path class="st1" d="M415.8,267.6c0-1.8-0.1-3.3-0.1-4.8h2.4l0.1,3h0.1c0.7-2,2.4-3.3,4.2-3.3c0.3,0,0.5,0.1,0.8,0.1v2.6
c-0.3-0.1-0.6-0.1-1-0.1c-2,0-3.3,1.5-3.7,3.6c-0.1,0.4-0.1,0.8-0.1,1.3v8.1h-2.7V267.6z"/>
</g>
<g>
<path class="st1" d="M614.7,277.4c-1,0.5-3,1-5.6,1c-6,0-10.5-3.8-10.5-10.8c0-6.7,4.5-11.2,11.1-11.2c2.7,0,4.3,0.6,5.1,1
l-0.7,2.3c-1-0.5-2.5-0.9-4.3-0.9c-5,0-8.3,3.2-8.3,8.7c0,5.2,3,8.6,8.2,8.6c1.7,0,3.4-0.4,4.5-0.9L614.7,277.4z"/>
<path class="st1" d="M631.9,270.3c0,5.7-3.9,8.1-7.6,8.1c-4.1,0-7.3-3-7.3-7.9c0-5.1,3.3-8.1,7.6-8.1
C629,262.4,631.9,265.6,631.9,270.3z M619.9,270.5c0,3.3,1.9,5.9,4.6,5.9c2.7,0,4.6-2.5,4.6-6c0-2.6-1.3-5.9-4.6-5.9
C621.2,264.5,619.9,267.6,619.9,270.5z"/>
<path class="st1" d="M635.9,266.9c0-1.5-0.1-2.9-0.1-4.1h2.4l0.2,2.5h0.1c0.8-1.4,2.5-2.9,5.1-2.9c2.1,0,5.4,1.2,5.4,6.5v9.1h-2.8
v-8.8c0-2.4-0.9-4.5-3.5-4.5c-1.8,0-3.3,1.3-3.7,2.9c-0.1,0.4-0.2,0.8-0.2,1.3v9.2h-2.8V266.9z"/>
<path class="st1" d="M657.1,258.4v4.4h4v2.1h-4v8.2c0,1.9,0.5,3,2.1,3c0.7,0,1.2-0.1,1.6-0.2l0.1,2.1c-0.5,0.2-1.4,0.4-2.4,0.4
c-1.3,0-2.3-0.4-3-1.2c-0.8-0.8-1.1-2.2-1.1-4v-8.3H652v-2.1h2.4v-3.6L657.1,258.4z"/>
<path class="st1" d="M664.6,267.6c0-1.8-0.1-3.3-0.1-4.8h2.4l0.1,3h0.1c0.7-2,2.4-3.3,4.2-3.3c0.3,0,0.5,0.1,0.8,0.1v2.6
c-0.3-0.1-0.6-0.1-1-0.1c-2,0-3.3,1.5-3.7,3.6c-0.1,0.4-0.1,0.8-0.1,1.3v8.1h-2.7V267.6z"/>
<path class="st1" d="M678.5,258.5c0.1,1-0.7,1.7-1.8,1.7c-1,0-1.7-0.8-1.7-1.7s0.7-1.7,1.7-1.7
C677.9,256.8,678.5,257.5,678.5,258.5z M675.4,278v-15.2h2.8V278H675.4z"/>
<path class="st1" d="M683.2,278c0.1-1,0.1-2.6,0.1-3.9v-18.4h2.7v9.6h0.1c1-1.7,2.7-2.8,5.2-2.8c3.8,0,6.5,3.2,6.4,7.8
c0,5.5-3.5,8.2-6.8,8.2c-2.2,0-4-0.8-5.1-2.9h-0.1l-0.1,2.5H683.2z M686,271.9c0,0.4,0.1,0.7,0.1,1c0.5,1.9,2.1,3.3,4.2,3.3
c2.9,0,4.6-2.4,4.6-5.9c0-3-1.6-5.7-4.5-5.7c-1.9,0-3.6,1.3-4.2,3.4c-0.1,0.3-0.2,0.7-0.2,1.1L686,271.9L686,271.9z"/>
<path class="st1" d="M714.4,273.9c0,1.5,0.1,3,0.1,4.2h-2.4l-0.2-2.5h-0.1c-0.7,1.2-2.3,2.9-5.1,2.9c-2.4,0-5.2-1.3-5.2-6.7v-8.9
h2.8v8.5c0,2.9,0.9,4.9,3.4,4.9c1.8,0,3.2-1.3,3.6-2.5c0.2-0.4,0.2-0.9,0.2-1.4v-9.3h2.8L714.4,273.9L714.4,273.9z"/>
<path class="st1" d="M722.8,258.4v4.4h4v2.1h-4v8.2c0,1.9,0.5,3,2.1,3c0.7,0,1.2-0.1,1.6-0.2l0.1,2.1c-0.5,0.2-1.4,0.4-2.4,0.4
c-1.3,0-2.3-0.4-3-1.2c-0.8-0.8-1.1-2.2-1.1-4v-8.3h-2.4v-2.1h2.4v-3.6L722.8,258.4z"/>
<path class="st1" d="M744,270.3c0,5.7-3.9,8.1-7.6,8.1c-4.1,0-7.3-3-7.3-7.9c0-5.1,3.3-8.1,7.6-8.1C741,262.4,744,265.6,744,270.3z
M731.9,270.5c0,3.3,1.9,5.9,4.6,5.9c2.7,0,4.6-2.5,4.6-6c0-2.6-1.3-5.9-4.6-5.9C733.3,264.5,731.9,267.6,731.9,270.5z"/>
<path class="st1" d="M747.9,267.6c0-1.8-0.1-3.3-0.1-4.8h2.4l0.1,3h0.1c0.7-2,2.4-3.3,4.2-3.3c0.3,0,0.5,0.1,0.8,0.1v2.6
c-0.3-0.1-0.6-0.1-1-0.1c-2,0-3.3,1.5-3.7,3.6c-0.1,0.4-0.1,0.8-0.1,1.3v8.1h-2.7V267.6L747.9,267.6z"/>
<path class="st1" d="M646.9,312.6c1.2,0.8,3,1.4,4.9,1.4c2.8,0,4.5-1.5,4.5-3.6c0-2-1.1-3.1-4-4.2c-3.5-1.2-5.6-3-5.6-6
c0-3.3,2.7-5.8,6.9-5.8c2.2,0,3.7,0.5,4.7,1l-0.8,2.3c-0.7-0.4-2.1-1-4-1c-2.9,0-4,1.7-4,3.2c0,2,1.3,3,4.2,4.1
c3.6,1.4,5.4,3.1,5.4,6.2c0,3.3-2.4,6.1-7.4,6.1c-2,0-4.3-0.6-5.4-1.4L646.9,312.6z"/>
<path class="st1" d="M663.2,305.6c0-2-0.1-3.5-0.1-5h2.5l0.1,2.6h0.1c1.1-1.8,2.9-3,5.4-3c3.7,0,6.5,3.1,6.5,7.7
c0,5.5-3.3,8.2-7,8.2c-2,0-3.8-0.9-4.7-2.4h-0.1v8.3h-2.7V305.6z M665.9,309.7c0,0.4,0.1,0.8,0.1,1.1c0.5,1.9,2.2,3.3,4.2,3.3
c2.9,0,4.6-2.4,4.6-5.9c0-3-1.6-5.7-4.5-5.7c-1.9,0-3.6,1.4-4.2,3.5c-0.1,0.4-0.2,0.8-0.2,1.1L665.9,309.7L665.9,309.7z"/>
<path class="st1" d="M695.4,308.1c0,5.7-3.9,8.1-7.6,8.1c-4.1,0-7.3-3-7.3-7.9c0-5.1,3.3-8.1,7.6-8.1
C692.4,300.3,695.4,303.4,695.4,308.1z M683.2,308.3c0,3.3,1.9,5.9,4.6,5.9c2.7,0,4.6-2.5,4.6-6c0-2.6-1.3-5.9-4.6-5.9
C684.7,302.4,683.2,305.4,683.2,308.3z"/>
<path class="st1" d="M699.3,304.8c0-1.5-0.1-2.9-0.1-4.1h2.4l0.2,2.5h0.1c0.8-1.4,2.5-2.9,5.1-2.9c2.1,0,5.4,1.2,5.4,6.5v9.1h-2.8
v-8.8c0-2.4-0.9-4.5-3.5-4.5c-1.8,0-3.3,1.3-3.7,2.9c-0.1,0.4-0.2,0.8-0.2,1.3v9.2h-2.8L699.3,304.8L699.3,304.8z"/>
<path class="st1" d="M716.9,313.1c0.8,0.5,2.3,1.1,3.6,1.1c2,0,3-1,3-2.3c0-1.3-0.8-2-2.9-2.8c-2.7-1-4-2.5-4-4.3
c0-2.4,2-4.5,5.2-4.5c1.5,0,2.9,0.4,3.7,1l-0.7,2c-0.6-0.4-1.7-0.9-3.1-0.9c-1.7,0-2.6,1-2.6,2.1c0,1.2,0.9,1.8,2.9,2.6
c2.7,1,4,2.3,4,4.6c0,2.7-2.1,4.6-5.7,4.6c-1.7,0-3.2-0.4-4.3-1L716.9,313.1z"/>
<path class="st1" d="M744,308.1c0,5.7-3.9,8.1-7.6,8.1c-4.1,0-7.3-3-7.3-7.9c0-5.1,3.3-8.1,7.6-8.1C741,300.3,744,303.4,744,308.1z
M731.9,308.3c0,3.3,1.9,5.9,4.6,5.9c2.7,0,4.6-2.5,4.6-6c0-2.6-1.3-5.9-4.6-5.9C733.3,302.4,731.9,305.4,731.9,308.3z"/>
<path class="st1" d="M747.9,305.4c0-1.8-0.1-3.3-0.1-4.8h2.4l0.1,3h0.1c0.7-2,2.4-3.3,4.2-3.3c0.3,0,0.5,0.1,0.8,0.1v2.6
c-0.3-0.1-0.6-0.1-1-0.1c-2,0-3.3,1.5-3.7,3.6c-0.1,0.4-0.1,0.8-0.1,1.3v8.2h-2.7V305.4L747.9,305.4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Server" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#039BE5;}
.st1{opacity:0.1;fill:#FFFFFF;enable-background:new ;}
.st2{opacity:5.000000e-02;enable-background:new ;}
.st3{fill:#303C42;}
.st4{opacity:0.1;enable-background:new ;}
.st5{opacity:0.2;enable-background:new ;}
.st6{fill:#69B342;}
.st7{fill:#C6CDD1;}
.st8{fill:url(#SVGID_1_);}
.st9{fill:url(#SVGID_2_);}
.st10{fill:url(#SVGID_3_);}
</style>
<circle class="st0" cx="11.1" cy="11.1" r="9.2"/>
<path class="st1" d="M11.1,2c-3.8,0-7,2.3-8.4,5.5h16.8C18.1,4.2,14.9,2,11.1,2z"/>
<path class="st2" d="M2.7,14.8c1.4,3.2,4.6,5.5,8.4,5.5s7-2.3,8.4-5.5H2.7z"/>
<path class="st1" d="M7.5,11.1C7.5,6.1,8.6,2,11.1,2C6.1,2,2,6.1,2,11.1s4.1,9.2,9.2,9.2C8.6,20.3,7.5,16.2,7.5,11.1z"/>
<path class="st2" d="M11.1,2c2.5,0,3.7,4.1,3.7,9.2s-1.1,9.2-3.7,9.2c5.1,0,9.2-4.1,9.2-9.2S16.2,2,11.1,2z"/>
<path class="st3" d="M6.5,16.2h14.7V18H6.5V16.2z"/>
<path class="st4" d="M6.5,16.2h14.7V18H6.5V16.2z"/>
<path class="st3" d="M21.2,16.6H6.5c-0.5,0-0.9-0.4-0.9-0.9V13c0-0.5,0.4-0.9,0.9-0.9h14.7c0.5,0,0.9,0.4,0.9,0.9v2.7
C22.1,16.2,21.7,16.6,21.2,16.6z"/>
<path class="st1" d="M21.2,12.1H6.5c-0.5,0-0.9,0.4-0.9,0.9v0.2c0-0.5,0.4-0.9,0.9-0.9h14.7c0.5,0,0.9,0.4,0.9,0.9V13
C22.1,12.5,21.7,12.1,21.2,12.1z"/>
<path class="st5" d="M21.2,16.4H6.5c-0.5,0-0.9-0.4-0.9-0.9v0.2c0,0.5,0.4,0.9,0.9,0.9h14.7c0.5,0,0.9-0.4,0.9-0.9v-0.2
C22.1,16,21.7,16.4,21.2,16.4z"/>
<path class="st3" d="M21.2,22.1H6.5c-0.5,0-0.9-0.4-0.9-0.9v-2.7c0-0.5,0.4-0.9,0.9-0.9h14.7c0.5,0,0.9,0.4,0.9,0.9v2.7
C22.1,21.7,21.7,22.1,21.2,22.1z"/>
<circle class="st6" cx="19.8" cy="19.8" r="0.5"/>
<circle class="st6" cx="18" cy="19.8" r="0.5"/>
<circle class="st6" cx="16.2" cy="19.8" r="0.5"/>
<circle class="st7" cx="7.9" cy="19.8" r="0.9"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="7.336" y1="6.7378" x2="8.3616" y2="5.7121" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<circle class="st8" cx="7.9" cy="19.8" r="0.9"/>
<circle class="st6" cx="19.8" cy="14.3" r="0.5"/>
<circle class="st6" cx="18" cy="14.3" r="0.5"/>
<circle class="st6" cx="16.2" cy="14.3" r="0.5"/>
<path class="st1" d="M21.2,17.6H6.5c-0.5,0-0.9,0.4-0.9,0.9v0.2c0-0.5,0.4-0.9,0.9-0.9h14.7c0.5,0,0.9,0.4,0.9,0.9v-0.2
C22.1,18,21.7,17.6,21.2,17.6z"/>
<path class="st5" d="M21.2,21.9H6.5c-0.5,0-0.9-0.4-0.9-0.9v0.2c0,0.5,0.4,0.9,0.9,0.9h14.7c0.5,0,0.9-0.4,0.9-0.9V21
C22.1,21.5,21.7,21.9,21.2,21.9z"/>
<circle class="st7" cx="7.9" cy="14.3" r="0.9"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="7.336" y1="12.2373" x2="8.3616" y2="11.2116" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<circle class="st9" cx="7.9" cy="14.3" r="0.9"/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="2.2175" y1="17.461" x2="23.5011" y2="7.5369" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<path class="st10" d="M22.1,15.7V13c0-0.5-0.4-0.9-0.9-0.9h-1c0-0.3,0-0.6,0-0.9c0-5.1-4.1-9.2-9.2-9.2S2,6.1,2,11.1
c0,3,1.4,5.6,3.7,7.3l0,0v2.7c0,0.5,0.4,0.9,0.9,0.9h14.7c0.5,0,0.9-0.4,0.9-0.9v-2.7c0-0.5-0.4-0.9-0.9-0.9v-0.9
C21.7,16.6,22.1,16.2,22.1,15.7z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
<style type="text/css">
.st0{fill:#29A1DC;}
.st1{fill:#FFFFFF;}
</style>
<circle class="st0" cx="100.5" cy="99.8" r="92.2"/>
<path class="st1" d="M113.4,127.1c0.6,0.3,0.7,1,0.2,1.5c-3.1,2.8-6.6,5.2-10.3,7.1c-6.6,3.2-13.8,4.8-21,4.7
c-7.2-0.3-14.3-2.2-20.4-5.7s-11.3-8.5-15.1-14.4c-3.7-5.9-5.8-12.6-6.4-19.4c-0.4-6.8,0.8-13.7,3.5-19.8c1.5-3,3.1-5.9,5.2-8.5
c2.1-2.6,4.5-5,7.1-7c5.2-4,11.4-6.7,17.8-7.8c-6.3,1.5-12.2,4.6-16.9,8.9c-2.4,2.1-4.5,4.5-6.2,7.1c-1.8,2.6-3.1,5.5-4.3,8.4
c-2.1,5.9-2.7,12.2-1.9,18.3c0.9,6.1,3.3,11.8,6.8,16.7c3.6,4.8,8.4,8.7,13.7,11.3c5.3,2.5,11.3,3.7,17,3.4c5.8-0.3,11.4-2,16.3-4.9
c1.9-1.2,3.8-2.5,5.4-4c0.3-0.3,0.7-0.3,1-0.1L113.4,127.1z"/>
<path class="st1" d="M131.5,143.1c0.4,0.4,0.3,1.1-0.1,1.4c-0.2,0.2-0.4,0.4-0.6,0.6c-2.6,2.3-5.4,4.4-8.3,6.3c-2.9,1.9-6,3.5-9.2,5
c-3.2,1.4-6.4,2.6-9.8,3.5c-13.3,3.6-27.7,2.9-40.4-1.9c-12.8-4.8-23.8-13.5-31.2-24.7c-7.4-11.1-11-24.4-10.6-37.6
c0.4-13.1,5.2-25.9,13.2-36.1c7.9-10.2,19-17.7,31.3-21.2c12.2-3.5,25.4-3.2,37.2,1c5.9,2.1,11.4,5.1,16.3,8.8s9.2,8.2,12.7,13.3
c-3.8-4.8-8.3-9-13.4-12.4c-5-3.4-10.6-6-16.4-7.7c-11.6-3.4-24.1-2.9-35.2,1c-11.2,3.9-20.9,11.4-27.5,21
c-6.6,9.5-10.1,21-9.8,32.4c0.3,11.4,4.2,22.6,10.9,31.5c6.7,8.9,16.3,15.5,26.7,18.7c10.5,3.3,21.8,3.1,32-0.3
c8.1-2.7,15.4-7.4,21.2-13.6c0.4-0.4,1.1-0.5,1.5-0.1c0.6,0.6,1.3,1.3,1.8,1.9C123.8,134,129.5,140.8,131.5,143.1z"/>
<path class="st1" d="M171.3,74.2l-35.9,43.7l2,4.1l4.1,8.6c0.7,1.5,0.4,3.3-0.8,4.5l-2.9,2.7c-0.2,0.2-0.4,0.2-0.7,0.2
c-0.1,0-0.2-0.1-0.3-0.2c0,0-0.1,0-0.1-0.1l-7.9-9.4c-0.8-0.9-1.6-1.8-2.5-2.6c-0.7-0.6-1.3-1.2-2.1-1.8c-1.4-1.1-2.9-2.2-4.6-3
c-0.3-0.2-0.5-0.3-0.8-0.4l-9.3-4.8l-1.7-0.9c-0.3-0.2-0.5-0.6-0.3-1l2-3.4c0.9-1.5,2.6-2.2,4.2-1.8l13.8,3.1l14-18.1L112.9,81
c-0.4-0.2-0.5-0.7-0.3-1l4.5-5.6c1.8-2.3,4.8-3.4,7.7-3l30.3,5.1l7.5-9.6c1.7-2.2,3.9-3.9,6.4-5l3.5-1.5c0.5-0.2,1-0.2,1.4-0.1
c0.3,0.1,0.5,0.2,0.7,0.3l0,0c0.5,0.5,0.9,1.2,0.7,2l-0.6,3.7C174.4,69.2,173.1,71.9,171.3,74.2z"/>
<g>
<path class="st1" d="M175.6,119.1l-4.5,5.6c-0.2,0.2-0.5,0.3-0.7,0.2c-0.1,0-0.3-0.1-0.4-0.3l-17.3-23.3l13.5-16.1l10.6,25.8
C177.9,113.7,177.5,116.8,175.6,119.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Server" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#D9DBDC;}
.st1{opacity:0.1;fill:#010101;enable-background:new ;}
.st2{opacity:0.2;fill:#FFFFFF;enable-background:new ;}
.st3{fill:#818181;}
.st4{fill:url(#SVGID_1_);}
.st5{fill:url(#SVGID_2_);}
.st6{fill:#333333;}
.st7{opacity:5.000000e-02;fill:#FFFFFF;enable-background:new ;}
.st8{fill:url(#SVGID_3_);}
.st9{fill:url(#SVGID_4_);}
.st10{fill:#00425A;}
.st11{fill:#27A0DA;}
</style>
<path class="st0" d="M1.1,14.7v1.8c0,1,0.8,1.8,1.8,1.8h6.4c0,0.7-0.2,1.9-0.6,2.5c-0.2,0.2-0.5,0.3-0.7,0.3s-0.5,0.2-0.5,0.5
S7.6,22,7.9,22h8.2c0.3,0,0.5-0.2,0.5-0.5s-0.2-0.5-0.5-0.5c-0.3,0-0.5-0.1-0.7-0.3c-0.5-0.5-0.6-1.7-0.6-2.5h6.4
c1,0,1.8-0.8,1.8-1.8v-1.8H1.1z"/>
<path class="st1" d="M21.1,18.2H2.9c-1,0-1.8-0.8-1.8-1.8v0.2c0,1,0.8,1.8,1.8,1.8h18.2c1,0,1.8-0.8,1.8-1.8v-0.3
C22.9,17.3,22.1,18.2,21.1,18.2z"/>
<path class="st2" d="M7.9,21.3h8.2c0.2,0,0.4,0.2,0.5,0.4v-0.1c0-0.3-0.2-0.5-0.5-0.5H7.9c-0.3-0.1-0.5,0.1-0.5,0.4v0.1
C7.6,21.4,7.7,21.3,7.9,21.3z"/>
<path class="st3" d="M12,17.7c-0.4,0-0.6-0.4-0.6-0.7c0-0.4,0.3-0.6,0.6-0.6s0.6,0.4,0.6,0.7C12.6,17.3,12.4,17.6,12,17.7z"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="11.3652" y1="-732.7223" x2="12.6001" y2="-733.298" gradientTransform="matrix(1 0 0 -1 0 -716)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<path class="st4" d="M12,17.7c-0.4,0-0.6-0.4-0.6-0.7c0-0.4,0.3-0.6,0.6-0.6s0.6,0.4,0.6,0.7C12.6,17.3,12.4,17.6,12,17.7z"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="10.8905" y1="-733.225" x2="14.6633" y2="-736.9988" gradientTransform="matrix(1 0 0 -1 0 -716)">
<stop offset="0" style="stop-color:#010101;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#010101;stop-opacity:0"/>
</linearGradient>
<path class="st5" d="M15.4,20.8c-0.5-0.5-0.6-1.7-0.6-2.5H9.3l2.7,2.7h4.1C15.8,21.1,15.5,21,15.4,20.8z"/>
<path class="st6" d="M22.9,3.8c0-1-0.8-1.8-1.8-1.8H2.9c-1,0-1.8,0.8-1.8,1.8v11.8h21.8V3.8z"/>
<path class="st7" d="M2.9,2.3h18.2c1,0,1.8,0.8,1.8,1.8V3.8c0-1-0.8-1.8-1.8-1.8H2.9c-1,0-1.8,0.8-1.8,1.8v0.3
C1.1,3,1.9,2.3,2.9,2.3z"/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="0.2378" y1="-721.2634" x2="23.3135" y2="-732.0244" gradientTransform="matrix(1 0 0 -1 0 -716)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<path class="st8" d="M21.1,2H2.9c-1,0-1.8,0.8-1.8,1.8v12.7c0,1,0.8,1.8,1.8,1.8h6.4c0,0.7-0.2,1.9-0.6,2.5
c-0.2,0.2-0.5,0.3-0.7,0.3s-0.5,0.2-0.5,0.5S7.6,22,7.9,22h8.2c0.3,0,0.5-0.2,0.5-0.5s-0.2-0.5-0.5-0.5c-0.3,0-0.5-0.1-0.7-0.3
c-0.5-0.5-0.6-1.7-0.6-2.5h6.4c1,0,1.8-0.8,1.8-1.8V3.8C22.9,2.8,22.1,2,21.1,2z"/>
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="1.7228" y1="746.1478" x2="22.4117" y2="755.7944" gradientTransform="matrix(1 0 0 1 0 -742)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<path class="st9" d="M22,3.7c0-0.5-0.4-0.8-0.7-0.8H2.7C2.4,2.9,2,3.3,2,3.7v11h20V3.7z"/>
<path class="st10" d="M6.7,13.8c-0.3,0-0.5-0.1-0.6-0.3c-0.4-0.4-0.4-1,0-1.4l3.1-3.1L6.1,5.9c-0.4-0.4-0.4-1,0-1.4
c0.4-0.4,1-0.4,1.4,0l3.8,3.8c0.4,0.4,0.4,1,0,1.4l-3.8,3.8C7.3,13.7,7,13.8,6.7,13.8z M17.3,13.8h-4.7c-0.5,0-0.9-0.5-0.9-0.9
s0.5-0.9,0.9-0.9h4.7c0.5,0,0.9,0.5,0.9,0.9S17.7,13.8,17.3,13.8z"/>
<g>
<path class="st11" d="M6.7,13.3c-0.3,0-0.5-0.1-0.6-0.3c-0.4-0.4-0.4-1,0-1.4l3.1-3.1L6.1,5.4c-0.4-0.4-0.4-1,0-1.4
c0.4-0.4,1-0.4,1.4,0l3.8,3.8c0.4,0.4,0.4,1,0,1.4l-3.8,3.8C7.3,13.2,7,13.3,6.7,13.3z"/>
</g>
<g>
<path class="st11" d="M17.3,13.3h-4.7c-0.5,0-0.9-0.5-0.9-0.9c0-0.5,0.5-0.9,0.9-0.9h4.7c0.5,0,0.9,0.5,0.9,0.9
S17.7,13.3,17.3,13.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Server" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#303C42;}
.st1{opacity:0.1;enable-background:new ;}
.st2{opacity:0.2;enable-background:new ;}
.st3{opacity:0.1;fill:#FFFFFF;enable-background:new ;}
.st4{fill:#428EB3;}
.st5{fill:#C6CDD1;}
.st6{fill:url(#SVGID_1_);}
.st7{fill:url(#SVGID_2_);}
.st8{fill:#29A1DC;}
.st9{opacity:0.2;fill:#FFFFFF;enable-background:new ;}
.st10{fill:url(#SVGID_3_);}
</style>
<path class="st0" d="M2,7.5h18.2v2.7H2V7.5z"/>
<path class="st1" d="M2,7.5h18.2v2.7H2V7.5z"/>
<path class="st0" d="M1.1,3.8v3.6C1.1,8,1.5,8.4,2,8.4h18.2c0.5,0,0.9-0.4,0.9-0.9V3.8c0-0.5-0.4-0.9-0.9-0.9H2
C1.5,2.9,1.1,3.3,1.1,3.8z"/>
<path class="st2" d="M20.2,8.1H2c-0.5,0-0.9-0.4-0.9-0.9v0.2C1.1,8,1.5,8.4,2,8.4h18.2c0.5,0,0.9-0.4,0.9-0.9V7.2
C21.1,7.7,20.7,8.1,20.2,8.1z"/>
<path class="st3" d="M20.2,2.9H2c-0.5,0-0.9,0.4-0.9,0.9v0.2c0-0.5,0.4-0.9,0.9-0.9h18.2c0.5,0,0.9,0.4,0.9,0.9V3.8
C21.1,3.3,20.7,2.9,20.2,2.9z"/>
<circle class="st4" cx="17.9" cy="5.6" r="0.5"/>
<circle class="st4" cx="16.1" cy="5.6" r="0.5"/>
<circle class="st4" cx="14.3" cy="5.6" r="0.5"/>
<circle class="st5" cx="4.7" cy="5.6" r="0.9"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="4.1628" y1="20.9292" x2="5.1788" y2="19.9133" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<circle class="st6" cx="4.7" cy="5.6" r="0.9"/>
<path class="st0" d="M1.1,10.2v3.6c0,0.5,0.4,0.9,0.9,0.9h18.2c0.5,0,0.9-0.4,0.9-0.9v-3.6c0-0.5-0.4-0.9-0.9-0.9H2
C1.5,9.3,1.1,9.7,1.1,10.2z"/>
<path class="st2" d="M20.2,14.5H2c-0.5,0-0.9-0.4-0.9-0.9v0.2c0,0.5,0.4,0.9,0.9,0.9h18.2c0.5,0,0.9-0.4,0.9-0.9v-0.2
C21.1,14.1,20.7,14.5,20.2,14.5z"/>
<path class="st3" d="M20.2,9.3H2c-0.5,0-0.9,0.4-0.9,0.9v0.2c0-0.5,0.4-0.9,0.9-0.9h18.2c0.5,0,0.9,0.4,0.9,0.9v-0.2
C21.1,9.7,20.7,9.3,20.2,9.3z"/>
<circle class="st4" cx="17.9" cy="12" r="0.5"/>
<circle class="st4" cx="16.1" cy="12" r="0.5"/>
<circle class="st4" cx="14.3" cy="12" r="0.5"/>
<circle class="st5" cx="4.7" cy="12" r="0.9"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="4.1628" y1="14.5738" x2="5.1788" y2="13.5578" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<circle class="st7" cx="4.7" cy="12" r="0.9"/>
<path class="st8" d="M22.4,13.8h-4.4l-0.9-0.9h-3.8c-0.3,0-0.5,0.2-0.5,0.5v7.3c0,0.3,0.2,0.5,0.5,0.5h9.1c0.3,0,0.5-0.2,0.5-0.5
v-6.4C22.9,14,22.7,13.8,22.4,13.8z"/>
<path class="st9" d="M22.4,13.8h-4.4l-0.9-0.9h-3.8c-0.3,0-0.5,0.2-0.5,0.5v0.2c0-0.3,0.2-0.5,0.5-0.5h3.8l0.9,0.9h4.4
c0.3,0,0.5,0.2,0.5,0.5v-0.2C22.9,14,22.7,13.8,22.4,13.8z"/>
<path class="st1" d="M22.4,20.9h-9.1c-0.3,0-0.5-0.2-0.5-0.5v0.2c0,0.3,0.2,0.5,0.5,0.5h9.1c0.3,0,0.5-0.2,0.5-0.5v-0.2
C22.9,20.6,22.7,20.9,22.4,20.9z"/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="0.7043" y1="21.5139" x2="25.1518" y2="10.1132" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<path class="st10" d="M22.4,13.8h-1.4v-3.6c0-0.5-0.4-0.9-0.9-0.9V8.4c0.5,0,0.9-0.4,0.9-0.9V3.8c0-0.5-0.4-0.9-0.9-0.9H2
c-0.5,0-0.9,0.4-0.9,0.9v3.6C1.1,8,1.5,8.4,2,8.4v0.9c-0.5,0-0.9,0.4-0.9,0.9v3.6c0,0.5,0.4,0.9,0.9,0.9h10.9v5.9
c0,0.3,0.2,0.5,0.5,0.5h9.1c0.3,0,0.5-0.2,0.5-0.5v-6.4C22.9,14,22.7,13.8,22.4,13.8z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

View File

@@ -0,0 +1,380 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Server" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:#173E51;}
.st2{fill:#51BCF0;}
.st3{fill:#29A1DC;}
.st4{fill:#1381B7;}
.st5{fill:#D1D6D8;}
.st6{fill:#C0C2C3;}
.st7{fill:url(#SVGID_24_);}
.st8{fill:#CECECE;}
.st9{fill:#727272;}
.st10{fill:url(#SVGID_25_);}
.st11{fill:url(#SVGID_26_);}
.st12{fill:url(#SVGID_27_);}
.st13{fill:url(#SVGID_28_);}
.st14{fill:url(#SVGID_29_);}
.st15{fill:url(#SVGID_30_);}
.st16{fill:url(#SVGID_31_);}
.st17{fill:url(#SVGID_32_);}
.st18{fill:url(#SVGID_33_);}
.st19{fill:url(#SVGID_34_);}
.st20{fill:url(#SVGID_35_);}
.st21{fill:url(#SVGID_36_);}
.st22{fill:url(#SVGID_37_);}
.st23{fill:url(#SVGID_38_);}
.st24{fill:url(#SVGID_39_);}
.st25{fill:url(#SVGID_40_);}
.st26{fill:url(#SVGID_41_);}
.st27{fill:url(#SVGID_42_);}
.st28{fill:url(#SVGID_43_);}
.st29{fill:url(#SVGID_44_);}
.st30{fill:url(#SVGID_45_);}
.st31{fill:url(#SVGID_46_);}
</style>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_1_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_10_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st2" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_11_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_12_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st2" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_13_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_14_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st2" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_15_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_16_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_17_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_18_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_19_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_2_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st3" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_20_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st3" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_21_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st4" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_22_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st5" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_23_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st2" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_3_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st4" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_4_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_5_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st5" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_6_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st6" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_7_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern y="24" width="37.5" height="40.5" patternUnits="userSpaceOnUse" id="SVGID_8_" viewBox="0 -40.5 37.5 40.5" style="overflow:visible;">
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<g>
<rect y="-40.5" class="st0" width="37.5" height="40.5"/>
<path class="st0" d="M0-40.5h37.5V0H0V-40.5z"/>
<path class="st2" d="M0-40.5h37.5V0H0V-40.5z"/>
</g>
</g>
</pattern>
<pattern y="24" width="103.5" height="99" patternUnits="userSpaceOnUse" id="SVGID_9_" viewBox="0 -99 103.5 99" style="overflow:visible;">
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<g>
<rect y="-99" class="st0" width="103.5" height="99"/>
<path class="st0" d="M0-99h103.5V0H0V-99z"/>
<path class="st1" d="M0-99h103.5V0H0V-99z"/>
</g>
</g>
</pattern>
<pattern id="SVGID_24_" xlink:href="#SVGID_1_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st7" d="M15.9,4.3h-1.6V4c0-0.4-0.3-0.7-0.8-0.7h-1.6c-0.1,0-0.2,0-0.2-0.1c0-0.1,0-0.3-0.1-0.4
c-0.2-0.5-0.7-0.9-1.3-0.9C9.9,1.8,9.4,2,9,2.3c-0.3,0.3-0.5,0.6-0.5,1c0,0,0,0,0,0c0,0-0.1,0-0.1,0H6.8C6.4,3.3,6,3.6,6,4v0.3H4.5
C3.7,4.3,3,4.9,3,5.8v14.6c0,0.8,0.7,1.5,1.5,1.5h11.4c0.8,0,1.5-0.7,1.5-1.5V5.8C17.4,4.9,16.7,4.3,15.9,4.3z M6.7,4
c0,0,0.1-0.1,0.2-0.1h1.6c0.2,0,0.4-0.1,0.6-0.2c0.1-0.1,0.2-0.3,0.2-0.5l0,0c0-0.2,0.1-0.3,0.3-0.5c0.3-0.2,0.6-0.3,0.9-0.3
c0.3,0.1,0.7,0.3,0.8,0.6c0,0.1,0,0.1,0,0.2c0,0.2,0.1,0.3,0.2,0.4c0.2,0.2,0.3,0.3,0.6,0.3h1.6c0.1,0,0.2,0.1,0.2,0.1v1.2
c0,0-0.1,0.1-0.2,0.1H6.8c-0.1,0-0.1,0-0.2-0.1C6.7,5.2,6.7,4,6.7,4z M16.8,20.4c0,0.5-0.4,0.9-0.9,0.9H4.5c0,0-0.1,0-0.1,0
s0,0-0.1,0s-0.1,0-0.1,0c0,0-0.1,0-0.1,0S4,21.2,4,21.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0,0-0.1-0.1-0.1
c0,0-0.1-0.1-0.1-0.1c-0.1-0.1-0.1-0.3-0.1-0.4V5.8c0-0.5,0.4-0.9,0.9-0.9h1.6v0.3c0,0.4,0.3,0.7,0.8,0.7h6.7c0.4,0,0.8-0.3,0.8-0.7
V4.9h1.6c0.2,0,0.3,0,0.4,0.1l0,0c0.1,0,0.1,0.1,0.2,0.1c0,0,0,0,0.1,0.1c0.1,0.1,0.1,0.1,0.1,0.2c0,0,0,0.1,0.1,0.1
c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1s0,0,0,0.1s0,0.1,0,0.1L16.8,20.4L16.8,20.4z"/>
<path class="st8" d="M16.8,5.7C16.8,5.7,16.8,5.7,16.8,5.7c0-0.1,0-0.1,0-0.2c0,0,0-0.1,0-0.1c0,0,0-0.1-0.1-0.1
c0-0.1-0.1-0.1-0.1-0.2C16.5,5.1,16.4,5,16.3,5l0,0c-0.1-0.1-0.3-0.1-0.4-0.1h-1.6v0.3c0,0.4-0.3,0.7-0.8,0.7H6.8
c-0.4,0-0.8-0.3-0.8-0.7V4.9H4.5C4,4.9,3.6,5.3,3.6,5.8v14.6c0,0.2,0,0.3,0.1,0.4c0,0,0,0.1,0.1,0.1c0,0.1,0,0.1,0.1,0.1
c0,0,0.1,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1c0,0,0.1,0,0.1,0.1c0.1,0,0.1,0,0.1,0.1c0,0,0.1,0,0.1,0s0,0,0.1,0s0.1,0,0.1,0h11.4
c0.5,0,0.9-0.4,0.9-0.9L16.8,5.7C16.8,5.7,16.8,5.7,16.8,5.7z M4.6,6.9c0-0.2,0.1-0.3,0.3-0.3h10.7c0.2,0,0.3,0.1,0.3,0.3v13.3
c0,0.2-0.1,0.3-0.3,0.3H4.8c-0.2,0-0.3-0.1-0.3-0.3L4.6,6.9L4.6,6.9z"/>
<path class="st9" d="M16.8,5.8v14.6c0,0.5-0.4,0.9-0.9,0.9H4.5c-0.3,0-0.7-0.2-0.8-0.5c0.1,0.1,0.3,0.1,0.4,0.1h11.4
c0.5,0,0.9-0.4,0.9-0.9V5.4c0-0.2,0-0.3-0.1-0.4C16.6,5.1,16.8,5.4,16.8,5.8z"/>
<pattern id="SVGID_25_" xlink:href="#SVGID_2_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st10" d="M13.7,4v1.2c0,0-0.1,0.1-0.2,0.1H6.8c-0.1,0-0.1,0-0.2-0.1V4c0,0,0.1-0.1,0.2-0.1h1.6c0.2,0,0.4-0.1,0.6-0.2
c0.1-0.1,0.2-0.3,0.2-0.5l0,0c0-0.2,0.1-0.3,0.3-0.5c0.3-0.2,0.6-0.3,0.9-0.3c0.3,0.1,0.7,0.3,0.8,0.6c0,0.1,0,0.1,0,0.2
c0,0.2,0.1,0.3,0.2,0.4c0.2,0.2,0.3,0.3,0.6,0.3L13.7,4C13.7,3.9,13.7,4,13.7,4z"/>
<pattern id="SVGID_26_" xlink:href="#SVGID_3_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st11" d="M13.7,4v1.2c0,0-0.1,0.1-0.2,0.1H6.8c-0.1,0-0.1,0-0.2-0.1V4.8H13c0.1,0,0.2,0,0.2-0.1V3.9h0.4
C13.7,3.9,13.7,4,13.7,4z"/>
<pattern id="SVGID_27_" xlink:href="#SVGID_4_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st12" d="M15.5,6.6H4.8c-0.2,0-0.3,0.1-0.3,0.3v13.3c0,0.2,0.1,0.3,0.3,0.3h10.7c0.2,0,0.3-0.1,0.3-0.3V6.9
C15.9,6.7,15.7,6.6,15.5,6.6L15.5,6.6z M15.2,19.9H5.2V7.2h10.1V19.9z"/>
<pattern id="SVGID_28_" xlink:href="#SVGID_5_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st13" d="M5.2,7.2v12.7h10.1V7.2H5.2z M8.6,18.8c0,0.2-0.1,0.3-0.3,0.3H6.8c-0.2,0-0.3-0.1-0.3-0.3v-1.5
c0-0.2,0.1-0.3,0.3-0.3h1.5c0.2,0,0.3,0.1,0.3,0.3V18.8z M8.6,15.8c0,0.2-0.1,0.3-0.3,0.3H6.8c-0.2,0-0.3-0.1-0.3-0.3v-1.5
c0-0.2,0.1-0.3,0.3-0.3h1.5c0.2,0,0.3,0.1,0.3,0.3V15.8z M8.6,12.8c0,0.2-0.1,0.3-0.3,0.3H6.8c-0.2,0-0.3-0.1-0.3-0.3v-1.5
c0-0.2,0.1-0.3,0.3-0.3h1.5c0.2,0,0.3,0.1,0.3,0.3V12.8z M8.6,9.8c0,0.2-0.1,0.3-0.3,0.3H6.8c-0.2,0-0.3-0.1-0.3-0.3V8.2
c0-0.2,0.1-0.3,0.3-0.3h1.5c0.2,0,0.3,0.1,0.3,0.3V9.8z M13.6,18.4H9.5c-0.2,0-0.3-0.1-0.3-0.3c0-0.2,0.1-0.3,0.3-0.3h4.1
c0.2,0,0.3,0.1,0.3,0.3C13.9,18.2,13.7,18.4,13.6,18.4z M13.6,15.4H9.5c-0.2,0-0.3-0.1-0.3-0.3s0.1-0.3,0.3-0.3h4.1
c0.2,0,0.3,0.1,0.3,0.3S13.7,15.4,13.6,15.4z M13.6,12.3H9.5c-0.2,0-0.3-0.1-0.3-0.3s0.1-0.3,0.3-0.3h4.1c0.2,0,0.3,0.1,0.3,0.3
S13.7,12.3,13.6,12.3z M13.6,9.3H9.5C9.3,9.3,9.2,9.2,9.2,9c0-0.2,0.1-0.3,0.3-0.3h4.1c0.2,0,0.3,0.1,0.3,0.3
C13.9,9.2,13.7,9.3,13.6,9.3z"/>
<pattern id="SVGID_29_" xlink:href="#SVGID_6_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st14" d="M15.2,7.2v12.7H5.2v-0.6h9.5V7.2H15.2z"/>
<pattern id="SVGID_30_" xlink:href="#SVGID_7_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st15" d="M8.3,8H6.8C6.7,8,6.5,8.1,6.5,8.3v1.5c0,0.2,0.1,0.3,0.3,0.3h1.5c0.2,0,0.3-0.1,0.3-0.3V8.3
C8.6,8.1,8.5,8,8.3,8z M8,9.5H7.1V8.6H8V9.5z"/>
<pattern id="SVGID_31_" xlink:href="#SVGID_8_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st16" d="M7.1,8.6H8v0.9H7.1V8.6z"/>
<pattern id="SVGID_32_" xlink:href="#SVGID_9_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st17" d="M8.3,11H6.8c-0.2,0-0.3,0.1-0.3,0.3v1.5c0,0.2,0.1,0.3,0.3,0.3h1.5c0.2,0,0.3-0.1,0.3-0.3v-1.5
C8.6,11.1,8.5,11,8.3,11z M8,12.5H7.1v-0.9H8V12.5z"/>
<pattern id="SVGID_33_" xlink:href="#SVGID_10_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st18" d="M7.1,11.6H8v0.9H7.1V11.6z"/>
<pattern id="SVGID_34_" xlink:href="#SVGID_11_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st19" d="M8.3,14H6.8c-0.2,0-0.3,0.1-0.3,0.3v1.5c0,0.2,0.1,0.3,0.3,0.3h1.5c0.2,0,0.3-0.1,0.3-0.3v-1.5
C8.6,14.2,8.5,14,8.3,14z M8,15.5H7.1v-0.9H8V15.5z"/>
<pattern id="SVGID_35_" xlink:href="#SVGID_12_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st20" d="M7.1,14.6H8v0.9H7.1V14.6z"/>
<pattern id="SVGID_36_" xlink:href="#SVGID_13_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st21" d="M8.3,17H6.8c-0.2,0-0.3,0.1-0.3,0.3l0,0v1.5c0,0.2,0.1,0.3,0.3,0.3h1.5c0.2,0,0.3-0.1,0.3-0.3v-1.5
C8.6,17.2,8.5,17,8.3,17z M8,18.6H7.1v-0.9H8V18.6z"/>
<pattern id="SVGID_37_" xlink:href="#SVGID_14_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st22" d="M7.1,17.7H8v0.9H7.1V17.7z"/>
<pattern id="SVGID_38_" xlink:href="#SVGID_15_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st23" d="M13.9,9c0,0.2-0.1,0.3-0.3,0.3H9.5C9.3,9.3,9.2,9.2,9.2,9c0-0.2,0.1-0.3,0.3-0.3h4.1C13.7,8.7,13.9,8.9,13.9,9
z"/>
<pattern id="SVGID_39_" xlink:href="#SVGID_16_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st24" d="M13.9,12.1c0,0.2-0.1,0.3-0.3,0.3H9.5c-0.2,0-0.3-0.1-0.3-0.3s0.1-0.3,0.3-0.3h4.1
C13.7,11.7,13.9,11.9,13.9,12.1z"/>
<pattern id="SVGID_40_" xlink:href="#SVGID_17_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st25" d="M13.9,15.1c0,0.2-0.1,0.3-0.3,0.3H9.5c-0.2,0-0.3-0.1-0.3-0.3s0.1-0.3,0.3-0.3h4.1
C13.7,14.8,13.9,14.9,13.9,15.1z"/>
<pattern id="SVGID_41_" xlink:href="#SVGID_18_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st26" d="M13.9,18.1c0,0.2-0.1,0.3-0.3,0.3H9.5c-0.2,0-0.3-0.1-0.3-0.3c0-0.2,0.1-0.3,0.3-0.3h4.1
C13.7,17.8,13.9,17.9,13.9,18.1z"/>
<pattern id="SVGID_42_" xlink:href="#SVGID_19_" patternTransform="matrix(1 0 0 1 -636.654 15918.918)">
</pattern>
<path class="st27" d="M21,19.3C21,19.3,20.9,19.3,21,19.3l0-9.4l0,0v0c0,0,0-0.1,0-0.1l0,0l-1-2.3c-0.1-0.1-0.2-0.2-0.3-0.2
s-0.2,0.1-0.3,0.2l-0.9,2.3l0,0c0,0,0,0,0,0.1s0,0,0,0.1l0,0l0,10.7c0,0.7,0.6,1.3,1.3,1.3l0,0h0.1c0.3,0,0.6-0.1,0.9-0.4
c0.2-0.2,0.4-0.5,0.4-0.9V19.3C20.9,19.3,20.9,19.3,21,19.3z M19.6,8.4l0.5,1.3h-1L19.6,8.4z M20.3,10.2l0,8.8H19l0-8.8
C19,10.3,20.3,10.2,20.3,10.2z M20.2,21.1c-0.1,0.1-0.3,0.2-0.4,0.2h-0.1c-0.2,0-0.3-0.1-0.4-0.2S19,20.8,19,20.7v-1h1.3v1
C20.4,20.8,20.3,21,20.2,21.1z"/>
<pattern id="SVGID_43_" xlink:href="#SVGID_20_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st28" d="M20.4,19H19l0-8.8h1.3L20.4,19z"/>
<pattern id="SVGID_44_" xlink:href="#SVGID_21_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st29" d="M20.4,19H19v-0.4h1.1l0-8.4h0.3L20.4,19z"/>
<pattern id="SVGID_45_" xlink:href="#SVGID_22_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st30" d="M20.2,9.7h-1l0.5-1.3L20.2,9.7z"/>
<pattern id="SVGID_46_" xlink:href="#SVGID_23_" patternTransform="matrix(1 0 0 1 -585.044 15869.5332)">
</pattern>
<path class="st31" d="M20.4,20.6c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2h-0.1c-0.2,0-0.3-0.1-0.4-0.2
c-0.1-0.1-0.2-0.3-0.2-0.4v-1h1.3V20.6z"/>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 KiB

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Server" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#29A1DC;}
.st1{clip-path:url(#SVGID_2_);fill:#7DBCE7;}
.st2{fill:#010101;}
.st3{fill:#F5CCB3;}
.st4{fill:#FFFFFF;}
.st5{fill:#AF5C51;}
.st6{fill:#C4E5D9;}
</style>
<path class="st0" d="M18.6,19.8c0,1.3-2.9,2.3-6.5,2.3s-6.5-1-6.5-2.3c0-1.3,2.9-2.3,6.5-2.3S18.6,18.5,18.6,19.8z"/>
<g>
<defs>
<path id="SVGID_1_" d="M9.3,23.8c0.1,0.7,0.5,1.1,0.8,1.3h3.7c0.5-0.3,0.9-0.9,0.9-2v-2.8c0,0,0.1-0.7,0.7-0.9c0,0,0.4-0.3,0-0.4
c0,0-1.8-0.1-1.8,1.3v2.1c0,0,0.1,0.8-0.3,1.1V21c0,0,0-0.8,0.5-1.2c0,0,0.3-0.5-0.3-0.4c0,0-1.2,0.2-1.3,1.6l0,2.7h-0.3l0-2.7
c-0.1-1.4-1.3-1.6-1.3-1.6c-0.6-0.1-0.3,0.4-0.3,0.4c0.4,0.3,0.5,1.2,0.5,1.2v2.7c-0.4-0.3-0.3-1.1-0.3-1.1v-2.1
c0-1.4-1.8-1.3-1.8-1.3c-0.4,0.1,0,0.4,0,0.4c0.6,0.2,0.7,0.9,0.7,0.9v2L9.3,23.8L9.3,23.8z"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<path class="st1" d="M18.6,19.8c0,1.3-2.9,2.3-6.5,2.3s-6.5-1-6.5-2.3c0-1.3,2.9-2.3,6.5-2.3S18.6,18.5,18.6,19.8z"/>
</g>
<path class="st0" d="M4.7,13.1l-0.2,0.6c0,0,0,0.2,0.2,0.3c0.2,0,0.2-0.2,0.2-0.3L4.7,13.1L4.7,13.1z"/>
<path class="st2" d="M23.5,10.4L23.5,10.4c-1.9-0.5-3.8-0.5-5-0.4c0.2-0.7,0.3-1.5,0.3-2.4c0-1.3-0.5-2.3-1.3-3.1
C17.6,4,17.8,3,17.3,1.8c0,0-0.9-0.3-2.9,1.1c-0.8-0.2-1.6-0.3-2.5-0.3c-0.9,0-1.8,0.1-2.7,0.4c-2.1-1.4-3-1.1-3-1.1
C5.7,3.3,6,4.4,6.1,4.6C5.4,5.4,5,6.4,5,7.6c0,0.9,0.1,1.7,0.4,2.4c-1.2,0-3.1,0-4.9,0.3l0,0.1C2.3,10,4.2,10,5.4,10
c0.1,0.1,0.1,0.3,0.2,0.4c-1.2,0-3.2,0.2-5.1,0.7l0,0.1c1.9-0.5,3.9-0.7,5.1-0.7c0.7,1.3,2.1,2.1,4.5,2.4c-0.4,0.2-0.7,0.6-0.8,1.3
c-0.5,0.2-2,0.8-2.9-0.8c0,0-0.5-0.9-1.5-1c0,0-0.9,0-0.1,0.6c0,0,0.6,0.3,1.1,1.4c0,0,0.6,1.9,3.3,1.3v1.9c0,0-0.1,0.7-0.7,0.9
c0,0-0.4,0.3,0,0.4c0,0,1.8,0.1,1.8-1.3v-2.1c0,0-0.1-0.8,0.3-1.1V18c0,0,0,0.8-0.5,1.2c0,0-0.3,0.5,0.3,0.4c0,0,1.2-0.2,1.3-1.6
l0-3.5h0.3l0,3.5c0.1,1.4,1.3,1.6,1.3,1.6c0.6,0.1,0.3-0.4,0.3-0.4c-0.4-0.3-0.5-1.2-0.5-1.2v-3.5c0.4,0.3,0.3,1.1,0.3,1.1v2.1
c0,1.4,1.8,1.3,1.8,1.3c0.4-0.1,0-0.4,0-0.4c-0.6-0.2-0.7-0.9-0.7-0.9v-2.8c0-1.1-0.5-1.7-0.9-2c2.6-0.3,3.9-1.1,4.4-2.4
c1.1,0,3.2,0.2,5.2,0.7l0-0.1c-2-0.6-4-0.7-5.2-0.7c0.1-0.1,0.1-0.3,0.1-0.4C19.7,10,21.6,10,23.5,10.4L23.5,10.4z"/>
<path class="st3" d="M16.2,7.5c0.6,0.5,0.9,1.1,0.9,1.8c0,3.1-2.3,3.2-5.2,3.2S6.8,12,6.8,9.3c0-0.7,0.3-1.3,0.9-1.8
c0.9-0.8,2.5-0.4,4.3-0.4S15.3,6.6,16.2,7.5L16.2,7.5z"/>
<path class="st4" d="M10.2,9.4c0,0.9-0.5,1.5-1.1,1.5s-1.1-0.7-1.1-1.5c0-0.9,0.5-1.5,1.1-1.5C9.7,7.9,10.2,8.6,10.2,9.4z"/>
<path class="st5" d="M9.9,9.5c0,0.6-0.3,1-0.7,1c-0.4,0-0.7-0.5-0.7-1c0-0.6,0.3-1,0.7-1C9.6,8.4,9.9,8.9,9.9,9.5z"/>
<path class="st4" d="M16,9.4c0,0.9-0.5,1.5-1.1,1.5c-0.6,0-1.1-0.7-1.1-1.5c0-0.9,0.5-1.5,1.1-1.5C15.5,7.9,16,8.6,16,9.4z"/>
<path class="st5" d="M15.6,9.5c0,0.6-0.3,1-0.7,1c-0.4,0-0.7-0.5-0.7-1c0-0.6,0.3-1,0.7-1C15.3,8.4,15.6,8.9,15.6,9.5z M12.2,10.8
c0,0.1-0.1,0.3-0.3,0.3c-0.1,0-0.3-0.1-0.3-0.3c0-0.2,0.1-0.3,0.3-0.3C12.1,10.5,12.2,10.7,12.2,10.8z M11.3,11.5c0,0,0-0.1,0.1-0.1
c0,0,0.1,0,0.1,0.1c0.1,0.2,0.3,0.3,0.5,0.3c0.2,0,0.4-0.1,0.5-0.3c0,0,0.1-0.1,0.1-0.1c0,0,0.1,0.1,0.1,0.1
c-0.1,0.3-0.3,0.4-0.6,0.4C11.7,11.9,11.4,11.8,11.3,11.5L11.3,11.5z"/>
<path class="st6" d="M5.4,12.7c0,0.1-0.1,0.1-0.2,0.1c-0.1,0-0.2-0.1-0.2-0.1s0.1-0.1,0.2-0.1C5.3,12.6,5.4,12.6,5.4,12.7z M5.9,13
c0,0.1-0.1,0.1-0.2,0.1c-0.1,0-0.2-0.1-0.2-0.1s0.1-0.1,0.2-0.1C5.8,12.9,5.9,12.9,5.9,13z M6.2,13.4c0,0.1-0.1,0.1-0.2,0.1
c-0.1,0-0.2-0.1-0.2-0.1c0-0.1,0.1-0.1,0.2-0.1C6.1,13.3,6.2,13.3,6.2,13.4z M6.5,13.8c0,0.1-0.1,0.1-0.2,0.1
c-0.1,0-0.2-0.1-0.2-0.1c0-0.1,0.1-0.1,0.2-0.1C6.4,13.7,6.5,13.7,6.5,13.8z M6.8,14.2c0,0.1-0.1,0.1-0.2,0.1
c-0.1,0-0.2-0.1-0.2-0.1c0-0.1,0.1-0.1,0.2-0.1C6.7,14.1,6.8,14.1,6.8,14.2z M7.2,14.6c0,0.1-0.1,0.1-0.2,0.1
c-0.1,0-0.2-0.1-0.2-0.1c0-0.1,0.1-0.1,0.2-0.1C7.2,14.4,7.2,14.5,7.2,14.6z M7.8,14.8c0,0.1-0.1,0.1-0.2,0.1
c-0.1,0-0.2-0.1-0.2-0.1c0-0.1,0.1-0.1,0.2-0.1C7.8,14.7,7.8,14.7,7.8,14.8z M8.5,14.8c0,0.1-0.1,0.1-0.2,0.1
c-0.1,0-0.2-0.1-0.2-0.1c0-0.1,0.1-0.1,0.2-0.1C8.4,14.7,8.5,14.7,8.5,14.8z M9.1,14.7c0,0.1-0.1,0.1-0.2,0.1
c-0.1,0-0.2-0.1-0.2-0.1c0-0.1,0.1-0.1,0.2-0.1C9,14.6,9.1,14.6,9.1,14.7z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1,690 @@
<section class="oe_container custom_style description-odoo-font">
<div id="wrap" class="oe_structure oe_empty">
<section class="s_text_block o_colored_level pb120 pt168 oe_img_bg o_bg_img_center" data-snippet="s_text_block" data-name="Text" style="background-image: url('tower_website.svg'); position: relative;">
<div class="container">
<div class="row">
<div class="col-lg-6">
<h2 style="color: #0D3045; font-weight: 500; font-size: 48px" data-bs-original-title="" title="" aria-describedby="tooltip483440">
<strong style="font-weight: 800; color: #29A1DC; vertical-align: text-bottom;">| </strong> What is Cetmix Tower?
<br/>
</h2>
<p style="font-size: 18px; font-weight:300">
<b>Cetmix Tower</b> is an <b>open-source</b> DevOps framework built on Odoo. <br/><br/>
It empowers you to deploy, manage, and automate applications <b>directly from Odoo</b> whether it's Odoo itself, WordPress, ERPNext or Magento.<br/><br/>
Unlike traditional hosting platforms, Cetmix Tower is <b>not tied to any specific technology</b>. You can use it with Docker, Kubernetes, a bare operating system or whatever your infrastructure requires.<br/><br/>
Fully <b>self-hosted</b> and deeply integrated with the Odoo ecosystem, it gives you complete control over your servers and applications. <br/><br/>
<b>Cetmix Tower</b> is distributed under the <b>AGPL-3 license</b>, ensuring transparency and freedom.
</p>
</div>
<div class="col-lg-6">
<img src="cetmix_tower_server_kanban.png" alt="" class="img img-fluid o_we_custom_image" data-original-id="1256" data-original-src="cetmix_tower_server_kanban.png" data-mimetype="image/png" style="width: 100% !important;" loading="eager"/>
</div>
</div>
</div>
</section>
<section class="s_text_image pb32 o_colored_level o_cc o_cc1" data-snippet="s_image_text" style="color: #343A40;" data-name="Custom Image - Text (2)" data-bs-original-title="" title="" aria-describedby="tooltip882751">
<div class="container">
<div class="row">
<div class="col-lg-6 table-responsive">
<h2 style="color: #0D3045; font-weight: 500; font-size: 48px"> <strong style="font-weight: 800; color: #29A1DC; vertical-align: text-bottom;">| </strong>Key Differences</h2>
<!-- Bootstrap 5 CSS -->
<table class="table table-striped align-middle border">
<thead>
<tr class="align-middle">
<th class="text-center"> </th>
<th class="text-center"><b>Cetmix Tower</b></th>
<th class="text-center">Odoo.sh</th>
<th class="text-center">Other Odoo Hosting</th>
<th class="text-center">Generic DevOps Tools</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-start">Can Deploy Odoo Enterprise</td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
</tr>
<tr>
<td class="text-start">Can Deploy Odoo Community</td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
</tr>
<tr>
<td class="text-start">Can Deploy Other Software besides Odoo</td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
</tr>
<tr>
<td class="text-start">Runs on Your Own Server</td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center">Some*</td>
</tr>
<tr>
<td class="text-start">Native Odoo App</td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
</tr>
<tr>
<td class="text-start">Export/Import &amp; Share Configurations</td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center">Some*</td>
</tr>
<tr>
<td class="text-start">Is Open Source</td>
<td class="text-center"><i class="fa fa-check text-success"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center"><i class="fa fa-close text-danger"></i></td>
<td class="text-center">Some*</td>
</tr>
</tbody>
</table>
<p class="small text-muted">* depends on the tool</p>
</div>
<div class="col-lg-6">
<h2 style="color: #0D3045; font-weight: 500; font-size: 48px"> <strong style="font-weight: 800; color: #29A1DC; vertical-align: text-bottom;">| </strong>Why Cetmix Tower?</h2>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li><strong>Easy to use for non-technical users:</strong> Deploy a server or run a multi-step scenario with a single click in the UI.</li>
<li><strong>Power and flexibility for technical users:</strong> Leverage powerful features to build complex workflows and automate server and application management tasks.</li>
<li><strong>Not limited to a single technology:</strong> Run any software manageable via shell commands or API, whether you're using Docker, Kubernetes, or direct OS commands.</li>
<li><strong>Odoo Integration:</strong> Take advantage of the Odoo ecosystem for server management tasks. Integrate with Sales, Accounting, Subscriptions, Helpdesk, or any other Odoo module.</li>
<li><strong>Not limited to Odoo:</strong> While optimized for Odoo, Cetmix Tower can manage virtually any software.</li>
<li><strong>Extensibility:</strong> Develop your own Odoo modules based on Cetmix Tower to implement custom features.</li>
<li><strong>Self-Hosting:</strong> Deploy Cetmix Tower on your own infrastructure for complete control over your server and application management.</li>
<li><strong>Open Source:</strong> Cetmix Tower is distributed under the AGPL-3 license, ensuring transparency and freedom.</li>
</ul>
</div>
</div>
<div class="container pt64">
<h2 class="pb32" style="color: #0D3045; font-weight: 500; font-size: 48px"><strong style="font-weight: 800; color: #29A1DC; vertical-align: text-bottom;">| </strong> Core Features</h2>
<div class="container">
<div class="pt32" style="margin-left: 40px; background-color:#0D3045; border-radius: 40px; padding: 24px;">
<p class="card-text text-800" style="font-size: 18px; font-weight:300; color: #d7dcdf !important; text-align: left;"><strong style="font-weight: 800; color: #29A1DC; vertical-align: text-bottom;">| </strong>Note</p>
<p class="card-text text-800 pb32" style="font-size: 18px; font-weight:300; color: #d7dcdf !important; text-align: left;">Cetmix Tower is designed with usability and simplicity in mind, though some features might require a foundational understanding of server management principles</p>
<h4 style="font-size: 24px; color: #ffffff; font-weight: 200;">
For documentation please check <strong style="font-size: 32px; font-weight: 800; color: #29A1DC;"> | </strong> <a href="https://tower.cetmix.com" style="color: #29A1DC;"> tower.cetmix.com</a>
</h4>
</div>
</div>
</div>
<div class="container pt64">
<h3 style="color: #0D3045; font-weight: 500; font-size: 48px"><img src="self-host.svg" style="height: 48px; margin-right: 10px; vertical-align: text-top;"/>Server Management</h3>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li>Variable-based flexible configuration</li>
<li>Create Servers using pre-defined Server Templates</li>
</ul>
<section
class="s_image_gallery pt24 pb24 o_colored_level o_spc-small o_masonry o_cc o_cc1"
data-vcss="001"
data-columns="2"
data-snippet="s_images_wall"
data-name="Images Wall"
style="overflow: hidden"
>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="server_1.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1218"
data-original-src="server_1.png"
data-mimetype="image/png"
data-resize-width="1920"
loading="eager"
title="Server Management"
aria-describedby="tooltip65859"
/>
<img
src="server_template_form.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1242"
data-original-src="server_template_form.png"
data-mimetype="image/png"
data-resize-width="1920"
data-bs-original-title=""
title="Server Management"
aria-describedby="tooltip990969"
loading="eager"
/>
</div>
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="server_form_configuration.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-id="1225"
data-original-src="server_form_configuration.png"
data-mimetype="image/png"
title="Server Management"
aria-describedby="tooltip997009"
/>
</div>
</div>
</div>
</section>
</div>
<div class="container pt64">
<h3 style="color: #0D3045; font-weight: 500; font-size: 48px"><img src="connectivity.svg" style="height: 48px; margin-right: 10px; vertical-align: text-top;"/>Connectivity</h3>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li>Password and key-based authentication for outgoing SSH connections</li>
<li>Built-in support of the Python requests library for outgoing API calls</li>
</ul>
</div>
<div class="container pt64">
<h3 style="color: #0D3045; font-weight: 500; font-size: 48px"><img src="development.svg" style="height: 48px; margin-right: 10px; vertical-align: text-top;"/>Commands</h3>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li>Execute SSH Commands on remote servers</li>
<li>Run Python Commands on the Tower Odoo server</li>
<li>Run Flight Plan from command</li>
<li>Render commands using Variables</li>
<li>Secrets/Keys for private data storage</li>
</ul>
<section
class="s_image_gallery pt24 pb24 o_colored_level o_spc-small o_masonry o_cc o_cc1"
data-vcss="001"
data-columns="2"
data-snippet="s_images_wall"
data-name="Images Wall"
style="overflow: hidden"
>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="commands_1.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1218"
data-original-src="commands_1.png"
data-mimetype="image/png"
data-resize-width="1920"
loading="eager"
title="Commands"
aria-describedby="tooltip65859"
/>
</div>
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="commands_2.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-id="1225"
data-original-src="commands_2.png"
data-mimetype="image/png"
title="Commands"
aria-describedby="tooltip997009"
/>
</div>
</div>
</div>
</section>
</div>
<div class="container pt64">
<h3 style="color: #0D3045; font-weight: 500; font-size: 48px"><img src="flight-plan.svg" style="height: 48px; margin-right: 10px; vertical-align: text-top;"/>Flight Plans</h3>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li>Execute multiple Commands in a row</li>
<li>Condition-based flow:</li>
<ul>
<li>Based on conditions using Python syntax</li>
<li>Based on the previous command exit code</li>
</ul>
</ul>
<section
class="s_image_gallery pt24 pb24 o_colored_level o_spc-small o_masonry o_cc o_cc1"
data-vcss="001"
data-columns="2"
data-snippet="s_images_wall"
data-name="Images Wall"
style="overflow: hidden"
>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="flight_plan_1.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1218"
data-original-src="flight_plan_1.png"
data-mimetype="image/png"
data-resize-width="1920"
loading="eager"
title="Flight Plans"
aria-describedby="tooltip65859"
/>
<img
src="flight_plan_3.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1242"
data-original-src="flight_plan_3.png"
data-mimetype="image/png"
data-resize-width="1920"
title="Flight Plans"
aria-describedby="tooltip990969"
loading="eager"
/>
</div>
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="flight_plan_2.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-id="1225"
data-original-src="flight_plan_2.png"
data-mimetype="image/png"
title="Flight Plans"
aria-describedby="tooltip997009"
/>
</div>
</div>
</div>
</section>
</div>
<div class="container pt64">
<h3 style="color: #0D3045; font-weight: 500; font-size: 48px"><img src="files.svg" style="height: 48px; margin-right: 10px; vertical-align: text-top;"/>Files</h3>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li>Download Files from a remote server using SFTP</li>
<li>Upload Files to a remote server using SFTP</li>
<li>Support for <code>text</code> and <code>binary</code> file formats</li>
<li>Manage Files using pre-defined File Templates</li>
</ul>
<section
class="s_image_gallery pt24 pb24 o_colored_level o_spc-small o_masonry o_cc o_cc1"
data-vcss="001"
data-columns="2"
data-snippet="s_images_wall"
data-name="Images Wall"
style="overflow: hidden"
>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="files_1.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1218"
data-original-src="files_1.png"
data-mimetype="image/png"
data-resize-width="1920"
loading="eager"
title="Files"
aria-describedby="tooltip65859"
/>
<img
src="files_3.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1242"
data-original-src="files_3.png"
data-mimetype="image/png"
data-resize-width="1920"
title="Files"
aria-describedby="tooltip990969"
loading="eager"
/>
</div>
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="files_2.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-id="1225"
data-original-src="files_2.png"
data-mimetype="image/png"
title="Files"
aria-describedby="tooltip997009"
/>
</div>
</div>
</div>
</section>
</div>
<div class="container pt64">
<h3 style="color: #0D3045; font-weight: 500; font-size: 48px"><img src="server-logs.svg" style="height: 48px; margin-right: 10px; vertical-align: text-top;"/>Server Logs</h3>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li>Fetch Logs from a remote server using Commands</li>
<li>Fetch Logs from a remote server using Files</li>
</ul>
<section
class="s_image_gallery pt24 pb24 o_colored_level o_spc-small o_masonry o_cc o_cc1"
data-vcss="001"
data-columns="2"
data-snippet="s_images_wall"
data-name="Images Wall"
style="overflow: hidden"
>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="logs_1.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1218"
data-original-src="logs_1.png"
data-mimetype="image/png"
data-resize-width="1920"
loading="eager"
title="Server Logs"
aria-describedby="tooltip65859"
/>
</div>
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="logs_2.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-id="1225"
data-original-src="logs_2.png"
data-mimetype="image/png"
title="Server Logs"
aria-describedby="tooltip997009"
/>
</div>
</div>
</div>
</section>
</div>
<div class="container pt64 pb64">
<h3 style="color: #0D3045; font-weight: 500; font-size: 48px"><img src="tools.svg" style="height: 48px; margin-right: 10px; vertical-align: text-top;"/>Import/Export Data in YAML Format</h3>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li>Share and manage data easily using YAML format</li>
</ul>
<section
class="s_image_gallery pt24 pb24 o_colored_level o_spc-small o_masonry o_cc o_cc1"
data-vcss="001"
data-columns="2"
data-snippet="s_images_wall"
data-name="Images Wall"
style="overflow: hidden"
>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="yaml_1.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1218"
data-original-src="yaml_1.png"
data-mimetype="image/png"
data-resize-width="1920"
loading="eager"
title="Import/Export Data in YAML Format"
aria-describedby="tooltip65859"
/>
<img
src="yaml_4.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1218"
data-original-src="yaml_4.png"
data-mimetype="image/png"
data-resize-width="1920"
loading="eager"
title="Import/Export Data in YAML Format"
aria-describedby="tooltip65859"
/>
</div>
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="yaml_3.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-src="yaml_3.png"
data-mimetype="image/png"
title="Import/Export Data in YAML Format"
/>
<img
src="yaml_5.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-src="yaml_5.png"
data-mimetype="image/png"
title="Import/Export Data in YAML Format"
/>
<img
src="yaml_2.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-src="yaml_2.png"
data-mimetype="image/png"
title="Import/Export Data in YAML Format"
/>
</div>
</div>
</div>
</section>
</div>
<div class="container pt64 pb64">
<h3 style="color: #0D3045; font-weight: 500; font-size: 48px"><img src="git.svg" style="height: 48px; margin-right: 10px; vertical-align: text-top;"/>Manage Git Projects</h3>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">
<li>
Manage Git projects directly from Odoo
</li>
<li>
User-friendly interface for controlling git repositories linked to your servers
</li>
</ul>
<section
class="s_image_gallery pt24 pb24 o_colored_level o_spc-small o_masonry o_cc o_cc1"
data-vcss="001"
data-columns="2"
data-snippet="s_images_wall"
data-name="Images Wall"
style="overflow: hidden"
>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="git_1.png"
alt=""
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
data-original-id="1218"
data-original-src="git_1.png"
data-mimetype="image/png"
data-resize-width="1920"
loading="eager"
title="Git Projects"
aria-describedby="tooltip65859"
/>
</div>
<div class="o_masonry_col o_snippet_not_selectable col-lg-6">
<img
src="git_2.png"
class="img-fluid d-block rounded shadow mb16 o_visible img o_we_custom_image"
loading="eager"
data-original-src="git_2.png"
data-mimetype="image/png"
title="Git Projects"
/>
</div>
</div>
</div>
</section>
</div>
</div>
</section>
<section class="s_text_image o_colored_level pt64 pb64 o_cc o_cc5 " data-snippet="s_image_text" style="background-color: #0D3045 !important; background-image: none; position: relative; border-top-right-radius: 40px; border-top-left-radius: 40px;" data-name="Custom Image - Text" data-bs-original-title="" title="" aria-describedby="tooltip522920" data-oe-shape-data="{&quot;shape&quot;:&quot;web_editor/Origins/16&quot;,&quot;colors&quot;:{&quot;c3&quot;:&quot;#0D2945&quot;},&quot;flip&quot;:[]}">
<div class="container" style="padding: 30px;">
<div class="col-lg-6" style="text-align: right; margin-left: auto;">
<img src="cetmix.svg" alt="" class="img img-fluid o_we_custom_image" data-original-id="1256" data-original-src="cetmix.svg" data-mimetype="image/svg+xml" data-bs-original-title="" title="" aria-describedby="tooltip359107" style="width: 50% !important;" loading="eager"/>
</div>
<h3 class="pt64" style="color: #ffffff; font-weight: 500; font-size: 48px"><strong style="font-weight: 800; color: #29A1DC; vertical-align: text-bottom;">| </strong> Warning</h3>
<p class="card-text text-800" style="font-size: 18px; font-weight:300; color: #ffffff !important; text-align: left;">
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.
</p>
</div>
</section>
<section class="s_title o_colored_level o_cc o_cc1" style="position: relative; background-color: #0D3045 !important">
<div style="background-color: #3d4856 !important; border-top-right-radius: 40px; border-top-left-radius: 40px; padding: 20px;">
&nbsp;
</div>
</section>
<section class="s_features o_colored_level pb64 o_cc o_cc1" data-snippet="s_features" data-name="Features" style="position: relative; background-color: #3d4856 !important" data-oe-shape-data="">
<div class="container mx-3">
<h2 style="font-size: 48px; font-weight:500; color: #d7dcdf;">License</h2>
<p class="card-text text-800" style="font-size: 18px; font-weight:300; color: #d7dcdf !important; text-align: left;">Cetmix Tower is distributed under the AGPL-3 license. In case you want to use this software in projects that are not compatible with AGPL-3 license, you should contact us directly.</p>
</div>
</section>
<section class="s_title o_colored_level o_cc o_cc1" style="position: relative; background-color: #3d4856">
<div style="background-color: #d7dcdf !important; border-top-right-radius: 40px; border-top-left-radius: 40px; padding: 20px;">
&nbsp;
</div>
</section>
<section class="s_text_block o_colored_level pt32 pb64 o_cc o_cc1" data-snippet="s_text_block" data-name="Text" style="position: relative; background-color: #d7dcdf !important; color: #3d4856;">
<div class="container mx-3">
<h2 style="font-size: 48px; font-weight:500; color: #3d4856;">Copyright</h2>
<p class="card-text text-800" style="font-size: 18px; font-weight:300; color: #3d4856 !important; text-align: left;">Cetmix Tower is a trademark of Cetmix. All rights reserved.</p>
</div>
</section>
<section class="s_title o_colored_level o_cc o_cc1" style="position: relative; background-color: #d7dcdf">
<div style="background-color: #3d4856 !important; border-top-right-radius: 40px; border-top-left-radius: 40px; padding: 20px;">
&nbsp;
</div>
</section>
<section class="s_text_block o_colored_level pt32 pb64 o_cc o_cc1" data-snippet="s_text_block" data-name="Text" style="position: relative; background-color: #3d4856 !important; color: #3d4856;">
<div class="container mx-3">
<h2 style="font-size: 48px; font-weight:500; color: #d7dcdf;">Support</h2>
<ul class="card-text text-800" style="font-size: 18px; font-weight:300; color: #d7dcdf !important; text-align: left;">
<li>This project is open source. All issues and feature requests should be reported in the GitHub repository</li>
<li>Your contribution is welcome. Please refer to the CONTRIBUTING.md file for more details.</li>
<li>Dedicated support is available on request. Contact us for details at cetmix.com</li>
</ul>
</div>
</section>
<section class="s_title o_colored_level o_cc o_cc1" style="position: relative; background-color: #3d4856">
<div style="background-color: #f4f4f4 !important; border-top-right-radius: 40px; border-top-left-radius: 40px; padding: 20px;">
&nbsp;
</div>
</section>
<section id="cetmix" class="s_text_image o_colored_level pt64 pb64 o_cc o_cc5" data-snippet="s_image_text" style="background-color: #f4f4f4 !important; background-image: none; position: relative;" data-name="Custom Image - Text" data-bs-original-title="" title="" aria-describedby="tooltip522920">
<div class="container">
<div class="row align-items-center">
<div class="pt16 pb16 o_colored_level col-lg-4" style="position: relative;">
<img src="cx_logo.svg" alt="" class="img img-fluid mx-auto o_we_custom_image" style="position: relative;" data-original-id="1229" data-original-src="pdf.svg" data-mimetype="image/svg+xml" data-resize-width="undefined" loading="eager"/>
</div>
<div class="pb16 o_colored_level col-lg-8" >
<h1 style="text-align: left; color:#0D3045; font-size: 48px; font-weight:500;">
Cetmix is not just another IT company
</h1>
<h5 class="pt32" style="text-align: left; color:#3d4856; font-size: 22px; font-weight:300">
We know how the business works. Our experts have management
experience in heavy machinery, energy sector, logistics,
accounting, public services and many other industries _
<br/>
<br/>
We are the people of business
</h5>
</div>
</div>
</div>
</section>
<section class="s_title o_colored_level o_cc o_cc1" style="position: relative; background-color: #f4f4f4">
<div style="background-color: #29A1DC !important; border-top-right-radius: 40px; border-top-left-radius: 40px; padding: 20px;">
&nbsp;
</div>
</section>
<section class="s_call_to_action pt48 pb64 o_colored_level o_cc o_cc5" data-snippet="s_call_to_action" data-name="Call to Action" style="background-color: #29A1DC; color: #ffffff;">
<div class="container" style="margin-left: 100px">
<div class="row o_header_white_border_left">
<div class="col-lg-6 pb16 o_colored_level">
<h3 style="text-align: left; color:#ffffff; font-size: 48px; font-weight:500;">Solutions for your business</h3>
<h5 class="pt16" style="text-align: left; color:#3d4856; font-size: 22px; font-weight:300">Choose an existing one or we can develop a custom one for you</h5>
</div>
<div class="col pt32 o_colored_level">
<p style="text-align: center;" data-bs-original-title="" title="" aria-describedby="tooltip742456">
<a class="mb-2 btn btn-lg shadow" href="https://apps.odoo.com/apps/modules/browse?author=Cetmix" data-bs-original-title="" title="" style="color: #ffffff; border-color: #ffffff; border-radius:20px; font-size: 22px; font-weight:300">Check our Apps</a>
</p>
</div>
</div>
</div>
</section>
<section class="s_text_block o_colored_level o_cc o_cc5" data-snippet="s_text_block" data-name="Text" style="position: relative; background-color: #29A1DC; color: #ffffff; ">
<div class="s_allow_columns container-fluid">
<div class="row d-flex mx-3 pb64">
<div class="o_colored_level col-lg-4" >
<h2 style="text-align: center;">
<span style="color: #ffffff; font-size: 36px; font-weight:500;">>9 <br/> years</span>
</h2>
<h5 style="text-align: center; color:#3d4856; font-size: 22px; font-weight:300">of Odoo experience
</h5>
</div>
<div class="o_colored_level col-lg-4" >
<h2 style="text-align: center;">
<span style="color: #ffffff; font-size: 36px; font-weight:500;">> 15 000 <br/> downloads</span>
</h2>
<h5 style="text-align: center; color:#3d4856; font-size: 22px; font-weight:300">of our apps from Odoo App Store
</h5>
</div>
<div class="o_colored_level col-lg-3" >
<h2 style="text-align: center;">
<span style="color: #ffffff; font-size: 36px; font-weight:500;">>100 <br/> clients</span>
</h2>
<h5 style="text-align: center; color:#3d4856; font-size: 22px; font-weight:300">
are happy with our services
</h5>
</div>
</div>
</div>
</section>
<section class="s_title o_colored_level o_cc o_cc1" style="position: relative; background-color: #0D3045">
<div style="background-color: #29A1DC !important; border-bottom-right-radius: 40px; border-bottom-left-radius: 40px; padding: 20px;">
&nbsp;
</div>
</section>
<section class="s_text_block pt64 pb48 o_colored_level" data-snippet="s_text_block" data-name="Text" style="background-color: #0D3045 !important; border-bottom-right-radius: 40px; border-bottom-left-radius: 40px;" data-bs-original-title="" title="" aria-describedby="tooltip180671">
<div class="s_allow_columns container mx-5" data-bs-original-title="" title="" aria-describedby="tooltip154809">
<h2 style="text-align: left; color:#ffffff; font-size: 48px; font-weight:500;">
Need support, customization<br/>or interested in collaboration ?
</h2>
<h5 class="pb32" style="font-size: 24px; left; color: #ffffff;">
<strong style="font-weight: 800; color: #29A1DC; vertical-align: text-bottom;">| </strong>cetmix.com
<br/>
</h5>
<p style="color: #ffffff;">
<span class="fa fa-linkedin-square fa-3x pt16 mr-3" data-bs-original-title="" title="" aria-describedby="tooltip359279" style="color: #29A1DC !important;"></span>
https://www.linkedin.com/company/cetmix/
</p>
<p style="color: #ffffff;">
<span class="fa fa-github-square fa-3x pt16 mr-3" data-bs-original-title="" title="" aria-describedby="tooltip359279" style="color: #29A1DC !important;"></span>
https://github.com/cetmix/
</p>
<p style="color: #ffffff;">
<span class="fa fa-facebook-square fa-3x pt16 mr-3" data-bs-original-title="" title="" aria-describedby="tooltip359279" style="color: #29A1DC !important;"></span>
https://www.facebook.com//cetmixteam
</p>
<p style="color: #ffffff;">
<span class="fa fa-twitter-square fa-3x pt16 mr-3" data-bs-original-title="" title="" aria-describedby="tooltip359279" style="color: #29A1DC !important;"></span>
https://twitter.com/cetmix_team
</p>
</div>
</div>
</section>
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="Server"><path fill="#303c42" d="M2 7h20v3H2z" class="color303c42 svgShape"></path><path d="M2 7h20v3H2z" opacity=".1" fill="#000000" class="color000000 svgShape"></path><path fill="#303c42" d="M2 14h20v3H2z" class="color303c42 svgShape"></path><path d="M2 14h20v3H2z" opacity=".1" fill="#000000" class="color000000 svgShape"></path><path fill="#303c42" d="M1 3v4a1 1 0 0 0 1 1h20a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1z" class="color303c42 svgShape"></path><path d="M22 7.75H2a1 1 0 0 1-1-1V7a1 1 0 0 0 1 1h20a1 1 0 0 0 1-1v-.25a1 1 0 0 1-1 1z" opacity=".2" fill="#000000" class="color000000 svgShape"></path><path fill="#ffffff" d="M22 2H2a1 1 0 0 0-1 1v.25a1 1 0 0 1 1-1h20a1 1 0 0 1 1 1V3a1 1 0 0 0-1-1z" opacity=".1" class="colorffffff svgShape"></path><circle cx="19.5" cy="5" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="17.5" cy="5" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="15.5" cy="5" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="5" cy="5" r="1" fill="#29a1dc" class="colorc6cdd1 svgShape"></circle><linearGradient id="a" x1="4.368" x2="5.487" y1="4.368" y2="5.487" gradientUnits="userSpaceOnUse"><stop offset="0" stop-opacity=".1"></stop><stop offset="1" stop-opacity="0"></stop></linearGradient><circle cx="5" cy="5" r="1" fill="url(#a)"></circle><path fill="#303c42" d="M1 10v4a1 1 0 0 0 1 1h20a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1z" class="color303c42 svgShape"></path><path d="M22 14.75H2a1 1 0 0 1-1-1V14a1 1 0 0 0 1 1h20a1 1 0 0 0 1-1v-.25a1 1 0 0 1-1 1z" opacity=".2" fill="#000000" class="color000000 svgShape"></path><path fill="#ffffff" d="M22 9H2a1 1 0 0 0-1 1v.25a1 1 0 0 1 1-1h20a1 1 0 0 1 1 1V10a1 1 0 0 0-1-1z" opacity=".1" class="colorffffff svgShape"></path><circle cx="19.5" cy="12" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="17.5" cy="12" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="15.5" cy="12" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="5" cy="12" r="1" fill="#29a1dc" class="colorc6cdd1 svgShape"></circle><linearGradient id="b" x1="4.368" x2="5.487" y1="11.368" y2="12.487" gradientUnits="userSpaceOnUse"><stop offset="0" stop-opacity=".1"></stop><stop offset="1" stop-opacity="0"></stop></linearGradient><circle cx="5" cy="12" r="1" fill="url(#b)"></circle><path fill="#303c42" d="M1 17v4a1 1 0 0 0 1 1h20a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1z" class="color303c42 svgShape"></path><path d="M22 21.75H2a1 1 0 0 1-1-1V21a1 1 0 0 0 1 1h20a1 1 0 0 0 1-1v-.25a1 1 0 0 1-1 1z" opacity=".2" fill="#000000" class="color000000 svgShape"></path><path fill="#ffffff" d="M22 16H2a1 1 0 0 0-1 1v.25a1 1 0 0 1 1-1h20a1 1 0 0 1 1 1V17a1 1 0 0 0-1-1z" opacity=".1" class="colorffffff svgShape"></path><circle cx="19.5" cy="19" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="17.5" cy="19" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="15.5" cy="19" r=".5" fill="#428eb3" class="color69b342 svgShape"></circle><circle cx="5" cy="19" r="1" fill="#29a1dc" class="colorc6cdd1 svgShape"></circle><linearGradient id="c" x1="4.368" x2="5.487" y1="18.368" y2="19.487" gradientUnits="userSpaceOnUse"><stop offset="0" stop-opacity=".1"></stop><stop offset="1" stop-opacity="0"></stop></linearGradient><circle cx="5" cy="19" r="1" fill="url(#c)"></circle><linearGradient id="d" x1="-.568" x2="24.568" y1="6.14" y2="17.86" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffffff" stop-opacity=".2" class="stopColorffffff svgShape"></stop><stop offset="1" stop-color="#ffffff" stop-opacity="0" class="stopColorffffff svgShape"></stop></linearGradient><path fill="url(#d)" d="M23 7V3a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1v1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1v1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h20a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1v-1a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1V8a1 1 0 0 0 1-1z"></path></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Server" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#303C42;}
.st1{opacity:0.1;enable-background:new ;}
.st2{opacity:0.1;fill:#FFFFFF;enable-background:new ;}
.st3{opacity:0.2;enable-background:new ;}
.st4{fill:#428EB3;}
.st5{fill:#C6CDD1;}
.st6{fill:url(#SVGID_1_);}
.st7{fill:url(#SVGID_2_);}
.st8{fill:#D8DBDC;}
.st9{fill:#333333;}
.st10{fill:#4D4D4D;}
.st11{fill:url(#SVGID_3_);}
.st12{opacity:0.2;fill:#FFFFFF;enable-background:new ;}
.st13{fill:#29A1DC;}
.st14{fill:url(#SVGID_4_);}
.st15{fill:url(#SVGID_5_);}
.st16{fill:url(#SVGID_6_);}
</style>
<path class="st0" d="M2.8,6h14.7v1.8H2.8V6z"/>
<path class="st1" d="M2.8,6h14.7v1.8H2.8V6z"/>
<path class="st0" d="M17.5,6.5H2.8C2.3,6.5,1.8,6,1.8,5.5V2.8c0-0.5,0.4-0.9,0.9-0.9h14.7c0.5,0,0.9,0.4,0.9,0.9v2.8
C18.4,6,18,6.5,17.5,6.5z"/>
<path class="st2" d="M17.5,1.9H2.8c-0.5,0-0.9,0.4-0.9,0.9V3c0-0.5,0.4-0.9,0.9-0.9h14.7c0.5,0,0.9,0.4,0.9,0.9V2.8
C18.4,2.3,18,1.9,17.5,1.9z"/>
<path class="st3" d="M17.5,6.2H2.8c-0.5,0-0.9-0.4-0.9-0.9v0.2c0,0.5,0.4,0.9,0.9,0.9h14.7c0.5,0,0.9-0.4,0.9-0.9V5.3
C18.4,5.8,18,6.2,17.5,6.2z"/>
<path class="st0" d="M17.5,12H2.8c-0.5,0-0.9-0.4-0.9-0.9V8.3c0-0.5,0.4-0.9,0.9-0.9h14.7c0.5,0,0.9,0.4,0.9,0.9v2.8
C18.4,11.6,18,12,17.5,12z"/>
<circle class="st4" cx="16.1" cy="9.7" r="0.5"/>
<circle class="st4" cx="14.3" cy="9.7" r="0.5"/>
<circle class="st4" cx="12.4" cy="9.7" r="0.5"/>
<circle class="st5" cx="4.1" cy="9.7" r="0.9"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="3.5643" y1="16.9049" x2="4.5946" y2="15.8746" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<circle class="st6" cx="4.1" cy="9.7" r="0.9"/>
<circle class="st4" cx="16.1" cy="4.2" r="0.5"/>
<circle class="st4" cx="14.3" cy="4.2" r="0.5"/>
<circle class="st4" cx="12.4" cy="4.2" r="0.5"/>
<path class="st2" d="M17.5,7.4H2.8c-0.5,0-0.9,0.4-0.9,0.9v0.2c0-0.5,0.4-0.9,0.9-0.9h14.7c0.5,0,0.9,0.4,0.9,0.9V8.3
C18.4,7.8,18,7.4,17.5,7.4z"/>
<path class="st3" d="M17.5,11.7H2.8c-0.5,0-0.9-0.4-0.9-0.9v0.2c0,0.5,0.4,0.9,0.9,0.9h14.7c0.5,0,0.9-0.4,0.9-0.9v-0.2
C18.4,11.3,18,11.7,17.5,11.7z"/>
<circle class="st5" cx="4.1" cy="4.2" r="0.9"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="3.5643" y1="22.4291" x2="4.5946" y2="21.3988" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<circle class="st7" cx="4.1" cy="4.2" r="0.9"/>
<path class="st8" d="M17,19.3c0-0.3-0.2-0.5-0.5-0.5c-0.3,0-0.5,0.2-0.5,0.5h-1.8c0-0.3-0.2-0.5-0.5-0.5s-0.5,0.2-0.5,0.5
c0,1-0.5,1.8-0.9,1.8v0.5H18v-0.5C17.5,21.2,17,20.3,17,19.3z"/>
<path class="st9" d="M22.1,10.6c0-0.8-0.6-1.4-1.4-1.4h-11c-0.8,0-1.4,0.6-1.4,1.4V18h13.8V10.6z"/>
<path class="st8" d="M8.3,18v0.5c0,0.8,0.6,1.4,1.4,1.4h11c0.8,0,1.4-0.6,1.4-1.4V18H8.3z"/>
<path class="st1" d="M20.7,19.6h-11c-0.8,0-1.4-0.6-1.4-1.4v0.2c0,0.8,0.6,1.4,1.4,1.4h11c0.8,0,1.4-0.6,1.4-1.4v-0.2
C22.1,19,21.5,19.6,20.7,19.6z"/>
<path class="st2" d="M9.7,9.4h11c0.8,0,1.4,0.6,1.4,1.4v-0.2c0-0.8-0.6-1.4-1.4-1.4h-11c-0.8,0-1.4,0.6-1.4,1.4v0.2
C8.3,10.1,8.9,9.4,9.7,9.4z"/>
<path class="st10" d="M21.2,10.6c0-0.3-0.2-0.5-0.5-0.5h-11c-0.3,0-0.5,0.2-0.5,0.5V17h12V10.6z"/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="9.0616" y1="15.1862" x2="21.4007" y2="9.4328" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<path class="st11" d="M21.2,10.6c0-0.3-0.2-0.5-0.5-0.5h-11c-0.3,0-0.5,0.2-0.5,0.5V17h12V10.6z"/>
<path class="st8" d="M18,22.1h-5.5c-0.3,0-0.5-0.2-0.5-0.5c0-0.3,0.2-0.5,0.5-0.5H18c0.3,0,0.5,0.2,0.5,0.5
C18.4,21.9,18.2,22.1,18,22.1z"/>
<path class="st12" d="M12.4,21.4H18c0.2,0,0.4,0.1,0.4,0.3c0,0,0-0.1,0-0.1c0-0.3-0.2-0.5-0.5-0.5h-5.5c-0.3,0-0.5,0.2-0.5,0.5
c0,0,0,0.1,0,0.1C12,21.6,12.2,21.4,12.4,21.4z"/>
<circle class="st13" cx="15.2" cy="18.9" r="0.5"/>
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="14.7771" y1="7.3105" x2="15.6119" y2="6.9216" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<circle class="st14" cx="15.2" cy="18.9" r="0.5"/>
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="14.4175" y1="6.9761" x2="16.8002" y2="4.5933" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<path class="st15" d="M17.1,19.8h-3.8l1.4,1.4H18C17.6,21.2,17.2,20.6,17.1,19.8z"/>
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="0.5921" y1="20.7473" x2="23.4202" y2="10.102" gradientTransform="matrix(1 0 0 -1 0 26)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<path class="st16" d="M20.7,9.2h-2.3V8.3c0-0.5-0.4-0.9-0.9-0.9V6.5c0.5,0,0.9-0.4,0.9-0.9V2.8c0-0.5-0.4-0.9-0.9-0.9H2.8
c-0.5,0-0.9,0.4-0.9,0.9v2.8c0,0.5,0.4,0.9,0.9,0.9v0.9c-0.5,0-0.9,0.4-0.9,0.9v2.8c0,0.5,0.4,0.9,0.9,0.9h5.5v6.4
c0,0.8,0.6,1.4,1.4,1.4h3.6c-0.1,0.8-0.5,1.4-0.9,1.4c-0.3,0-0.5,0.2-0.5,0.5c0,0.3,0.2,0.5,0.5,0.5H18c0.3,0,0.5-0.2,0.5-0.5
c0-0.3-0.2-0.5-0.5-0.5c-0.4,0-0.8-0.6-0.9-1.4h3.6c0.8,0,1.4-0.6,1.4-1.4v-7.8C22.1,9.8,21.5,9.2,20.7,9.2z"/>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Server" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#303C42;}
.st1{opacity:0.1;enable-background:new ;}
.st2{opacity:0.2;enable-background:new ;}
.st3{opacity:0.1;fill:#FFFFFF;enable-background:new ;}
.st4{fill:#428EB3;}
.st5{fill:#C6CDD1;}
.st6{fill:url(#SVGID_1_);}
.st7{fill:url(#SVGID_2_);}
.st8{fill:none;}
.st9{fill:url(#SVGID_3_);}
.st10{fill:#29A1DC;}
.st11{fill:#EFF2F4;}
.st12{fill:#ACB5BA;}
.st13{fill:#CEDAE0;}
.st14{fill:#E6EBEE;}
.st15{fill:#3F5C6B;}
.st16{fill:#22353F;}
.st17{fill:#2B424E;}
.st18{fill:#324F5E;}
</style>
<path class="st0" d="M2,7.5h18.2v2.7H2V7.5z"/>
<path class="st1" d="M2,7.5h18.2v2.7H2V7.5z"/>
<path class="st0" d="M1.1,3.8v3.6c0,0.6,0.4,1,0.9,1h18.2c0.5,0,0.9-0.4,0.9-0.9V3.8c0-0.5-0.4-0.9-0.9-0.9H2
C1.5,2.9,1.1,3.3,1.1,3.8z"/>
<path class="st2" d="M20.2,8.1H2c-0.5,0-0.9-0.4-0.9-0.9v0.2c0,0.6,0.4,1,0.9,1h18.2c0.5,0,0.9-0.4,0.9-0.9V7.2
C21.1,7.7,20.7,8.1,20.2,8.1z"/>
<path class="st3" d="M20.2,2.9H2c-0.5,0-0.9,0.4-0.9,0.9V4c0-0.5,0.4-0.9,0.9-0.9h18.2c0.5,0,0.9,0.4,0.9,0.9V3.8
C21.1,3.3,20.7,2.9,20.2,2.9z"/>
<circle class="st4" cx="17.9" cy="5.6" r="0.5"/>
<circle class="st4" cx="16.1" cy="5.6" r="0.5"/>
<circle class="st4" cx="14.3" cy="5.6" r="0.5"/>
<circle class="st5" cx="4.7" cy="5.6" r="0.9"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="4.1668" y1="-1953.0668" x2="5.1828" y2="-1954.0828" gradientTransform="matrix(1 0 0 -1 0 -1948)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<circle class="st6" cx="4.7" cy="5.6" r="0.9"/>
<path class="st0" d="M1.1,10.2v3.6c0,0.5,0.4,0.9,0.9,0.9h18.2c0.5,0,0.9-0.4,0.9-0.9v-3.6c0-0.5-0.4-0.9-0.9-0.9H2
C1.5,9.3,1.1,9.7,1.1,10.2z"/>
<path class="st2" d="M20.2,14.5H2c-0.5,0-0.9-0.4-0.9-0.9v0.2c0,0.5,0.4,0.9,0.9,0.9h18.2c0.5,0,0.9-0.4,0.9-0.9v-0.2
C21.1,14.1,20.7,14.5,20.2,14.5z"/>
<path class="st3" d="M20.2,9.3H2c-0.5,0-0.9,0.4-0.9,0.9v0.2c0-0.5,0.4-0.9,0.9-0.9h18.2c0.5,0,0.9,0.4,0.9,0.9v-0.2
C21.1,9.7,20.7,9.3,20.2,9.3z"/>
<circle class="st4" cx="17.9" cy="12" r="0.5"/>
<circle class="st4" cx="16.1" cy="12" r="0.5"/>
<circle class="st4" cx="14.3" cy="12" r="0.5"/>
<circle class="st5" cx="4.7" cy="12" r="0.9"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="4.1445" y1="-1959.4445" x2="5.1605" y2="-1960.4604" gradientTransform="matrix(1 0 0 -1 0 -1948)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:0"/>
</linearGradient>
<circle class="st7" cx="4.7" cy="12" r="0.9"/>
<path class="st8" d="M19.1,13c0,0.4,0.3,0.7,0.7,0.8l0,0c0.4,0,0.8-0.3,0.8-0.8c0-0.4-0.3-0.7-0.7-0.8c0,0,0,0-0.1,0
C19.5,12.3,19.1,12.6,19.1,13L19.1,13z"/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="0.6335" y1="1978.4908" x2="25.081" y2="1989.8916" gradientTransform="matrix(1 0 0 1 0 -1974)">
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.2"/>
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
</linearGradient>
<path class="st9" d="M22.4,13.8H21v-3.6c0-0.5-0.4-0.9-0.9-0.9V8.4C20.6,8.4,21,8,21,7.5V3.8c0-0.5-0.4-0.9-0.9-0.9H2
C1.5,2.9,1,3.3,1,3.8v3.6c0,0.6,0.4,1,0.9,1v0.9C1.5,9.3,1,9.7,1,10.2v3.6c0,0.5,0.4,0.9,0.9,0.9h10.9v5.9c0,0.3,0.2,0.5,0.5,0.5
h9.1c0.3,0,0.5-0.2,0.5-0.5v-6.4C22.9,14,22.7,13.8,22.4,13.8z"/>
<path class="st10" d="M22.4,16.2c0,2.7-2.2,4.8-4.8,4.8c-2.7,0-4.8-2.1-4.8-4.8c0-2.7,2.2-4.8,4.8-4.8
C20.2,11.3,22.4,13.5,22.4,16.2z"/>
<path class="st11" d="M22,12.7l-0.5-0.1c0,0-0.1,0-0.1-0.1c0-0.2-0.1-0.3-0.2-0.5c0,0,0-0.1,0-0.1l0.2-0.4c0,0,0-0.1,0-0.1l-0.3-0.3
c0,0-0.1,0-0.1,0l-0.4,0.2c0,0-0.1,0-0.1,0c-0.1-0.1-0.3-0.1-0.4-0.2c0,0-0.1,0-0.1-0.1L20,10.6c0,0-0.1-0.1-0.1-0.1h-0.4
c0,0-0.1,0-0.1,0.1l-0.1,0.5c0,0,0,0.1-0.1,0.1c0,0-0.1,0-0.1,0c-0.1,0-0.2,0.1-0.2,0.1c0,0-0.1,0-0.1,0.1c0,0,0,0,0,0c0,0,0,0,0,0
c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0l-0.4-0.2c0,0-0.1,0-0.1,0l-0.2,0.2h0l-0.1,0.1h0c0,0,0,0,0,0.1c0,0,0,0.1,0,0.1l0.2,0.4
c0,0,0,0,0,0c0,0,0,0.1,0,0.1c-0.1,0.1-0.1,0.3-0.2,0.5c0,0,0,0.1-0.1,0.1l-0.5,0.1c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0.1v0.4
c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0l0.5,0.1c0,0,0.1,0,0.1,0.1c0,0.2,0.1,0.3,0.2,0.5c0,0,0,0.1,0,0.1l-0.2,0.4
c0,0,0,0.1,0,0.1c0,0,0,0,0,0.1h0l0.3,0.3c0,0,0.1,0,0.1,0l0.4-0.2c0,0,0,0,0,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0.1
c0.1,0,0.2,0.1,0.2,0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0.1l0.1,0.5c0,0,0.1,0.1,0.1,0.1h0.4c0.1,0,0.1,0,0.1-0.1l0.1-0.5
c0,0,0-0.1,0.1-0.1c0.2,0,0.3-0.1,0.4-0.2c0,0,0.1,0,0.1,0l0.4,0.2c0,0,0.1,0,0.1,0l0.3-0.3c0,0,0-0.1,0-0.1l-0.2-0.4
c0,0,0-0.1,0-0.1c0.1-0.1,0.1-0.3,0.2-0.5c0,0,0,0,0-0.1c0,0,0,0,0,0l0.5-0.1c0,0,0.1-0.1,0.1-0.1v-0.4C22.1,12.8,22.1,12.7,22,12.7
z M19.8,14.1c-0.1,0-0.3,0-0.4,0c-0.2,0-0.4-0.1-0.6-0.3c0,0,0,0,0,0c-0.1-0.2-0.2-0.3-0.2-0.5c0-0.1,0-0.3,0-0.4
c0-0.5,0.4-0.9,0.8-1c0.2,0,0.3-0.1,0.5,0c0,0,0,0,0,0c0.2,0,0.4,0.1,0.6,0.3c0,0,0,0,0,0c0.1,0.1,0.1,0.1,0.1,0.2l0,0
c0.1,0.1,0.1,0.3,0.1,0.4C20.9,13.4,20.4,14,19.8,14.1C19.8,14.1,19.8,14.1,19.8,14.1z"/>
<path class="st8" d="M18.9,13c0,0.4,0.3,0.7,0.7,0.8c0,0,0,0,0,0c0.4,0,0.8-0.3,0.8-0.8c0-0.4-0.3-0.7-0.7-0.8c0,0,0,0-0.1,0
C19.2,12.3,18.9,12.6,18.9,13L18.9,13z"/>
<path class="st12" d="M20.8,13c0-0.6-0.5-1.2-1.1-1.2c0.1,0.1,0.2,0.2,0.1,0.3c0,0.1-0.1,0.1-0.2,0.1c0.4,0,0.7,0.4,0.7,0.8
c0,0.4-0.3,0.8-0.8,0.8c0,0,0,0,0,0c-0.1,0-0.2,0.1-0.2,0.2c0,0.1,0.1,0.2,0.2,0.2c0,0,0,0,0.1,0C20.3,14.2,20.8,13.7,20.8,13z"/>
<path class="st13" d="M18.9,13.3c0-0.1-0.1-0.2-0.1-0.3c0-0.4,0.3-0.8,0.8-0.8c0,0,0,0,0.1,0c0.1,0,0.2-0.2,0.2-0.3
c0-0.1-0.1-0.1-0.1-0.2c0,0-0.1,0-0.1,0c-0.7,0-1.2,0.5-1.2,1.2c0,0.1,0,0.2,0,0.3C18.5,13.3,18.9,13.3,18.9,13.3z"/>
<path class="st13" d="M19.7,13.8C19.7,13.8,19.6,13.8,19.7,13.8c-0.5,0-0.8-0.3-0.8-0.8c0,0,0,0,0-0.1h-0.5c0,0,0,0,0,0.1
c0,0.7,0.5,1.2,1.2,1.2c0,0,0,0,0.1,0c0.1,0,0.2-0.1,0.2-0.2C19.9,13.9,19.8,13.8,19.7,13.8z"/>
<path class="st8" d="M20.5,13c0,0.5-0.4,0.8-0.8,0.9c0,0,0,0,0,0c-0.5,0-0.9-0.4-0.9-0.9c0-0.5,0.3-0.8,0.8-0.8c0,0,0,0,0.1,0
C20.1,12.2,20.5,12.6,20.5,13L20.5,13z"/>
<path class="st14" d="M19.2,14.8c-0.6-0.4-1-1-1-1.8c0-0.8,0.4-1.4,1-1.8v-0.1c-0.2,0-0.3,0.1-0.5,0.2c0,0-0.1,0-0.1,0l-0.4-0.2
c0,0-0.1,0-0.1,0l-0.3,0.3c0,0,0,0.1,0,0.1l0.2,0.4c0,0,0,0.1,0,0.1c-0.1,0.1-0.1,0.3-0.2,0.5c0,0,0,0.1-0.1,0.1l-0.5,0.1
c0,0-0.1,0.1-0.1,0.1v0.4c0,0.1,0,0.1,0.1,0.1l0.5,0.1c0,0,0.1,0,0.1,0.1c0,0.2,0.1,0.3,0.2,0.5c0,0,0,0.1,0,0.1l-0.2,0.4
c0,0,0,0.1,0,0.1l0.3,0.3c0,0,0.1,0,0.1,0l0.4-0.2c0,0,0.1,0,0.1,0C18.8,14.8,19,14.9,19.2,14.8L19.2,14.8L19.2,14.8z"/>
<path class="st15" d="M23,18.3l-0.3-0.1c0,0-0.1,0-0.1-0.1c0-0.1-0.1-0.2-0.1-0.3c0,0,0-0.1,0-0.1l0.2-0.3c0,0,0-0.1,0-0.1l-0.2-0.2
c0,0-0.1,0-0.1,0l-0.3,0.2c0,0-0.1,0-0.1,0c-0.1-0.1-0.2-0.1-0.3-0.1c0,0-0.1,0-0.1-0.1l-0.1-0.3c0,0,0-0.1-0.1-0.1h-0.3
c0,0-0.1,0-0.1,0.1l-0.1,0.3c0,0,0,0-0.1,0.1c0,0,0,0-0.1,0c-0.1,0-0.1,0-0.2,0.1c0,0-0.1,0-0.1,0c0,0,0,0,0,0c0,0,0,0,0,0
c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0l-0.3-0.2c0,0-0.1,0-0.1,0l-0.2,0.2h0l0,0h0c0,0,0,0,0,0c0,0,0,0,0,0.1l0.2,0.3c0,0,0,0,0,0
c0,0,0,0,0,0.1c-0.1,0.1-0.1,0.2-0.1,0.3c0,0,0,0-0.1,0.1l-0.3,0.1c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0v0.3c0,0,0,0,0,0
c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0l0.3,0.1c0,0,0.1,0,0.1,0.1c0,0.1,0.1,0.2,0.1,0.3c0,0,0,0.1,0,0.1l-0.2,0.3c0,0,0,0,0,0.1
c0,0,0,0,0,0h0l0.2,0.2c0,0,0.1,0,0.1,0l0.3-0.2c0,0,0,0,0,0c0,0,0,0,0.1,0c0,0,0.1,0,0.1,0c0.1,0,0.1,0.1,0.2,0.1c0,0,0,0,0.1,0
c0,0,0.1,0,0.1,0.1l0.1,0.3c0,0,0,0.1,0.1,0.1h0.3c0,0,0.1,0,0.1-0.1l0.1-0.3c0,0,0-0.1,0.1-0.1c0.1,0,0.2-0.1,0.3-0.1
c0,0,0.1,0,0.1,0l0.3,0.2c0,0,0.1,0,0.1,0l0.2-0.2c0,0,0-0.1,0-0.1l-0.2-0.3c0,0,0-0.1,0-0.1c0.1-0.1,0.1-0.2,0.1-0.3c0,0,0,0,0,0
c0,0,0,0,0,0l0.3-0.1c0,0,0.1,0,0.1-0.1L23,18.3C23.1,18.3,23.1,18.3,23,18.3L23,18.3z M21.4,19.3c-0.1,0-0.2,0-0.3,0
c-0.1,0-0.3-0.1-0.5-0.2c0,0,0,0,0,0c-0.1-0.1-0.2-0.3-0.2-0.4c0-0.1,0-0.2,0-0.3c0-0.4,0.3-0.7,0.6-0.8c0.1,0,0.2,0,0.4,0
c0,0,0,0,0,0c0.1,0,0.3,0.1,0.4,0.2c0,0,0,0,0,0c0,0.1,0.1,0.1,0.1,0.2l0,0c0,0.1,0.1,0.2,0.1,0.3C22.2,18.8,21.9,19.3,21.4,19.3
C21.4,19.3,21.4,19.3,21.4,19.3L21.4,19.3z"/>
<path class="st8" d="M20.7,18.5c0,0.3,0.2,0.5,0.5,0.6c0,0,0,0,0,0c0.3,0,0.6-0.3,0.6-0.6c0-0.3-0.2-0.5-0.5-0.6c0,0,0,0,0,0
C20.9,18,20.7,18.2,20.7,18.5z"/>
<path class="st16" d="M22.2,18.5c0-0.5-0.4-0.9-0.8-0.9c0.1,0,0.1,0.1,0.1,0.2c0,0-0.1,0.1-0.1,0.1c0.3,0,0.5,0.3,0.5,0.6
c0,0.3-0.3,0.6-0.6,0.6c0,0,0,0,0,0c-0.1,0-0.1,0.1-0.1,0.2c0,0.1,0.1,0.1,0.1,0.2c0,0,0,0,0,0C21.8,19.4,22.2,19,22.2,18.5
L22.2,18.5z"/>
<path class="st17" d="M21.3,17.6c-0.1,0-0.2,0-0.2,0V18c0.1,0,0.1,0,0.2,0c0.3,0,0.5,0.2,0.6,0.5c0-0.1,0.1-0.2,0.2-0.1
c0.1,0,0.1,0.1,0.1,0.1c0,0,0,0,0,0C22.1,18,21.7,17.6,21.3,17.6L21.3,17.6z"/>
<path class="st16" d="M20.7,18.7c0-0.1,0-0.1,0-0.2c0-0.3,0.3-0.6,0.6-0.6c0,0,0,0,0,0c0.1,0,0.2-0.1,0.1-0.2c0-0.1-0.1-0.1-0.1-0.1
c0,0,0,0-0.1,0c-0.5,0-0.9,0.4-0.9,0.9c0,0.1,0,0.2,0,0.2C20.4,18.7,20.7,18.7,20.7,18.7z"/>
<path class="st17" d="M21.3,19.1C21.3,19.1,21.3,19.1,21.3,19.1c-0.3,0-0.6-0.2-0.6-0.6c0,0,0,0,0-0.1h-0.3c0,0,0,0,0,0.1
c0,0.5,0.4,0.9,0.9,0.9c0,0,0,0,0,0c0.1,0,0.1-0.1,0.1-0.2C21.4,19.2,21.4,19.1,21.3,19.1L21.3,19.1z"/>
<path class="st8" d="M21.9,18.5c0,0.3-0.3,0.6-0.6,0.6c0,0,0,0,0,0c-0.4,0-0.6-0.3-0.6-0.6c0-0.3,0.3-0.6,0.6-0.6c0,0,0,0,0,0
C21.6,17.9,21.9,18.2,21.9,18.5L21.9,18.5z"/>
<path class="st18" d="M20.9,19.9c-0.4-0.3-0.7-0.8-0.7-1.3c0-0.6,0.3-1.1,0.7-1.3v-0.1c-0.1,0-0.2,0.1-0.4,0.1c0,0-0.1,0-0.1,0
l-0.3-0.2c0,0-0.1,0-0.1,0l-0.2,0.2c0,0,0,0.1,0,0.1l0.2,0.3c0,0,0,0.1,0,0.1c-0.1,0.1-0.1,0.2-0.1,0.3c0,0,0,0.1-0.1,0.1l-0.3,0.1
c0,0-0.1,0-0.1,0.1v0.3c0,0,0,0.1,0.1,0.1l0.3,0.1c0,0,0.1,0,0.1,0.1c0,0.1,0.1,0.2,0.1,0.3c0,0,0,0.1,0,0.1l-0.2,0.3
c0,0,0,0.1,0,0.1l0.2,0.2c0,0,0.1,0,0.1,0l0.3-0.2c0,0,0.1,0,0.1,0C20.7,19.8,20.8,19.9,20.9,19.9C20.9,19.9,20.9,19.9,20.9,19.9z"
/>
<path class="st15" d="M19.3,16.9l-0.9-0.1c0,0-0.1,0-0.1-0.1c0-0.1,0-0.1-0.1-0.2c0,0,0-0.1,0-0.1l0.6-0.6c0,0,0-0.1,0-0.2l-0.4-0.5
c0,0-0.1-0.1-0.2,0l-0.8,0.4c0,0-0.1,0-0.1,0c-0.1,0-0.1-0.1-0.2-0.1c0,0-0.1-0.1-0.1-0.1l0.1-0.9c0-0.1,0-0.1-0.1-0.1L16.7,14
c-0.1,0-0.1,0-0.1,0.1l-0.4,0.8c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1-0.1l-0.1-0.3L15.3,14
c0-0.1-0.1-0.1-0.1-0.1l-0.6,0.2c-0.1,0-0.1,0.1-0.1,0.1l0.1,0.9c0,0,0,0.1-0.1,0.1c-0.1,0-0.1,0.1-0.2,0.1c0,0-0.1,0-0.1,0L13.5,15
c-0.1,0-0.1,0-0.2,0L13,15.6c0,0,0,0.1,0,0.2l0.6,0.6c0,0,0,0.1,0,0.1c0,0.1,0,0.1-0.1,0.2c0,0-0.1,0.1-0.1,0.1l-0.7,0.1
c0,0.3,0.1,0.6,0.2,1l0.5,0.1c0,0,0.1,0,0.1,0.1c0,0.1,0,0.1,0.1,0.2c0,0,0,0.1,0,0.1l-0.3,0.3c0.2,0.3,0.4,0.6,0.6,0.8l0.3-0.2
c0,0,0.1,0,0.1,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0.1,0.1,0.2,0.1c0,0,0.1,0.1,0.1,0.1L14.6,20c0.3,0.2,0.5,0.4,0.8,0.5l0.3-0.6
c0,0,0.1-0.1,0.1-0.1h0.2c0,0,0.1,0,0.1,0.1l0.4,0.8c0,0.1,0.1,0.1,0.1,0.1l0.6-0.2c0.1,0,0.1-0.1,0.1-0.1l-0.1-0.9
c0-0.1,0-0.1,0.1-0.1c0.1,0,0.1-0.1,0.2-0.1c0,0,0.1,0,0.1,0l0.8,0.4c0.1,0,0.1,0,0.2,0l0.4-0.5c0-0.1,0-0.1,0-0.2l-0.6-0.6
c0,0,0-0.1,0-0.1c0-0.1,0.1-0.1,0.1-0.2c0,0,0-0.1,0.1-0.1l0.9-0.1c0.1,0,0.1-0.1,0.1-0.1v-0.6C19.4,17,19.4,17,19.3,16.9z
M15.2,18.3C15.2,18.3,15.2,18.2,15.2,18.3c-0.1-0.1-0.1-0.1-0.2-0.2c0,0-0.1-0.1-0.1-0.1c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.1,0-0.2
c0-0.1,0-0.2,0-0.2v0c0-0.6,0.5-1.2,1.2-1.2c0,0,0.1,0,0.1,0l0.1,0c0,0,0,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0s0.1,0,0.1,0
l0.1,0c0,0,0,0,0.1,0.1l0.1,0.1c0.1,0.1,0.1,0.1,0.1,0.2c0,0,0,0.1,0.1,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1
c0,0.1,0,0.2,0,0.2l0,0.2c0,0,0,0.1,0,0.1l-0.2,0.4c0,0,0,0.1-0.1,0.1c0,0,0,0-0.1,0.1c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0.1
c-0.1,0-0.1,0.1-0.2,0.1c0,0-0.1,0-0.1,0C15.9,18.6,15.6,18.5,15.2,18.3C15.3,18.3,15.3,18.3,15.2,18.3z"/>
<path class="st18" d="M15.3,14c0-0.1-0.1-0.1-0.1-0.1l-0.6,0.2c-0.1,0-0.1,0.1-0.1,0.1l0.1,0.9c0,0,0,0.1-0.1,0.1
c-0.1,0-0.1,0.1-0.2,0.1c0,0-0.1,0-0.1,0L13.5,15c-0.1,0-0.1,0-0.2,0L13,15.6c0,0,0,0.1,0,0.2l0.6,0.6c0,0,0,0.1,0,0.1
c0,0.1,0,0.1-0.1,0.2c0,0-0.1,0.1-0.1,0.1l-0.7,0.1c0,0.3,0.1,0.6,0.2,1l0.5,0.1c0,0,0.1,0,0.1,0.1c0,0.1,0,0.1,0.1,0.2
c0,0,0,0.1,0,0.1l-0.3,0.3c0.2,0.3,0.4,0.6,0.6,0.8l0.3-0.2c0,0,0.1,0,0.1,0c0,0,0,0,0,0l0,0v0c-0.1-0.4-0.2-0.9-0.2-1.4
c0,0,0,0,0-0.1c0-0.2,0-0.4,0-0.6c0-0.3,0.1-0.6,0.2-0.9c0,0,0-0.1,0-0.1c0.2-0.7,0.6-1.4,1.1-1.8L15.3,14z"/>
<path class="st17" d="M17.2,16.1c-0.3-0.3-0.8-0.5-1.2-0.5c-0.1,0-0.2,0-0.3,0c-0.5,0.1-0.9,0.4-1.2,0.8c-0.2,0.3-0.3,0.6-0.3,0.9
c0,0.2,0,0.3,0.1,0.5c0.1,0.3,0.2,0.6,0.5,0.8c0.4,0.4,0.9,0.6,1.5,0.5c0.4,0,0.8-0.2,1-0.5c0.2-0.2,0.4-0.6,0.5-0.9v0
c0-0.1,0-0.2,0-0.3C17.7,16.9,17.5,16.4,17.2,16.1z M15.3,18.3C15.3,18.3,15.3,18.3,15.3,18.3c-0.1-0.1-0.1-0.1-0.2-0.1
c0,0-0.1-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.1,0-0.2c0-0.1,0-0.2,0-0.2v0c0-0.6,0.5-1.2,1.2-1.2
c0,0,0.1,0,0.1,0l0.1,0c0,0,0,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0l0.1,0c0,0,0,0,0.1,0.1l0.1,0.1
c0.1,0.1,0.1,0.1,0.1,0.2c0,0,0,0.1,0.1,0.1s0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.1,0,0.2,0,0.2l0,0.2c0,0,0,0.1,0,0.1
l-0.2,0.4c0,0,0,0.1-0.1,0.1c0,0,0,0-0.1,0.1c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0.1c-0.1,0-0.1,0.1-0.2,0.1c0,0-0.1,0-0.1,0
c-0.1,0-0.2,0-0.2,0C15.7,18.5,15.5,18.5,15.3,18.3z"/>
<path class="st16" d="M14.5,17.4c0.1,0,0.3-0.1,0.3-0.2c0-0.2,0.2-0.4,0.3-0.6c0.2-0.2,0.4-0.3,0.6-0.3c0.1,0,0.2-0.1,0.2-0.3
c0-0.2-0.2-0.3-0.3-0.3c-0.3,0.1-0.7,0.2-0.9,0.5c-0.2,0.2-0.4,0.6-0.5,0.9C14.2,17.2,14.3,17.4,14.5,17.4z M17.4,17.4
c-0.1,0-0.3,0.1-0.3,0.2c0,0.2-0.2,0.4-0.3,0.6c-0.2,0.2-0.4,0.3-0.6,0.3c-0.1,0-0.2,0.1-0.2,0.3c0,0.2,0.2,0.3,0.3,0.3
c0.3-0.1,0.7-0.2,0.9-0.5c0.2-0.2,0.4-0.6,0.5-0.9C17.7,17.6,17.6,17.4,17.4,17.4z"/>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 988 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 333 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,125 @@
================
Cetmix Tower Git
================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:583744e8956f294682a551fc082f086b174b8d2b72652c21b1dd68f3933e7211
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-cetmix%2Fcetmix--tower-lightgray.png?logo=github
:target: https://github.com/cetmix/cetmix-tower/tree/16.0/cetmix_tower_git
:alt: cetmix/cetmix-tower
|badge1| |badge2| |badge3|
This module implements Git Management functionality for `Cetmix
Tower <https://cetmix.com/tower>`__.
Please refer to the `official
documentation <https://cetmix.com/tower>`__ for detailed information.
**Table of contents**
.. contents::
:local:
Configuration
=============
Please refer to the `official
documentation <https://cetmix.com/tower>`__ for detailed configuration
instructions.
Usage
=====
Please refer to the `official
documentation <https://cetmix.com/tower>`__ for detailed usage
instructions.
Changelog
=========
16.0.2.0.1 (2025-12-11)
-----------------------
- Features: Improve search views, implement the search panel for
selected views. (5139)
16.0.2.0.0 (2025-10-27)
-----------------------
- Features: Major refactoring: implement Git repository entity. (4914)
16.0.1.0.6 (2025-08-18)
-----------------------
- Features: Link or copy a git project when uploading the linked file
using command (4759)
16.0.1.0.5 (2025-08-17)
-----------------------
- Features: Search servers by git reference (4838)
16.0.1.0.4 (2025-07-29)
-----------------------
- Features: Export related commands and flight plans together with
server (4849)
16.0.1.0.3 (2025-05-23)
-----------------------
- Bugfixes: Duplicated file is created when importing a YAML file with a
git project. (4715)
16.0.1.0.2 (2025-05-16)
-----------------------
- Features: Record references for git relations. (4670)
16.0.1.0.1 (2025-05-09)
-----------------------
- Bugfixes: Non-critical issues and performance improvements. (4663)
16.0.1.0.0
----------
Release for Odoo 16.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/cetmix/cetmix-tower/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/cetmix/cetmix-tower/issues/new?body=module:%20cetmix_tower_git%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Cetmix
Maintainers
-----------
This module is part of the `cetmix/cetmix-tower <https://github.com/cetmix/cetmix-tower/tree/16.0/cetmix_tower_git>`_ project on GitHub.
You are welcome to contribute.

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,40 @@
# Copyright Cetmix OU
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Cetmix Tower Git",
"summary": "Cetmix Tower Git Management Tools",
"version": "16.0.2.0.2",
"development_status": "Beta",
"category": "Productivity",
"website": "https://tower.cetmix.com",
"author": "Cetmix",
"license": "AGPL-3",
"application": False,
"depends": ["cetmix_tower_yaml"],
"external_dependencies": {
"python": ["giturlparse==0.12.0"],
},
"data": [
"security/ir.model.access.csv",
"security/cx_tower_git_project_security.xml",
"security/cx_tower_git_source_security.xml",
"security/cx_tower_git_remote_security.xml",
"security/cx_tower_git_repo_security.xml",
"security/cx_tower_git_repo_owner_security.xml",
"security/cx_tower_git_project_rel_security.xml",
"security/cx_tower_git_project_file_template_rel_security.xml",
"views/cx_tower_git_project_views.xml",
"views/cx_tower_git_source_views.xml",
"views/cx_tower_git_remote_views.xml",
"views/cx_tower_git_repo_views.xml",
"views/cx_tower_git_repo_owner_views.xml",
"views/cx_tower_file_views.xml",
"views/cx_tower_file_template_views.xml",
"views/cx_tower_server_view.xml",
"views/cx_tower_plan_line_view.xml",
"views/menuitems.xml",
],
"demo": [
"demo/demo_data.xml",
],
}

View File

@@ -0,0 +1,166 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<!-- Git Project -->
<record id="git_project_demo" model="cx.tower.git.project">
<field name="name">Demo Git Project</field>
<field name="reference">demo_git_project</field>
<field name="note">This is a demo git project.</field>
</record>
<!-- Repositories -->
<record id="repo_demo_cetmix_tower" model="cx.tower.git.repo">
<field name="url">https://github.com/cetmix-demo/cetmix-tower-demo.git</field>
</record>
<record id="repo_demo_oca_web" model="cx.tower.git.repo">
<field name="url">https://github.com/oca-demo/web-demo.git</field>
</record>
<record id="repo_demo_odoo_enterprise" model="cx.tower.git.repo">
<field name="url">https://github.com/odoo-demo/enterprise-demo.git</field>
<field name="is_private" eval="True" />
</record>
<record id="repo_demo_gitlab_private" model="cx.tower.git.repo">
<field name="url">https://gitlab.com/cetmix-demo/cetmix-tower-demo.git</field>
<field name="is_private" eval="True" />
</record>
<record id="repo_demo_bitbucket_private" model="cx.tower.git.repo">
<field
name="url"
>https://bitbucket.com/cetmix-demo/cetmix-tower-demo-enterprise.git</field>
<field name="is_private" eval="True" />
</record>
<!-- Sources -->
<!-- Cetmix Tower -->
<record id="source_demo_cetmix_tower" model="cx.tower.git.source">
<field name="name">Cetmix Tower</field>
<field name="reference">cetmix_tower</field>
<field name="git_project_id" ref="git_project_demo" />
</record>
<!-- Remotes-->
<record id="remote_demo_cetmix_tower_14_0_dev" model="cx.tower.git.remote">
<field name="source_id" ref="source_demo_cetmix_tower" />
<field name="repo_id" ref="repo_demo_cetmix_tower" />
<field name="head_type">branch</field>
<field name="head">14.0</field>
</record>
<record id="remote_demo_cetmix_tower_pr_176" model="cx.tower.git.remote">
<field name="source_id" ref="source_demo_cetmix_tower" />
<field name="repo_id" ref="repo_demo_cetmix_tower" />
<field name="head_type">pr</field>
<field name="head">176</field>
</record>
<!-- OCA Web -->
<record id="source_demo_oca_web" model="cx.tower.git.source">
<field name="name">OCA Web</field>
<field name="reference">oca_web</field>
<field name="git_project_id" ref="git_project_demo" />
</record>
<!-- Remotes -->
<record id="remote_demo_oca_web_14_0" model="cx.tower.git.remote">
<field name="source_id" ref="source_demo_oca_web" />
<field name="repo_id" ref="repo_demo_oca_web" />
<field name="head_type">branch</field>
<field name="head">14.0</field>
</record>
<!-- Odoo Enterprise -->
<record id="source_demo_odoo_enterprise" model="cx.tower.git.source">
<field name="name">Odoo Enterprise (Private)</field>
<field name="reference">odoo_enterprise</field>
<field name="git_project_id" ref="git_project_demo" />
</record>
<!-- Remotes -->
<record id="remote_demo_odoo_enterprise" model="cx.tower.git.remote">
<field name="source_id" ref="source_demo_odoo_enterprise" />
<field name="repo_id" ref="repo_demo_odoo_enterprise" />
<field name="head_type">branch</field>
<field name="head">19.0</field>
<field name="is_private" eval="True" />
</record>
<!-- Sample Private Gitlab -->
<record id="source_demo_gitlab_private" model="cx.tower.git.source">
<field name="name">Sample Semi Private Gitlab</field>
<field name="reference">gitlab_private</field>
<field name="git_project_id" ref="git_project_demo" />
</record>
<!-- Remotes -->
<record id="remote_demo_gitlab_private_main" model="cx.tower.git.remote">
<field name="source_id" ref="source_demo_gitlab_private" />
<field name="repo_id" ref="repo_demo_gitlab_private" />
<field name="head_type">branch</field>
<field name="head">main</field>
</record>
<record id="remote_demo_gitlab_private_mr_1234" model="cx.tower.git.remote">
<field name="source_id" ref="source_demo_gitlab_private" />
<field name="repo_id" ref="repo_demo_gitlab_private" />
<field name="head_type">pr</field>
<field name="head">1234</field>
</record>
<!-- Sample Private Bitbucket -->
<record id="source_demo_bitbucket_private" model="cx.tower.git.source">
<field name="name">Sample Private Bitbucket</field>
<field name="reference">bitbucket_private</field>
<field name="git_project_id" ref="git_project_demo" />
</record>
<!-- Remotes -->
<record id="remote_demo_bitbucket_private_main" model="cx.tower.git.remote">
<field name="source_id" ref="source_demo_bitbucket_private" />
<field name="repo_id" ref="repo_demo_bitbucket_private" />
<field name="head_type">branch</field>
<field name="head">dev</field>
</record>
<record id="remote_demo_bitbucket_private_feature" model="cx.tower.git.remote">
<field name="source_id" ref="source_demo_bitbucket_private" />
<field name="repo_id" ref="repo_demo_bitbucket_private" />
<field name="head_type">commit</field>
<field name="head">1234567890</field>
</record>
<!-- Files -->
<record id="file_demo_cetmix_tower_14_0_dev" model="cx.tower.file">
<field name="name">repos.yaml</field>
<field name="server_id" ref="cetmix_tower_server.server_demo_1" />
<field name="source">tower</field>
<field name="file_type">text</field>
<field name="server_dir">{{ instance_name }}/config</field>
</record>
<!-- Link file to git project -->
<record
id="git_project_rel_demo_cetmix_tower_14_0_dev"
model="cx.tower.git.project.rel"
>
<field name="git_project_id" ref="git_project_demo" />
<field name="server_id" ref="cetmix_tower_server.server_demo_1" />
<field name="file_id" ref="file_demo_cetmix_tower_14_0_dev" />
<field name="project_format">git_aggregator</field>
</record>
<!-- Demo variable for testing giturlparse -->
<record id="variable_demo_git_url" model="cx.tower.variable">
<field name="name">Demo Git URL</field>
<field name="reference">demo_git_url</field>
</record>
<!-- Demo command to test giturlparse -->
<record id="command_demo_git_url" model="cx.tower.command">
<field name="name">Parse Git URL</field>
<field name="action">python_code</field>
<field name="code">
if {{ demo_git_url }}:
parsed_url = giturlparse.parse({{ demo_git_url }})
repo = parsed_url.repo
owner = parsed_url.owner
host = parsed_url.host
platform = parsed_url.platform
message = "Repo: " + repo + ", Owner: " + owner + ", Host: " + host + ", Platform: " + platform
result={"exit_code": 0, "message": message}
else:
result={"exit_code": -100, "message": "Git URL is not defined!"}
</field>
<field name="access_level">1</field>
<field
name="tag_ids"
eval="[(6, 0, [ref('cetmix_tower_server.tag_custom')])]"
/>
<field name="note">Run Python Code: Check Branch</field>
</record>
</odoo>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,595 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * cetmix_tower_git
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: fi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_project.py:0
#, python-format
msgid ""
"\n"
"# You need to set the following variables in your environment:\n"
"# %(vars)s \n"
"# and run git-aggregator with '--expand-env' parameter.\n"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_project.py:0
#, python-format
msgid ""
"# This file is generated with Cetmix Tower https://cetmix.com/tower\n"
"# It's designed to be used with git-aggregator tool developed by Acsone.\n"
"# Documentation for git-aggregator: https://github.com/acsone/git-aggregator\n"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "* Sources where all remotes are private"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "* Sources where some remotes are private"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid ""
"<b>Managers.</b> All users who have \"Manager\" group and are set as \"Managers\" in <b><u>all</u></b> related servers.\n"
" This is done to avoid unpredictable consequences when some of the servers are not updated due to access restrictions when a project is updated."
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid ""
"<b>Users.</b> All users who have \"Manager\" group and are either set in "
"\"Users\" or in \"Managers\" in <b><u>all</u></b> related servers."
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Access"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__active
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__active
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__active
msgid "Active"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Archived"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__repo_provider__bitbucket
msgid "Bitbucket"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__head_type__branch
msgid "Branch"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_remote_view_form
msgid "Branch/PR/commit number or link"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__reference
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__reference
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_source__reference
msgid ""
"Can contain English letters, digits and '_'. Leave blank to autogenerate"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_git_project
msgid "Cetmix Tower Git Configuration"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_git_remote
msgid "Cetmix Tower Git Remote"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_git_source
msgid "Cetmix Tower Git Source"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_server
msgid "Cetmix Tower Server"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_project_rel.py:0
#, python-format
msgid "Code generator function for '%(project_format)s' format not found."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__head_type__commit
msgid "Commit"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__create_uid
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__create_uid
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__create_uid
msgid "Created by"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__create_date
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__create_date
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__create_date
msgid "Created on"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_file
msgid "Cx Tower File"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_remote_view_form
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid "Disabled"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server__display_name
msgid "Display Name"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__enabled
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_source__enabled
msgid "Enable in configuration and exported to files"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__enabled
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__enabled
msgid "Enabled"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Export YAML"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__file_id
msgid "File"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_project_rel.py:0
#, python-format
msgid "File '%(file)s' doesn't belong to server '%(server)s'"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_file.py:0
#, python-format
msgid ""
"File '%(file)s' is related to multiple projects: %(projects)s \n"
"Please select only one project."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.constraint,message:cetmix_tower_git.constraint_cx_tower_git_project_rel_project_server_file_format_uniq
msgid "File is already related to the same project and format"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__file_ids
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Files"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__project_format
msgid "Format"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__git_aggregator_root_dir
msgid "Git Aggregator Root Dir"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid ""
"Git Aggregator: Bitbucket does not support fetching PRs. Please use branch instead.\n"
"\n"
"Source: %(src)s\n"
"URL: %(url)s\n"
"Head: %(head)s"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid "Git Aggregator: Head number is empty in %(head)s"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__git_project_id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__git_project_id
msgid "Git Configuration"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file__git_project_id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__git_project_id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server__git_project_ids
msgid "Git Project"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server__git_project_rel_ids
msgid "Git Project Rel"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__git_project_rel_ids
msgid "Git Project Server File Relations"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_git_project_rel
msgid "Git Project relation to other model records"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.actions.act_window,name:cetmix_tower_git.cx_tower_git_project_action
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file__git_project_ids
#: model:ir.ui.menu,name:cetmix_tower_git.menu_cx_tower_git_project
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_server_view_form
msgid "Git Projects"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__git_aggregator_root_dir
msgid ""
"Git aggregator root directory where sources will be cloned. Eg '/tmp/git-"
"aggregator' Will use '.' if not set"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid ""
"Git aggregator root directory where sources will be cloned. Leave blank to "
"use '.'"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__url
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_remote_view_form
msgid ""
"Git remote URL. Eg 'https://github.com/cetmix/cetmix-tower.git' or "
"'git@github.com:cetmix/cetmix-tower.git'"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__head
msgid ""
"Git remote head. Link to branch, PR, commit or commit hash. Leave blank to "
"auto-detect"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__repo_provider__github
msgid "GitHub"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__repo_provider__gitlab
msgid "GitLab"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__url_protocol__https
msgid "HTTPS"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__has_partially_private_remotes
msgid "Has Partially Private Remotes"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__has_private_remotes
msgid "Has Private Remotes"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__head
msgid "Head"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__head_type
msgid "Head Type"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server__id
msgid "ID"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__has_partially_private_remotes
msgid "Indicates if the project has any partially private remotes."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__has_private_remotes
msgid "Indicates if the project has any private remotes."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__is_private
msgid "Is Private"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server____last_update
msgid "Last Modified on"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__write_uid
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__write_uid
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__write_uid
msgid "Last Updated by"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__write_date
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__write_date
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__write_date
msgid "Last Updated on"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__manager_ids
msgid "Managers"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__manager_ids
msgid "Managers who can modify this record"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__name
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid "Name"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid "Not a valid URL. URL must end with '.git'"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid "Not a valid URL. URL must start with 'https://' or 'git@'"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid ""
"Not a valid URL: %(url_msg)s\n"
"URL must contain at least two parts separated by dot."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__repo_provider__other
msgid "Other"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid "Private"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__remote_count_private
msgid "Private Remotes"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__head_type__pr
msgid "Pull/Merge Request"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__reference
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__reference
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__reference
msgid "Reference"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid ""
"Reference. Can contain English letters, digits and '_'. Leave blank to "
"autogenerate"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__remote_count
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__remote_ids
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid "Remotes"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__repo_provider
msgid "Repository Provider"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__is_private
msgid "Repository is private"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__url_protocol__ssh
msgid "SSH"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__sequence
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__sequence
msgid "Sequence"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__server_id
msgid "Server"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__server_ids
msgid "Servers"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__server_ids
msgid ""
"Servers are added automatically based on the files linked to the project.\n"
"IMPORTANT: This field may contain duplicates because of the relation nature!"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__source_id
msgid "Source"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__source_ids
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Sources"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid ""
"The top one remote will be used as a merge target.\n"
" You can re-arrange remotes by dragging them or changing their sequence value."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__url
msgid "URL"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__url_protocol
msgid "URL Protocol"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid "URL is required"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__user_ids
msgid "Users"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__user_ids
msgid "Users who can view this record"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__repo_provider
msgid ""
"Will be tried to be determined from the URL. Please select manually if auto-"
"detection fails."
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "YAML"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__yaml_code
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__yaml_code
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__yaml_code
msgid "Yaml Code"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid ""
"You can edit these fields at your own risk. However keep in mind that they "
"will be automatically updated each time related servers are added, removed "
"or updated."
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "You must be a member of the \"YAML/Export\" group to export data as YAML."
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "managers who can modify this record"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "users who can view this record"
msgstr ""

View File

@@ -0,0 +1,635 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * cetmix_tower_git
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 09:11+0000\n"
"Last-Translator: Bole <bole@dajmi5.com>\n"
"Language-Team: Croatian <https://hosted.weblate.org/projects/"
"tower-server-14-0-dev/cetmix_tower_git/hr/>\n"
"Language: hr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Weblate 5.10.3-dev\n"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_project.py:0
#, python-format
msgid ""
"\n"
"# You need to set the following variables in your environment:\n"
"# %(vars)s \n"
"# and run git-aggregator with '--expand-env' parameter.\n"
msgstr ""
"\n"
"# Potrebno je postaviti sljedeće varijable u vaše okruženje:\n"
"# %(vars)s \n"
"# i pokrenuti git-aggregator sa ' --expand-env' parametrom\n"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_project.py:0
#, python-format
msgid ""
"# This file is generated with Cetmix Tower https://cetmix.com/tower\n"
"# It's designed to be used with git-aggregator tool developed by Acsone.\n"
"# Documentation for git-aggregator: https://github.com/acsone/git-aggregator\n"
msgstr ""
"# Ova datotek aje generiran pomoću Cetmix Tower sustava: https://cetmix.com/"
"tower\n"
"# Dizajniran je za korištenje sa git-aggregator alatom razvijenim od Ascone."
"\n"
"# Dokumentacija za git-aggregator : https://github.com/acsone/git-"
"aggregator\n"
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "* Sources where all remotes are private"
msgstr "* izvori sa svim udaljenim lokacijama koje su privatne"
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "* Sources where some remotes are private"
msgstr "* Izvori u kojima su neke udaljene lokacije privatne"
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid ""
"<b>Managers.</b> All users who have \"Manager\" group and are set as \"Managers\" in <b><u>all</u></b> related servers.\n"
" This is done to avoid unpredictable consequences when some of the servers are not updated due to access restrictions when a project is updated."
msgstr ""
"<b>Manageri.</b> Svi korisnici koji imaju \"Manager\" grupu i postavljeni su "
"kao \"Manageri\" u <b><u>svim</u></b> povezanim serverima.\n"
" "
"Ovo je napravljeno kako bi izbjegli nepredviđene posljedice kad neki od "
"servera nisu ažurirani zbog ograničenog pristupa prilikom ažuriranja "
"projekta."
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid ""
"<b>Users.</b> All users who have \"Manager\" group and are either set in "
"\"Users\" or in \"Managers\" in <b><u>all</u></b> related servers."
msgstr ""
"<b>Korisnici.</b> Svi korisnici koji imaju \"Manager\" grupu i postavljeni "
"su ili kao \"Korisnik\" ili kao \"Manager\" u <b><u>svim</u></b> povezanim "
"serverima."
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Access"
msgstr "Pristup"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__active
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__active
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__active
msgid "Active"
msgstr "Aktivno"
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Archived"
msgstr "Arhivirano"
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__repo_provider__bitbucket
msgid "Bitbucket"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__head_type__branch
msgid "Branch"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_remote_view_form
msgid "Branch/PR/commit number or link"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__reference
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__reference
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_source__reference
msgid ""
"Can contain English letters, digits and '_'. Leave blank to autogenerate"
msgstr ""
"Može sadržavati slova engleske abecede, brojke i ':'. Ostavite prazno za "
"automatsko generiranje"
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_git_project
msgid "Cetmix Tower Git Configuration"
msgstr "Cetmix Tower Git postavke"
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_git_remote
msgid "Cetmix Tower Git Remote"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_git_source
msgid "Cetmix Tower Git Source"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_server
msgid "Cetmix Tower Server"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_project_rel.py:0
#, python-format
msgid "Code generator function for '%(project_format)s' format not found."
msgstr ""
"Funkcija generiranja koda za '%(project_format)s' format nije pronađena."
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__head_type__commit
msgid "Commit"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__create_uid
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__create_uid
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__create_date
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__create_date
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_file
msgid "Cx Tower File"
msgstr "Cx Tower datoteka"
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_remote_view_form
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid "Disabled"
msgstr "Onemogućen"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__display_name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server__display_name
msgid "Display Name"
msgstr "Naziv"
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__enabled
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_source__enabled
msgid "Enable in configuration and exported to files"
msgstr "Omogućen u postavkama i izvezen u datoteku"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__enabled
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__enabled
msgid "Enabled"
msgstr "Omogućen"
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Export YAML"
msgstr "Izvoz YAML"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__file_id
msgid "File"
msgstr "Datoteka"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_project_rel.py:0
#, python-format
msgid "File '%(file)s' doesn't belong to server '%(server)s'"
msgstr "Datoteka '%(file)s' ne pripada serveru '%(server)s'"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_file.py:0
#, python-format
msgid ""
"File '%(file)s' is related to multiple projects: %(projects)s \n"
"Please select only one project."
msgstr ""
"Datoteka '%(file)s' je povezana sa višestrukim projektima: %(projects)s \n"
"Molim odaberite samo jedan projekt."
#. module: cetmix_tower_git
#: model:ir.model.constraint,message:cetmix_tower_git.constraint_cx_tower_git_project_rel_project_server_file_format_uniq
msgid "File is already related to the same project and format"
msgstr "Datoteka je već povezana sa ovim projektom i ovim formatom"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__file_ids
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Files"
msgstr "Datoteke"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__project_format
msgid "Format"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__git_aggregator_root_dir
msgid "Git Aggregator Root Dir"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid ""
"Git Aggregator: Bitbucket does not support fetching PRs. Please use branch instead.\n"
"\n"
"Source: %(src)s\n"
"URL: %(url)s\n"
"Head: %(head)s"
msgstr ""
"Git Aggregator: BitBucket ne podržava dohvaćanje PRova. Molim koristite "
"branch.\n"
"\n"
"Source: %(src)s\n"
"URL: %(url)s\n"
"Head: %(head)s"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid "Git Aggregator: Head number is empty in %(head)s"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__git_project_id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__git_project_id
msgid "Git Configuration"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file__git_project_id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__git_project_id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server__git_project_ids
msgid "Git Project"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server__git_project_rel_ids
msgid "Git Project Rel"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__git_project_rel_ids
msgid "Git Project Server File Relations"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model,name:cetmix_tower_git.model_cx_tower_git_project_rel
msgid "Git Project relation to other model records"
msgstr "Git projekt povezan sa ostalim zapisima modela"
#. module: cetmix_tower_git
#: model:ir.actions.act_window,name:cetmix_tower_git.cx_tower_git_project_action
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file__git_project_ids
#: model:ir.ui.menu,name:cetmix_tower_git.menu_cx_tower_git_project
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_server_view_form
msgid "Git Projects"
msgstr "Git projekti"
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__git_aggregator_root_dir
msgid ""
"Git aggregator root directory where sources will be cloned. Eg '/tmp/git-"
"aggregator' Will use '.' if not set"
msgstr ""
"GitAgregator izvorni direktorij u koji će izvori biti klonirani. Npr. '/tmp/"
"git-aggregator' Ako ništa nije postavljeno koristi se '.'"
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid ""
"Git aggregator root directory where sources will be cloned. Leave blank to "
"use '.'"
msgstr ""
"GitAgregtor izvorni dirketorij u koji će izvori biti klonirani. Ostavite "
"prazno za korištenje '.'"
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__url
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_remote_view_form
msgid ""
"Git remote URL. Eg 'https://github.com/cetmix/cetmix-tower.git' or "
"'git@github.com:cetmix/cetmix-tower.git'"
msgstr ""
"Git remote URL. Eg 'https://github.com/cetmix/cetmix-tower.git' ili "
"'git@github.com:cetmix/cetmix-tower.git'"
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__head
msgid ""
"Git remote head. Link to branch, PR, commit or commit hash. Leave blank to "
"auto-detect"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__repo_provider__github
msgid "GitHub"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__repo_provider__gitlab
msgid "GitLab"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__url_protocol__https
msgid "HTTPS"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__has_partially_private_remotes
msgid "Has Partially Private Remotes"
msgstr "Ima djelomično privatne udaljene izvore"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__has_private_remotes
msgid "Has Private Remotes"
msgstr "Ima privatne udaljene izvore"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__head
msgid "Head"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__head_type
msgid "Head Type"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__id
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server__id
msgid "ID"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__has_partially_private_remotes
msgid "Indicates if the project has any partially private remotes."
msgstr "Indicira ima li projekt djelomično privatnih udaljenih izvora."
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__has_private_remotes
msgid "Indicates if the project has any private remotes."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__is_private
msgid "Is Private"
msgstr "Je privatno"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_file____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source____last_update
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_server____last_update
msgid "Last Modified on"
msgstr "Zadnje modificirano"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__write_uid
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__write_uid
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__write_date
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__write_date
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__manager_ids
msgid "Managers"
msgstr "Manageri"
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__manager_ids
msgid "Managers who can modify this record"
msgstr "Manageri koji mogu urediti ovaj zapis"
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__name
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__name
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid "Name"
msgstr "Naziv"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid "Not a valid URL. URL must end with '.git'"
msgstr "Nije valjani URL. URL mora završavati sa '.git'"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid "Not a valid URL. URL must start with 'https://' or 'git@'"
msgstr "Nije valjani URL. URL mora počinjati sa 'https://' ili 'git@'"
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid ""
"Not a valid URL: %(url_msg)s\n"
"URL must contain at least two parts separated by dot."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__repo_provider__other
msgid "Other"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid "Private"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__remote_count_private
msgid "Private Remotes"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__head_type__pr
msgid "Pull/Merge Request"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__reference
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__reference
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__reference
msgid "Reference"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid ""
"Reference. Can contain English letters, digits and '_'. Leave blank to "
"autogenerate"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__remote_count
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__remote_ids
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid "Remotes"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__repo_provider
msgid "Repository Provider"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__is_private
msgid "Repository is private"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields.selection,name:cetmix_tower_git.selection__cx_tower_git_remote__url_protocol__ssh
msgid "SSH"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__sequence
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__sequence
msgid "Sequence"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project_rel__server_id
msgid "Server"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__server_ids
msgid "Servers"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__server_ids
msgid ""
"Servers are added automatically based on the files linked to the project.\n"
"IMPORTANT: This field may contain duplicates because of the relation nature!"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__source_id
msgid "Source"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__source_ids
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "Sources"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_source_view_form
msgid ""
"The top one remote will be used as a merge target.\n"
" You can re-arrange remotes by dragging them or changing their sequence value."
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__url
msgid "URL"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__url_protocol
msgid "URL Protocol"
msgstr ""
#. module: cetmix_tower_git
#: code:addons/cetmix_tower_git/models/cx_tower_git_remote.py:0
#, python-format
msgid "URL is required"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__user_ids
msgid "Users"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_project__user_ids
msgid "Users who can view this record"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,help:cetmix_tower_git.field_cx_tower_git_remote__repo_provider
msgid ""
"Will be tried to be determined from the URL. Please select manually if auto-"
"detection fails."
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "YAML"
msgstr ""
#. module: cetmix_tower_git
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_project__yaml_code
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_remote__yaml_code
#: model:ir.model.fields,field_description:cetmix_tower_git.field_cx_tower_git_source__yaml_code
msgid "Yaml Code"
msgstr "YAML kod"
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid ""
"You can edit these fields at your own risk. However keep in mind that they "
"will be automatically updated each time related servers are added, removed "
"or updated."
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "You must be a member of the \"YAML/Export\" group to export data as YAML."
msgstr "Morate bit član \"YAML/Izvoz\" grupe za izvoz podataka u YAML."
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "managers who can modify this record"
msgstr ""
#. module: cetmix_tower_git
#: model_terms:ir.ui.view,arch_db:cetmix_tower_git.cx_tower_git_project_view_form
msgid "users who can view this record"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
import logging
from odoo import SUPERUSER_ID, api
_logger = logging.getLogger(__name__)
def migrate(cr, version):
"""
Convert URLs in remotes to repositories.
Add repo_id to remotes.
"""
_logger.info(
"Converting URLs in remotes to repositories and adding repo_id to remotes."
)
env = api.Environment(cr, SUPERUSER_ID, {})
# Fetch all remotes using SQL query Group them {"url": [remote_id, remote_id, ...]}
cr.execute(
"""
SELECT url, array_agg(id) as remote_ids
FROM cx_tower_git_remote
GROUP BY url
"""
)
remote_urls = cr.fetchall()
remote_urls_dict = {url: remote_ids for url, remote_ids in remote_urls}
# Create repo for each url and add this repo to all remotes
url_count = 0
remote_obj = env["cx.tower.git.remote"]
repo_obj = env["cx.tower.git.repo"]
for url, remote_ids in remote_urls_dict.items():
repo_id = repo_obj.name_create(url)[0]
# Check if any of the remotes is private
remotes = remote_obj.browse(remote_ids)
is_private = bool(remotes.filtered(lambda r: r.is_private))
# Add repo to remotes
# We are using SQL to avoid post-write triggers
cr.execute(
"""
UPDATE cx_tower_git_remote
SET repo_id = %s
WHERE id = ANY(%s)
""",
(repo_id, remote_ids),
)
# Update repo.is_private
# We are using SQL to avoid post-write triggers
if is_private:
cr.execute(
"""
UPDATE cx_tower_git_repo
SET is_private = true
WHERE id = %s
""",
(repo_id,),
)
url_count += 1
# Compute project_ids for repositories
_logger.info("Computing project_ids for repositories.")
remote_obj.invalidate_model()
repo_obj.invalidate_model()
repo_obj.search([])._compute_git_project_ids()
# Sanitize all remote heads that contain a slash
# Use the SQL query to avoid post-write triggers
_logger.info("Sanitizing remote heads that contain a slash.")
cr.execute(
"""
UPDATE cx_tower_git_remote
SET head = (regexp_match(head, '[^/]+$'))[1]
WHERE head LIKE '%/%'
"""
)
_logger.info("Migration completed. %s unique urls processed", url_count)

View File

@@ -0,0 +1,15 @@
# cx_tower_git_project_rel must be the first one in the list
# in order to create the relation table properly
from . import cx_tower_git_project_rel
from . import cx_tower_git_project_file_template_rel
from . import cx_tower_file
from . import cx_tower_file_template
from . import cx_tower_git_project
from . import cx_tower_git_remote
from . import cx_tower_git_repo
from . import cx_tower_git_repo_owner
from . import cx_tower_git_source
from . import cx_tower_server
from . import cetmix_tower
from . import cx_tower_plan_line
from . import cx_tower_command

View File

@@ -0,0 +1,35 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models
class CetmixTower(models.AbstractModel):
_inherit = "cetmix.tower"
@api.model
def servers_by_git_ref(self, repository_url, head=None, head_type=None):
"""
Return servers linked to a given Git repository reference.
This is a thin shortcut that delegates to
:meth:`cx.tower.server.get_servers_by_git_ref`.
Parameters
----------
repository_url : str
Pre-normalized canonical Git URL
(e.g. ``https://host/owner/repo.git``).
head : str, optional
Branch name, commit SHA, or PR identifier.
head_type : {'branch', 'commit', 'pr'}, optional
Type of the ``head`` argument.
Returns
-------
recordset of cx.tower.server
Matching servers. Empty recordset if no matches.
"""
return self.env["cx.tower.server"].get_servers_by_git_ref(
repository_url, head, head_type
)

View File

@@ -0,0 +1,37 @@
# Copyright 2024 Cetmix OÜ
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, models
from odoo.tools.safe_eval import wrap_module
# Wrap giturlparse safely
giturlparse = wrap_module(__import__("giturlparse"), ["parse", "validate"])
class CxTowerCommand(models.Model):
"""Extends cx.tower.command to add giturlparse functionality."""
_inherit = "cx.tower.command"
def _custom_python_libraries(self):
"""
Add the giturlparse library to the available libraries.
"""
custom_python_libraries = super()._custom_python_libraries()
custom_python_libraries.update(
{
"cetmix_tower_git": {
"giturlparse": {
"import": giturlparse,
"help": _(
"Python library for Git URL parsing. "
"Available methods: 'parse', 'validate'. "
" <a "
"href='https://github.com/nephila/giturlparse/'"
" target='_blank'>Documentation on GitHub</a>."
),
},
}
}
)
return custom_python_libraries

View File

@@ -0,0 +1,47 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class CxTowerFile(models.Model):
_inherit = "cx.tower.file"
git_project_id = fields.Many2one(
comodel_name="cx.tower.git.project",
compute="_compute_git_project_id",
store=True,
)
git_project_rel_ids = fields.One2many(
comodel_name="cx.tower.git.project.rel",
inverse_name="file_id",
string="Git Project Relations",
copy=False,
)
# Get server from the first related git project relation
# This is needed for YAML import
server_id = fields.Many2one(
comodel_name="cx.tower.server",
compute="_compute_git_project_id",
store=True,
readonly=False,
)
@api.depends("git_project_rel_ids.server_id", "git_project_rel_ids.git_project_id")
def _compute_git_project_id(self):
"""
Link to project using the proxy model.
"""
for record in self:
# File is related to project via proxy model.
# So there can be only one record in o2m field.
git_project_relation = (
record.git_project_rel_ids and record.git_project_rel_ids[0]
)
if git_project_relation:
record.update(
{
"git_project_id": git_project_relation.git_project_id,
"server_id": git_project_relation.server_id,
}
)

View File

@@ -0,0 +1,32 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class CxTowerFileTemplate(models.Model):
_inherit = "cx.tower.file.template"
git_project_ids = fields.Many2many(
comodel_name="cx.tower.git.project",
relation="cx_tower_git_project_file_template_rel",
column1="file_template_id",
column2="git_project_id",
string="Git Projects",
copy=False,
)
git_project_id = fields.Many2one(
comodel_name="cx.tower.git.project",
compute="_compute_git_project_id",
)
@api.depends("git_project_ids")
def _compute_git_project_id(self):
"""
Link to project using the proxy model.
"""
for record in self:
# File is related to project via proxy model.
# So there can be only one record in o2m field.
record.git_project_id = (
record.git_project_ids and record.git_project_ids[0].id
)

View File

@@ -0,0 +1,334 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import re
from odoo import _, api, fields, models
class CxTowerGitProject(models.Model):
"""
Git Project.
Implements pre-defined git configuration.
"""
_name = "cx.tower.git.project"
_description = "Cetmix Tower Git Project"
_order = "name"
_inherit = [
"cx.tower.reference.mixin",
"cx.tower.yaml.mixin",
"cx.tower.access.role.mixin",
]
def _get_post_create_fields(self):
res = super()._get_post_create_fields()
return res + [
"source_ids",
"git_project_rel_ids",
"git_project_file_template_rel_ids",
]
active = fields.Boolean(default=True)
# IMPORTANT: This field may contain duplicates because of the relation nature!
server_ids = fields.Many2many(
comodel_name="cx.tower.server",
relation="cx_tower_git_project_rel",
column1="git_project_id",
column2="server_id",
string="Servers",
readonly=True,
copy=False,
help="Servers are added automatically based on the files linked to the project."
"\nIMPORTANT: This field may contain duplicates"
" because of the relation nature!",
)
source_ids = fields.One2many(
comodel_name="cx.tower.git.source",
inverse_name="git_project_id",
string="Sources",
auto_join=True,
copy=True,
)
git_project_rel_ids = fields.One2many(
comodel_name="cx.tower.git.project.rel",
inverse_name="git_project_id",
string="Git Project Server File Relations",
copy=False,
)
# Helper field to get all files related to git project
file_ids = fields.Many2many(
comodel_name="cx.tower.file",
relation="cx_tower_git_project_rel",
column1="git_project_id",
column2="file_id",
string="Files",
readonly=True,
depends=["git_project_rel_ids"],
copy=False,
)
git_project_file_template_rel_ids = fields.One2many(
comodel_name="cx.tower.git.project.file.template.rel",
inverse_name="git_project_id",
string="Git Project File Template Relations",
copy=False,
)
# Helper field to get all file templates related to git project
file_template_ids = fields.Many2many(
comodel_name="cx.tower.file.template",
relation="cx_tower_git_project_file_template_rel",
column1="git_project_id",
column2="file_template_id",
string="File Templates",
readonly=True,
depends=["git_project_file_template_rel_ids"],
copy=False,
)
# Helper field to get all repositories used in this project
repo_ids = fields.Many2many(
comodel_name="cx.tower.git.repo",
relation="cx_tower_git_repo_project_rel",
column1="project_id",
column2="repo_id",
string="Repositories",
readonly=True,
copy=False,
help="Repositories used in this project through its sources and remotes",
)
note = fields.Text()
# ---- Access. Add relation for mixin fields
user_ids = fields.Many2many(
relation="cx_tower_git_project_user_rel",
compute="_compute_user_ids",
readonly=False,
store=True,
precompute=True,
domain=lambda self: [
("groups_id", "in", self.env.ref("cetmix_tower_server.group_manager").ids)
],
)
manager_ids = fields.Many2many(
relation="cx_tower_git_project_manager_rel",
compute="_compute_user_ids",
readonly=False,
store=True,
precompute=True,
)
# -- UI/UX fields
has_private_remotes = fields.Boolean(
compute="_compute_has_private_remotes",
help="Indicates if the project has any private remotes.",
)
has_partially_private_remotes = fields.Boolean(
compute="_compute_has_private_remotes",
help="Indicates if the project has any partially private remotes.",
)
# -- Git Aggregator related fields
git_aggregator_root_dir = fields.Char(
help="Git aggregator root directory where sources will be cloned."
" Eg '/tmp/git-aggregator'"
" Will use '.' if not set",
)
def _selection_project_format(self):
"""
Possible project formats.
Inherit and extend when adding new project formats.
Returns:
List of tuples: (code, name)
"""
return [
("git_aggregator", "Git Aggregator"),
]
def _default_project_format(self):
"""
Default project format.
"""
return "git_aggregator"
@api.depends(
"git_project_rel_ids.server_id",
"git_project_rel_ids.server_id.user_ids",
"git_project_rel_ids.server_id.manager_ids",
)
def _compute_user_ids(self):
"""
Users. All users who have "Manager" group and are either set in "Users"
or in "Managers" in all related servers.
Managers. All users who have "Manager" group and are set as "Managers"
in all related servers.
This is done to avoid unpredictable consequences when some of the servers
are not updated due to access restrictions when a project is updated.
"""
for project in self:
# Do not compute if no servers are related
server_ids = project.git_project_rel_ids.server_id
if not server_ids:
continue
# Get all user and manager ids from related servers
all_user_ids = server_ids.user_ids.filtered(
lambda u: u.has_group("cetmix_tower_server.group_manager")
).ids
all_manager_ids = server_ids.manager_ids.ids
# Create a final list of user and manager ids
user_ids = []
manager_ids = []
# Check if user is present in all servers
for user_id in all_user_ids:
if all(
user_id in server.user_ids.ids or user_id in server.manager_ids.ids
for server in server_ids
):
user_ids.append(user_id)
# Check if manager is present in all servers
for manager_id in all_manager_ids:
if all(manager_id in server.manager_ids.ids for server in server_ids):
manager_ids.append(manager_id)
# Set the final lists
project.update(
{
"user_ids": [(6, 0, user_ids)],
"manager_ids": [(6, 0, manager_ids)],
}
)
@api.depends(
"source_ids", "source_ids.remote_ids", "source_ids.remote_ids.is_private"
)
def _compute_has_private_remotes(self):
for project in self:
project.has_private_remotes = any(
source.remote_count > 0
and source.remote_count_private == source.remote_count
for source in project.source_ids
)
project.has_partially_private_remotes = any(
source.remote_count_private > 0
and source.remote_count_private != source.remote_count
for source in project.source_ids
)
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
# Update related files and templates on create
res._update_related_files_and_templates()
return res
def write(self, vals):
res = super().write(vals)
# Update related files and templates on update
self._update_related_files_and_templates()
return res
def _update_related_files_and_templates(self):
# Update related files and templates
if self.git_project_rel_ids:
self.git_project_rel_ids._save_to_file()
if self.git_project_file_template_rel_ids:
self.git_project_file_template_rel_ids._save_to_file_template()
def _extract_variables_from_text(self, text):
"""Extract environment variables from text.
Helper method for file content generation.
Returns:
List: List of variables
"""
variables = re.findall(r"\$([A-Z0-9_]+)", text)
return sorted(list(set(variables)))
# ------------------------------
# YAML mixin methods
# ------------------------------
def _get_fields_for_yaml(self):
res = super()._get_fields_for_yaml()
res += [
"name",
"note",
"source_ids",
"git_aggregator_root_dir",
]
return res
# -------------------------------
# Git Aggregator related methods
# -------------------------------
def _git_aggregator_prepare_record(self):
"""Prepare json structure for git aggregator.
Returns:
Dict: Json structure for git aggregator
"""
self.ensure_one()
values = {}
for source in self.source_ids:
if source.enabled and source.remote_count:
root_dir = self.git_aggregator_root_dir or "."
values.update(
{
f"/{source.reference}"
if root_dir == "/"
else f"{root_dir}/{source.reference}": source._git_aggregator_prepare_record() # noqa: E501
}
)
return values
def _git_aggregator_prepare_yaml_comment(self, yaml_code):
"""Generate commentary for yaml file.
It includes brief instructions for git aggregator
and lists environment variables that are required.
Args:
yaml_code (str): Yaml code
Returns:
Char: comment text or None
"""
comment_text = _(
"# This file is generated with Cetmix Tower https://cetmix.com/tower\n"
"# It's designed to be used with git-aggregator tool developed by Acsone.\n"
"# Documentation for git-aggregator: https://github.com/acsone/git-aggregator\n"
)
variable_list = self._extract_variables_from_text(yaml_code)
if variable_list:
comment_text += _(
"\n# You need to set the following variables in your environment:\n# %(vars)s\n" # noqa: E501
"# and run git-aggregator with '--expand-env' parameter.\n", # noqa: E501
vars=(", ".join(variable_list)),
)
return comment_text
def _generate_code_git_aggregator(self, record):
"""Generate code in git-aggregator format.
Args:
record (recordset()): Model record to generate code for.
must be a single record and have git_project_id field.
Returns:
Text: Yaml code
"""
yaml_mixin = self.env["cx.tower.yaml.mixin"]
# Do not generate code if record values are empty
record_values = record.git_project_id._git_aggregator_prepare_record()
if record_values:
yaml_code = yaml_mixin._convert_dict_to_yaml(record_values)
# Prepend comment to yaml code
comment = record.git_project_id._git_aggregator_prepare_yaml_comment(
yaml_code
)
return f"{comment}\n{yaml_code}"
return ""

View File

@@ -0,0 +1,113 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class CxTowerGitProjectFileTemplateRel(models.Model):
"""
Relation between git projects and file templates.
"""
_name = "cx.tower.git.project.file.template.rel"
_table = "cx_tower_git_project_file_template_rel"
_description = "Cetmix Tower Git Project relation to File Templates"
_log_access = False
name = fields.Char(related="git_project_id.name", readonly=True)
git_project_id = fields.Many2one(
comodel_name="cx.tower.git.project",
index=True,
required=True,
ondelete="cascade",
)
file_template_id = fields.Many2one(
comodel_name="cx.tower.file.template",
required=True,
ondelete="cascade",
)
project_format = fields.Selection(
selection=lambda self: self.env[
"cx.tower.git.project"
]._selection_project_format(),
default=lambda self: self.env["cx.tower.git.project"]._default_project_format(),
required=True,
string="Format",
)
_sql_constraints = [
(
"project_server_file_format_uniq",
"unique(git_project_id, file_template_id, project_format)",
"File template is already related to the same project and format",
),
]
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
# Export project to file
res._save_to_file_template()
return res
def write(self, vals):
res = super().write(vals)
# Export project to file
self._save_to_file_template()
return res
def action_open_file_template(self):
"""
Open file template record in current window
"""
self.ensure_one()
return {
"type": "ir.actions.act_window",
"name": self.file_template_id.name,
"res_model": "cx.tower.file.template",
"res_id": self.file_template_id.id, # pylint: disable=no-member
"view_mode": "form",
"view_type": "form",
"target": "current",
}
# ----------------------------------------------------
# Save project to linked file based on selected format
# ----------------------------------------------------
def _save_to_file_template(self):
"""Save project to linked file using format-specific function."""
# Get required function based on project format
# Following the pattern: _generate_code__<format> where format
# is one of the values in _selection_project_format
# Function gets a single record as an argument.
# Save resolved functions to dict for faster access
code_generator_functions = {}
for record in self:
code_generator_function = code_generator_functions.get(
record.project_format
)
if not code_generator_function:
code_generator_function = getattr(
self.git_project_id, f"_generate_code_{record.project_format}", None
)
if not code_generator_function:
raise ValidationError(
_(
"Code generator function for '%(project_format)s'"
" format not found.",
project_format=record.project_format,
)
)
code_generator_functions[
record.project_format
] = code_generator_function
# Generate code for current record
code = code_generator_function(record)
if record.file_template_id.code != code:
record.file_template_id.write({"code": code})

View File

@@ -0,0 +1,177 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class CxTowerGitProjectRel(models.Model):
"""
Relation between git projects and other model records.
"""
_name = "cx.tower.git.project.rel"
_inherit = [
"cx.tower.reference.mixin",
"cx.tower.yaml.mixin",
]
_table = "cx_tower_git_project_rel"
_description = "Cetmix Tower Git Project relation to Files and Servers"
_log_access = False
name = fields.Char(related="git_project_id.name", readonly=True)
git_project_id = fields.Many2one(
comodel_name="cx.tower.git.project",
index=True,
required=True,
ondelete="cascade",
)
server_id = fields.Many2one(
comodel_name="cx.tower.server",
index=True,
required=True,
ondelete="cascade",
)
file_id = fields.Many2one(
comodel_name="cx.tower.file",
domain="[('server_id', '=', server_id),"
"('source', '=', 'tower'),"
"('file_type', '=', 'text')]",
required=True,
ondelete="cascade",
)
project_format = fields.Selection(
selection=lambda self: self.env[
"cx.tower.git.project"
]._selection_project_format(),
default=lambda self: self.env["cx.tower.git.project"]._default_project_format(),
required=True,
string="Format",
)
auto_sync = fields.Boolean(related="file_id.auto_sync", readonly=False)
_sql_constraints = [
(
"project_server_file_format_uniq",
"unique(git_project_id, file_id, project_format)",
"File is already related to the same project and format",
),
]
@api.constrains("server_id", "file_id")
def _check_server_file_relation(self):
"""
Check if server and file are related.
"""
for record in self:
if (
record.file_id.server_id
and record.server_id != record.file_id.server_id
):
raise ValidationError(
_(
"File '%(file)s' doesn't belong to server '%(server)s'",
file=record.file_id.name,
server=record.server_id.name,
)
)
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
# Export project to file
res._save_to_file()
return res
def write(self, vals):
res = super().write(vals)
# Export project to file
self._save_to_file()
return res
def action_open_project(self):
"""
Open project record in current window
"""
self.ensure_one()
return {
"type": "ir.actions.act_window",
"name": self.name,
"res_model": "cx.tower.git.project",
"res_id": self.git_project_id.id, # pylint: disable=no-member
"view_mode": "form",
"view_type": "form",
"target": "current",
}
def action_open_server(self):
"""
Open server record in current window
"""
self.ensure_one()
return {
"type": "ir.actions.act_window",
"name": self.server_id.name,
"res_model": "cx.tower.server",
"res_id": self.server_id.id, # pylint: disable=no-member
"view_mode": "form",
"view_type": "form",
"target": "current",
}
# ----------------------------------------------------
# Save project to linked file based on selected format
# ----------------------------------------------------
def _save_to_file(self):
"""Save project to linked file using format-specific function."""
# Get required function based on project format
# Following the pattern: _generate_code_<format> where format
# is one of the values in _selection_project_format
# Function gets a single record as an argument.
# Save resolved functions to dict for faster access
code_generator_functions = {}
for record in self:
# Disconnect file from file template if it is connected
if record.file_id.template_id:
record.file_id.action_unlink_from_template()
code_generator_function = code_generator_functions.get(
record.project_format
)
if not code_generator_function:
code_generator_function = getattr(
self.git_project_id, f"_generate_code_{record.project_format}", None
)
if not code_generator_function:
raise ValidationError(
_(
"Code generator function for '%(project_format)s'"
" format not found.",
project_format=record.project_format,
)
)
code_generator_functions[
record.project_format
] = code_generator_function
# Generate code for current record
code = code_generator_function(record)
if record.file_id.code != code:
record.file_id.write({"code": code})
# ------------------------------
# YAML mixin methods
# ------------------------------
def _get_fields_for_yaml(self):
res = super()._get_fields_for_yaml()
res += [
"file_id",
"git_project_id",
"project_format",
"auto_sync",
]
return res

View File

@@ -0,0 +1,415 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import giturlparse
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class CxTowerGitRemote(models.Model):
"""
Git Remote.
Implements single git remote.
Eg a branch or a pull request.
"""
_name = "cx.tower.git.remote"
_inherit = [
"cx.tower.reference.mixin",
"cx.tower.yaml.mixin",
]
_description = "Cetmix Tower Git Remote"
_order = "sequence, name"
# Used to detect git ssh urls
GIT_SSH_URL_PATTERN = r"^[\w\.-]+@[\w\.-]+:.*\.git$"
GIT_HTTPS_URL_PATTERN = r"^https://.*\.git$"
GIT_GIT_URL_PATTERN = r"^git://.*\.git$"
active = fields.Boolean(related="source_id.active", store=True, readonly=True)
enabled = fields.Boolean(
default=True, help="Enable in configuration and exported to files"
)
sequence = fields.Integer(default=10)
name = fields.Char(compute="_compute_name", store=True, default="remote")
source_id = fields.Many2one(
comodel_name="cx.tower.git.source",
required=True,
ondelete="cascade",
auto_join=True,
)
git_project_id = fields.Many2one(
comodel_name="cx.tower.git.project",
related="source_id.git_project_id",
store=True,
readonly=True,
)
repo_id = fields.Many2one(
comodel_name="cx.tower.git.repo",
string="Repository",
required=True,
ondelete="restrict",
help="If selected, the remote URL will be filled from the"
" repo settings based on the remote protocol",
)
repo_provider = fields.Selection(
related="repo_id.provider",
readonly=True,
)
# -- Repo related fields
url_protocol = fields.Selection(
string="Protocol",
selection=[
("ssh", "SSH"),
("https", "HTTPS"),
("git", "GIT"),
],
required=True,
default=lambda self: self._get_default_url_protocol(),
)
is_private = fields.Boolean(
string="Private",
help="Repository is private",
related="repo_id.is_private",
store=True,
readonly=True,
)
head_type = fields.Selection(
selection=[
("branch", "Branch"),
("pr", "Pull/Merge Request"),
("commit", "Commit"),
],
required=True,
)
head = fields.Char(
help="Git remote head. Link to branch, PR, commit or commit hash.",
required=True,
index=True,
)
def _get_default_url_protocol(self):
"""Default URL protocol for new remote.
Returns:
Char: Default URL protocol.
"""
return "https"
@api.depends("source_id", "sequence")
def _compute_name(self):
"""
Compute remote name.
By default all remotes are named `remote_<position>`
where position is the position of the remote in the source.
Eg first remote is `remote_1`, second is `remote_2`, etc.
"""
for remote in self:
if remote.source_id:
for index, source_remote in enumerate(remote.source_id.remote_ids):
source_remote.name = f"remote_{index + 1}"
@api.onchange("head")
def onchange_head(self):
"""
Extract head number from head url
and set it as head.
"""
for remote in self:
if remote.head and "/" in remote.head:
remote.head = self._sanitize_head(remote.head)
@api.model_create_multi
def create(self, vals_list):
# Sanitize head
for vals in vals_list:
head = vals.get("head")
if head and "/" in head:
vals["head"] = self._sanitize_head(head)
res = super().create(vals_list)
# Export project to related files and templates
res._update_related_files_and_templates()
return res
def write(self, vals):
# Sanitize head
if "head" in vals:
head = vals["head"]
if head and "/" in head:
vals["head"] = self._sanitize_head(head)
res = super().write(vals)
# Update related files and templates on update
self._update_related_files_and_templates()
return res
def unlink(self):
"""
Override to update related files and templates on unlink
"""
related_files = self.mapped("git_project_id").mapped("git_project_rel_ids")
related_templates = self.mapped("git_project_id").mapped(
"git_project_file_template_rel_ids"
)
res = super().unlink()
# Update related files and templates on unlink
if related_files:
related_files._save_to_file()
if related_templates:
related_templates._save_to_file_template()
return res
def _sanitize_head(self, head):
"""Sanitize head.
Extract head number from head url
and set it as head.
Args:
head (Char): Head to sanitize
Returns:
Char: Sanitized head
"""
if head and "/" in head:
return head.split("/")[-1].strip()
return head
@api.model
def get_head_data(self):
"""
This method is used to get values for the dropdown dynamic widget.
It is designed for integrations with repo providers using APIs.
Returns:
List: List of tuples(selection, name)
eg [('18.0', '18.0'), ('main', 'main'), ('develop', 'develop')]
"""
values = [
("18.0", "18.0"),
("main", "Main"),
("develop", "Develop"),
("17.0", "17.0"),
]
return values
def _update_related_files_and_templates(self):
# Update related files on update
related_files = self.mapped("git_project_id").mapped("git_project_rel_ids")
if related_files:
related_files._save_to_file()
related_templates = self.mapped("git_project_id").mapped(
"git_project_file_template_rel_ids"
)
if related_templates:
related_templates._save_to_file_template()
# ------------------------------
# Reference mixin methods
# ------------------------------
def _get_pre_populated_model_data(self):
res = super()._get_pre_populated_model_data()
res.update({"cx.tower.git.remote": ["cx.tower.git.source", "source_id"]})
return res
# ------------------------------
# YAML mixin methods
# ------------------------------
def _get_fields_for_yaml(self):
res = super()._get_fields_for_yaml()
res += [
"name",
"enabled",
"sequence",
"repo_id",
"head",
"head_type",
]
return res
# ------------------------------
# Git Aggregator related methods
# ------------------------------
def _git_aggregator_prepare_url(self):
"""Prepare url for git aggregator
Returns:
Char: Prepared url for git aggregator
"""
self.ensure_one()
if not self.repo_id:
raise ValidationError(_("Repository is required"))
if not self.repo_id.url:
raise ValidationError(_("Repository URL is not set"))
url = self.repo_id.url
prepared_url = giturlparse.parse(url).urls.get(self.url_protocol, url)
# If repo is public or is not using HTTPS protocol return URL as is
if not self.is_private or self.url_protocol != "https":
return prepared_url
if self.repo_provider == "github":
prepared_url = self._git_aggregator_prepare_url_github(prepared_url)
elif self.repo_provider == "gitlab":
prepared_url = self._git_aggregator_prepare_url_gitlab(prepared_url)
elif self.repo_provider == "bitbucket":
prepared_url = self._git_aggregator_prepare_url_bitbucket(prepared_url)
return prepared_url
def _git_aggregator_prepare_url_github(self, url):
"""Prepare url for git aggregator
for private Github repo using https protocol.
Args:
url (Char): URL to prepare
Returns:
Char: Prepared url for git aggregator
"""
self.ensure_one()
# This is how final url will look like
# https://$GITHUB_TOKEN:x-oauth-basic@github.com/soem_org/some_private_repo.git
url_without_protocol = url.replace("https://", "")
url = f"https://$GITHUB_TOKEN:x-oauth-basic@{url_without_protocol}"
return url
def _git_aggregator_prepare_url_gitlab(self, url):
"""Prepare url for git aggregator
for private GitLab repo using https protocol.
Args:
url (Char): URL to prepare
Returns:
Char: Prepared url for git aggregator
"""
self.ensure_one()
# This is how final url will look like
# https://<token-name>:<token-value>@<gitlaburl-repository>.git
url_without_protocol = url.replace("https://", "")
url = f"https://$GITLAB_TOKEN_NAME:$GITLAB_TOKEN@{url_without_protocol}"
return url
def _git_aggregator_prepare_url_bitbucket(self, url):
"""Prepare url for git aggregator
for private Github repo using https protocol.
Args:
url (Char): URL to prepare
Returns:
Char: Prepared url for git aggregator
"""
self.ensure_one()
# This is how final url will look like
# https://x-token-auth:{access_token}@bitbucket.org/user/repo.git
# From https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/
url_without_protocol = url.replace("https://", "")
url = f"https://x-token-auth:$BITBUCKET_TOKEN@{url_without_protocol}"
return url
def _git_aggregator_prepare_head(self):
"""Prepare head for git aggregator
Returns:
Char: Prepared head for git aggregator
"""
self.ensure_one()
if self.repo_provider == "github":
return self._git_aggregator_prepare_head_github()
if self.repo_provider == "gitlab":
return self._git_aggregator_prepare_head_gitlab()
if self.repo_provider == "bitbucket":
return self._git_aggregator_prepare_head_bitbucket()
return self.head
def _git_aggregator_prepare_head_github(self):
"""Prepare head for git aggregator for Github.
Returns:
Char: Prepared head for git aggregator
"""
# Extract branch name, PR/MR or commit number from head
head_number = self.head.split("/")[-1]
if not head_number:
raise ValidationError(
_("Git Aggregator: " "Head number is empty in %(head)s", head=self.head)
)
# PR/MR
if self.head_type == "pr":
return f"refs/pull/{head_number}/head"
# Commit
if self.head_type in ["commit", "branch"]:
return f"{head_number}"
# Fallback to original head
return self.head
def _git_aggregator_prepare_head_gitlab(self):
"""Prepare head for git aggregator for GitLab.
Returns:
Char: Prepared head for git aggregator
"""
# Extract branch name, PR/MR or commit number from head
head_number = self.head.split("/")[-1]
if not head_number:
raise ValidationError(
_("Git Aggregator: " "Head number is empty in %(head)s", head=self.head)
)
# PR/MR
if self.head_type == "pr":
return f"merge-requests/{head_number}/head"
# Commit
# https://gitlab.com/cetmix/test/-/tree/17.0-test-branch?ref_type=heads
if self.head_type in ["commit", "branch"]:
head_parts = head_number.split("?")
return f"{head_parts[0]}"
# Fallback to original head
return self.head
def _git_aggregator_prepare_head_bitbucket(self):
"""Prepare head for git aggregator for Bitbucket.
Returns:
Char: Prepared head for git aggregator
"""
# Extract branch name, PR/MR or commit number from head
head_number = self.head.split("/")[-1]
if not head_number:
raise ValidationError(
_("Git Aggregator: " "Head number is empty in %(head)s", head=self.head)
)
# PR/MR
if self.head_type == "pr":
raise ValidationError(
_(
"Git Aggregator: "
"Bitbucket does not support"
" fetching PRs. Please use branch instead.\n\n"
"Source: %(src)s\n"
"URL: %(url)s\n"
"Head: %(head)s",
src=self.source_id.name,
url=self.repo_id.url,
head=self.head,
)
)
# Commit
if self.head_type in ["commit", "branch"]:
return f"{head_number}"
# Fallback to original head
return self.head

View File

@@ -0,0 +1,409 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import giturlparse
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import ormcache
class CxTowerGitRepo(models.Model):
"""
Git Repository.
Represents a git repository with its metadata and configuration.
"""
_name = "cx.tower.git.repo"
_inherit = [
"cx.tower.reference.mixin",
"cx.tower.yaml.mixin",
]
_description = "Cetmix Tower Git Repository"
_order = "name"
_rec_names_search = ["repo", "host", "owner_id"]
active = fields.Boolean(default=True, help="Indicates if the repository is active")
name = fields.Char(
compute="_compute_name", store=True, required=False, index="trigram"
)
reference = fields.Char(
index=True,
compute="_compute_name",
required=False,
store=True,
)
repo = fields.Char(
string="Repository Name",
readonly=True,
help="Repository name (e.g., 'cetmix-tower', 'odoo')",
)
url = fields.Char(
string="Generic URL",
help="Displayed in 'https' format, but can be entered in any format",
compute="_compute_url",
inverse="_inverse_url",
required=True,
compute_sudo=True,
)
url_ssh = fields.Char(
string="SSH URL",
help="SSH URL of the repository",
compute="_compute_url",
compute_sudo=True,
)
url_git = fields.Char(
string="GIT URL",
help="GIT URL of the repository",
compute="_compute_url",
compute_sudo=True,
)
is_private = fields.Boolean(
string="Private", default=False, help="Indicates if the repository is private"
)
provider = fields.Selection(
selection="_selection_provider",
required=True,
default="other",
help="Repository provider to determine provider-based behaviour",
)
host = fields.Char(
readonly=True,
index=True,
help="Repository host (e.g., 'github.com', 'gitlab.com')",
)
owner_id = fields.Many2one(
comodel_name="cx.tower.git.repo.owner",
readonly=True,
help="Repository owner (e.g., 'cetmix' or 'OCA')",
)
secret_id = fields.Many2one(
comodel_name="cx.tower.key",
string="Secret",
domain="[('key_type', '=', 's')]",
help="Custom secret used for this repository",
)
remote_ids = fields.One2many(
comodel_name="cx.tower.git.remote",
inverse_name="repo_id",
help="Remotes that use this repository",
)
git_project_ids = fields.Many2many(
comodel_name="cx.tower.git.project",
relation="cx_tower_git_repo_project_rel",
column1="repo_id",
column2="project_id",
compute="_compute_git_project_ids",
store=True,
help="Projects this repository is used in",
)
remote_count = fields.Integer(
compute="_compute_remote_count",
help="Number of remotes this repository is used in",
)
git_project_count = fields.Integer(
compute="_compute_git_project_count",
help="Number of projects this repository is used in",
)
_sql_constraints = [
(
"unique_repo_host_owner",
"unique(repo, host, owner_id)",
"A repository with the same name, host, and owner already exists.",
),
]
# -- Selection
def _selection_provider(self):
"""Available repository providers.
Returns:
List of tuples: available options.
"""
return [
("github", "GitHub"),
("gitlab", "GitLab"),
("bitbucket", "Bitbucket"),
("assembla", "Assembla"),
("other", "Other"),
]
# -- Computes
@api.depends("host", "owner_id", "repo")
def _compute_name(self):
"""
Compute name in format: host/owner/name.
Compute reference based on name.
"""
for repo in self:
if repo.host and repo.owner_id and repo.repo:
name = f"{repo.host}/{repo.owner_id.name}/{repo.repo}"
reference = repo._generate_or_fix_reference(name)
repo.update(
{
"name": name,
"reference": reference,
}
)
else:
repo.update(
{
"name": False,
"reference": False,
}
)
@api.depends("remote_ids", "remote_ids.git_project_id")
def _compute_git_project_ids(self):
"""Compute projects this repository is used in."""
for repo in self:
projects = repo.remote_ids.mapped("git_project_id")
repo.git_project_ids = [(6, 0, projects.ids)]
@api.depends("remote_ids")
def _compute_remote_count(self):
"""Compute remote count field."""
for repo in self:
repo.remote_count = len(repo.remote_ids)
@api.depends("git_project_ids")
def _compute_git_project_count(self):
"""Compute project count field."""
for repo in self:
repo.git_project_count = len(repo.git_project_ids)
@api.depends("repo", "host", "owner_id")
def _compute_url(self):
"""Compute URL from repository properties."""
for repo in self:
if repo.repo and repo.host and repo.owner_id:
https_url = f"https://{repo.host}/{repo.owner_id.name}/{repo.repo}.git"
elif repo.repo and repo.host:
https_url = f"https://{repo.host}/{repo.repo}.git"
else:
https_url = ""
if https_url:
try:
parsed_urls = giturlparse.parse(https_url).urls
urls = {
"url": https_url,
"url_ssh": parsed_urls["ssh"],
"url_git": parsed_urls["git"],
}
except Exception as e: # noqa: F841 catch all errors
urls = {
"url": "",
"url_ssh": "",
"url_git": "",
}
else:
urls = {
"url": "",
"url_ssh": "",
"url_git": "",
}
repo.update(urls)
def _inverse_url(self):
"""Parse URL to update repository properties."""
for repo in self:
if not repo.url:
continue
# Parse URL
parsed_url_dict = self._parse_url(repo.url)
# Update repository properties
repo.update(parsed_url_dict)
def action_view_remotes(self):
"""Open remotes list view."""
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id(
"cetmix_tower_git.action_cx_tower_git_remote"
)
action.update(
{
"domain": [("repo_id", "=", self.id)],
"context": {"default_repo_id": self.id},
}
)
return action
def action_view_projects(self):
"""Open projects list view."""
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id(
"cetmix_tower_git.cx_tower_git_project_action"
)
action.update(
{
"domain": [("repo_ids", "in", self.id)],
"context": {"default_repo_ids": [(4, self.id)]},
}
)
return action
@api.model_create_multi
def create(self, vals_list):
"""Create multiple repositories."""
# Check if any of the repositories already exist
# This is needed to allow creating repositories using just an URL.
# Eg when importing repositories from a YAML file.
res = self.browse()
existing_repo_ids = []
vals_list_to_create = []
for vals in vals_list:
url = vals.get("url")
if url:
# Try to get repository by URL
repo_id = self._get_repo_id_by_url(
url=url, create=False, raise_if_invalid=False
)
if repo_id:
existing_repo_ids.append(repo_id)
continue
# Parse URL and update vals
parsed_url_dict = self._parse_url(url=url, raise_if_invalid=True)
vals.update(parsed_url_dict)
# Otherwise, add to create list
vals_list_to_create.append(vals)
# Compose the result
if vals_list_to_create:
res |= super().create(vals_list_to_create)
if existing_repo_ids:
res |= self.browse(existing_repo_ids)
self.clear_caches()
return res
def write(self, vals):
"""Write repositories."""
res = super().write(vals)
self.clear_caches()
return res
def unlink(self):
"""Unlink repositories."""
res = super().unlink()
self.clear_caches()
return res
@api.model
def name_create(self, name):
"""
Create a new repository from a URL.
"""
repo_id = self._get_repo_id_by_url(url=name, create=True, raise_if_invalid=True)
repo = self.browse(repo_id)
return repo_id, repo.display_name
@ormcache("self.env.uid", "self.env.su", "url")
def _get_repo_id_by_url(self, url, create=False, raise_if_invalid=False):
"""Get repository id by URL.
Args:
url (Char): URL to get repository id
create (Bool, optional): Create repository if not found.
Default is False.
raise_if_invalid (Bool, optional): Raise ValidationError
if the URL is not valid. Default is False.
Returns:
int: Repository ID
or False if the URL is not valid and raise_if_invalid is False
Raises:
ValidationError: If the URL is not valid and raise_if_invalid is True
"""
# Parse URL
parsed_url_dict = self._parse_url(url, raise_if_invalid=raise_if_invalid)
if not parsed_url_dict:
return False
# Check if repository already exists and use it
repo = self.search(
[
("repo", "=", parsed_url_dict["repo"]),
("host", "=", parsed_url_dict["host"]),
("owner_id", "=", parsed_url_dict["owner_id"]),
],
limit=1,
)
# Otherwise, create a new one
if not repo and create:
repo = self.create(parsed_url_dict)
return repo.id if repo else False
def _parse_url(self, url, raise_if_invalid=True):
"""Parse URL to get name, host and owner.
Args:
url (Char): URL to parse
Raises:
ValidationError: If the URL is not valid
Returns:
Dict: Dictionary with name, host and owner
or empty dict if the URL is not valid and raise_if_invalid is False
"""
# Validate URL
if not giturlparse.validate(url):
if raise_if_invalid:
raise ValidationError(_("Not a valid repository URL!"))
return {}
# Parse URL
parsed_url = giturlparse.parse(url)
# Get or create owner
owner_id = self.env["cx.tower.git.repo.owner"]._get_owner_id_by_name(
name=parsed_url.owner,
create=True,
)
# Get provider based on host
provider = self._get_provider(parsed_url)
return {
"repo": parsed_url.repo,
"host": parsed_url.host,
"owner_id": owner_id,
"provider": provider,
}
def _get_provider(self, parsed_url):
"""Get provider.
Args:
parsed_url (GitUrlParsed): Parsed URL object
Returns:
str: Provider name
"""
provider = "other"
if parsed_url.assembla:
provider = "assembla"
elif parsed_url.bitbucket or "bitbucket" in parsed_url.host:
provider = "bitbucket"
elif parsed_url.gitlab:
provider = "gitlab"
elif parsed_url.github:
provider = "github"
return provider
# ------------------------------
# YAML mixin methods
# ------------------------------
def _get_fields_for_yaml(self):
res = super()._get_fields_for_yaml()
res += [
"url",
"is_private",
"secret_id",
]
return res

View File

@@ -0,0 +1,107 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools import ormcache
class CxTowerGitRepoOwner(models.Model):
"""
Git Repository Owner.
Represents an organization or user that owns repositories.
Examples: "cetmix", "OCA", etc.
"""
_name = "cx.tower.git.repo.owner"
_inherit = ["cx.tower.reference.mixin", "cx.tower.yaml.mixin"]
_description = "Cetmix Tower Git Repository Owner"
_order = "name"
display_name = fields.Char(
readonly=False, compute="_compute_display_name", store=True
)
name = fields.Char(
help="Name of the repository owner (e.g., 'cetmix', 'OCA')",
)
reference = fields.Char(
index=True,
compute="_compute_display_name",
required=False,
store=True,
)
repo_ids = fields.One2many(
comodel_name="cx.tower.git.repo",
inverse_name="owner_id",
string="Repositories",
copy=False,
help="Repositories owned by this organization/user",
)
secret_id = fields.Many2one(
comodel_name="cx.tower.key",
string="Secret",
domain="[('key_type', '=', 's')]",
help="Custom secret used for this repository owner",
)
@api.depends("name")
def _compute_display_name(self):
"""Compute display name."""
for owner in self:
# By default, display name is the same as name
name = owner.name
owner.update(
{
"display_name": name or False,
"reference": owner._generate_or_fix_reference(name)
if name
else False,
}
)
@ormcache("self.env.uid", "self.env.su", "name")
def _get_owner_id_by_name(self, name, create=False):
"""Get owner id by name.
Args:
name (str): Owner name
create (bool): Create owner if not found
Returns:
int: Owner ID or None if not found
"""
owner = self.search([("name", "=ilike", name)], limit=1) if name else None
if not owner and create and name:
owner = self.create({"name": name})
return owner.id if owner else None
@api.model_create_multi
def create(self, vals_list):
"""Clear cache on create."""
res = super().create(vals_list)
self.clear_caches()
return res
def write(self, vals):
"""Clear cache on write."""
res = super().write(vals)
if "name" in vals:
self.clear_caches()
return res
def unlink(self):
"""Clear cache on unlink."""
res = super().unlink()
self.clear_caches()
return res
# ------------------------------
# YAML mixin methods
# ------------------------------
def _get_fields_for_yaml(self):
res = super()._get_fields_for_yaml()
res += [
"display_name",
"name",
"secret_id",
]
return res

View File

@@ -0,0 +1,189 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
class CxTowerGitSource(models.Model):
"""
Git Source.
Implements single git source.
Each source can include multiple remotes which can be
branches or pull requests of different repositories.
"""
_name = "cx.tower.git.source"
_description = "Cetmix Tower Git Source"
_inherit = [
"cx.tower.reference.mixin",
"cx.tower.yaml.mixin",
]
_order = "sequence, name"
active = fields.Boolean(related="git_project_id.active", store=True, readonly=True)
enabled = fields.Boolean(
default=True, help="Enable in configuration and exported to files"
)
name = fields.Char(required=False)
sequence = fields.Integer(default=10)
git_project_id = fields.Many2one(
comodel_name="cx.tower.git.project",
string="Git Configuration",
required=True,
ondelete="cascade",
auto_join=True,
)
remote_ids = fields.One2many(
comodel_name="cx.tower.git.remote",
inverse_name="source_id",
auto_join=True,
copy=True,
)
remote_count = fields.Integer(
compute="_compute_remote_count",
string="Remotes",
)
remote_count_private = fields.Integer(
compute="_compute_remote_count",
string="Private Remotes",
)
@api.depends("remote_ids", "remote_ids.enabled", "remote_ids.is_private")
def _compute_remote_count(self):
for record in self:
remote_count = private_remote_count = 0
for remote in record.remote_ids:
if not remote.enabled:
continue
if remote.is_private:
private_remote_count += 1
remote_count += 1
record.update(
{
"remote_count": remote_count,
"remote_count_private": private_remote_count,
}
)
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
# Update name
res._compose_name()
# Update related files and templates on create
res._update_related_files_and_templates()
return res
def write(self, vals):
res = super().write(vals)
# Compose name
if "name" in vals and not vals.get("name"):
self._compose_name()
# Update related files and templates on update
self._update_related_files_and_templates()
return res
def unlink(self):
"""
Override to update related files and templates on unlink
"""
related_files = self.mapped("git_project_id").mapped("git_project_rel_ids")
related_templates = self.mapped("git_project_id").mapped(
"git_project_file_template_rel_ids"
)
res = super().unlink()
# Update related files and templates on unlink
if related_files:
related_files._save_to_file()
if related_templates:
related_templates._save_to_file_template()
return res
def _compose_name(self):
"""Compose name if not provided explicitly"""
for source in self:
if source.name:
continue
remote = fields.first(source.remote_ids)
if not remote:
source.name = _("Empty Source")
continue
remote_repo = remote.repo_id
source.name = f"{remote_repo.owner_id.name}/{remote_repo.repo}"
def _update_related_files_and_templates(self):
# Update related files and templates on update
related_files = self.mapped("git_project_id").mapped("git_project_rel_ids")
if related_files:
related_files._save_to_file()
related_templates = self.mapped("git_project_id").mapped(
"git_project_file_template_rel_ids"
)
if related_templates:
related_templates._save_to_file_template()
# ------------------------------
# Reference mixin methods
# ------------------------------
def _get_pre_populated_model_data(self):
res = super()._get_pre_populated_model_data()
res.update({"cx.tower.git.source": ["cx.tower.git.project", "git_project_id"]})
return res
# ------------------------------
# YAML mixin methods
# ------------------------------
def _get_fields_for_yaml(self):
res = super()._get_fields_for_yaml()
res += [
"name",
"enabled",
"sequence",
"remote_ids",
]
return res
# ------------------------------
# Git Aggregator related methods
# ------------------------------
def _git_aggregator_prepare_record(self):
"""Prepare json structure for git aggregator.
Returns:
Dict: Json structure for git aggregator
"""
self.ensure_one()
# Prepare remotes, merges and target
remotes = {}
merges = []
target = None
for remote in self.remote_ids:
if remote.enabled:
remotes.update({remote.name: remote._git_aggregator_prepare_url()})
merges.append(
{
"remote": remote.name,
"ref": remote._git_aggregator_prepare_head(),
}
)
# Set target to first remote name
if not target:
target = remote.name
# If no remotes, return empty dict
if not remotes:
return {}
vals = {
"remotes": remotes,
"merges": merges,
"target": target,
}
# Fetch only first commit if there is only one remote
if len(remotes) == 1:
vals.update({"defaults": {"depth": 1}})
return vals

View File

@@ -0,0 +1,32 @@
# Copyright (C) 2025 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class CxTowerPlanLine(models.Model):
"""Flight Plan Line"""
_inherit = "cx.tower.plan.line"
git_project_id = fields.Many2one(
comodel_name="cx.tower.git.project",
string="Git Project",
help="Select a git project to be linked to the file and server.",
)
is_make_copy = fields.Boolean(
string="Make a Copy",
help="Create a copy of the Git Project instead of linking "
"the file to the existing one.",
)
# ------------------------------
# YAML mixin methods
# ------------------------------
def _get_fields_for_yaml(self):
res = super()._get_fields_for_yaml()
res += [
"git_project_id",
"is_make_copy",
]
return res

View File

@@ -0,0 +1,156 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class CxTowerServer(models.Model):
_inherit = "cx.tower.server"
git_project_rel_ids = fields.One2many(
comodel_name="cx.tower.git.project.rel",
inverse_name="server_id",
copy=False,
depends=["git_project_ids"],
groups="cetmix_tower_server.group_manager,cetmix_tower_server.group_root",
)
# Helper field to get all git projects related to server
# IMPORTANT: This field may contain duplicates because of the relation nature!
git_project_ids = fields.Many2many(
comodel_name="cx.tower.git.project",
relation="cx_tower_git_project_rel",
column1="server_id",
column2="git_project_id",
readonly=True,
copy=False,
depends=["git_project_rel_ids"],
groups="cetmix_tower_server.group_manager,cetmix_tower_server.group_root",
)
# ------------------------------
# YAML mixin methods
# ------------------------------
def _get_fields_for_yaml(self):
res = super()._get_fields_for_yaml()
res += [
"git_project_rel_ids",
]
return res
def _get_force_x2m_resolve_models(self):
res = super()._get_force_x2m_resolve_models()
# Add File in order to always try to use existing one
res += ["cx.tower.file"]
return res
def _update_or_create_related_record(
self, model, reference, values, create_immediately=False
):
# Files must be created immediately because they are related
# to both server and git project.
# So if a file is not created immediately when it is created
# for the server, the same file will be created for the git project.
# This will lead to creation of two files with the same content
# for the same server.
if model._name == "cx.tower.file":
create_immediately = True
return super()._update_or_create_related_record(
model, reference, values, create_immediately=create_immediately
)
@api.model
def get_servers_by_git_ref(self, repository_url, head=None, head_type=None):
"""
Return servers linked to a given Git repository reference.
Parameters
----------
repository_url : str
Pre-normalized canonical Git URL
(e.g. ``https://host/owner/repo.git``).
head : str, optional
Branch name, commit SHA, or PR identifier.
head_type : {'branch', 'commit', 'pr'}, optional
Type of the ``head`` argument.
If only ``head`` is provided, it will match across all head types.
If only ``head_type`` is provided, it will filter by type regardless of head
Returns
-------
recordset of cx.tower.server
Matching servers. Empty recordset if no matches.
"""
server_obj = self.env["cx.tower.server"]
# URL MUST be already canonical.
if not repository_url:
return server_obj
# Get repository id by URL
repo_id = self.env["cx.tower.git.repo"]._get_repo_id_by_url(
repository_url, raise_if_invalid=False
)
if not repo_id:
return server_obj
repo = self.env["cx.tower.git.repo"].browse(repo_id)
# Compose domain for remotes
remote_domain = [
("source_id.enabled", "=", True),
("enabled", "=", True),
]
if head:
head = self.env["cx.tower.git.remote"]._sanitize_head(head)
remote_domain.append(("head", "=", head))
if head_type:
remote_domain.append(("head_type", "=", head_type))
# Get remotes
remotes = repo.remote_ids.filtered_domain(remote_domain)
if not remotes:
return server_obj
# Get servers from remotes
servers = remotes.mapped("git_project_id.git_project_rel_ids.server_id")
return servers
def _command_runner_file_using_template_create_file(
self,
file_template_id,
server_dir,
plan_line,
if_file_exists,
**kwargs,
):
"""Override to create git project relation
when creating a file using a template.
"""
file = super()._command_runner_file_using_template_create_file(
file_template_id, server_dir, plan_line, if_file_exists, **kwargs
)
if file and plan_line:
git_project = plan_line.git_project_id
if not git_project:
return file
if plan_line.is_make_copy:
# Remove default_server_ids from context, because this relation
# will be created through git_project_rel_ids.
# default_server_ids will interfere at the moment when
# pairs of values are created through SQL query
# in the method write_real and it does not take into account
# that in this case we are creating a copy of the git project
git_project = git_project.with_context(default_server_ids=False).copy()
self.env["cx.tower.git.project.rel"].create(
{
"git_project_id": git_project.id,
"server_id": self.id,
"file_id": file.id,
"project_format": git_project._default_project_format(),
}
)
return file

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1 @@
Please refer to the [official documentation](https://cetmix.com/tower) for detailed configuration instructions.

View File

@@ -0,0 +1,3 @@
This module implements Git Management functionality for [Cetmix Tower](https://cetmix.com/tower).
Please refer to the [official documentation](https://cetmix.com/tower) for detailed information.

View File

@@ -0,0 +1,43 @@
## 16.0.2.0.1 (2025-12-11)
- Features: Improve search views, implement the search panel for selected views. (5139)
## 16.0.2.0.0 (2025-10-27)
- Features: Major refactoring: implement Git repository entity. (4914)
## 16.0.1.0.6 (2025-08-18)
- Features: Link or copy a git project when uploading the linked file using command (4759)
## 16.0.1.0.5 (2025-08-17)
- Features: Search servers by git reference (4838)
## 16.0.1.0.4 (2025-07-29)
- Features: Export related commands and flight plans together with server (4849)
## 16.0.1.0.3 (2025-05-23)
- Bugfixes: Duplicated file is created when importing a YAML file with a git project. (4715)
## 16.0.1.0.2 (2025-05-16)
- Features: Record references for git relations. (4670)
## 16.0.1.0.1 (2025-05-09)
- Bugfixes: Non-critical issues and performance improvements. (4663)
## 16.0.1.0.0
Release for Odoo 16.0

View File

@@ -0,0 +1 @@
Please refer to the [official documentation](https://cetmix.com/tower) for detailed usage instructions.

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Manager Read Rule -->
<record id="rule_git_project_file_template_rel_manager_read" model="ir.rule">
<field
name="name"
>Git Project File Template Relation: Manager Read Access</field>
<field name="model_id" ref="model_cx_tower_git_project_file_template_rel" />
<field name="domain_force">['&amp;',
'|',
('git_project_id.user_ids', 'in', [user.id]),
('git_project_id.manager_ids', 'in', [user.id]),
'|',
('file_template_id.user_ids', 'in', [user.id]),
('file_template_id.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Manager Write/Create/Delete Rule -->
<record id="rule_git_project_file_template_rel_manager_write" model="ir.rule">
<field
name="name"
>Git Project File Template Relation: Manager Write Access</field>
<field name="model_id" ref="model_cx_tower_git_project_file_template_rel" />
<field name="domain_force">[
('git_project_id.manager_ids', 'in', [user.id]),
('file_template_id.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="1" />
</record>
<!-- Root Access Rule -->
<record id="rule_git_project_file_template_rel_root" model="ir.rule">
<field name="name">Git Project File Template Relation: Root Full Access</field>
<field name="model_id" ref="model_cx_tower_git_project_file_template_rel" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
</record>
</odoo>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Manager Read Rule -->
<record id="rule_git_project_rel_manager_read" model="ir.rule">
<field name="name">Git Project Relation: Manager Read Access</field>
<field name="model_id" ref="model_cx_tower_git_project_rel" />
<field name="domain_force">['&amp;',
'|',
('git_project_id.user_ids', 'in', [user.id]),
('git_project_id.manager_ids', 'in', [user.id]),
'|',
('server_id.user_ids', 'in', [user.id]),
('server_id.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Manager Write/Create/Delete Rule -->
<record id="rule_git_project_rel_manager_create_write_unlink" model="ir.rule">
<field
name="name"
>Git Project Relation: Manager Create/Write/Delete Access</field>
<field name="model_id" ref="model_cx_tower_git_project_rel" />
<field name="domain_force">[('git_project_id.manager_ids', 'in', [user.id]),
('server_id.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="1" />
</record>
<!-- Root Access Rule -->
<record id="rule_git_project_rel_root" model="ir.rule">
<field name="name">Git Project Relation: Root Full Access</field>
<field name="model_id" ref="model_cx_tower_git_project_rel" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
</record>
</odoo>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Manager Read Rule -->
<record id="rule_git_project_manager_read" model="ir.rule">
<field name="name">Git Project: Manager Read Access</field>
<field name="model_id" ref="model_cx_tower_git_project" />
<field
name="domain_force"
>['|', ('user_ids', 'in', [user.id]), ('manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Additional Manager Read Rule with Server Access -->
<record id="rule_git_project_manager_read_server" model="ir.rule">
<field name="name">Git Project: Manager Read Access via Server</field>
<field name="model_id" ref="model_cx_tower_git_project" />
<field name="domain_force">['|',
('server_ids.user_ids', 'in', [user.id]),
('server_ids.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Manager Write/Create Rule -->
<record id="rule_git_project_manager_write" model="ir.rule">
<field name="name">Git Project: Manager Write Access</field>
<field name="model_id" ref="model_cx_tower_git_project" />
<field name="domain_force">[('manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Manager Delete Rule -->
<record id="rule_git_project_manager_unlink" model="ir.rule">
<field name="name">Git Project: Manager Delete Access</field>
<field name="model_id" ref="model_cx_tower_git_project" />
<field
name="domain_force"
>[('manager_ids', 'in', [user.id]), ('create_uid', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="1" />
</record>
<!-- Root Access Rule -->
<record id="rule_git_project_root" model="ir.rule">
<field name="name">Git Project: Root Full Access</field>
<field name="model_id" ref="model_cx_tower_git_project" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
</record>
</odoo>

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Manager Read Rule -->
<record id="rule_git_remote_manager_read" model="ir.rule">
<field name="name">Git Remote: Manager Read Access</field>
<field name="model_id" ref="model_cx_tower_git_remote" />
<field
name="domain_force"
>['|', ('git_project_id.user_ids', 'in', [user.id]), ('git_project_id.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Additional Manager Read Rule with Server Access -->
<record id="rule_git_remote_manager_read_server" model="ir.rule">
<field name="name">Git Remote: Manager Read Access via Server</field>
<field name="model_id" ref="model_cx_tower_git_remote" />
<field name="domain_force">['|',
('git_project_id.server_ids.user_ids', 'in', [user.id]),
('git_project_id.server_ids.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Manager Write/Create Rule -->
<record id="rule_git_remote_manager_write" model="ir.rule">
<field name="name">Git Remote: Manager Write/Create Access</field>
<field name="model_id" ref="model_cx_tower_git_remote" />
<field
name="domain_force"
>[('git_project_id.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Manager Delete Rule -->
<record id="rule_git_remote_manager_unlink" model="ir.rule">
<field name="name">Git Remote: Manager Delete Access</field>
<field name="model_id" ref="model_cx_tower_git_remote" />
<field
name="domain_force"
>[('git_project_id.manager_ids', 'in', [user.id]), ('create_uid', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="1" />
</record>
<!-- Root Access Rule -->
<record id="rule_git_remote_root" model="ir.rule">
<field name="name">Git Remote: Root Full Access</field>
<field name="model_id" ref="model_cx_tower_git_remote" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="1" />
</record>
</odoo>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Manager Read Rule - View All Records - nothing to add as this is default -->
<!-- Manager Write/Create Rule -->
<record id="rule_git_repo_owner_manager_write" model="ir.rule">
<field name="name">Git Repository Owner: Manager Write/Create Access</field>
<field name="model_id" ref="model_cx_tower_git_repo_owner" />
<field name="domain_force">[('create_uid', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Root Access Rule -->
<record id="rule_git_repo_owner_root" model="ir.rule">
<field name="name">Git Repository Owner: Root Full Access</field>
<field name="model_id" ref="model_cx_tower_git_repo_owner" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
</record>
</odoo>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Manager Read Rule - View All Records - nothing to add as this is default -->
<!-- Manager Write/Create Rule -->
<record id="rule_git_repo_manager_write" model="ir.rule">
<field name="name">Git Repository: Manager Write/Create Access</field>
<field name="model_id" ref="model_cx_tower_git_repo" />
<field name="domain_force">[('create_uid', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Root Access Rule -->
<record id="rule_git_repo_root" model="ir.rule">
<field name="name">Git Repository: Root Full Access</field>
<field name="model_id" ref="model_cx_tower_git_repo" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
</record>
</odoo>

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Git Source Record Rules -->
<!-- Manager Read Rule -->
<record id="rule_git_source_manager_read" model="ir.rule">
<field name="name">Git Source: Manager Read Access</field>
<field name="model_id" ref="model_cx_tower_git_source" />
<field
name="domain_force"
>['|', ('git_project_id.user_ids', 'in', [user.id]), ('git_project_id.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Additional Manager Read Rule with Server Access -->
<record id="rule_git_source_manager_read_server" model="ir.rule">
<field name="name">Git Source: Manager Read Access via Server</field>
<field name="model_id" ref="model_cx_tower_git_source" />
<field name="domain_force">['|',
('git_project_id.server_ids.user_ids', 'in', [user.id]),
('git_project_id.server_ids.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Manager Write/Create Rule -->
<record id="rule_git_source_manager_write" model="ir.rule">
<field name="name">Git Source: Manager Write/Create Access</field>
<field name="model_id" ref="model_cx_tower_git_source" />
<field
name="domain_force"
>[('git_project_id.manager_ids', 'in', [user.id])]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="0" />
</record>
<!-- Manager Delete Rule -->
<record id="rule_git_source_manager_unlink" model="ir.rule">
<field name="name">Git Source: Manager Delete Access</field>
<field name="model_id" ref="model_cx_tower_git_source" />
<field
name="domain_force"
>[('git_project_id.manager_ids', 'in', [user.id]), ('create_uid', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
<field name="perm_read" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_unlink" eval="1" />
</record>
<!-- Root Access Rule -->
<record id="rule_git_source_root" model="ir.rule">
<field name="name">Git Source: Root Full Access</field>
<field name="model_id" ref="model_cx_tower_git_source" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
<field name="perm_read" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="1" />
</record>
</odoo>

View File

@@ -0,0 +1,15 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_git_config_manager,Git Config Manager,model_cx_tower_git_project,cetmix_tower_server.group_manager,1,1,1,1
access_git_config_root,Git Config Root,model_cx_tower_git_project,cetmix_tower_server.group_root,1,1,1,1
access_git_source_manager,Git Source Manager,model_cx_tower_git_source,cetmix_tower_server.group_manager,1,1,1,1
access_git_source_root,Git Source Root,model_cx_tower_git_source,cetmix_tower_server.group_root,1,1,1,1
access_git_remote_manager,Git Remote Manager,model_cx_tower_git_remote,cetmix_tower_server.group_manager,1,1,1,1
access_git_remote_root,Git Remote Root,model_cx_tower_git_remote,cetmix_tower_server.group_root,1,1,1,1
access_git_repo_manager,Git Repository Manager,model_cx_tower_git_repo,cetmix_tower_server.group_manager,1,1,1,1
access_git_repo_root,Git Repository Root,model_cx_tower_git_repo,cetmix_tower_server.group_root,1,1,1,1
access_git_repo_owner_manager,Git Repository Owner Manager,model_cx_tower_git_repo_owner,cetmix_tower_server.group_manager,1,1,1,0
access_git_repo_owner_root,Git Repository Owner Root,model_cx_tower_git_repo_owner,cetmix_tower_server.group_root,1,1,1,1
access_git_project_server_file_rel,Git Project Server File Rel Manager,model_cx_tower_git_project_rel,cetmix_tower_server.group_manager,1,1,1,1
access_git_project_server_file_rel_root,Git Project Server File Rel Root,model_cx_tower_git_project_rel,cetmix_tower_server.group_root,1,1,1,1
access_git_project_file_template_rel,Git Project File Template Rel Manager,model_cx_tower_git_project_file_template_rel,cetmix_tower_server.group_manager,1,1,1,1
access_git_project_file_template_rel_root,Git Project File Template Rel Root,model_cx_tower_git_project_file_template_rel,cetmix_tower_server.group_root,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_git_config_manager Git Config Manager model_cx_tower_git_project cetmix_tower_server.group_manager 1 1 1 1
3 access_git_config_root Git Config Root model_cx_tower_git_project cetmix_tower_server.group_root 1 1 1 1
4 access_git_source_manager Git Source Manager model_cx_tower_git_source cetmix_tower_server.group_manager 1 1 1 1
5 access_git_source_root Git Source Root model_cx_tower_git_source cetmix_tower_server.group_root 1 1 1 1
6 access_git_remote_manager Git Remote Manager model_cx_tower_git_remote cetmix_tower_server.group_manager 1 1 1 1
7 access_git_remote_root Git Remote Root model_cx_tower_git_remote cetmix_tower_server.group_root 1 1 1 1
8 access_git_repo_manager Git Repository Manager model_cx_tower_git_repo cetmix_tower_server.group_manager 1 1 1 1
9 access_git_repo_root Git Repository Root model_cx_tower_git_repo cetmix_tower_server.group_root 1 1 1 1
10 access_git_repo_owner_manager Git Repository Owner Manager model_cx_tower_git_repo_owner cetmix_tower_server.group_manager 1 1 1 0
11 access_git_repo_owner_root Git Repository Owner Root model_cx_tower_git_repo_owner cetmix_tower_server.group_root 1 1 1 1
12 access_git_project_server_file_rel Git Project Server File Rel Manager model_cx_tower_git_project_rel cetmix_tower_server.group_manager 1 1 1 1
13 access_git_project_server_file_rel_root Git Project Server File Rel Root model_cx_tower_git_project_rel cetmix_tower_server.group_root 1 1 1 1
14 access_git_project_file_template_rel Git Project File Template Rel Manager model_cx_tower_git_project_file_template_rel cetmix_tower_server.group_manager 1 1 1 1
15 access_git_project_file_template_rel_root Git Project File Template Rel Root model_cx_tower_git_project_file_template_rel cetmix_tower_server.group_root 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1,497 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Cetmix Tower Git</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="cetmix-tower-git">
<h1 class="title">Cetmix Tower Git</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:583744e8956f294682a551fc082f086b174b8d2b72652c21b1dd68f3933e7211
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/cetmix/cetmix-tower/tree/16.0/cetmix_tower_git"><img alt="cetmix/cetmix-tower" src="https://img.shields.io/badge/github-cetmix%2Fcetmix--tower-lightgray.png?logo=github" /></a></p>
<p>This module implements Git Management functionality for <a class="reference external" href="https://cetmix.com/tower">Cetmix
Tower</a>.</p>
<p>Please refer to the <a class="reference external" href="https://cetmix.com/tower">official
documentation</a> for detailed information.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
<li><a class="reference internal" href="#changelog" id="toc-entry-3">Changelog</a><ul>
<li><a class="reference internal" href="#section-1" id="toc-entry-4">16.0.2.0.1 (2025-12-11)</a></li>
<li><a class="reference internal" href="#section-2" id="toc-entry-5">16.0.2.0.0 (2025-10-27)</a></li>
<li><a class="reference internal" href="#section-3" id="toc-entry-6">16.0.1.0.6 (2025-08-18)</a></li>
<li><a class="reference internal" href="#section-4" id="toc-entry-7">16.0.1.0.5 (2025-08-17)</a></li>
<li><a class="reference internal" href="#section-5" id="toc-entry-8">16.0.1.0.4 (2025-07-29)</a></li>
<li><a class="reference internal" href="#section-6" id="toc-entry-9">16.0.1.0.3 (2025-05-23)</a></li>
<li><a class="reference internal" href="#section-7" id="toc-entry-10">16.0.1.0.2 (2025-05-16)</a></li>
<li><a class="reference internal" href="#section-8" id="toc-entry-11">16.0.1.0.1 (2025-05-09)</a></li>
<li><a class="reference internal" href="#section-9" id="toc-entry-12">16.0.1.0.0</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-13">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-14">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-15">Authors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-16">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<p>Please refer to the <a class="reference external" href="https://cetmix.com/tower">official
documentation</a> for detailed configuration
instructions.</p>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
<p>Please refer to the <a class="reference external" href="https://cetmix.com/tower">official
documentation</a> for detailed usage
instructions.</p>
</div>
<div class="section" id="changelog">
<h1><a class="toc-backref" href="#toc-entry-3">Changelog</a></h1>
<div class="section" id="section-1">
<h2><a class="toc-backref" href="#toc-entry-4">16.0.2.0.1 (2025-12-11)</a></h2>
<ul class="simple">
<li>Features: Improve search views, implement the search panel for
selected views. (5139)</li>
</ul>
</div>
<div class="section" id="section-2">
<h2><a class="toc-backref" href="#toc-entry-5">16.0.2.0.0 (2025-10-27)</a></h2>
<ul class="simple">
<li>Features: Major refactoring: implement Git repository entity. (4914)</li>
</ul>
</div>
<div class="section" id="section-3">
<h2><a class="toc-backref" href="#toc-entry-6">16.0.1.0.6 (2025-08-18)</a></h2>
<ul class="simple">
<li>Features: Link or copy a git project when uploading the linked file
using command (4759)</li>
</ul>
</div>
<div class="section" id="section-4">
<h2><a class="toc-backref" href="#toc-entry-7">16.0.1.0.5 (2025-08-17)</a></h2>
<ul class="simple">
<li>Features: Search servers by git reference (4838)</li>
</ul>
</div>
<div class="section" id="section-5">
<h2><a class="toc-backref" href="#toc-entry-8">16.0.1.0.4 (2025-07-29)</a></h2>
<ul class="simple">
<li>Features: Export related commands and flight plans together with
server (4849)</li>
</ul>
</div>
<div class="section" id="section-6">
<h2><a class="toc-backref" href="#toc-entry-9">16.0.1.0.3 (2025-05-23)</a></h2>
<ul class="simple">
<li>Bugfixes: Duplicated file is created when importing a YAML file with a
git project. (4715)</li>
</ul>
</div>
<div class="section" id="section-7">
<h2><a class="toc-backref" href="#toc-entry-10">16.0.1.0.2 (2025-05-16)</a></h2>
<ul class="simple">
<li>Features: Record references for git relations. (4670)</li>
</ul>
</div>
<div class="section" id="section-8">
<h2><a class="toc-backref" href="#toc-entry-11">16.0.1.0.1 (2025-05-09)</a></h2>
<ul class="simple">
<li>Bugfixes: Non-critical issues and performance improvements. (4663)</li>
</ul>
</div>
<div class="section" id="section-9">
<h2><a class="toc-backref" href="#toc-entry-12">16.0.1.0.0</a></h2>
<p>Release for Odoo 16.0</p>
</div>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-13">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/cetmix/cetmix-tower/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/cetmix/cetmix-tower/issues/new?body=module:%20cetmix_tower_git%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-14">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-15">Authors</a></h2>
<ul class="simple">
<li>Cetmix</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-16">Maintainers</a></h2>
<p>This module is part of the <a class="reference external" href="https://github.com/cetmix/cetmix-tower/tree/16.0/cetmix_tower_git">cetmix/cetmix-tower</a> project on GitHub.</p>
<p>You are welcome to contribute.</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,7 @@
from . import test_remote
from . import test_source
from . import test_project
from . import test_file_rel
from . import test_file_template_rel
from . import test_server
from . import test_repo

View File

@@ -0,0 +1,136 @@
from odoo.addons.cetmix_tower_server.tests.common import TestTowerCommon
class CommonTest(TestTowerCommon):
"""Common test class for all tests."""
@classmethod
def setUpClass(cls):
super().setUpClass()
# Models
cls.GitProject = cls.env["cx.tower.git.project"]
cls.GitProjectRel = cls.env["cx.tower.git.project.rel"]
cls.GitProjectFileTemplateRel = cls.env[
"cx.tower.git.project.file.template.rel"
]
cls.GitSource = cls.env["cx.tower.git.source"]
cls.GitRemote = cls.env["cx.tower.git.remote"]
# Data
# Project
cls.git_project_1 = cls.GitProject.create({"name": "Git Project 1"})
# Sources
cls.git_source_1 = cls.GitSource.create(
{"name": "Git Source 1", "git_project_id": cls.git_project_1.id}
)
cls.git_source_2 = cls.GitSource.create(
{"name": "Git Source 2", "git_project_id": cls.git_project_1.id}
)
# Repositories
cls.Repo = cls.env["cx.tower.git.repo"]
cls.RepoOwner = cls.env["cx.tower.git.repo.owner"]
cls.repo_cetmix_tower = cls.Repo.create(
{
"name": "Cetmix Tower",
"url": "https://github.com/cetmix-test/cetmix-tower-test.git",
}
)
cls.repo_oca_web = cls.Repo.create(
{
"name": "OCA Web",
"url": "https://github.com/oca-test/web-test.git",
}
)
cls.repo_odoo_enterprise = cls.Repo.create(
{
"name": "Odoo Enterprise",
"url": "https://github.com/odoo-test/enterprise-test.git",
"is_private": True,
}
)
cls.repo_gitlab_private = cls.Repo.create(
{
"name": "GitLab Private",
"url": "git@my.gitlab.com:cetmix-test/cetmix-tower-test.git",
"is_private": True,
}
)
cls.repo_bitbucket_private = cls.Repo.create(
{
"name": "Bitbucket Private",
"url": "https://bitbucket.com/cetmix-test/cetmix-tower-test-enterprise.git",
"is_private": True,
}
)
# Same urls, different protocols (intentionally aliased)
cls.repo_other_ssh = cls.Repo.create(
{"url": "git@memegit.com:cetmix-test/cetmix-tower-test.git"}
)
cls.repo_other_https = cls.repo_other_ssh
# Remotes
cls.remote_github_https = cls.GitRemote.create(
{
"repo_id": cls.repo_cetmix_tower.id,
"source_id": cls.git_source_1.id,
"head_type": "pr",
"head": "https://github.com/cetmix-test/cetmix-tower-test/pull/123",
"sequence": 1,
}
)
cls.remote_gitlab_https = cls.GitRemote.create(
{
"repo_id": cls.repo_gitlab_private.id,
"source_id": cls.git_source_1.id,
"head_type": "branch",
"head": "main",
"sequence": 2,
}
)
cls.remote_gitlab_ssh = cls.GitRemote.create(
{
"repo_id": cls.repo_gitlab_private.id,
"source_id": cls.git_source_1.id,
"head_type": "commit",
"url_protocol": "ssh",
"head": "10000000",
"sequence": 3,
}
)
cls.remote_bitbucket_https = cls.GitRemote.create(
{
"repo_id": cls.repo_bitbucket_private.id,
"source_id": cls.git_source_2.id,
"head_type": "branch",
"head": "dev",
"sequence": 4,
}
)
cls.remote_other_ssh = cls.GitRemote.create(
{
"repo_id": cls.repo_other_ssh.id,
"source_id": cls.git_source_2.id,
"head_type": "branch",
"url_protocol": "ssh",
"head": "old",
"sequence": 5,
}
)
# File
cls.server_1_file_1 = cls.File.create(
{
"name": "File 1",
"server_id": cls.server_test_1.id,
"source": "tower",
}
)
cls.file_template_1 = cls.FileTemplate.create(
{
"name": "File Template 1",
}
)

View File

@@ -0,0 +1,390 @@
from odoo.exceptions import AccessError
from .common import CommonTest
class TestFileRel(CommonTest):
"""Test class for git file relation."""
def setUp(self):
super().setUp()
self.file_1_rel = self.GitProjectRel.create(
{
"server_id": self.server_test_1.id,
"file_id": self.server_1_file_1.id,
"git_project_id": self.git_project_1.id,
"project_format": "git_aggregator",
}
)
def test_file_rel_create(self):
"""Test if file relation is created correctly"""
# -- 1 --
# Check if file content is updated
# Get code from project
yaml_code_from_project = (
self.file_1_rel.git_project_id._generate_code_git_aggregator(
self.file_1_rel
)
)
self.assertEqual(
self.server_1_file_1.code,
yaml_code_from_project,
"File content is not updated correctly",
)
# Check specific if remote is present in file
self.assertIn(
self.remote_other_ssh.repo_id.url_ssh,
self.server_1_file_1.code,
"Remote is not present in file",
)
# -- 2 --
# Modify remove and check if file content is updated
self.remote_other_ssh.repo_id = self.Repo.create(
{
"url": "https://github.com/cetmix/cetmix-memes.git",
}
)
self.remote_other_ssh.url_protocol = "https"
# Must be different from previous project code
self.assertNotEqual(
self.server_1_file_1.code,
yaml_code_from_project,
"File content is not updated correctly",
)
# New remote must be present in file
self.assertIn(
"https://github.com/cetmix/cetmix-memes.git",
self.server_1_file_1.code,
"Remote is not present in file",
)
# -- 3 --
# Disable source and check if file content is updated
self.git_source_2.active = False
self.assertNotIn(
"https://github.com/cetmix/cetmix-memes.git",
self.server_1_file_1.code,
"Remote is present in file",
)
def test_format_git_aggregator(self):
"""Test if format git aggregator works correctly"""
# -- 1 --
# Check if YAML code is generated correctly
yaml_code = """# This file is generated with Cetmix Tower https://cetmix.com/tower
# It's designed to be used with git-aggregator tool developed by Acsone.
# Documentation for git-aggregator: https://github.com/acsone/git-aggregator
# You need to set the following variables in your environment:
# BITBUCKET_TOKEN, GITLAB_TOKEN, GITLAB_TOKEN_NAME
# and run git-aggregator with '--expand-env' parameter.
./git_project_1_git_source_1:
remotes:
remote_1: https://github.com/cetmix-test/cetmix-tower-test.git
remote_2: https://$GITLAB_TOKEN_NAME:$GITLAB_TOKEN@my.gitlab.com/cetmix-test/cetmix-tower-test.git
remote_3: git@my.gitlab.com:cetmix-test/cetmix-tower-test.git
merges:
- remote: remote_1
ref: refs/pull/123/head
- remote: remote_2
ref: main
- remote: remote_3
ref: '10000000'
target: remote_1
./git_project_1_git_source_1_2:
remotes:
remote_1: https://x-token-auth:$BITBUCKET_TOKEN@bitbucket.com/cetmix-test/cetmix-tower-test-enterprise.git
remote_2: git@memegit.com:cetmix-test/cetmix-tower-test.git
merges:
- remote: remote_1
ref: dev
- remote: remote_2
ref: old
target: remote_1
""" # noqa: E501
# Get code from project
yaml_code_from_project = (
self.file_1_rel.git_project_id._generate_code_git_aggregator(
self.file_1_rel
)
)
self.assertEqual(
yaml_code_from_project,
yaml_code,
"YAML code is not generated correctly",
)
# -- 2 --
# Unlink remote and check if file content is updated
self.remote_github_https.unlink()
yaml_code_from_project = (
self.file_1_rel.git_project_id._generate_code_git_aggregator(
self.file_1_rel
)
)
yaml_code = """# This file is generated with Cetmix Tower https://cetmix.com/tower
# It's designed to be used with git-aggregator tool developed by Acsone.
# Documentation for git-aggregator: https://github.com/acsone/git-aggregator
# You need to set the following variables in your environment:
# BITBUCKET_TOKEN, GITLAB_TOKEN, GITLAB_TOKEN_NAME
# and run git-aggregator with '--expand-env' parameter.
./git_project_1_git_source_1:
remotes:
remote_2: https://$GITLAB_TOKEN_NAME:$GITLAB_TOKEN@my.gitlab.com/cetmix-test/cetmix-tower-test.git
remote_3: git@my.gitlab.com:cetmix-test/cetmix-tower-test.git
merges:
- remote: remote_2
ref: main
- remote: remote_3
ref: '10000000'
target: remote_2
./git_project_1_git_source_1_2:
remotes:
remote_1: https://x-token-auth:$BITBUCKET_TOKEN@bitbucket.com/cetmix-test/cetmix-tower-test-enterprise.git
remote_2: git@memegit.com:cetmix-test/cetmix-tower-test.git
merges:
- remote: remote_1
ref: dev
- remote: remote_2
ref: old
target: remote_1
""" # noqa: E501
self.assertEqual(
yaml_code_from_project,
yaml_code,
"YAML code is not generated correctly",
)
# -- 3 --
# Unlink source and check if file content is updated
self.git_source_2.unlink()
yaml_code_from_project = (
self.file_1_rel.git_project_id._generate_code_git_aggregator(
self.file_1_rel
)
)
yaml_code = """# This file is generated with Cetmix Tower https://cetmix.com/tower
# It's designed to be used with git-aggregator tool developed by Acsone.
# Documentation for git-aggregator: https://github.com/acsone/git-aggregator
# You need to set the following variables in your environment:
# GITLAB_TOKEN, GITLAB_TOKEN_NAME
# and run git-aggregator with '--expand-env' parameter.
./git_project_1_git_source_1:
remotes:
remote_2: https://$GITLAB_TOKEN_NAME:$GITLAB_TOKEN@my.gitlab.com/cetmix-test/cetmix-tower-test.git
remote_3: git@my.gitlab.com:cetmix-test/cetmix-tower-test.git
merges:
- remote: remote_2
ref: main
- remote: remote_3
ref: '10000000'
target: remote_2
""" # noqa: E501
self.assertEqual(
yaml_code_from_project,
yaml_code,
"YAML code is not generated correctly",
)
def test_user_access(self):
"""Test that regular users have no access to git project relations"""
user_rel = self.GitProjectRel.with_user(self.user)
# Try create - should fail
with self.assertRaises(AccessError):
user_rel.create(
{
"server_id": self.server_test_1.id,
"file_id": self.server_1_file_1.id,
"git_project_id": self.git_project_1.id,
"project_format": "git_aggregator",
}
)
# Try read - should fail
with self.assertRaises(AccessError):
user_rel.browse(self.file_1_rel.id).read(["name"])
# Try write - should fail
with self.assertRaises(AccessError):
user_rel.browse(self.file_1_rel.id).write(
{"project_format": "git_aggregator"}
)
# Try unlink - should fail
with self.assertRaises(AccessError):
user_rel.browse(self.file_1_rel.id).unlink()
def test_manager_read_access(self):
"""Test manager read access rules"""
manager_rel = self.GitProjectRel.with_user(self.manager)
# Initially manager should not have access
with self.assertRaises(AccessError):
manager_rel.browse(self.file_1_rel.id).read(["name"])
# Add manager as project user - should have read access
self.git_project_1.write({"user_ids": [(4, self.manager.id)]})
self.assertEqual(manager_rel.browse(self.file_1_rel.id).name, "Git Project 1")
# Remove from project, add as server user - should have read access
self.git_project_1.write({"user_ids": [(3, self.manager.id)]})
self.server_test_1.write({"user_ids": [(4, self.manager.id)]})
self.assertEqual(manager_rel.browse(self.file_1_rel.id).name, "Git Project 1")
# Remove from server users, add as project manager - should have read access
self.server_test_1.write({"user_ids": [(3, self.manager.id)]})
self.git_project_1.write({"manager_ids": [(4, self.manager.id)]})
self.assertEqual(manager_rel.browse(self.file_1_rel.id).name, "Git Project 1")
# Remove from project, add as server manager - should have read access
self.git_project_1.write({"manager_ids": [(3, self.manager.id)]})
self.server_test_1.write({"manager_ids": [(4, self.manager.id)]})
self.assertEqual(manager_rel.browse(self.file_1_rel.id).name, "Git Project 1")
def test_manager_write_access(self):
"""Test manager write/create access rules"""
manager_rel = self.GitProjectRel.with_user(self.manager)
# Create new file to avoid unique constraint violation
file_2 = self.File.create(
{
"name": "test_file_2",
"server_id": self.server_test_1.id,
"source": "tower",
"file_type": "text",
}
)
# Try create without being project and server manager - should fail
with self.assertRaises(AccessError):
manager_rel.create(
{
"server_id": self.server_test_1.id,
"file_id": file_2.id,
"git_project_id": self.git_project_1.id,
"project_format": "git_aggregator",
}
)
# Add as project manager only - should still fail
file_3 = self.File.create(
{
"name": "test_file_3",
"server_id": self.server_test_1.id,
"source": "tower",
"file_type": "text",
}
)
self.git_project_1.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
manager_rel.create(
{
"server_id": self.server_test_1.id,
"file_id": file_3.id,
"git_project_id": self.git_project_1.id,
"project_format": "git_aggregator",
}
)
# Add as server manager - should succeed
file_4 = self.File.create(
{
"name": "test_file_4",
"server_id": self.server_test_1.id,
"source": "tower",
"file_type": "text",
}
)
self.server_test_1.write({"manager_ids": [(4, self.manager.id)]})
rel = manager_rel.create(
{
"server_id": self.server_test_1.id,
"file_id": file_4.id,
"git_project_id": self.git_project_1.id,
"project_format": "git_aggregator",
}
)
self.assertTrue(rel.exists())
# Test write access
rel.write({"project_format": "git_aggregator"})
# Remove server manager access - should fail to write
self.server_test_1.write({"manager_ids": [(3, self.manager.id)]})
with self.assertRaises(AccessError):
rel.write({"project_format": "git_aggregator"})
# Remove project manager access - should fail to write
self.git_project_1.write({"manager_ids": [(3, self.manager.id)]})
with self.assertRaises(AccessError):
rel.write({"project_format": "git_aggregator"})
def test_manager_unlink_access(self):
"""Test manager unlink access rules"""
manager_rel = self.GitProjectRel.with_user(self.manager)
# Try delete without being project and server manager - should fail
with self.assertRaises(AccessError):
manager_rel.browse(self.file_1_rel.id).unlink()
# Add as project manager only - should fail
self.git_project_1.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
manager_rel.browse(self.file_1_rel.id).unlink()
# Add as server manager - should succeed
self.server_test_1.write({"manager_ids": [(4, self.manager.id)]})
self.file_1_rel.unlink()
self.assertFalse(self.file_1_rel.exists())
def test_root_access(self):
"""Test root access rules"""
root_rel = self.GitProjectRel.with_user(self.root)
# Create new file to avoid unique constraint violation
file_3 = self.File.create(
{
"name": "test_file_3",
"server_id": self.server_test_1.id,
"source": "tower",
"file_type": "text",
}
)
# Create - should succeed
rel = root_rel.create(
{
"server_id": self.server_test_1.id,
"file_id": file_3.id,
"git_project_id": self.git_project_1.id,
"project_format": "git_aggregator",
}
)
self.assertTrue(rel.exists())
# Read - should succeed
self.assertEqual(root_rel.browse(rel.id).name, "Git Project 1")
# Write - should succeed
root_rel.browse(rel.id).write({"project_format": "git_aggregator"})
# Delete - should succeed
rel.unlink()
self.assertFalse(rel.exists())

View File

@@ -0,0 +1,308 @@
from odoo.exceptions import AccessError
from .common import CommonTest
class TestFileTemplateRel(CommonTest):
"""Test class for git file template relation."""
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.file_template_1_rel = cls.GitProjectFileTemplateRel.create(
{
"git_project_id": cls.git_project_1.id,
"file_template_id": cls.file_template_1.id,
"project_format": "git_aggregator",
}
)
def test_file_template_rel_create(self):
"""Test if file template relation is created correctly"""
# -- 1 --
# Check if file content is updated
# Get code from project
yaml_code_from_project = (
self.file_template_1_rel.git_project_id._generate_code_git_aggregator(
self.file_template_1_rel
)
)
self.assertEqual(
self.file_template_1.code,
yaml_code_from_project,
"File template content is not updated correctly",
)
# Check specific if remote is present in file
self.assertIn(
self.remote_other_ssh.repo_id.url_ssh,
self.file_template_1.code,
"Remote is not present in file template",
)
# -- 2 --
# Modify remove and check if file template content is updated
self.remote_other_ssh.repo_id = self.Repo.create(
{
"url": "https://github.com/cetmix/cetmix-memes.git",
}
)
self.remote_other_ssh.url_protocol = "https"
# Must be different from previous project code
self.assertNotEqual(
self.file_template_1.code,
yaml_code_from_project,
"File template content is not updated correctly",
)
# New remote must be present in file
self.assertIn(
"https://github.com/cetmix/cetmix-memes.git",
self.file_template_1.code,
"Remote is not present in file template",
)
# -- 3 --
# Disable source and check if file content is updated
self.git_source_2.active = False
self.assertNotIn(
"https://github.com/cetmix/cetmix-memes.git",
self.file_template_1.code,
"Remote is present in file template",
)
def test_format_git_aggregator(self):
"""Test if format git aggregator works correctly"""
# -- 1 --
# Check if YAML code is generated correctly
yaml_code = """# This file is generated with Cetmix Tower https://cetmix.com/tower
# It's designed to be used with git-aggregator tool developed by Acsone.
# Documentation for git-aggregator: https://github.com/acsone/git-aggregator
# You need to set the following variables in your environment:
# BITBUCKET_TOKEN, GITLAB_TOKEN, GITLAB_TOKEN_NAME
# and run git-aggregator with '--expand-env' parameter.
./git_project_1_git_source_1:
remotes:
remote_1: https://github.com/cetmix-test/cetmix-tower-test.git
remote_2: https://$GITLAB_TOKEN_NAME:$GITLAB_TOKEN@my.gitlab.com/cetmix-test/cetmix-tower-test.git
remote_3: git@my.gitlab.com:cetmix-test/cetmix-tower-test.git
merges:
- remote: remote_1
ref: refs/pull/123/head
- remote: remote_2
ref: main
- remote: remote_3
ref: '10000000'
target: remote_1
./git_project_1_git_source_1_2:
remotes:
remote_1: https://x-token-auth:$BITBUCKET_TOKEN@bitbucket.com/cetmix-test/cetmix-tower-test-enterprise.git
remote_2: git@memegit.com:cetmix-test/cetmix-tower-test.git
merges:
- remote: remote_1
ref: dev
- remote: remote_2
ref: old
target: remote_1
""" # noqa: E501
# Get code from project
yaml_code_from_project = (
self.file_template_1_rel.git_project_id._generate_code_git_aggregator(
self.file_template_1_rel
)
)
self.assertEqual(
yaml_code_from_project,
yaml_code,
"YAML code is not generated correctly",
)
def test_user_access(self):
"""Test that regular users have no access to git project relations"""
user_rel = self.GitProjectFileTemplateRel.with_user(self.user)
# Try create - should fail
with self.assertRaises(AccessError):
user_rel.create(
{
"git_project_id": self.git_project_1.id,
"file_template_id": self.file_template_1.id,
"project_format": "git_aggregator",
}
)
# Try read - should fail
with self.assertRaises(AccessError):
user_rel.browse(self.file_template_1_rel.id).read(["name"])
# Try write - should fail
with self.assertRaises(AccessError):
user_rel.browse(self.file_template_1_rel.id).write(
{"project_format": "git_aggregator"}
)
# Try unlink - should fail
with self.assertRaises(AccessError):
user_rel.browse(self.file_template_1_rel.id).unlink()
def test_manager_read_access(self):
"""Test manager read access rules"""
manager_rel = self.GitProjectFileTemplateRel.with_user(self.manager)
# Initially manager should not have access
with self.assertRaises(AccessError):
manager_rel.browse(self.file_template_1_rel.id).read(["name"])
# Add manager as project user - should have read access
self.git_project_1.write({"user_ids": [(4, self.manager.id)]})
self.assertEqual(
manager_rel.browse(self.file_template_1_rel.id).name, "Git Project 1"
)
# Remove from project, add as file template user
# should have read access
self.git_project_1.write({"user_ids": [(3, self.manager.id)]})
self.file_template_1.write({"user_ids": [(4, self.manager.id)]})
self.assertEqual(
manager_rel.browse(self.file_template_1_rel.id).name, "Git Project 1"
)
# Remove from file template users, add as project manager
# should have read access
self.file_template_1.write({"user_ids": [(3, self.manager.id)]})
self.git_project_1.write({"manager_ids": [(4, self.manager.id)]})
self.assertEqual(
manager_rel.browse(self.file_template_1_rel.id).name, "Git Project 1"
)
# Remove from project, add as file template manager
# should have read access
self.git_project_1.write({"manager_ids": [(3, self.manager.id)]})
self.file_template_1.write({"manager_ids": [(4, self.manager.id)]})
self.assertEqual(
manager_rel.browse(self.file_template_1_rel.id).name, "Git Project 1"
)
def test_manager_write_access(self):
"""Test manager write/create access rules"""
manager_rel = self.GitProjectFileTemplateRel.with_user(self.manager)
# Create new file template to avoid unique constraint violation
file_template_2 = self.FileTemplate.create(
{
"name": "test_file_template_2",
}
)
# Try create without being project and file template manager - should fail
with self.assertRaises(AccessError):
manager_rel.create(
{
"git_project_id": self.git_project_1.id,
"file_template_id": file_template_2.id,
"project_format": "git_aggregator",
}
)
# Add as project manager only - should still fail
file_template_3 = self.FileTemplate.create(
{
"name": "test_file_template_3",
}
)
self.git_project_1.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
manager_rel.create(
{
"git_project_id": self.git_project_1.id,
"file_template_id": file_template_3.id,
"project_format": "git_aggregator",
}
)
# Add as file template manager - should succeed
file_template_4 = self.FileTemplate.create(
{
"name": "test_file_template_4",
}
)
file_template_4.write({"manager_ids": [(4, self.manager.id)]})
rel = manager_rel.create(
{
"git_project_id": self.git_project_1.id,
"file_template_id": file_template_4.id,
"project_format": "git_aggregator",
}
)
self.assertTrue(rel.exists())
# Test write access
rel.write({"project_format": "git_aggregator"})
# Remove file template manager access - should fail to write
file_template_4.write({"manager_ids": [(3, self.manager.id)]})
with self.assertRaises(AccessError):
rel.write({"project_format": "git_aggregator"})
# Remove project manager access - should fail to write
self.git_project_1.write({"manager_ids": [(3, self.manager.id)]})
file_template_4.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
rel.write({"project_format": "git_aggregator"})
def test_manager_unlink_access(self):
"""Test manager unlink access rules"""
manager_rel = self.GitProjectFileTemplateRel.with_user(self.manager)
# Try delete without being project and server manager - should fail
with self.assertRaises(AccessError):
manager_rel.browse(self.file_template_1_rel.id).unlink()
# Add as project manager only - should fail
self.git_project_1.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
manager_rel.browse(self.file_template_1_rel.id).unlink()
# Add as file template manager - should succeed
self.file_template_1.write({"manager_ids": [(4, self.manager.id)]})
self.file_template_1_rel.unlink()
self.assertFalse(self.file_template_1_rel.exists())
def test_root_access(self):
"""Test root access rules"""
root_rel = self.GitProjectFileTemplateRel.with_user(self.root)
# Create new file to avoid unique constraint violation
file_template_3 = self.FileTemplate.create(
{
"name": "test_file_template_3",
}
)
# Create - should succeed
rel = root_rel.create(
{
"git_project_id": self.git_project_1.id,
"file_template_id": file_template_3.id,
"project_format": "git_aggregator",
}
)
self.assertTrue(rel.exists())
# Read - should succeed
self.assertEqual(root_rel.browse(rel.id).name, "Git Project 1")
# Write - should succeed
root_rel.browse(rel.id).write({"project_format": "git_aggregator"})
# Delete - should succeed
rel.unlink()
self.assertFalse(rel.exists())

View File

@@ -0,0 +1,315 @@
from odoo.exceptions import AccessError
from .common import CommonTest
class TestProject(CommonTest):
"""Test class for git project."""
@classmethod
def setUpClass(cls):
super().setUpClass()
# Remove user bob from all groups
cls.remove_from_group(
cls.user_bob,
[
"cetmix_tower_server.group_user",
"cetmix_tower_server.group_manager",
"cetmix_tower_server.group_root",
],
)
# Create another manager for testing
cls.manager_2 = cls.Users.create(
{
"name": "Second Manager",
"login": "manager2",
"email": "manager2@test.com",
"groups_id": [(4, cls.env.ref("cetmix_tower_server.group_manager").id)],
}
)
# Create test project as root
cls.project = cls.GitProject.create(
{
"name": "Test Project",
}
)
def test_user_access(self):
"""Test that regular users have no access to git projects"""
user_project = self.GitProject.with_user(self.user)
# Test CRUD operations
with self.assertRaises(AccessError):
user_project.create({"name": "New Project"})
with self.assertRaises(AccessError):
user_project.browse(self.project.id).read(["name"])
with self.assertRaises(AccessError):
user_project.browse(self.project.id).write({"name": "Updated Name"})
with self.assertRaises(AccessError):
user_project.browse(self.project.id).unlink()
def test_manager_read_access(self):
"""Test manager read access rules"""
manager_project = self.GitProject.with_user(self.manager)
# Manager not in user_ids or manager_ids - should not read
with self.assertRaises(AccessError):
manager_project.browse(self.project.id).read(["name"])
# Add manager to user_ids - should read
self.project.write({"user_ids": [(4, self.manager.id)]})
self.assertEqual(manager_project.browse(self.project.id).name, "Test Project")
# Remove from user_ids, add to manager_ids - should read
self.project.write(
{"user_ids": [(3, self.manager.id)], "manager_ids": [(4, self.manager.id)]}
)
self.assertEqual(manager_project.browse(self.project.id).name, "Test Project")
def test_manager_write_access(self):
"""Test manager write/create access rules"""
manager_project = self.GitProject.with_user(self.manager)
# Create - should succeed as manager is added by default
new_project = manager_project.create({"name": "New Project"})
self.assertTrue(new_project.exists())
self.assertIn(self.manager, new_project.manager_ids)
# Write - not in manager_ids, should fail
with self.assertRaises(AccessError):
manager_project.browse(self.project.id).write({"name": "Updated Name"})
# Add to manager_ids - should write
self.project.write({"manager_ids": [(4, self.manager.id)]})
manager_project.browse(self.project.id).write({"name": "Updated Name"})
self.assertEqual(self.project.name, "Updated Name")
def test_manager_unlink_access(self):
"""Test manager unlink access rules"""
# Create project as manager_2
project = self.GitProject.with_user(self.manager_2).create(
{"name": "Project to Delete"}
)
manager_project = self.GitProject.with_user(self.manager)
# Try delete as different manager - should fail
with self.assertRaises(AccessError):
manager_project.browse(project.id).unlink()
# Add to manager_ids but not creator - should fail
project.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
manager_project.browse(project.id).unlink()
# Create as manager and try delete - should succeed
own_project = manager_project.create({"name": "Own Project"})
self.assertTrue(own_project.exists())
own_project.unlink()
self.assertFalse(own_project.exists())
def test_root_access(self):
"""Test root access rules"""
root_project = self.GitProject.with_user(self.root)
# Create
new_project = root_project.create({"name": "Root Project"})
self.assertTrue(new_project.exists())
# Read
self.assertEqual(root_project.browse(self.project.id).name, "Test Project")
# Write
root_project.browse(self.project.id).write({"name": "Updated by Root"})
self.assertEqual(self.project.name, "Updated by Root")
# Delete
new_project.unlink()
self.assertFalse(new_project.exists())
def test_compute_user_ids(self):
"""Test computation of user_ids and manager_ids for git projects"""
# Add users "Bob" and "user" to the group "cetmix_tower_server.group_manager"
self.add_to_group(self.user_bob, "cetmix_tower_server.group_manager")
self.add_to_group(self.user, "cetmix_tower_server.group_manager")
# -- 1 --
# Create project as manager
project_as_manager = self.GitProject.with_user(self.manager).create(
{
"name": "Project As Manager",
}
)
# Check that manager is added to both user_ids and manager_ids by default
self.assertEqual(len(project_as_manager.user_ids), 1)
self.assertIn(self.manager, project_as_manager.user_ids)
self.assertEqual(len(project_as_manager.manager_ids), 1)
self.assertIn(self.manager, project_as_manager.manager_ids)
# -- 2 --
# Create servers with multiple users and managers
server_1 = self.Server.create(
{
"name": "Test Server 1",
"ip_v4_address": "localhost",
"ssh_username": "admin",
"ssh_password": "password",
"os_id": self.os_debian_10.id,
"user_ids": [(6, 0, [self.user_bob.id, self.user.id])], # Two users
"manager_ids": [
(6, 0, [self.manager.id, self.manager_2.id])
], # Two managers
}
)
server_2 = self.Server.create(
{
"name": "Test Server 2",
"ip_v4_address": "localhost",
"ssh_username": "admin",
"ssh_password": "password",
"os_id": self.os_debian_10.id,
"user_ids": [
(6, 0, [self.user_bob.id, self.user.id])
], # Same two users
"manager_ids": [
(6, 0, [self.manager.id, self.manager_2.id])
], # Same two managers
}
)
# Create project and link servers
project = self.GitProject.create(
{
"name": "Test Project",
}
)
# Create files and link them to the project
for server in [server_1, server_2]:
file = self.File.create(
{
"name": f"test_file_{server.name}",
"server_id": server.id,
}
)
self.GitProjectRel.create(
{
"server_id": server.id,
"file_id": file.id,
"git_project_id": project.id,
"project_format": "git_aggregator",
}
)
# Invalidate cache to ensure computed fields are updated
project.invalidate_recordset(["server_ids", "user_ids", "manager_ids"])
# -- 3 --
# Test computed values with linked servers
# Each user/manager should be counted only once even if present in both servers
self.assertEqual(len(project.server_ids), 2)
self.assertEqual(len(project.user_ids), 2) # Two unique users
self.assertIn(self.user_bob, project.user_ids)
self.assertIn(self.user, project.user_ids)
self.assertEqual(len(project.manager_ids), 2) # Two unique managers
self.assertIn(self.manager, project.manager_ids)
self.assertIn(self.manager_2, project.manager_ids)
# -- 4 --
# Add server with different users/managers
server_3 = self.Server.create(
{
"name": "Test Server 3",
"ip_v4_address": "localhost",
"ssh_username": "admin",
"ssh_password": "password",
"os_id": self.os_debian_10.id,
"user_ids": [(6, 0, [self.user_bob.id])], # Only one user
"manager_ids": [(6, 0, [self.manager_2.id])], # Only second manager
}
)
file_3 = self.File.create(
{
"name": "test_file_3",
"server_id": server_3.id,
}
)
self.GitProjectRel.create(
{
"server_id": server_3.id,
"file_id": file_3.id,
"git_project_id": project.id,
"project_format": "git_aggregator",
}
)
# Invalidate cache to ensure computed fields are updated
project.invalidate_recordset(["server_ids", "user_ids", "manager_ids"])
# Test that computed values are updated correctly
# Only users/managers present in all servers should remain
self.assertEqual(len(project.server_ids), 3)
self.assertEqual(len(project.user_ids), 1) # Only bob is in all servers
self.assertIn(self.user_bob, project.user_ids)
self.assertEqual(
len(project.manager_ids), 1
) # Only manager_2 is in all servers
self.assertIn(self.manager_2, project.manager_ids)
# -- 5 --
# Verify that first manager can still access the project
project_as_manager_1 = self.GitProject.with_user(self.manager).browse(
project.id
)
self.assertTrue(project_as_manager_1.exists())
self.assertEqual(project_as_manager_1.name, "Test Project")
def test_manager_server_based_access(self):
"""Test manager access through server relationships"""
manager_project = self.GitProject.with_user(self.manager)
# Create a server where manager is a user
server = self.Server.create(
{
"name": "Test Server",
"ip_v4_address": "localhost",
"ssh_username": "admin",
"ssh_password": "password",
"os_id": self.os_debian_10.id,
"user_ids": [(4, self.manager.id)],
}
)
# Create a file and link project to server
file = self.File.create(
{
"name": "test_file",
"server_id": server.id,
}
)
self.GitProjectRel.create(
{
"server_id": server.id,
"file_id": file.id,
"git_project_id": self.project.id,
"project_format": "git_aggregator",
}
)
# Manager should be able to read project through server relationship
self.assertEqual(manager_project.browse(self.project.id).name, "Test Project")
# Remove manager from server users
server.write({"user_ids": [(3, self.manager.id)]})
# Manager should not be able to read project anymore
with self.assertRaises(AccessError):
manager_project.browse(self.project.id).read(["name"])
# Add manager to server managers
server.write({"manager_ids": [(4, self.manager.id)]})
# Manager should be able to read project again
self.assertEqual(manager_project.browse(self.project.id).name, "Test Project")

View File

@@ -0,0 +1,462 @@
from odoo.exceptions import AccessError
from .common import CommonTest
class TestRemote(CommonTest):
"""Test class for git remote."""
@classmethod
def setUpClass(cls):
super().setUpClass()
# Create another manager for testing
cls.manager_2 = cls.Users.create(
{
"name": "Second Manager",
"login": "manager2",
"email": "manager2@test.com",
"groups_id": [(4, cls.env.ref("cetmix_tower_server.group_manager").id)],
}
)
# Create test project and source as root
cls.project = cls.GitProject.create(
{
"name": "Test Project",
}
)
cls.source = cls.GitSource.create(
{
"name": "Test Source",
"git_project_id": cls.project.id,
}
)
cls.repo_cetmix_tower = cls.Repo.create(
{
"name": "Cetmix Tower",
"url": "https://github.com/cetmix-test/cetmix-tower.git",
}
)
cls.remote = cls.GitRemote.create(
{
"repo_id": cls.repo_cetmix_tower.id,
"source_id": cls.source.id,
"head_type": "branch",
"head": "main",
}
)
cls.repo_test = cls.Repo.create(
{
"name": "Test Repository",
"url": "https://github.com/cetmix-test/test.git",
}
)
def test_user_access(self):
"""Test that regular users have no access to git remotes"""
user_remote = self.GitRemote.with_user(self.user)
# Test CRUD operations
with self.assertRaises(AccessError):
user_remote.create(
{
"repo_id": self.repo_test.id,
"url_protocol": "https",
"source_id": self.source.id,
"head": "main",
}
)
with self.assertRaises(AccessError):
user_remote.search([("id", "=", self.remote.id)])
with self.assertRaises(AccessError):
self.remote.with_user(self.user).write({"head": "dev"})
with self.assertRaises(AccessError):
self.remote.with_user(self.user).unlink()
def test_manager_read_access(self):
"""Test manager read access rules"""
manager_remote = self.GitRemote.with_user(self.manager)
# Manager not in project user_ids or manager_ids - should not read
self.assertFalse(manager_remote.search([("id", "=", self.remote.id)]))
# Add manager to project user_ids - should read
self.project.write({"user_ids": [(4, self.manager.id)]})
remote = manager_remote.search([("id", "=", self.remote.id)])
self.assertTrue(remote)
self.assertEqual(remote.head, "main")
# Remove from user_ids, add to manager_ids - should read
self.project.write(
{"user_ids": [(3, self.manager.id)], "manager_ids": [(4, self.manager.id)]}
)
remote = manager_remote.search([("id", "=", self.remote.id)])
self.assertTrue(remote.exists())
def test_manager_write_access(self):
"""Test manager write/create access rules"""
manager_remote = self.GitRemote.with_user(self.manager)
# Create project as manager - should be added to manager_ids automatically
project = self.GitProject.with_user(self.manager).create(
{
"name": "Manager Project",
}
)
source = self.GitSource.create(
{
"name": "Manager Source",
"git_project_id": project.id,
}
)
# Create remote in own project - should succeed
new_remote = manager_remote.create(
{
"repo_id": self.repo_test.id,
"url_protocol": "https",
"source_id": source.id,
"head_type": "branch",
"head": "main",
}
)
self.assertTrue(new_remote.exists())
# Write to own remote - should succeed
new_remote.write({"head": "dev"})
self.assertEqual(new_remote.head, "dev")
# Write to other's remote - should fail
with self.assertRaises(AccessError):
self.remote.with_user(self.manager).write({"head": "dev"})
def test_manager_unlink_access(self):
"""Test manager unlink access rules"""
# Create project and remote as manager_2
project = self.GitProject.with_user(self.manager_2).create(
{
"name": "Manager 2 Project",
}
)
source = self.GitSource.create(
{
"name": "Manager 2 Source",
"git_project_id": project.id,
}
)
remote = self.GitRemote.with_user(self.manager_2).create(
{
"repo_id": self.repo_test.id,
"url_protocol": "https",
"source_id": source.id,
"head_type": "branch",
"head": "main",
}
)
# Try delete as different manager - should fail even if added to manager_ids
project.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
remote.with_user(self.manager).unlink()
# Create remote as manager and try delete - should succeed
own_remote = self.GitRemote.with_user(self.manager).create(
{
"repo_id": self.repo_test.id,
"url_protocol": "https",
"source_id": source.id,
"head_type": "branch",
"head": "main",
}
)
self.assertTrue(own_remote.exists())
own_remote.with_user(self.manager).unlink()
self.assertFalse(own_remote.exists())
def test_root_access(self):
"""Test root access rules"""
root_remote = self.GitRemote.with_user(self.root)
# Create
new_remote = root_remote.create(
{
"repo_id": self.repo_test.id,
"url_protocol": "https",
"source_id": self.source.id,
"head_type": "branch",
"head": "main",
}
)
self.assertTrue(new_remote.exists())
# Read
remote = root_remote.search([("id", "=", self.remote.id)])
self.assertTrue(remote)
self.assertEqual(remote.head, "main")
# Write
self.remote.with_user(self.root).write({"head": "dev"})
self.assertEqual(self.remote.head, "dev")
# Delete
new_remote.with_user(self.root).unlink()
self.assertFalse(new_remote.exists())
def test_remote_provider_protocol_and_name(self):
"""Test if remote provider is detected correctly"""
# -- 1--
# GitHub + https
# Check if remote provider is detected correctly
self.assertEqual(
self.remote_github_https.repo_provider,
"github",
"Provider is not detected correctly",
)
self.assertEqual(
self.remote_github_https.url_protocol,
"https",
"Protocol is not detected correctly",
)
self.assertEqual(
self.remote_github_https.name,
"remote_1",
"Name is not prepared correctly",
)
# -- 2 --
# GitLab + ssh
# Check if remote provider is detected correctly
self.assertEqual(
self.remote_gitlab_ssh.repo_provider,
"gitlab",
"Provider is not detected correctly",
)
self.assertEqual(
self.remote_gitlab_ssh.url_protocol,
"ssh",
"Protocol is not detected correctly",
)
self.assertEqual(
self.remote_gitlab_ssh.name,
"remote_3",
"Name is not prepared correctly",
)
# -- 3 --
# Bitbucket + https
# Check if remote provider is detected correctly
self.assertEqual(
self.remote_bitbucket_https.repo_provider,
"bitbucket",
"Provider is not detected correctly",
)
self.assertEqual(
self.remote_bitbucket_https.url_protocol,
"https",
"Protocol is not detected correctly",
)
self.assertEqual(
self.remote_bitbucket_https.name,
"remote_1",
"Name is not prepared correctly",
)
# -- 4 --
# Other + ssh
# Check if remote provider is detected correctly
self.assertEqual(
self.remote_other_ssh.repo_provider,
"gitlab", # this is how giturlparse detects the provider
"Provider is not detected correctly",
)
self.assertEqual(
self.remote_other_ssh.url_protocol,
"ssh",
"Protocol is not detected correctly",
)
self.assertEqual(
self.remote_other_ssh.name,
"remote_2",
"Name is not prepared correctly",
)
def test_git_aggregator_prepare_url(self):
"""Test if url is prepared correctly"""
# -- 1 --
# GitHub + https
self.remote_github_https.repo_id.is_private = False
self.assertEqual(
self.remote_github_https._git_aggregator_prepare_url(),
self.remote_github_https.repo_id.url,
"URL is not prepared correctly",
)
# -- 2 --
# GitHub + https -> private
self.remote_github_https.repo_id.is_private = True
self.assertEqual(
self.remote_github_https._git_aggregator_prepare_url(),
"https://$GITHUB_TOKEN:x-oauth-basic@github.com/cetmix-test/cetmix-tower-test.git",
"URL is not prepared correctly",
)
# -- 3 --
# Gitlab + https
self.remote_gitlab_https.repo_id.is_private = False
self.assertEqual(
self.remote_gitlab_https._git_aggregator_prepare_url(),
self.remote_gitlab_https.repo_id.url,
"URL is not prepared correctly",
)
# -- 4 --
# Gitlab + https -> private
self.remote_gitlab_https.repo_id.is_private = True
self.assertEqual(
self.remote_gitlab_https._git_aggregator_prepare_url(),
"https://$GITLAB_TOKEN_NAME:$GITLAB_TOKEN@my.gitlab.com/cetmix-test/cetmix-tower-test.git",
"URL is not prepared correctly",
)
# -- 5 --
# Bitbucket + https
self.remote_bitbucket_https.repo_id.is_private = False
self.assertEqual(
self.remote_bitbucket_https._git_aggregator_prepare_url(),
self.remote_bitbucket_https.repo_id.url,
"URL is not prepared correctly",
)
# -- 6 --
# Bitbucket + https -> private
self.remote_bitbucket_https.repo_id.is_private = True
self.assertEqual(
self.remote_bitbucket_https._git_aggregator_prepare_url(),
"https://x-token-auth:$BITBUCKET_TOKEN@bitbucket.com/cetmix-test/cetmix-tower-test-enterprise.git",
"URL is not prepared correctly",
)
# -- 7 --
# Other + ssh
self.remote_other_ssh.repo_id.is_private = False
self.assertEqual(
self.remote_other_ssh._git_aggregator_prepare_url(),
self.remote_other_ssh.repo_id.url_ssh,
"URL is not prepared correctly",
)
def test_git_aggregator_prepare_head(self):
"""Test if head is prepared correctly"""
# -- 1 --
# GitHub + PR/MR as link
self.assertEqual(
self.remote_github_https._git_aggregator_prepare_head(),
"refs/pull/123/head",
"Head is not prepared correctly",
)
# -- 2 --
# GitHub + PR/MR as number
self.remote_github_https.write({"head": "123", "head_type": "pr"})
self.assertEqual(
self.remote_github_https._git_aggregator_prepare_head(),
"refs/pull/123/head",
"Head is not prepared correctly",
)
# -- 3 --
# GitHub + branch as name
self.remote_github_https.write({"head": "main", "head_type": "branch"})
self.assertEqual(
self.remote_github_https._git_aggregator_prepare_head(),
self.remote_github_https.head,
"Head is not prepared correctly",
)
# -- 4 --
# GitHub + branch as link
self.remote_github_https.write(
{
"head": "https://github.com/cetmix-test/cetmix-tower/tree/14.0-demo-branch",
"head_type": "branch",
}
)
self.assertEqual(
self.remote_github_https._git_aggregator_prepare_head(),
"14.0-demo-branch",
"Head is not prepared correctly",
)
# -- 5 --
# GitHub + commit as number
self.remote_github_https.write({"head": "1234567890", "head_type": "commit"})
self.assertEqual(
self.remote_github_https._git_aggregator_prepare_head(),
"1234567890",
"Head is not prepared correctly",
)
# -- 6 --
# GitHub + commit as link
self.remote_github_https.head = (
"https://github.com/cetmix-test/cetmix-tower/commit/1234567890"
)
self.assertEqual(
self.remote_github_https._git_aggregator_prepare_head(),
"1234567890",
"Head is not prepared correctly",
)
def test_manager_server_based_access(self):
"""Test manager access to remotes through server relationships"""
manager_remote = self.GitRemote.with_user(self.manager)
# Create a server where manager is a user
server = self.Server.create(
{
"name": "Test Server",
"ip_v4_address": "localhost",
"ssh_username": "admin",
"ssh_password": "password",
"os_id": self.os_debian_10.id,
"user_ids": [(4, self.manager.id)],
}
)
# Link project to server
file = self.File.create(
{
"name": "test_file",
"server_id": server.id,
}
)
self.GitProjectRel.create(
{
"server_id": server.id,
"file_id": file.id,
"git_project_id": self.project.id,
"project_format": "git_aggregator",
}
)
# Manager should be able to read remote through server relationship
remote = manager_remote.search([("id", "=", self.remote.id)])
self.assertTrue(remote)
self.assertEqual(remote.head, "main")
# Remove manager from server users
server.write({"user_ids": [(3, self.manager.id)]})
# Manager should not be able to read remote anymore
self.assertFalse(manager_remote.search([("id", "=", self.remote.id)]))
# Add manager to server managers
server.write({"manager_ids": [(4, self.manager.id)]})
# Manager should be able to read remote again
remote = manager_remote.search([("id", "=", self.remote.id)])
self.assertTrue(remote)
self.assertEqual(remote.head, "main")

View File

@@ -0,0 +1,84 @@
from odoo.exceptions import ValidationError
from .common import CommonTest
class TestRepo(CommonTest):
"""Test class for git repository."""
@classmethod
def setUpClass(cls):
super().setUpClass()
def test_repo_create_from_url_https_success(self):
"""Test if repository is created correctly"""
# -- 1 --
# Valid HTTPS URL
repo = self.Repo.create(
{
"url": "https://github.com/memes-demo/doge-memes.git",
}
)
repo.invalidate_recordset()
self.assertEqual(repo.name, "github.com/memes-demo/doge-memes")
self.assertEqual(repo.host, "github.com")
self.assertEqual(repo.owner_id.name, "memes-demo")
self.assertEqual(repo.provider, "github")
self.assertEqual(repo.is_private, False)
self.assertEqual(repo.url_ssh, "git@github.com:memes-demo/doge-memes.git")
self.assertEqual(repo.url_git, "git://github.com/memes-demo/doge-memes.git")
def test_repo_create_from_url_ssh_success(self):
"""Test if repository is created correctly"""
# -- 1 --
# Valid SSH URL
repo = self.Repo.create(
{
"url": "git@gitlab.com:chad-guy/chad-guy.git",
}
)
repo.invalidate_recordset()
self.assertEqual(repo.name, "gitlab.com/chad-guy/chad-guy")
self.assertEqual(repo.host, "gitlab.com")
self.assertEqual(repo.owner_id.name, "chad-guy")
self.assertEqual(repo.provider, "gitlab")
self.assertEqual(repo.is_private, False)
self.assertEqual(repo.url, "https://gitlab.com/chad-guy/chad-guy.git")
self.assertEqual(repo.url_git, "git://gitlab.com/chad-guy/chad-guy.git")
def test_repo_create_from_url_git_success(self):
"""Test if repository is created correctly"""
# -- 1 --
# Valid GIT URL
repo = self.Repo.create(
{
"url": "git://bitbucket.com/much-pepe/pepe-memes.git",
}
)
self.assertEqual(repo.name, "bitbucket.com/much-pepe/pepe-memes")
self.assertEqual(repo.host, "bitbucket.com")
self.assertEqual(repo.owner_id.name, "much-pepe")
self.assertEqual(repo.provider, "bitbucket")
self.assertEqual(repo.is_private, False)
self.assertEqual(repo.url_ssh, "git@bitbucket.com:much-pepe/pepe-memes.git")
self.assertEqual(repo.url, "https://bitbucket.com/much-pepe/pepe-memes.git")
def test_repo_create_from_url_fails(self):
"""Test if repository creation fails with invalid URLs"""
# Invalid URL 1
with self.assertRaises(ValidationError):
self.Repo.create(
{
"url": "something.com",
}
)
# Invalid URL 2
with self.assertRaises(ValidationError):
self.Repo.create(
{
"url": "random string",
}
)

View File

@@ -0,0 +1,198 @@
try:
from odoo.addons.queue_job.tests.common import trap_jobs
except ImportError:
trap_jobs = None
from .common import CommonTest
class TestServer(CommonTest):
"""Test setting git project to server from plan line."""
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.GitProjectRel.create(
{
"git_project_id": cls.git_project_1.id,
"server_id": cls.server_test_1.id,
"file_id": cls.server_1_file_1.id,
}
)
def test_server_creation_running_flight_plan(self):
"""Test that server is created with git project from plan line."""
git_project = self.GitProject.create(
{
"name": "Test Git Project",
"manager_ids": [(4, self.manager.id)],
}
)
file_template = self.FileTemplate.create(
{
"name": "Git Config Template",
"file_name": "repos.yaml",
"server_dir": "/var/test",
"code": "repositories:\n test_repo:\n "
"url: https://github.com/test/repo.git\n target: main",
}
)
command = self.Command.create(
{
"name": "Create Git Config File",
"action": "file_using_template",
"file_template_id": file_template.id,
}
)
flight_plan = self.Plan.create(
{
"name": "Git Project Setup Plan",
"note": "Sets up a git project on the server",
}
)
self.plan_line.create(
{
"plan_id": flight_plan.id,
"command_id": command.id,
"sequence": 10,
"git_project_id": git_project.id,
}
)
server_template = self.ServerTemplate.create(
{
"name": "Git Server Template",
"ssh_port": 22,
"ssh_username": "admin",
"ssh_password": "password",
"ssh_auth_mode": "p",
"os_id": self.os_debian_10.id,
"flight_plan_id": flight_plan.id,
"manager_ids": [(4, self.manager.id)],
}
)
action = server_template.action_create_server()
# Open the wizard and fill in the data
wizard = (
self.env["cx.tower.server.template.create.wizard"]
.with_context(**action["context"])
.create(
{
"name": "Git Server",
"ip_v4_address": "192.168.1.10",
"server_template_id": server_template.id,
}
)
)
# If cetmix_tower_server_queue module is installed, test async processing
if self.env["ir.module.module"].search_count(
[("name", "=", "cetmix_tower_server_queue"), ("state", "=", "installed")]
):
with trap_jobs() as trap:
wizard.action_confirm()
# Verify that jobs were created
self.assertGreater(
len(trap.enqueued_jobs), 0, "Jobs should have been enqueued"
)
# Execute all trapped jobs to simulate async processing
trap.perform_enqueued_jobs()
else:
wizard.action_confirm()
# Now search for the created records after jobs have been executed
server = self.Server.search(
[
("name", "=", "Git Server"),
("server_template_id", "=", server_template.id),
]
)
self.assertEqual(len(server), 1, "Exactly one server should have been created")
# Verify the file was created
file = self.File.search(
[("server_id", "=", server.id), ("name", "=", "repos.yaml")]
)
self.assertEqual(
len(file), 1, "Exactly one git config file should have been created"
)
# Verify the git project relation exists
git_project_rel = self.GitProjectRel.search(
[
("server_id", "=", server.id),
("git_project_id", "=", git_project.id),
("file_id", "=", file.id),
]
)
self.assertEqual(
len(git_project_rel), 1, "Exactly one git project relation should exist"
)
self.assertEqual(
git_project_rel.file_id,
file,
"The related file should be the git config file",
)
self.assertEqual(
git_project_rel.git_project_id,
git_project,
"The related git project should match the one in the flight plan",
)
self.assertEqual(
git_project_rel.project_format,
git_project._default_project_format(),
"Project format should match the default format",
)
def test_server_get_servers_by_git_ref_success(self):
"""Check the success case of server.get_servers_by_git_ref"""
# 1. URL only
servers = self.Server.get_servers_by_git_ref(
self.remote_github_https.repo_id.url
)
self.assertEqual(servers, self.server_test_1)
# 2. Specific URL with specific head
servers = self.Server.get_servers_by_git_ref(
self.remote_github_https.repo_id.url, "123"
)
self.assertEqual(servers, self.server_test_1)
# 2. Specific URL with specific head and head type
servers = self.Server.get_servers_by_git_ref(
self.remote_github_https.repo_id.url, "123", "pr"
)
self.assertEqual(servers, self.server_test_1)
def test_server_get_servers_by_git_ref_no_match(self):
"""Check the no match case of server.get_servers_by_git_ref"""
# 1. Repo link does not exist
servers = self.Server.get_servers_by_git_ref(
"https://github.com/other-org/other-repo.git", "main", "branch"
)
self.assertFalse(servers)
# 2. Repo link exists, but remote does not exist
servers = self.Server.get_servers_by_git_ref(
self.repo_cetmix_tower.url, "3311", "pr"
)
self.assertFalse(servers)
# 3. Repo link exists, but remote type does not exist
servers = self.Server.get_servers_by_git_ref(
self.repo_cetmix_tower.url, "main", "commit"
)
self.assertFalse(servers)

View File

@@ -0,0 +1,226 @@
from odoo.exceptions import AccessError
from .common import CommonTest
class TestSource(CommonTest):
"""Test class for git source."""
@classmethod
def setUpClass(cls):
super().setUpClass()
# Create another manager for testing
cls.manager_2 = cls.Users.create(
{
"name": "Second Manager",
"login": "manager2",
"email": "manager2@test.com",
"groups_id": [(4, cls.env.ref("cetmix_tower_server.group_manager").id)],
}
)
# Create test project and source as root
cls.project = cls.GitProject.create(
{
"name": "Test Project",
}
)
cls.source = cls.GitSource.create(
{
"name": "Test Source",
"git_project_id": cls.project.id,
}
)
def test_user_access(self):
"""Test that regular users have no access to git sources"""
user_source = self.GitSource.with_user(self.user)
# Test CRUD operations
with self.assertRaises(AccessError):
user_source.create(
{
"name": "New Source",
"git_project_id": self.project.id,
}
)
with self.assertRaises(AccessError):
user_source.browse(self.source.id).read(["name"])
with self.assertRaises(AccessError):
user_source.browse(self.source.id).write({"name": "Updated Name"})
with self.assertRaises(AccessError):
user_source.browse(self.source.id).unlink()
def test_manager_read_access(self):
"""Test manager read access rules"""
manager_source = self.GitSource.with_user(self.manager)
# Manager not in project user_ids or manager_ids - should not read
with self.assertRaises(AccessError):
manager_source.browse(self.source.id).read(["name"])
# Add manager to project user_ids - should read
self.project.write({"user_ids": [(4, self.manager.id)]})
self.assertEqual(manager_source.browse(self.source.id).name, "Test Source")
# Remove from user_ids, add to manager_ids - should read
self.project.write(
{"user_ids": [(3, self.manager.id)], "manager_ids": [(4, self.manager.id)]}
)
self.assertEqual(manager_source.browse(self.source.id).name, "Test Source")
def test_manager_write_access(self):
"""Test manager write/create access rules"""
manager_source = self.GitSource.with_user(self.manager)
# Create project as manager - should be added to manager_ids automatically
project = self.GitProject.with_user(self.manager).create(
{
"name": "Manager Project",
}
)
self.assertIn(self.manager, project.manager_ids)
# Create source in own project - should succeed
new_source = manager_source.create(
{
"name": "New Source",
"git_project_id": project.id,
}
)
self.assertTrue(new_source.exists())
# Write to own source - should succeed
new_source.write({"name": "Updated Name"})
self.assertEqual(new_source.name, "Updated Name")
# Write to other's source - should fail
with self.assertRaises(AccessError):
manager_source.browse(self.source.id).write({"name": "Updated Name"})
def test_manager_unlink_access(self):
"""Test manager unlink access rules"""
# Create project and source as manager_2
project = self.GitProject.with_user(self.manager_2).create(
{
"name": "Manager 2 Project",
}
)
source = self.GitSource.with_user(self.manager_2).create(
{
"name": "Source to Delete",
"git_project_id": project.id,
}
)
manager_source = self.GitSource.with_user(self.manager)
# Try delete as different manager - should fail even if added to manager_ids
project.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
manager_source.browse(source.id).unlink()
# Create source as manager and try delete - should succeed
own_source = manager_source.create(
{
"name": "Own Source",
"git_project_id": project.id,
}
)
self.assertTrue(own_source.exists())
own_source.unlink()
self.assertFalse(own_source.exists())
def test_root_access(self):
"""Test root access rules"""
root_source = self.GitSource.with_user(self.root)
# Create
new_source = root_source.create(
{
"name": "Root Source",
"git_project_id": self.project.id,
}
)
self.assertTrue(new_source.exists())
# Read
self.assertEqual(root_source.browse(self.source.id).name, "Test Source")
# Write
root_source.browse(self.source.id).write({"name": "Updated by Root"})
self.assertEqual(self.source.name, "Updated by Root")
# Delete
new_source.unlink()
self.assertFalse(new_source.exists())
def test_source_git_aggregator_prepare_record(self):
"""Test if source prepare record method works correctly."""
# -- 1 --
# Source 1
expected_result = {
"remotes": {
"remote_1": "https://github.com/cetmix-test/cetmix-tower-test.git",
"remote_2": "https://$GITLAB_TOKEN_NAME:$GITLAB_TOKEN@my.gitlab.com/cetmix-test/cetmix-tower-test.git",
"remote_3": "git@my.gitlab.com:cetmix-test/cetmix-tower-test.git",
},
"merges": [
{"remote": "remote_1", "ref": "refs/pull/123/head"},
{"remote": "remote_2", "ref": "main"},
{"remote": "remote_3", "ref": "10000000"},
],
"target": "remote_1",
}
prepared_result = self.git_source_1._git_aggregator_prepare_record()
self.assertEqual(
prepared_result, expected_result, "Prepared result is not correct"
)
def test_manager_server_based_access(self):
"""Test manager access to sources through server relationships"""
manager_source = self.GitSource.with_user(self.manager)
# Create a server where manager is a user
server = self.Server.create(
{
"name": "Test Server",
"ip_v4_address": "localhost",
"ssh_username": "admin",
"ssh_password": "password",
"os_id": self.os_debian_10.id,
"user_ids": [(4, self.manager.id)],
}
)
# Link project to server
file = self.File.create(
{
"name": "test_file",
"server_id": server.id,
}
)
self.GitProjectRel.create(
{
"server_id": server.id,
"file_id": file.id,
"git_project_id": self.project.id,
"project_format": "git_aggregator",
}
)
# Manager should be able to read source through server relationship
self.assertEqual(manager_source.browse(self.source.id).name, "Test Source")
# Remove manager from server users
server.write({"user_ids": [(3, self.manager.id)]})
# Manager should not be able to read source anymore
with self.assertRaises(AccessError):
manager_source.browse(self.source.id).read(["name"])
# Add manager to server managers
server.write({"manager_ids": [(4, self.manager.id)]})
# Manager should be able to read source again
self.assertEqual(manager_source.browse(self.source.id).name, "Test Source")

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="cx_tower_file_template_view_form" model="ir.ui.view">
<field name="name">cx.tower.file.template.view.form</field>
<field name="model">cx.tower.file.template</field>
<field
name="inherit_id"
ref="cetmix_tower_server.cx_tower_file_template_view_form"
/>
<field name="arch" type="xml">
<field name="source" position="after">
<field
name="git_project_id"
attrs="{'invisible': [('git_project_id', '=', False)]}"
/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="cx_tower_file_view_form" model="ir.ui.view">
<field name="name">cx.tower.file.view.form</field>
<field name="model">cx.tower.file</field>
<field name="inherit_id" ref="cetmix_tower_server.cx_tower_file_view_form" />
<field name="arch" type="xml">
<field name="auto_sync" position="before">
<field
name="git_project_id"
attrs="{'invisible': [('git_project_id', '=', False)]}"
/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,236 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Tree View -->
<record id="cx_tower_git_project_view_tree" model="ir.ui.view">
<field name="name">cx.tower.git.project.tree</field>
<field name="model">cx.tower.git.project</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="server_ids" widget="many2many_tags" />
<field name="active" widget="boolean_toggle" />
</tree>
</field>
</record>
<!-- Form View -->
<record id="cx_tower_git_project_view_form" model="ir.ui.view">
<field name="name">cx.tower.git.project.form</field>
<field name="model">cx.tower.git.project</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget
name="web_ribbon"
title="Archived"
bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<div class="oe_title">
<h1>
<field name="name" placeholder="Name" />
</h1>
<h3>
<field
name="reference"
placeholder="Reference. Can contain English letters, digits and '_'. Leave blank to autogenerate"
/>
</h3>
</div>
<group>
<group string="General">
<field name="active" invisible="1" />
<field
name="server_ids"
widget="many2many_tags"
attrs="{'invisible': [('server_ids', '=', [])]}"
/>
<field
name="file_template_ids"
widget="many2many_tags"
attrs="{'invisible': [('file_template_ids', '=', [])]}"
/>
</group>
<group string="Git Aggregator">
<field
name="git_aggregator_root_dir"
string="Root Directory"
placeholder="Git aggregator root directory where sources will be cloned. Leave blank to use '.'"
/>
</group>
<field name="note" placeholder="Put your notes here..." />
</group>
<notebook>
<page name="sources" string="Sources">
<field name="source_ids">
<tree
decoration-muted="not enabled"
decoration-info="remote_count_private == remote_count and remote_count &gt; 0"
decoration-warning="remote_count_private != remote_count and remote_count &gt; 0 and remote_count_private &gt; 0"
>
<field name="sequence" widget="handle" />
<field
name="name"
placeholder="..to be autogenerated"
/>
<field name="remote_count" optional="show" />
<field
name="remote_count_private"
optional="hide"
/>
<field name="enabled" widget="boolean_toggle" />
<field name="reference" optional="hide" />
<field name="create_uid" optional="hide" />
</tree>
</field>
<field name="has_private_remotes" invisible="1" />
<field name="has_partially_private_remotes" invisible="1" />
<div
class="text-info"
attrs="{'invisible': [('has_private_remotes', '=', False)]}"
>
<p>
* Sources where all remotes are private
</p>
</div>
<div
class="text-warning"
attrs="{'invisible': [('has_partially_private_remotes', '=', False)]}"
>
<p>
* Sources where some remotes are private
</p>
</div>
</page>
<page name="files" string="Files">
<field name="git_project_rel_ids">
<tree editable="bottom">
<field
name="server_id"
options="{'no_create': True, 'no_create_edit': True}"
/>
<field
name="file_id"
options="{'no_create': True, 'no_create_edit': True}"
/>
<field name="project_format" />
<field name="auto_sync" />
<button
type="object"
name="action_open_server"
string="Open Server"
title="Open Server"
class="btn-secondary"
/>
</tree>
<form>
<group>
<field name="server_id" />
<field name="file_id" />
<field name="project_format" />
<field name="auto_sync" />
</group>
</form>
</field>
</page>
<page name="file_templates" string="File Templates">
<field name="git_project_file_template_rel_ids">
<tree editable="bottom">
<field
name="file_template_id"
options="{'no_create': True, 'no_create_edit': True}"
/>
<field name="project_format" />
<button
type="object"
string="Open file template"
name="action_open_file_template"
title="Open File Template"
class="btn-secondary"
/>
</tree>
<form>
<group>
<field name="file_template_id" />
<field name="project_format" />
</group>
</form>
</field>
</page>
<page
name="repos"
string="Repos"
groups="base.group_no_one"
attrs="{'invisible': [('repo_ids', '=', [])]}"
>
<field name="repo_ids" />
</page>
<page
name="access"
string="Access"
groups="cetmix_tower_server.group_manager"
>
<group name="access">
<field
name="user_ids"
widget="many2many_tags"
placeholder="users who can view this record"
options="{'no_create': True}"
/>
<field
name="manager_ids"
widget="many2many_tags"
placeholder="managers who can modify this record"
options="{'no_create': True}"
/>
</group>
<div
class="alert alert-warning"
role="alert"
style="margin-bottom:0px;"
>
<ul>
<li>
<b
>Users.</b> All users who have "Manager" group and are either set in "Users" or in "Managers" in <b
><u>all</u></b> related servers.
</li>
<li>
<b
>Managers.</b> All users who have "Manager" group and are set as "Managers" in <b
><u>all</u></b> related servers.
This is done to avoid unpredictable consequences when some of the servers are not updated due to access restrictions when a project is updated.
</li>
</ul>
You can edit these fields at your own risk. However keep in mind that they will be automatically updated each time related servers are added, removed or updated.
</div>
</page>
<page name="yaml" string="YAML">
<div groups="!cetmix_tower_yaml.group_export">
<h3
>You must be a member of the "YAML/Export" group to export data as YAML.</h3>
</div>
<button
type="object"
groups="cetmix_tower_yaml.group_export"
class="oe_highlight"
name="action_open_yaml_export_wizard"
string="Export YAML"
/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record id="cx_tower_git_project_action" model="ir.actions.act_window">
<field name="name">Git Projects</field>
<field name="res_model">cx.tower.git.project</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Tree View -->
<record id="cx_tower_git_remote_view_tree" model="ir.ui.view">
<field name="name">cx.tower.git.remote.tree</field>
<field name="model">cx.tower.git.remote</field>
<field name="arch" type="xml">
<tree decoration-info="is_private == True">
<field
name="repo_id"
placeholder="select or enter a link"
options="{'no_create_edit': True}"
/>
<field name="is_private" optional="hide" />
<field name="head_type" />
<field name="head" />
<field name="enabled" widget="boolean_toggle" />
<field name="create_uid" optional="hide" />
<field name="reference" optional="hide" />
</tree>
</field>
</record>
<!-- Form View -->
<record id="cx_tower_git_remote_view_form" model="ir.ui.view">
<field name="name">cx.tower.git.remote.form</field>
<field name="model">cx.tower.git.remote</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget
name="web_ribbon"
title="Disabled"
bg_color="bg-danger"
attrs="{'invisible': [('enabled', '=', True)]}"
/>
<group>
<field name="sequence" />
<field name="enabled" />
<field name="active" invisible="1" />
<field
name="repo_id"
placeholder="select or enter a link"
options="{'no_create_edit': True}"
/>
<field name="is_private" />
<field
name="url_protocol"
widget="radio"
options="{'horizontal': true}"
/>
<field
name="head_type"
widget="radio"
options="{'horizontal': true}"
/>
<field
name="head"
placeholder="Branch/PR/commit number or link"
/>
<field name="create_uid" />
</group>
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record id="action_cx_tower_git_remote" model="ir.actions.act_window">
<field name="name">Git Remotes</field>
<field name="res_model">cx.tower.git.remote</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first git remote!
</p>
<p>
Git remotes represent branches, pull requests, or commits from git repositories.
</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Tree View -->
<record id="cx_tower_git_repo_owner_view_tree" model="ir.ui.view">
<field name="name">cx.tower.git.repo.owner.tree</field>
<field name="model">cx.tower.git.repo.owner</field>
<field name="arch" type="xml">
<tree>
<field name="display_name" />
<field name="name" />
</tree>
</field>
</record>
<!-- Form View -->
<record id="cx_tower_git_repo_owner_view_form" model="ir.ui.view">
<field name="name">cx.tower.git.repo.owner.form</field>
<field name="model">cx.tower.git.repo.owner</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="display_name" placeholder="e.g., Cetmix, OCA" />
<field name="name" placeholder="e.g., cetmix, oca" />
<field
name="reference"
placeholder="Can contain English letters, digits and '_'. Leave blank to autogenerate"
/>
<field name="secret_id" />
</group>
<notebook>
<page string="Repositories" name="repositories">
<field name="repo_ids" readonly="1">
<tree>
<field name="name" />
<field name="reference" optional="hide" />
<field name="provider" />
<field name="is_private" />
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record id="action_cx_tower_git_repo_owner" model="ir.actions.act_window">
<field name="name">Repository Owners</field>
<field name="res_model">cx.tower.git.repo.owner</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first repository owner!
</p>
<p>
Repository owners represent organizations or users that own git repositories.
Examples include "cetmix", "OCA", etc.
</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Tree View -->
<record id="cx_tower_git_repo_view_tree" model="ir.ui.view">
<field name="name">cx.tower.git.repo.tree</field>
<field name="model">cx.tower.git.repo</field>
<field name="arch" type="xml">
<tree decoration-info="is_private == True">
<field name="name" />
<field name="reference" optional="hide" />
<field name="provider" optional="show" />
<field name="owner_id" optional="hide" />
<field name="is_private" optional="hide" />
<field name="remote_count" optional="hide" />
<field name="git_project_count" optional="hide" />
</tree>
</field>
</record>
<!-- Form View -->
<record id="cx_tower_git_repo_view_form" model="ir.ui.view">
<field name="name">cx.tower.git.repo.form</field>
<field name="model">cx.tower.git.repo</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_button_box" name="button_box">
<button
name="action_view_remotes"
type="object"
string="Remotes"
class="oe_stat_button"
icon="fa-external-link"
attrs="{'invisible': [('remote_count', '=', 0)]}"
>
<field
name="remote_count"
widget="statinfo"
string="Remotes"
/>
</button>
<button
name="action_view_projects"
type="object"
string="GitProjects"
class="oe_stat_button"
icon="fa-folder"
attrs="{'invisible': [('git_project_count', '=', 0)]}"
>
<field
name="git_project_count"
widget="statinfo"
string="Projects"
/>
</button>
</div>
<group>
<group name="info">
<field
name="url"
placeholder="https, ssh or git formats are accepted"
/>
<field name="url_ssh" />
<field name="url_git" />
<field name="repo" placeholder="e.g., cetmix-tower, odoo" />
<field name="host" />
</group>
<group name="details">
<field
name="reference"
placeholder="Can contain English letters, digits and '_'. Leave blank to autogenerate"
/>
<field name="active" />
<field name="owner_id" />
<field name="provider" />
<field name="is_private" />
<field name="secret_id" />
</group>
</group>
</sheet>
</form>
</field>
</record>
<!-- Search View -->
<record id="cx_tower_git_repo_view_search" model="ir.ui.view">
<field name="name">cx.tower.git.repo.search</field>
<field name="model">cx.tower.git.repo</field>
<field name="arch" type="xml">
<search>
<field
name="repo"
string="Name/Reference"
filter_domain="['|', ('repo', 'ilike', self), ('reference', 'ilike', self)]"
/>
<field name="owner_id" string="Org" />
<field name="provider" />
<filter
string="Public"
name="public"
domain="[('is_private', '=', False)]"
/>
<filter
string="Private"
name="private"
domain="[('is_private', '=', True)]"
/>
<separator />
<filter
string="Provider: Other"
name="no_provider"
domain="[('provider', '=', 'other')]"
/>
<group expand="0" string="Group By">
<filter
string="Provider"
name="group_provider"
context="{'group_by': 'provider'}"
/>
<filter
string="Org"
name="group_owner"
context="{'group_by': 'owner_id'}"
/>
</group>
<searchpanel>
<field
name="provider"
string="Provider"
icon="fa-globe"
enable_counters="1"
/>
<field
name="owner_id"
string="Org"
icon="fa-building"
enable_counters="1"
/>
</searchpanel>
</search>
</field>
</record>
<!-- Action -->
<record id="action_cx_tower_git_repo" model="ir.actions.act_window">
<field name="name">Repositories</field>
<field name="res_model">cx.tower.git.repo</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first repository!
</p>
<p>
Repositories represent git repositories with their metadata and configuration.
They can be linked to remotes to automatically populate URL information.
</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Tree View -->
<record id="cx_tower_git_source_view_tree" model="ir.ui.view">
<field name="name">cx.tower.git.source.tree</field>
<field name="model">cx.tower.git.source</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="git_project_id" />
</tree>
</field>
</record>
<!-- Form View -->
<record id="cx_tower_git_source_view_form" model="ir.ui.view">
<field name="name">cx.tower.git.source.form</field>
<field name="model">cx.tower.git.source</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget
name="web_ribbon"
title="Disabled"
bg_color="bg-danger"
attrs="{'invisible': [('enabled', '=', True)]}"
/>
<div class="oe_title">
<h1>
<field
name="name"
placeholder="Name. Leave blank to autogenerate"
/>
</h1>
<h3>
<field
name="reference"
placeholder="Reference. Can contain English letters, digits and '_'. Leave blank to autogenerate"
attrs="{'invisible': [('reference', '=', False)]}"
/>
</h3>
</div>
<group>
<field name="sequence" />
<field name="enabled" />
<field name="active" invisible="1" />
</group>
<notebook>
<page name="remotes" string="Remotes">
<div
class="alert alert-warning"
role="alert"
style="margin-bottom:0px;"
attrs="{'invisible': [('remote_count', '&lt;', 2)]}"
>
<p>
The top one remote will be used as a merge target.
You can re-arrange remotes by dragging them or changing their sequence value.
</p>
</div>
<field name="remote_count" invisible="1" />
<field name="remote_ids">
<tree
decoration-muted="not enabled"
decoration-info="is_private == True"
>
<field name="sequence" widget="handle" />
<field name="repo_id" />
<field name="head_type" />
<field name="head" />
<field name="url_protocol" />
<field name="enabled" widget="boolean_toggle" />
<field name="is_private" optional="hide" />
<field name="reference" optional="hide" />
<field name="create_uid" optional="hide" />
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
</odoo>

Some files were not shown because too many files have changed in this diff Show More