mirror of
https://github.com/umami-software/umami.git
synced 2025-12-06 01:18:00 +01:00
Compare commits
883 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81e27fc18c | ||
|
|
2b771ff2b4 | ||
|
|
60271779de | ||
|
|
33e927ed1f | ||
|
|
7e42b5b35e | ||
|
|
2993db14f0 | ||
|
|
1483241494 | ||
|
|
c427c6f547 | ||
|
|
33cb195fd0 | ||
|
|
64767b1896 | ||
|
|
be1b787789 | ||
|
|
dae7327ed3 | ||
|
|
a06490af74 | ||
|
|
65f657dd23 | ||
|
|
6b584338e3 | ||
|
|
41d2a24f9d | ||
|
|
1ae13513d2 | ||
|
|
9a269ab811 | ||
|
|
32aee652a5 | ||
|
|
16cae691f6 | ||
|
|
1390e09400 | ||
|
|
23ff20a10b | ||
|
|
58acee8d25 | ||
|
|
a0940d78a7 | ||
|
|
89b985652a | ||
|
|
7b3be59c8d | ||
|
|
b08413ebea | ||
|
|
f47e1072d9 | ||
|
|
22f1b7d7c9 | ||
|
|
b0f38b266b | ||
|
|
e7cb613cec | ||
|
|
170821e2f9 | ||
|
|
935517ce3a | ||
|
|
c481bc5dcc | ||
|
|
b7807ed466 | ||
|
|
f5896f071b | ||
|
|
06251e1317 | ||
|
|
9a2827b50d | ||
|
|
b0c1f9041d | ||
|
|
cb034a1371 | ||
|
|
4b954fbc7c | ||
|
|
f5d6d0ebaf | ||
|
|
3071ee8b88 | ||
|
|
b16b98ffe8 | ||
|
|
4d70c3baf1 | ||
|
|
c86ea1a74f | ||
|
|
805bc57bbb | ||
|
|
92a7355ce3 | ||
|
|
875c03bca1 | ||
|
|
e5a5aeecb5 | ||
|
|
046cb6ef62 | ||
|
|
beb2bc0a06 | ||
|
|
776e404c6f | ||
|
|
3379cc6e89 | ||
|
|
d7fd22645c | ||
|
|
50bfee3328 | ||
|
|
a645dc7ba5 | ||
|
|
f5b5f159ec | ||
|
|
3cc2c5b7a8 | ||
|
|
5c9403f748 | ||
|
|
ac6ed9d762 | ||
|
|
5ea2a8659c | ||
|
|
a19b92a5cb | ||
|
|
dcc1ae1864 | ||
|
|
5a44e6deb2 | ||
|
|
67e1af7e55 | ||
|
|
2b34cbeb37 | ||
|
|
0ddec97bf0 | ||
|
|
fa8d8055df | ||
|
|
67981db524 | ||
|
|
099c8bf1b4 | ||
|
|
d51f0641a6 | ||
|
|
b9d52af215 | ||
|
|
94321192b8 | ||
|
|
ffa97d34e2 | ||
|
|
bc737268b6 | ||
|
|
b45971da33 | ||
|
|
15fda927ce | ||
|
|
af958b6462 | ||
|
|
aaa1f9dc58 | ||
|
|
abc1b50ad0 | ||
|
|
24b017cad8 | ||
|
|
ef3f7274e3 | ||
|
|
e6586c60b1 | ||
|
|
d34ad1d07f | ||
|
|
46388f8b41 | ||
|
|
1852acc333 | ||
|
|
cb63e49a9b | ||
|
|
d382ad2975 | ||
|
|
b1dc690e2f | ||
|
|
cc8254985b | ||
|
|
a3f32b036d | ||
|
|
5ded9abbfe | ||
|
|
6751bf88bb | ||
|
|
81bedec6d5 | ||
|
|
4531538ad3 | ||
|
|
9fbcec46af | ||
|
|
d98cc35208 | ||
|
|
97ebdc1bab | ||
|
|
8a66603d32 | ||
|
|
e13362bfec | ||
|
|
371ff47325 | ||
|
|
3aa09572f5 | ||
|
|
a56746ce6d | ||
|
|
678a2ccdf3 | ||
|
|
bf498d9239 | ||
|
|
30781430c5 | ||
|
|
14f5babea7 | ||
|
|
14f3db550b | ||
|
|
3d8402d2f1 | ||
|
|
7ac5913c86 | ||
|
|
a6e130ab2e | ||
|
|
4fe4bb99b7 | ||
|
|
592f7c0ae7 | ||
|
|
8787764e0e | ||
|
|
839bf3898f | ||
|
|
13ab84d50e | ||
|
|
a1d6204373 | ||
|
|
49e1582c28 | ||
|
|
64a6379c3c | ||
|
|
f3e246c64b | ||
|
|
9230f3cb7b | ||
|
|
f30724629c | ||
|
|
c44f6f8c9c | ||
|
|
bf548c5aca | ||
|
|
b9e90268d1 | ||
|
|
227201a73c | ||
|
|
03c892aac0 | ||
|
|
1879c161ee | ||
|
|
cf31ca20b9 | ||
|
|
c3f3a7db3f | ||
|
|
6ba9c1c40c | ||
|
|
de6515139e | ||
|
|
e3ca002d77 | ||
|
|
8119dae3c3 | ||
|
|
6ee93f7ac9 | ||
|
|
3e9ca8761e | ||
|
|
d2f512cae7 | ||
|
|
df3ca02e8b | ||
|
|
e49624a6da | ||
|
|
9ad17e0f62 | ||
|
|
6d16642a6c | ||
|
|
b200346fd3 | ||
|
|
a90b788138 | ||
|
|
dd6556968c | ||
|
|
04a05bbf26 | ||
|
|
437c9603db | ||
|
|
03ed5349f4 | ||
|
|
4272bb4c4d | ||
|
|
6135ef9dd2 | ||
|
|
b5795a8b3f | ||
|
|
98092004b6 | ||
|
|
a6d4519a98 | ||
|
|
5398cd89fe | ||
|
|
3cb7fa34b0 | ||
|
|
79e324aace | ||
|
|
684863d6c7 | ||
|
|
c9f522b24d | ||
|
|
eb3cfbfa88 | ||
|
|
067567cbf6 | ||
|
|
751568d871 | ||
|
|
b08a6e1113 | ||
|
|
504c459090 | ||
|
|
dfe969cabe | ||
|
|
f073fb1996 | ||
|
|
72fba187db | ||
|
|
ef55b63a3b | ||
|
|
c81b1c16c8 | ||
|
|
6eefb4173c | ||
|
|
74972bccb1 | ||
|
|
2ffde37f5b | ||
|
|
61b667c587 | ||
|
|
e71a34d1fa | ||
|
|
1d3e980eed | ||
|
|
d87ae84a29 | ||
|
|
f5bf148b2b | ||
|
|
2e1a5b444a | ||
|
|
533a42eb2e | ||
|
|
f98e683979 | ||
|
|
b7747b33e4 | ||
|
|
06230ad2e9 | ||
|
|
d8fdba77db | ||
|
|
ddc7affa6a | ||
|
|
9a5604f236 | ||
|
|
bcafa12349 | ||
|
|
40492ec7c4 | ||
|
|
036748cdeb | ||
|
|
4d2a7ea947 | ||
|
|
f23d5694ec | ||
|
|
a7a7293d73 | ||
|
|
a2b1089e62 | ||
|
|
9df012084d | ||
|
|
5c3a6ce8ce | ||
|
|
10bc2895eb | ||
|
|
be5f0494cc | ||
|
|
d9b08d9491 | ||
|
|
ba45972bd3 | ||
|
|
9fb38f6970 | ||
|
|
df3ae72ab7 | ||
|
|
14981717b9 | ||
|
|
53929626cf | ||
|
|
ac9edb8b5f | ||
|
|
8aa4192576 | ||
|
|
e4ce7c9071 | ||
|
|
038f397503 | ||
|
|
654156d239 | ||
|
|
64b5a72963 | ||
|
|
a8e3b5efbc | ||
|
|
8a13e2c70a | ||
|
|
bac3ab2c1a | ||
|
|
1b43aa8d37 | ||
|
|
d948e122ea | ||
|
|
36ae53654d | ||
|
|
d440a44d96 | ||
|
|
5a7c6a9816 | ||
|
|
d0aa266dce | ||
|
|
0d67f1fdaa | ||
|
|
cc3710880c | ||
|
|
5244d8608b | ||
|
|
895b41cb78 | ||
|
|
767b373484 | ||
|
|
3e163940da | ||
|
|
dbc9525c9c | ||
|
|
e7f565f143 | ||
|
|
dbac6192db | ||
|
|
f733690d38 | ||
|
|
e64a01d8f1 | ||
|
|
777515f754 | ||
|
|
aa376d25df | ||
|
|
caf04015bb | ||
|
|
c5994e5eb6 | ||
|
|
3496952769 | ||
|
|
d23ad5f272 | ||
|
|
35c27589b7 | ||
|
|
aaf92058d4 | ||
|
|
b152cfe480 | ||
|
|
82813f312a | ||
|
|
2d0104382c | ||
|
|
5c0dacf58d | ||
|
|
03adb6b7e1 | ||
|
|
ed013d5d58 | ||
|
|
eabfec9075 | ||
|
|
fdfa8b08f9 | ||
|
|
8971f23e72 | ||
|
|
904c313a64 | ||
|
|
92ee44756c | ||
|
|
4d06b0ca5b | ||
|
|
f70f98fed0 | ||
|
|
b36cd48b4a | ||
|
|
1def80ba42 | ||
|
|
da572864ac | ||
|
|
16451dd5cd | ||
|
|
ec81cd665f | ||
|
|
1809959b99 | ||
|
|
cd6ad0add2 | ||
|
|
8ca73268ba | ||
|
|
98bdc82239 | ||
|
|
f86c21b25b | ||
|
|
a8b4ddd054 | ||
|
|
8e05921227 | ||
|
|
25e8e18b73 | ||
|
|
581ddc0233 | ||
|
|
8a977b0164 | ||
|
|
55c8a6f7cc | ||
|
|
89d3cd4f5a | ||
|
|
bf99068bd7 | ||
|
|
1b54ba3e6e | ||
|
|
81dea02379 | ||
|
|
b9fbbc6453 | ||
|
|
1a66e3df73 | ||
|
|
1d7759408f | ||
|
|
9f027427b7 | ||
|
|
87f5cea636 | ||
|
|
257050f749 | ||
|
|
554054d3a1 | ||
|
|
2f5e69229c | ||
|
|
805b3ec853 | ||
|
|
5bbc1a94b3 | ||
|
|
c28c022366 | ||
|
|
dfc6161a53 | ||
|
|
1b400da7b2 | ||
|
|
f11773ad3f | ||
|
|
eca6b069f6 | ||
|
|
ce1120c3ff | ||
|
|
b777441788 | ||
|
|
9d49eaebac | ||
|
|
9e1fe2e363 | ||
|
|
27c342811e | ||
|
|
8115709a8b | ||
|
|
83a014e884 | ||
|
|
9ee8f301ed | ||
|
|
077eeceb88 | ||
|
|
e191d9dae4 | ||
|
|
a6966179f5 | ||
|
|
3afe843461 | ||
|
|
c51dd7e606 | ||
|
|
050df528a6 | ||
|
|
8c703eff93 | ||
|
|
1a5c7df671 | ||
|
|
ee70baaeb7 | ||
|
|
b115131f4c | ||
|
|
f639bb07f4 | ||
|
|
cb209eee81 | ||
|
|
4df6f06485 | ||
|
|
6faf16e9aa | ||
|
|
9a543d8966 | ||
|
|
6497cd0cd4 | ||
|
|
3a4f4c1e27 | ||
|
|
980e4e6b41 | ||
|
|
bf16ade184 | ||
|
|
d8b3c8d13c | ||
|
|
656fb8a3d1 | ||
|
|
5c9f97182e | ||
|
|
48c7028a3a | ||
|
|
9897c725de | ||
|
|
26bd498a05 | ||
|
|
7d9fe30626 | ||
|
|
d8075764e2 | ||
|
|
7effa16f00 | ||
|
|
c66553c023 | ||
|
|
5767208d8c | ||
|
|
ffc8f6faae | ||
|
|
2a559aa661 | ||
|
|
93e71d900f | ||
|
|
1c7f9da320 | ||
|
|
a84b890b23 | ||
|
|
0ae5c28da7 | ||
|
|
9c36f76e1b | ||
|
|
b2c829a077 | ||
|
|
6d9d8b353f | ||
|
|
23838c57fb | ||
|
|
03933bea7a | ||
|
|
8150b86a9c | ||
|
|
3acb34d599 | ||
|
|
39c99997ce | ||
|
|
a4a9d6c227 | ||
|
|
04c06443a8 | ||
|
|
aa398201be | ||
|
|
2826daad1a | ||
|
|
840e0314f5 | ||
|
|
28ba2a1666 | ||
|
|
cfd49e1742 | ||
|
|
8083482ba8 | ||
|
|
460200dfef | ||
|
|
fc01ee9f56 | ||
|
|
bfcc822b40 | ||
|
|
baba06c692 | ||
|
|
9ccafc390a | ||
|
|
433ce98719 | ||
|
|
e610de383a | ||
|
|
366c52d703 | ||
|
|
67105f2cff | ||
|
|
f3125c2add | ||
|
|
1825524e95 | ||
|
|
54437ee9b8 | ||
|
|
964651bad3 | ||
|
|
503a1f740c | ||
|
|
d471a972eb | ||
|
|
6799bd113a | ||
|
|
aa7d3cd1aa | ||
|
|
303947fe9b | ||
|
|
2177256a2c | ||
|
|
bf4e6ea96f | ||
|
|
f40e1b44f3 | ||
|
|
c5298d5d45 | ||
|
|
dc1736458b | ||
|
|
c4114f4349 | ||
|
|
c916e4ff9c | ||
|
|
f0ec24e8f5 | ||
|
|
d534c0b221 | ||
|
|
0d19e9a247 | ||
|
|
56af91950a | ||
|
|
5f27ba149b | ||
|
|
bab4f8ebcc | ||
|
|
1b6da0aaa0 | ||
|
|
de3e9d0be3 | ||
|
|
df786d1fbc | ||
|
|
19a87388cd | ||
|
|
d972765760 | ||
|
|
05f9a67727 | ||
|
|
dfaebcd1b7 | ||
|
|
8d5e8b072d | ||
|
|
7800fce2ec | ||
|
|
f9442001e4 | ||
|
|
58c2d068e7 | ||
|
|
c3b62e3a74 | ||
|
|
8c8e36c63b | ||
|
|
78c1fd8283 | ||
|
|
07665f4824 | ||
|
|
984f426cfe | ||
|
|
8df72c55e5 | ||
|
|
ea2206f2e9 | ||
|
|
f06ef6fbc9 | ||
|
|
6c832bd0db | ||
|
|
b2e03390da | ||
|
|
0f9669f886 | ||
|
|
04fd5d370c | ||
|
|
3f167e05ba | ||
|
|
08f9adaddf | ||
|
|
c8fe93dd9d | ||
|
|
0e6442c469 | ||
|
|
600a3d28c3 | ||
|
|
00adb00d2d | ||
|
|
f7ca583410 | ||
|
|
5d1f2a6f2d | ||
|
|
3a332b5947 | ||
|
|
8e766e2db7 | ||
|
|
65024d4bf7 | ||
|
|
2f1f704728 | ||
|
|
49055ebc7d | ||
|
|
7343ee4593 | ||
|
|
789b8b36d8 | ||
|
|
2631fa51da | ||
|
|
0ac8bd41b6 | ||
|
|
32febf0fbb | ||
|
|
3c5c1e48e9 | ||
|
|
d130242a0a | ||
|
|
eabdd18604 | ||
|
|
7abfa1cb5b | ||
|
|
b96b4941f4 | ||
|
|
7838204186 | ||
|
|
5f4b83b09c | ||
|
|
0558563d35 | ||
|
|
247e14646b | ||
|
|
88639dfe83 | ||
|
|
a1e3b5fd4a | ||
|
|
438baea956 | ||
|
|
69aa4ca035 | ||
|
|
6829d96862 | ||
|
|
822ddee9ae | ||
|
|
c60e8b3d23 | ||
|
|
a97445fb82 | ||
|
|
8897c2508d | ||
|
|
4e25c07160 | ||
|
|
0b4851125d | ||
|
|
274d654833 | ||
|
|
38f251ead5 | ||
|
|
2e67e27b2f | ||
|
|
eb7b6978d3 | ||
|
|
0a0c1f27c6 | ||
|
|
c1cad16cb9 | ||
|
|
2dbcf63eeb | ||
|
|
c8b4ee8ca5 | ||
|
|
fba7e12c36 | ||
|
|
554c627a58 | ||
|
|
86e0fc2262 | ||
|
|
b552868e0a | ||
|
|
2ad624ccc8 | ||
|
|
60eaaaff60 | ||
|
|
827c1074b6 | ||
|
|
784677e180 | ||
|
|
5b6292dd11 | ||
|
|
b6862de2be | ||
|
|
6e6c1df858 | ||
|
|
2e69e57445 | ||
|
|
45c9ea9c22 | ||
|
|
a025fc9552 | ||
|
|
630b91fbd2 | ||
|
|
038d3d6000 | ||
|
|
e8ff32b063 | ||
|
|
2203ba1fe7 | ||
|
|
6d124e7bb0 | ||
|
|
7670ec4136 | ||
|
|
dc39ba75c6 | ||
|
|
0debe89d05 | ||
|
|
5828445313 | ||
|
|
4dd4d66a3b | ||
|
|
a81b144cd6 | ||
|
|
ab0826d91a | ||
|
|
60c310fd77 | ||
|
|
25f96f6b6b | ||
|
|
da7f4cb2d0 | ||
|
|
2f7f8911cd | ||
|
|
876f4c883e | ||
|
|
90682b79d2 | ||
|
|
ccfb228509 | ||
|
|
01bfd7f52e | ||
|
|
2c0b7a6408 | ||
|
|
954404f8df | ||
|
|
a9a9b57f80 | ||
|
|
a534c51b5e | ||
|
|
5e6799a715 | ||
|
|
2dcb9e21bd | ||
|
|
195619aeed | ||
|
|
31f9b17942 | ||
|
|
465a03f987 | ||
|
|
8c26e310f7 | ||
|
|
bf6c9395c6 | ||
|
|
77131158f7 | ||
|
|
514ea70d2a | ||
|
|
b255b4738f | ||
|
|
2a8c707519 | ||
|
|
2dbe80b7ca | ||
|
|
3650204519 | ||
|
|
c98f324c22 | ||
|
|
1b81074752 | ||
|
|
23120ec011 | ||
|
|
87449ece9e | ||
|
|
5ed1d710cb | ||
|
|
ce1f6c3618 | ||
|
|
0c78e31300 | ||
|
|
abc02465e3 | ||
|
|
f64aab1495 | ||
|
|
b2a6e3f842 | ||
|
|
426157d32c | ||
|
|
b73a67915d | ||
|
|
b78ff3b477 | ||
|
|
cdf391d5c2 | ||
|
|
9503d2aaf1 | ||
|
|
5257b7b3e3 | ||
|
|
e75d009df3 | ||
|
|
f26f1b0581 | ||
|
|
dfeac89236 | ||
|
|
d6ae09ac18 | ||
|
|
b6d7b6443a | ||
|
|
ee6c68d27c | ||
|
|
74f0bdab89 | ||
|
|
5b300f1ff5 | ||
|
|
26ddfd5a80 | ||
|
|
8b64029409 | ||
|
|
ea83afbc13 | ||
|
|
ee8750d9df | ||
|
|
0c2070771b | ||
|
|
d09b3cc029 | ||
|
|
184a387ecd | ||
|
|
5c5ec18e67 | ||
|
|
0692134ea5 | ||
|
|
a753809a74 | ||
|
|
5a5e3a1502 | ||
|
|
d72833af13 | ||
|
|
5171bdaf47 | ||
|
|
b0023feee9 | ||
|
|
5ca51b3e8f | ||
|
|
d5f5716c90 | ||
|
|
863a0bb15b | ||
|
|
87e364d707 | ||
|
|
657ae8ebdb | ||
|
|
99c9eeeb72 | ||
|
|
42c0ccc2eb | ||
|
|
6d1603fa28 | ||
|
|
543674c7f2 | ||
|
|
5ffafc71fc | ||
|
|
25a9c011b3 | ||
|
|
bc1bd35efc | ||
|
|
0a43ef7b1b | ||
|
|
da173779e0 | ||
|
|
5a85433e63 | ||
|
|
a1654e88af | ||
|
|
fb7f671b32 | ||
|
|
8abb470234 | ||
|
|
c61f089729 | ||
|
|
3a737e7e25 | ||
|
|
96fcdefeed | ||
|
|
f41c9a635f | ||
|
|
acc323dbc9 | ||
|
|
f444c6373d | ||
|
|
8408bbd25c | ||
|
|
da8c7e99c5 | ||
|
|
768583e991 | ||
|
|
19ccfa0745 | ||
|
|
f61421b742 | ||
|
|
7b5591a3ce | ||
|
|
1649992654 | ||
|
|
095d1f2070 | ||
|
|
1ccc8a1a86 | ||
|
|
4995a0e1e4 | ||
|
|
b2aa37a3df | ||
|
|
e3cc19638c | ||
|
|
34a154e513 | ||
|
|
a4465aaa43 | ||
|
|
fdaf4b5688 | ||
|
|
e20db80fa1 | ||
|
|
796952698c | ||
|
|
49b4948d0f | ||
|
|
5be7ff224f | ||
|
|
8c42d9ef02 | ||
|
|
3a119acd10 | ||
|
|
79ea9974b7 | ||
|
|
0027502707 | ||
|
|
01bd21c5b4 | ||
|
|
883fd2580f | ||
|
|
6c6555d00b | ||
|
|
bfb7b611e8 | ||
|
|
28e872f219 | ||
|
|
9cc717f054 | ||
|
|
e799d89606 | ||
|
|
9a437dcfa2 | ||
|
|
fd7dddb43a | ||
|
|
d4bc72e90b | ||
|
|
2af95b5802 | ||
|
|
a167c590c5 | ||
|
|
cee05d762c | ||
|
|
a16846f4ce | ||
|
|
3847e32f39 | ||
|
|
826f29bbc0 | ||
|
|
21d081f7d3 | ||
|
|
57acaf9855 | ||
|
|
5159dd470f | ||
|
|
a9c7938887 | ||
|
|
76519e0d14 | ||
|
|
1840b8b419 | ||
|
|
bf94c5dc73 | ||
|
|
65f3628ed7 | ||
|
|
f6c3ad5aa6 | ||
|
|
49bcbfd7f9 | ||
|
|
0736289ce1 | ||
|
|
ebdd9095ab | ||
|
|
99330a1a4d | ||
|
|
18eceee4c4 | ||
|
|
4552256930 | ||
|
|
7662b77ce3 | ||
|
|
e8f166cc69 | ||
|
|
33110a44ec | ||
|
|
8d483d9283 | ||
|
|
bce6737f29 | ||
|
|
d0d11225f4 | ||
|
|
06f76dda13 | ||
|
|
6e41ba2e2c | ||
|
|
b04077db02 | ||
|
|
68fab48ab7 | ||
|
|
c5086be6eb | ||
|
|
1c22c18de5 | ||
|
|
0cfee43814 | ||
|
|
12cf66861c | ||
|
|
907a6850db | ||
|
|
7aa0c83e66 | ||
|
|
6ced493c22 | ||
|
|
6235aaf1c7 | ||
|
|
42be91b736 | ||
|
|
ba2f74c6ca | ||
|
|
94b4b66a3d | ||
|
|
f91dc8e73d | ||
|
|
b93bcecd7b | ||
|
|
75d4614a9d | ||
|
|
d18b0271c9 | ||
|
|
0cdb374130 | ||
|
|
97381f300a | ||
|
|
3f1ecf4c1b | ||
|
|
d3977eef7d | ||
|
|
3e01c7732b | ||
|
|
ed8cac4a3b | ||
|
|
c23f08fd23 | ||
|
|
5b144e0953 | ||
|
|
edbe52611e | ||
|
|
d2a3ed732a | ||
|
|
51d6f88a21 | ||
|
|
98eb26fd9e | ||
|
|
3b24ea3175 | ||
|
|
cd532fd53d | ||
|
|
1552a3f2f1 | ||
|
|
4d54f50739 | ||
|
|
f5a8be5add | ||
|
|
f7593718dc | ||
|
|
1ed74d5769 | ||
|
|
64505bb417 | ||
|
|
36b3233d4e | ||
|
|
1a794a8520 | ||
|
|
3004c37ccf | ||
|
|
a15c7cd596 | ||
|
|
519395c033 | ||
|
|
3e9a7ee9ad | ||
|
|
9101f8a478 | ||
|
|
92b283486e | ||
|
|
9b9cf32ee7 | ||
|
|
5369144b64 | ||
|
|
b26fc15fa0 | ||
|
|
671dcfceb5 | ||
|
|
e12e5b0d2e | ||
|
|
5974a3672d | ||
|
|
f4781169cc | ||
|
|
946a71fd87 | ||
|
|
03ba2819cb | ||
|
|
6595978522 | ||
|
|
a6f4270303 | ||
|
|
0a16ab38e4 | ||
|
|
c1d301ffdc | ||
|
|
65ebd736b9 | ||
|
|
1f36726f73 | ||
|
|
130c024c3e | ||
|
|
f69f793b87 | ||
|
|
6594c31a70 | ||
|
|
63e0873b5d | ||
|
|
c0ccffeab4 | ||
|
|
aa5fa0a07e | ||
|
|
63a0460ab7 | ||
|
|
64d4418d94 | ||
|
|
211e1826da | ||
|
|
8ccaeb96b6 | ||
|
|
a97752545d | ||
|
|
e89cf9e930 | ||
|
|
665a60dbc2 | ||
|
|
039dcd96e6 | ||
|
|
54dbb43b5c | ||
|
|
f522db44f9 | ||
|
|
4e37e10b6d | ||
|
|
615a6d444f | ||
|
|
ec7d5bdfe2 | ||
|
|
13755417b1 | ||
|
|
848f8d3ecf | ||
|
|
b3e1aef4ef | ||
|
|
510503045b | ||
|
|
73b45a9f5e | ||
|
|
de54290af6 | ||
|
|
c5efc27c07 | ||
|
|
b5efbbbb2e | ||
|
|
6a29f2ef6f | ||
|
|
c969603001 | ||
|
|
886b7e9e56 | ||
|
|
9d3c926d69 | ||
|
|
21367e166e | ||
|
|
6f551d5e0d | ||
|
|
fc6aa80176 | ||
|
|
fe2fcf2082 | ||
|
|
d667fd5fbe | ||
|
|
335f775d66 | ||
|
|
be1b2fc272 | ||
|
|
901a6c558a | ||
|
|
5aaff55a70 | ||
|
|
5cbf5a567c | ||
|
|
be3972bfb6 | ||
|
|
79b4c1312e | ||
|
|
d44be466d8 | ||
|
|
d4b786380b | ||
|
|
b8a582c8da | ||
|
|
84f7032f8e | ||
|
|
02f0df3a2e | ||
|
|
9ca5ce1812 | ||
|
|
dcd04e8572 | ||
|
|
ffa8d8dd88 | ||
|
|
e8a933f80e | ||
|
|
f659450f99 | ||
|
|
12b8ac4272 | ||
|
|
340cdce1dc | ||
|
|
0fd2d09dba | ||
|
|
5dccca0c3f | ||
|
|
48f5465334 | ||
|
|
5be38adf7a | ||
|
|
466316fb31 | ||
|
|
5cfaffa3ff | ||
|
|
c0ff7a31a4 | ||
|
|
54380dd929 | ||
|
|
48b6dfe72f | ||
|
|
afad255e5b | ||
|
|
e44992fb2b | ||
|
|
7a0765fb4b | ||
|
|
b6ba1d4ca8 | ||
|
|
8d3aad8454 | ||
|
|
337a5b6e33 | ||
|
|
8cc0860b64 | ||
|
|
b88432fcf4 | ||
|
|
3b5e1da39e | ||
|
|
b542dc265a | ||
|
|
52e1440089 | ||
|
|
88d658f72e | ||
|
|
bf01817cd4 | ||
|
|
05f0e7ba76 | ||
|
|
afb8fd3894 | ||
|
|
cffddd2073 | ||
|
|
5280fb4310 | ||
|
|
e79f4717e7 | ||
|
|
b97a790acd | ||
|
|
e648b4178f | ||
|
|
caae77c576 | ||
|
|
b192d90aaf | ||
|
|
2c4c99f069 | ||
|
|
e7fc482a30 | ||
|
|
7ffb3f7b52 | ||
|
|
e51ec70093 | ||
|
|
3da61989b7 | ||
|
|
40ca861c69 | ||
|
|
b9a2145766 | ||
|
|
65e46a1885 | ||
|
|
f0c6a9713c | ||
|
|
edaa30f7b1 | ||
|
|
9708915c45 | ||
|
|
e1a5a610bb | ||
|
|
bfdd3f9525 | ||
|
|
2f77e15bbc | ||
|
|
47e89afcb4 | ||
|
|
1d24e23a34 | ||
|
|
96c2c32d14 | ||
|
|
2b99274895 | ||
|
|
34a8fa100c | ||
|
|
d966668257 | ||
|
|
37ae0374d8 | ||
|
|
c71e9b5707 | ||
|
|
97b7a14a29 | ||
|
|
0ad58ec07c | ||
|
|
33c5a0f7e9 | ||
|
|
a9dbd9a646 | ||
|
|
eafd08b4ee | ||
|
|
224961447c | ||
|
|
109e8d6d31 | ||
|
|
2c80aa0b24 | ||
|
|
7f9f4957d3 | ||
|
|
acbcd05190 | ||
|
|
7d2c361725 | ||
|
|
53d6adf299 | ||
|
|
0f6cdf8b80 | ||
|
|
f5bc3dc6c2 | ||
|
|
42739c660e | ||
|
|
bc2518a369 | ||
|
|
5d01d778aa | ||
|
|
501d7aba5f | ||
|
|
6a6b9df36a | ||
|
|
85d89de072 | ||
|
|
7886c3f393 | ||
|
|
adca3c36d0 | ||
|
|
4888ecbcee | ||
|
|
5d2c1e27c2 | ||
|
|
64dcc5af80 | ||
|
|
a7dad20d8a | ||
|
|
a3fb27a0db | ||
|
|
f5c4e1b46e | ||
|
|
203e782530 | ||
|
|
16f1b15dee | ||
|
|
efd4f4ca00 | ||
|
|
5536e0b7e7 | ||
|
|
a9ba2504d7 | ||
|
|
e7163c4e7e | ||
|
|
556cc1b205 | ||
|
|
b5078e3fcc | ||
|
|
5120805e0b | ||
|
|
32d44e6c65 | ||
|
|
fa15a470fd | ||
|
|
1aa213d342 | ||
|
|
a407ff4693 | ||
|
|
e1e6493dec | ||
|
|
c948bbca12 | ||
|
|
b331da193f | ||
|
|
38ab685143 | ||
|
|
abde966647 | ||
|
|
36c4645e5b | ||
|
|
97c687ff05 | ||
|
|
833de1a1af | ||
|
|
1b21f264b0 | ||
|
|
3c1ea69a39 | ||
|
|
b1901c7278 | ||
|
|
b4be6cb221 | ||
|
|
5999bf6256 | ||
|
|
21a1487735 | ||
|
|
51f2a1c431 | ||
|
|
1205fc8c01 | ||
|
|
aac1a12e51 | ||
|
|
5682b4d217 | ||
|
|
72ac97c5d9 | ||
|
|
cfc3662c29 | ||
|
|
c52774c787 | ||
|
|
fdc73268b7 | ||
|
|
cb7eef200c | ||
|
|
925c756215 | ||
|
|
0a5a79e046 | ||
|
|
f3ad9a3146 | ||
|
|
65f18d12ab | ||
|
|
30b28793cf | ||
|
|
9a87442870 | ||
|
|
05db1a8ba2 | ||
|
|
a8835f385e | ||
|
|
3f00d88668 | ||
|
|
0d153a27dc | ||
|
|
bf9a069aa0 | ||
|
|
f166a01b2a | ||
|
|
75009f7e76 | ||
|
|
4c45285010 | ||
|
|
796f6d448c | ||
|
|
4e307ba985 | ||
|
|
bdeaa9e5c6 | ||
|
|
14077167ea | ||
|
|
75b0b2e677 | ||
|
|
5c988ab5ff | ||
|
|
b5c6194f36 | ||
|
|
4c24e54fdd | ||
|
|
88f2ac20bc | ||
|
|
edb7022c55 | ||
|
|
de8f5c4413 | ||
|
|
1c5ef97f84 | ||
|
|
b53606d497 | ||
|
|
a8a1ccce18 | ||
|
|
2978bf3c6f | ||
|
|
d2f829a9b2 | ||
|
|
f83a12d6cd | ||
|
|
cd944e14ce | ||
|
|
71e4f8f49b |
1299 changed files with 113644 additions and 38810 deletions
|
|
@ -4,4 +4,8 @@ Dockerfile
|
|||
.gitignore
|
||||
.DS_Store
|
||||
node_modules
|
||||
.idea
|
||||
.idea
|
||||
.env
|
||||
.env.*
|
||||
scripts/seed
|
||||
scripts/seed-data.ts
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2020": true,
|
||||
"node": true,
|
||||
"jest": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": 11,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"eslint:recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:import/errors",
|
||||
"plugin:import/typescript",
|
||||
"plugin:css-modules/recommended",
|
||||
"plugin:cypress/recommended",
|
||||
"prettier",
|
||||
"next"
|
||||
],
|
||||
"plugins": ["@typescript-eslint", "prettier", "promise", "css-modules", "cypress"],
|
||||
"rules": {
|
||||
"no-console": "error",
|
||||
"react/display-name": "off",
|
||||
"react-hooks/exhaustive-deps": "off",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/prop-types": "off",
|
||||
"import/no-anonymous-default-export": "off",
|
||||
"import/no-named-as-default": "off",
|
||||
"@next/next/no-img-element": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["error", { "ignoreRestSiblings": true }]
|
||||
},
|
||||
"globals": {
|
||||
"React": "writable"
|
||||
}
|
||||
}
|
||||
2
.github/ISSUE_TEMPLATE/1.bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/1.bug_report.yml
vendored
|
|
@ -25,7 +25,7 @@ body:
|
|||
- type: input
|
||||
attributes:
|
||||
label: Which Umami version are you using? (if relevant)
|
||||
description: 'For example: Chrome, Edge, Firefox, etc'
|
||||
description: 'For example: 2.18.0, 2.15.1, 1.39.0, etc'
|
||||
- type: input
|
||||
attributes:
|
||||
label: Which browser are you using? (if relevant)
|
||||
|
|
|
|||
2
.github/workflows/cd-cloud.yml
vendored
2
.github/workflows/cd-cloud.yml
vendored
|
|
@ -1,4 +1,4 @@
|
|||
name: Create docker images
|
||||
name: Create docker images (cloud)
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
|
|||
58
.github/workflows/cd-manual.yml
vendored
58
.github/workflows/cd-manual.yml
vendored
|
|
@ -1,58 +0,0 @@
|
|||
name: Create docker images (manual)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
type: string
|
||||
description: Version
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build, push, and deploy
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
db-type: [postgresql, mysql]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Extract version parts from input
|
||||
id: extract_version
|
||||
run: |
|
||||
echo "version=$(echo ${{ github.event.inputs.version }})" >> $GITHUB_ENV
|
||||
echo "major=$(echo ${{ github.event.inputs.version }} | cut -d. -f1)" >> $GITHUB_ENV
|
||||
echo "minor=$(echo ${{ github.event.inputs.version }} | cut -d. -f2)" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate tags
|
||||
id: generate_tags
|
||||
run: |
|
||||
echo "tag_major=$(echo ${{ matrix.db-type }}-${{ env.major }})" >> $GITHUB_ENV
|
||||
echo "tag_minor=$(echo ${{ matrix.db-type }}-${{ env.major }}.${{ env.minor }})" >> $GITHUB_ENV
|
||||
echo "tag_patch=$(echo ${{ matrix.db-type }}-${{ env.version }})" >> $GITHUB_ENV
|
||||
echo "tag_latest=$(echo ${{ matrix.db-type }}-latest)" >> $GITHUB_ENV
|
||||
|
||||
- uses: mr-smithers-excellent/docker-build-push@v6
|
||||
name: Build & push Docker image to ghcr.io for ${{ matrix.db-type }}
|
||||
with:
|
||||
image: umami
|
||||
tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
|
||||
buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
|
||||
registry: ghcr.io
|
||||
multiPlatform: true
|
||||
platform: linux/amd64,linux/arm64
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: mr-smithers-excellent/docker-build-push@v6
|
||||
name: Build & push Docker image to docker.io for ${{ matrix.db-type }}
|
||||
with:
|
||||
image: umamisoftware/umami
|
||||
tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
|
||||
buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
112
.github/workflows/cd.yml
vendored
112
.github/workflows/cd.yml
vendored
|
|
@ -1,50 +1,100 @@
|
|||
name: Create docker images
|
||||
|
||||
on: [create]
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Optional image version (e.g. 3.0.0, v3.0.0, or 3.0.0-beta.1)'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build, push, and deploy
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
db-type: [postgresql, mysql]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set env
|
||||
run: |
|
||||
echo "NOW=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate tags
|
||||
id: generate_tags
|
||||
run: |
|
||||
echo "tag_patch=$(echo ${{ matrix.db-type }})-${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
||||
echo "tag_minor=$(echo ${{ matrix.db-type }})-$(echo ${GITHUB_REF#refs/tags/} | cut -d. -f1,2)" >> $GITHUB_ENV
|
||||
echo "tag_major=$(echo ${{ matrix.db-type }})-$(echo ${GITHUB_REF#refs/tags/} | cut -d. -f1)" >> $GITHUB_ENV
|
||||
echo "tag_latest=$(echo ${{ matrix.db-type }})-latest" >> $GITHUB_ENV
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- uses: mr-smithers-excellent/docker-build-push@v6
|
||||
name: Build & push Docker image to ghcr.io for ${{ matrix.db-type }}
|
||||
- name: Log into GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
image: umami
|
||||
tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
|
||||
buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
|
||||
registry: ghcr.io
|
||||
multiPlatform: true
|
||||
platform: linux/amd64,linux/arm64
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: mr-smithers-excellent/docker-build-push@v6
|
||||
name: Build & push Docker image to docker.io for ${{ matrix.db-type }}
|
||||
- name: Log into Docker Hub
|
||||
if: github.repository == 'umami-software/umami'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
image: umamisoftware/umami
|
||||
tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
|
||||
buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Compute version tags
|
||||
id: compute
|
||||
run: |
|
||||
INPUT="${{ github.event.inputs.version }}"
|
||||
REF_TYPE="${{ github.ref_type }}"
|
||||
REF_NAME="${{ github.ref_name }}"
|
||||
|
||||
# Determine version source
|
||||
if [[ -n "$INPUT" ]]; then
|
||||
VERSION="${INPUT#v}"
|
||||
elif [[ "$REF_TYPE" == "tag" ]]; then
|
||||
VERSION="${REF_NAME#v}"
|
||||
else
|
||||
VERSION=""
|
||||
fi
|
||||
|
||||
TAGS=""
|
||||
|
||||
if [[ -n "$VERSION" ]]; then
|
||||
MAJOR=$(echo "$VERSION" | cut -d. -f1)
|
||||
MINOR=$(echo "$VERSION" | cut -d. -f2)
|
||||
|
||||
if [[ "$VERSION" == *-* ]]; then
|
||||
# prerelease: only version tag
|
||||
TAGS="$VERSION"
|
||||
else
|
||||
# stable release: version + hierarchy + latest
|
||||
TAGS="$VERSION,${MAJOR}.${MINOR},${MAJOR},postgresql-latest,latest"
|
||||
fi
|
||||
else
|
||||
# Non-tag build (e.g. from main branch)
|
||||
TAGS="${REF_NAME}"
|
||||
fi
|
||||
|
||||
echo "tags=$TAGS" >> $GITHUB_OUTPUT
|
||||
echo "Computed tags: $TAGS"
|
||||
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
TAGS="${{ steps.compute.outputs.tags }}"
|
||||
|
||||
# Set image targets conditionally
|
||||
if [[ "${{ github.repository }}" == "umami-software/umami" ]]; then
|
||||
IMAGES=("umamisoftware/umami" "ghcr.io/${{ github.repository }}")
|
||||
else
|
||||
IMAGES=("ghcr.io/${{ github.repository }}")
|
||||
fi
|
||||
|
||||
for IMAGE in "${IMAGES[@]}"; do
|
||||
echo "Building and pushing $IMAGE with tags: $TAGS"
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
$(echo "$TAGS" | tr ',' '\n' | sed "s|^|--tag ${IMAGE}:|") \
|
||||
--cache-from type=gha \
|
||||
--cache-to type=gha,mode=max \
|
||||
.
|
||||
done
|
||||
|
|
|
|||
21
.github/workflows/ci.yml
vendored
21
.github/workflows/ci.yml
vendored
|
|
@ -1,6 +1,3 @@
|
|||
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: Node.js CI
|
||||
|
||||
on: [push]
|
||||
|
|
@ -11,26 +8,30 @@ env:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.repository == 'umami-software/umami'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- node-version: 18.18
|
||||
pnpm-version: 10
|
||||
db-type: postgresql
|
||||
- node-version: 18.18
|
||||
db-type: mysql
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4 # required so that setup-node will work
|
||||
with:
|
||||
version: ${{ matrix.pnpm-version }}
|
||||
run_install: false
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'yarn'
|
||||
cache: 'pnpm'
|
||||
env:
|
||||
DATABASE_TYPE: ${{ matrix.db-type }}
|
||||
- run: npm install --global yarn
|
||||
- run: yarn install
|
||||
- run: yarn test
|
||||
- run: yarn build
|
||||
- run: npm install --global pnpm
|
||||
- run: pnpm install
|
||||
- run: pnpm test
|
||||
- run: pnpm build
|
||||
|
|
|
|||
9
.gitignore
vendored
9
.gitignore
vendored
|
|
@ -4,20 +4,23 @@
|
|||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
.pnpm-store
|
||||
package-lock.json
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
/prisma/
|
||||
/.next
|
||||
/out
|
||||
|
||||
# production
|
||||
/build
|
||||
/public/script.js
|
||||
/geo
|
||||
/dist
|
||||
/generated
|
||||
/src/generated
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -1,4 +1 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
/public/script.js
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf",
|
||||
"printWidth": 100,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
||||
|
|
@ -1,11 +1,6 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-config-recommended",
|
||||
"stylelint-config-css-modules",
|
||||
"stylelint-config-prettier"
|
||||
],
|
||||
"extends": ["stylelint-config-recommended", "stylelint-config-css-modules"],
|
||||
"rules": {
|
||||
"no-descending-specificity": null
|
||||
},
|
||||
"ignoreFiles": ["**/*.js", "**/*.md"]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
52
Dockerfile
52
Dockerfile
|
|
@ -1,53 +1,55 @@
|
|||
ARG NODE_IMAGE_VERSION="22-alpine"
|
||||
|
||||
# Install dependencies only when needed
|
||||
FROM node:22-alpine AS deps
|
||||
FROM node:${NODE_IMAGE_VERSION} AS deps
|
||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||
RUN apk add --no-cache libc6-compat
|
||||
WORKDIR /app
|
||||
COPY package.json yarn.lock ./
|
||||
# Add yarn timeout to handle slow CPU when Github Actions
|
||||
RUN yarn config set network-timeout 300000
|
||||
RUN yarn install --frozen-lockfile
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
RUN npm install -g pnpm
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Rebuild the source code only when needed
|
||||
FROM node:22-alpine AS builder
|
||||
FROM node:${NODE_IMAGE_VERSION} AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
COPY docker/middleware.js ./src
|
||||
COPY docker/middleware.ts ./src
|
||||
|
||||
ARG DATABASE_TYPE
|
||||
ARG BASE_PATH
|
||||
|
||||
ENV DATABASE_TYPE $DATABASE_TYPE
|
||||
ENV BASE_PATH $BASE_PATH
|
||||
ENV BASE_PATH=$BASE_PATH
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
ENV DATABASE_URL="postgresql://user:pass@localhost:5432/dummy"
|
||||
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN yarn build-docker
|
||||
RUN npm run build-docker
|
||||
|
||||
# Production image, copy all the files and run next
|
||||
FROM node:22-alpine AS runner
|
||||
FROM node:${NODE_IMAGE_VERSION} AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ARG PRISMA_VERSION="6.19.0"
|
||||
ARG NODE_OPTIONS
|
||||
|
||||
ENV NODE_ENV production
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
ENV NODE_OPTIONS $NODE_OPTIONS
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
ENV NODE_OPTIONS=$NODE_OPTIONS
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
RUN set -x \
|
||||
&& apk add --no-cache curl \
|
||||
&& yarn add npm-run-all dotenv semver prisma@6.1.0
|
||||
&& npm install -g pnpm
|
||||
|
||||
# Script dependencies
|
||||
RUN pnpm --allow-build='@prisma/engines' add npm-run-all dotenv chalk semver \
|
||||
prisma@${PRISMA_VERSION} \
|
||||
@prisma/adapter-pg@${PRISMA_VERSION}
|
||||
|
||||
# You only need to copy next.config.js if you are NOT using the default configuration
|
||||
COPY --from=builder /app/next.config.js .
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=builder /app/prisma ./prisma
|
||||
COPY --from=builder /app/scripts ./scripts
|
||||
COPY --from=builder /app/generated ./generated
|
||||
|
||||
# Automatically leverage output traces to reduce image size
|
||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||
|
|
@ -58,7 +60,7 @@ USER nextjs
|
|||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV HOSTNAME 0.0.0.0
|
||||
ENV PORT 3000
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
ENV PORT=3000
|
||||
|
||||
CMD ["yarn", "start-docker"]
|
||||
CMD ["pnpm", "start-docker"]
|
||||
|
|
|
|||
81
README.md
81
README.md
|
|
@ -9,18 +9,10 @@
|
|||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/umami-software/umami/releases">
|
||||
<img src="https://img.shields.io/github/release/umami-software/umami.svg" alt="GitHub Release" />
|
||||
</a>
|
||||
<a href="https://github.com/umami-software/umami/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/umami-software/umami.svg" alt="MIT License" />
|
||||
</a>
|
||||
<a href="https://github.com/umami-software/umami/actions">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml" alt="Build Status" />
|
||||
</a>
|
||||
<a href="https://analytics.umami.is/share/LGazGOecbDtaIwDr/umami.is" style="text-decoration: none;">
|
||||
<img src="https://img.shields.io/badge/Try%20Demo%20Now-Click%20Here-brightgreen" alt="Umami Demo" />
|
||||
</a>
|
||||
<a href="https://github.com/umami-software/umami/releases"><img src="https://img.shields.io/github/release/umami-software/umami.svg" alt="GitHub Release" /></a>
|
||||
<a href="https://github.com/umami-software/umami/blob/master/LICENSE"><img src="https://img.shields.io/github/license/umami-software/umami.svg" alt="MIT License" /></a>
|
||||
<a href="https://github.com/umami-software/umami/actions"><img src="https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml" alt="Build Status" /></a>
|
||||
<a href="https://analytics.umami.is/share/LGazGOecbDtaIwDr/umami.is" style="text-decoration: none;"><img src="https://img.shields.io/badge/Try%20Demo%20Now-Click%20Here-brightgreen" alt="Umami Demo" /></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
|
@ -35,21 +27,15 @@ A detailed getting started guide can be found at [umami.is/docs](https://umami.i
|
|||
|
||||
### Requirements
|
||||
|
||||
- A server with Node.js version 18.18 or newer
|
||||
- A database. Umami supports [MariaDB](https://www.mariadb.org/) (minimum v10.5), [MySQL](https://www.mysql.com/) (minimum v8.0) and [PostgreSQL](https://www.postgresql.org/) (minimum v12.14) databases.
|
||||
- A server with Node.js version 18.18+.
|
||||
- A PostgreSQL database version v12.14+.
|
||||
|
||||
### Install Yarn
|
||||
|
||||
```bash
|
||||
npm install -g yarn
|
||||
```
|
||||
|
||||
### Get the Source Code and Install Packages
|
||||
### Get the source code and install packages
|
||||
|
||||
```bash
|
||||
git clone https://github.com/umami-software/umami.git
|
||||
cd umami
|
||||
yarn install
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Configure Umami
|
||||
|
|
@ -64,47 +50,42 @@ The connection URL format:
|
|||
|
||||
```bash
|
||||
postgresql://username:mypassword@localhost:5432/mydb
|
||||
mysql://username:mypassword@localhost:3306/mydb
|
||||
```
|
||||
|
||||
### Build the Application
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
*The build step will create tables in your database if you are installing for the first time. It will also create a login user with username **admin** and password **umami**.*
|
||||
The build step will create tables in your database if you are installing for the first time. It will also create a login user with username **admin** and password **umami**.
|
||||
|
||||
### Start the Application
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
pnpm run start
|
||||
```
|
||||
|
||||
*By default, this will launch the application on `http://localhost:3000`. You will need to either [proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) requests from your web server or change the [port](https://nextjs.org/docs/api-reference/cli#production) to serve the application directly.*
|
||||
By default, this will launch the application on `http://localhost:3000`. You will need to either [proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) requests from your web server or change the [port](https://nextjs.org/docs/api-reference/cli#production) to serve the application directly.
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Installing with Docker
|
||||
|
||||
To build the Umami container and start up a Postgres database, run:
|
||||
Umami provides Docker images as well as a Docker compose file for easy deployment.
|
||||
|
||||
Docker image:
|
||||
|
||||
```bash
|
||||
docker pull docker.umami.is/umami-software/umami:latest
|
||||
```
|
||||
|
||||
Docker compose (Runs Umami with a PostgreSQL database):
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Alternatively, to pull just the Umami Docker image with PostgreSQL support:
|
||||
|
||||
```bash
|
||||
docker pull docker.umami.is/umami-software/umami:postgresql-latest
|
||||
```
|
||||
|
||||
Or with MySQL support:
|
||||
|
||||
```bash
|
||||
docker pull docker.umami.is/umami-software/umami:mysql-latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Getting Updates
|
||||
|
|
@ -113,8 +94,8 @@ To get the latest features, simply do a pull, install any new dependencies, and
|
|||
|
||||
```bash
|
||||
git pull
|
||||
yarn install
|
||||
yarn build
|
||||
pnpm install
|
||||
pnpm build
|
||||
```
|
||||
|
||||
To update the Docker image, simply pull the new images and rebuild:
|
||||
|
|
@ -129,18 +110,10 @@ docker compose up --force-recreate -d
|
|||
## 🛟 Support
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/umami-software/umami">
|
||||
<img src="https://img.shields.io/badge/GitHub--blue?style=social&logo=github" alt="GitHub" />
|
||||
</a>
|
||||
<a href="https://twitter.com/umami_software">
|
||||
<img src="https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter" alt="Twitter" />
|
||||
</a>
|
||||
<a href="https://linkedin.com/company/umami-software">
|
||||
<img src="https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin" alt="LinkedIn" />
|
||||
</a>
|
||||
<a href="https://umami.is/discord">
|
||||
<img src="https://img.shields.io/badge/Discord--blue?style=social&logo=discord" alt="Discord" />
|
||||
</a>
|
||||
<a href="https://github.com/umami-software/umami"><img src="https://img.shields.io/badge/GitHub--blue?style=social&logo=github" alt="GitHub" /></a>
|
||||
<a href="https://twitter.com/umami_software"><img src="https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter" alt="Twitter" /></a>
|
||||
<a href="https://linkedin.com/company/umami-software"><img src="https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin" alt="LinkedIn" /></a>
|
||||
<a href="https://umami.is/discord"><img src="https://img.shields.io/badge/Discord--blue?style=social&logo=discord" alt="Discord" /></a>
|
||||
</p>
|
||||
|
||||
[release-shield]: https://img.shields.io/github/release/umami-software/umami.svg
|
||||
|
|
|
|||
65
biome.json
Normal file
65
biome.json
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.3.6/schema.json",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": true
|
||||
},
|
||||
"files": {
|
||||
"includes": ["**", "!!**/dist"]
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"lineWidth": 100,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineEnding": "lf"
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"a11y": "off",
|
||||
"correctness": {
|
||||
"useExhaustiveDependencies": "off"
|
||||
},
|
||||
"style": {
|
||||
"noDescendingSpecificity": "off"
|
||||
},
|
||||
"complexity": {
|
||||
"noImportantStyles": "off"
|
||||
},
|
||||
"suspicious": {
|
||||
"noArrayIndexKey": "off",
|
||||
"noExplicitAny": "off",
|
||||
"noImplicitAnyLet": "off"
|
||||
},
|
||||
"performance": {
|
||||
"noImgElement": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "single",
|
||||
"trailingCommas": "all",
|
||||
"arrowParentheses": "asNeeded"
|
||||
}
|
||||
},
|
||||
"css": {
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineEnding": "lf"
|
||||
}
|
||||
},
|
||||
"assist": {
|
||||
"enabled": true,
|
||||
"actions": {
|
||||
"source": {
|
||||
"organizeImports": "on"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,5 +8,6 @@ export default defineConfig({
|
|||
env: {
|
||||
umami_user: 'admin',
|
||||
umami_password: 'umami',
|
||||
umami_user_id: '41e2b680-648e-4b09-bcd7-3e2b10c06264',
|
||||
},
|
||||
});
|
||||
|
|
|
|||
209
cypress/e2e/api-team.cy.ts
Normal file
209
cypress/e2e/api-team.cy.ts
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
describe('Team API tests', () => {
|
||||
Cypress.session.clearAllSavedSessions();
|
||||
|
||||
let teamId;
|
||||
let userId;
|
||||
|
||||
before(() => {
|
||||
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
|
||||
cy.fixture('users').then(data => {
|
||||
const userCreate = data.userCreate;
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/users',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: userCreate,
|
||||
}).then(response => {
|
||||
userId = response.body.id;
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('username', 'cypress1');
|
||||
expect(response.body).to.have.property('role', 'user');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Creates a team.', () => {
|
||||
cy.fixture('teams').then(data => {
|
||||
const teamCreate = data.teamCreate;
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/teams',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: teamCreate,
|
||||
}).then(response => {
|
||||
teamId = response.body[0].id;
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body[0]).to.have.property('name', 'cypress');
|
||||
expect(response.body[1]).to.have.property('role', 'team-owner');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Gets a teams by ID.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `/api/teams/${teamId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('id', teamId);
|
||||
});
|
||||
});
|
||||
|
||||
it('Updates a team.', () => {
|
||||
cy.fixture('teams').then(data => {
|
||||
const teamUpdate = data.teamUpdate;
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/teams/${teamId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: teamUpdate,
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('id', teamId);
|
||||
expect(response.body).to.have.property('name', 'cypressUpdate');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Get all users that belong to a team.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `/api/teams/${teamId}/users`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body.data[0]).to.have.property('id');
|
||||
expect(response.body.data[0]).to.have.property('teamId');
|
||||
expect(response.body.data[0]).to.have.property('userId');
|
||||
expect(response.body.data[0]).to.have.property('user');
|
||||
});
|
||||
});
|
||||
|
||||
it('Get a user belonging to a team.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `/api/teams/${teamId}/users/${Cypress.env('umami_user_id')}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('teamId');
|
||||
expect(response.body).to.have.property('userId');
|
||||
expect(response.body).to.have.property('role');
|
||||
});
|
||||
});
|
||||
|
||||
it('Get all websites belonging to a team.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `/api/teams/${teamId}/websites`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('data');
|
||||
});
|
||||
});
|
||||
|
||||
it('Add a user to a team.', () => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/teams/${teamId}/users`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: {
|
||||
userId,
|
||||
role: 'team-member',
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('userId', userId);
|
||||
expect(response.body).to.have.property('role', 'team-member');
|
||||
});
|
||||
});
|
||||
|
||||
it(`Update a user's role on a team.`, () => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/teams/${teamId}/users/${userId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: {
|
||||
role: 'team-view-only',
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('userId', userId);
|
||||
expect(response.body).to.have.property('role', 'team-view-only');
|
||||
});
|
||||
});
|
||||
|
||||
it(`Remove a user from a team.`, () => {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/teams/${teamId}/users/${userId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
|
||||
it('Deletes a team.', () => {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/teams/${teamId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('ok', true);
|
||||
});
|
||||
});
|
||||
|
||||
// it('Gets all teams that belong to a user.', () => {
|
||||
// cy.request({
|
||||
// method: 'GET',
|
||||
// url: `/api/users/${userId}/teams`,
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json',
|
||||
// Authorization: Cypress.env('authorization'),
|
||||
// },
|
||||
// }).then(response => {
|
||||
// expect(response.status).to.eq(200);
|
||||
// expect(response.body).to.have.property('data');
|
||||
// });
|
||||
// });
|
||||
|
||||
after(() => {
|
||||
cy.deleteUser(userId);
|
||||
});
|
||||
});
|
||||
125
cypress/e2e/api-user.cy.ts
Normal file
125
cypress/e2e/api-user.cy.ts
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
describe('User API tests', () => {
|
||||
Cypress.session.clearAllSavedSessions();
|
||||
|
||||
before(() => {
|
||||
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
|
||||
});
|
||||
|
||||
let userId;
|
||||
|
||||
it('Creates a user.', () => {
|
||||
cy.fixture('users').then(data => {
|
||||
const userCreate = data.userCreate;
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/users',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: userCreate,
|
||||
}).then(response => {
|
||||
userId = response.body.id;
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('username', 'cypress1');
|
||||
expect(response.body).to.have.property('role', 'user');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Returns all users. Admin access is required.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: '/api/admin/users',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body.data[0]).to.have.property('id');
|
||||
expect(response.body.data[0]).to.have.property('username');
|
||||
expect(response.body.data[0]).to.have.property('password');
|
||||
expect(response.body.data[0]).to.have.property('role');
|
||||
});
|
||||
});
|
||||
|
||||
it('Updates a user.', () => {
|
||||
cy.fixture('users').then(data => {
|
||||
const userUpdate = data.userUpdate;
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/users/${userId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: userUpdate,
|
||||
}).then(response => {
|
||||
userId = response.body.id;
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('id', userId);
|
||||
expect(response.body).to.have.property('username', 'cypress1');
|
||||
expect(response.body).to.have.property('role', 'view-only');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Gets a user by ID.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `/api/users/${userId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('id', userId);
|
||||
expect(response.body).to.have.property('username', 'cypress1');
|
||||
expect(response.body).to.have.property('role', 'view-only');
|
||||
});
|
||||
});
|
||||
|
||||
it('Deletes a user.', () => {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/users/${userId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('ok', true);
|
||||
});
|
||||
});
|
||||
|
||||
it('Gets all websites that belong to a user.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `/api/users/${userId}/websites`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('data');
|
||||
});
|
||||
});
|
||||
|
||||
it('Gets all teams that belong to a user.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `/api/users/${userId}/teams`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('data');
|
||||
});
|
||||
});
|
||||
});
|
||||
198
cypress/e2e/api-website.cy.ts
Normal file
198
cypress/e2e/api-website.cy.ts
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
import { uuid } from '../../src/lib/crypto';
|
||||
|
||||
describe('Website API tests', () => {
|
||||
Cypress.session.clearAllSavedSessions();
|
||||
|
||||
let websiteId;
|
||||
let teamId;
|
||||
|
||||
before(() => {
|
||||
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
|
||||
cy.fixture('teams').then(data => {
|
||||
const teamCreate = data.teamCreate;
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/teams',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: teamCreate,
|
||||
}).then(response => {
|
||||
teamId = response.body[0].id;
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body[0]).to.have.property('name', 'cypress');
|
||||
expect(response.body[1]).to.have.property('role', 'team-owner');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Creates a website for user.', () => {
|
||||
cy.fixture('websites').then(data => {
|
||||
const websiteCreate = data.websiteCreate;
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/websites',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: websiteCreate,
|
||||
}).then(response => {
|
||||
websiteId = response.body.id;
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('name', 'Cypress Website');
|
||||
expect(response.body).to.have.property('domain', 'cypress.com');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Creates a website for team.', () => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/websites',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: {
|
||||
name: 'Team Website',
|
||||
domain: 'teamwebsite.com',
|
||||
teamId: teamId,
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('name', 'Team Website');
|
||||
expect(response.body).to.have.property('domain', 'teamwebsite.com');
|
||||
});
|
||||
});
|
||||
|
||||
it('Creates a website with a fixed ID.', () => {
|
||||
cy.fixture('websites').then(data => {
|
||||
const websiteCreate = data.websiteCreate;
|
||||
const fixedId = uuid();
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/websites',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: { ...websiteCreate, id: fixedId },
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('id', fixedId);
|
||||
expect(response.body).to.have.property('name', 'Cypress Website');
|
||||
expect(response.body).to.have.property('domain', 'cypress.com');
|
||||
|
||||
// cleanup
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/websites/${fixedId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Returns all tracked websites.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: '/api/websites',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body.data[0]).to.have.property('id');
|
||||
expect(response.body.data[0]).to.have.property('name');
|
||||
expect(response.body.data[0]).to.have.property('domain');
|
||||
});
|
||||
});
|
||||
|
||||
it('Gets a website by ID.', () => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: `/api/websites/${websiteId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('name', 'Cypress Website');
|
||||
expect(response.body).to.have.property('domain', 'cypress.com');
|
||||
});
|
||||
});
|
||||
|
||||
it('Updates a website.', () => {
|
||||
cy.fixture('websites').then(data => {
|
||||
const websiteUpdate = data.websiteUpdate;
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/websites/${websiteId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: websiteUpdate,
|
||||
}).then(response => {
|
||||
websiteId = response.body.id;
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('name', 'Cypress Website Updated');
|
||||
expect(response.body).to.have.property('domain', 'cypressupdated.com');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Updates a website with only shareId.', () => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/websites/${websiteId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: { shareId: 'ABCDEF' },
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('shareId', 'ABCDEF');
|
||||
});
|
||||
});
|
||||
|
||||
it('Resets a website by removing all data related to the website.', () => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/websites/${websiteId}/reset`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('ok', true);
|
||||
});
|
||||
});
|
||||
|
||||
it('Deletes a website.', () => {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/websites/${websiteId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.property('ok', true);
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.deleteTeam(teamId);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,22 +1,36 @@
|
|||
describe('Login tests', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/login');
|
||||
});
|
||||
|
||||
it(
|
||||
'logs user in with correct credentials and logs user out',
|
||||
{
|
||||
defaultCommandTimeout: 10000,
|
||||
},
|
||||
() => {
|
||||
cy.visit('/login');
|
||||
cy.getDataTest('input-username').find('input').click();
|
||||
cy.getDataTest('input-username').find('input').type(Cypress.env('umami_user'), { delay: 50 });
|
||||
cy.getDataTest('input-password').find('input').click();
|
||||
cy.getDataTest('input-username').find('input').as('inputUsername').click();
|
||||
cy.get('@inputUsername').type(Cypress.env('umami_user'), { delay: 0 });
|
||||
cy.get('@inputUsername').click();
|
||||
cy.getDataTest('input-password')
|
||||
.find('input')
|
||||
.type(Cypress.env('umami_password'), { delay: 50 });
|
||||
.type(Cypress.env('umami_password'), { delay: 0 });
|
||||
cy.getDataTest('button-submit').click();
|
||||
cy.url().should('eq', Cypress.config().baseUrl + '/dashboard');
|
||||
cy.getDataTest('button-profile').click();
|
||||
cy.getDataTest('item-logout').click();
|
||||
cy.url().should('eq', Cypress.config().baseUrl + '/login');
|
||||
cy.logout();
|
||||
},
|
||||
);
|
||||
|
||||
it('login with blank inputs or incorrect credentials', () => {
|
||||
cy.getDataTest('button-submit').click();
|
||||
cy.contains(/Required/i).should('be.visible');
|
||||
|
||||
cy.getDataTest('input-username').find('input').as('inputUsername');
|
||||
cy.get('@inputUsername').click();
|
||||
cy.get('@inputUsername').type(Cypress.env('umami_user'), { delay: 0 });
|
||||
cy.get('@inputUsername').click();
|
||||
cy.getDataTest('input-password').find('input').type('wrongpassword', { delay: 0 });
|
||||
cy.getDataTest('button-submit').click();
|
||||
cy.contains(/Incorrect username and\/or password./i).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
65
cypress/e2e/user.cy.ts
Normal file
65
cypress/e2e/user.cy.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
describe('User tests', () => {
|
||||
Cypress.session.clearAllSavedSessions();
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
|
||||
cy.visit('/settings/users');
|
||||
});
|
||||
|
||||
it('Add a User', () => {
|
||||
// add user
|
||||
cy.contains(/Create user/i).should('be.visible');
|
||||
cy.getDataTest('button-create-user').click();
|
||||
cy.getDataTest('input-username').find('input').as('inputName').click();
|
||||
cy.get('@inputName').type('Test-user', { delay: 0 });
|
||||
cy.getDataTest('input-password').find('input').as('inputPassword').click();
|
||||
cy.get('@inputPassword').type('testPasswordCypress', { delay: 0 });
|
||||
cy.getDataTest('dropdown-role').click();
|
||||
cy.getDataTest('dropdown-item-user').click();
|
||||
cy.getDataTest('button-submit').click();
|
||||
cy.get('td[label="Username"]').should('contain.text', 'Test-user');
|
||||
cy.get('td[label="Role"]').should('contain.text', 'User');
|
||||
});
|
||||
|
||||
it('Edit a User role and password', () => {
|
||||
// edit user
|
||||
cy.get('table tbody tr')
|
||||
.contains('td', /Test-user/i)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.getDataTest('link-button-edit').click(); // Clicks the button inside the row
|
||||
});
|
||||
cy.getDataTest('input-password').find('input').as('inputPassword').click();
|
||||
cy.get('@inputPassword').type('newPassword', { delay: 0 });
|
||||
cy.getDataTest('dropdown-role').click();
|
||||
cy.getDataTest('dropdown-item-viewOnly').click();
|
||||
cy.getDataTest('button-submit').click();
|
||||
|
||||
cy.visit('/settings/users');
|
||||
cy.get('table tbody tr')
|
||||
.contains('td', /Test-user/i)
|
||||
.parent()
|
||||
.should('contain.text', 'View only');
|
||||
|
||||
cy.logout();
|
||||
cy.url().should('eq', Cypress.config().baseUrl + '/login');
|
||||
cy.getDataTest('input-username').find('input').as('inputUsername').click();
|
||||
cy.get('@inputUsername').type('Test-user', { delay: 0 });
|
||||
cy.get('@inputUsername').click();
|
||||
cy.getDataTest('input-password').find('input').type('newPassword', { delay: 0 });
|
||||
cy.getDataTest('button-submit').click();
|
||||
cy.url().should('eq', Cypress.config().baseUrl + '/dashboard');
|
||||
});
|
||||
|
||||
it('Delete a user', () => {
|
||||
// delete user
|
||||
cy.get('table tbody tr')
|
||||
.contains('td', /Test-user/i)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.getDataTest('button-delete').click(); // Clicks the button inside the row
|
||||
});
|
||||
cy.contains(/Are you sure you want to delete Test-user?/i).should('be.visible');
|
||||
cy.getDataTest('button-confirm').click();
|
||||
});
|
||||
});
|
||||
|
|
@ -10,10 +10,10 @@ describe('Website tests', () => {
|
|||
cy.visit('/settings/websites');
|
||||
cy.getDataTest('button-website-add').click();
|
||||
cy.contains(/Add website/i).should('be.visible');
|
||||
cy.getDataTest('input-name').find('input').click();
|
||||
cy.getDataTest('input-name').find('input').type('Add test', { delay: 50 });
|
||||
cy.getDataTest('input-name').find('input').as('inputUsername').click();
|
||||
cy.getDataTest('input-name').find('input').type('Add test', { delay: 0 });
|
||||
cy.getDataTest('input-domain').find('input').click();
|
||||
cy.getDataTest('input-domain').find('input').type('addtest.com', { delay: 50 });
|
||||
cy.getDataTest('input-domain').find('input').type('addtest.com', { delay: 0 });
|
||||
cy.getDataTest('button-submit').click();
|
||||
cy.get('td[label="Name"]').should('contain.text', 'Add test');
|
||||
cy.get('td[label="Domain"]').should('contain.text', 'addtest.com');
|
||||
|
|
@ -41,10 +41,10 @@ describe('Website tests', () => {
|
|||
cy.contains(/Details/i).should('be.visible');
|
||||
cy.getDataTest('input-name').find('input').click();
|
||||
cy.getDataTest('input-name').find('input').clear();
|
||||
cy.getDataTest('input-name').find('input').type('Updated website', { delay: 50 });
|
||||
cy.getDataTest('input-name').find('input').type('Updated website', { delay: 0 });
|
||||
cy.getDataTest('input-domain').find('input').click();
|
||||
cy.getDataTest('input-domain').find('input').clear();
|
||||
cy.getDataTest('input-domain').find('input').type('updatedwebsite.com', { delay: 50 });
|
||||
cy.getDataTest('input-domain').find('input').type('updatedwebsite.com', { delay: 0 });
|
||||
cy.getDataTest('button-submit').click({ force: true });
|
||||
cy.getDataTest('input-name').find('input').should('have.value', 'Updated website');
|
||||
cy.getDataTest('input-domain').find('input').should('have.value', 'updatedwebsite.com');
|
||||
|
|
|
|||
8
cypress/fixtures/teams.json
Normal file
8
cypress/fixtures/teams.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"teamCreate": {
|
||||
"name": "cypress"
|
||||
},
|
||||
"teamUpdate": {
|
||||
"name": "cypressUpdate"
|
||||
}
|
||||
}
|
||||
11
cypress/fixtures/users.json
Normal file
11
cypress/fixtures/users.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"userCreate": {
|
||||
"username": "cypress1",
|
||||
"password": "password",
|
||||
"role": "user"
|
||||
},
|
||||
"userUpdate": {
|
||||
"username": "cypress1",
|
||||
"role": "view-only"
|
||||
}
|
||||
}
|
||||
10
cypress/fixtures/websites.json
Normal file
10
cypress/fixtures/websites.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"websiteCreate": {
|
||||
"name": "Cypress Website",
|
||||
"domain": "cypress.com"
|
||||
},
|
||||
"websiteUpdate": {
|
||||
"name": "Cypress Website Updated",
|
||||
"domain": "cypressupdated.com"
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,12 @@ Cypress.Commands.add('getDataTest', (value: string) => {
|
|||
return cy.get(`[data-test=${value}]`);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('logout', () => {
|
||||
cy.getDataTest('button-profile').click();
|
||||
cy.getDataTest('item-logout').click();
|
||||
cy.url().should('eq', Cypress.config().baseUrl + '/login');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('login', (username: string, password: string) => {
|
||||
cy.session([username, password], () => {
|
||||
cy.request({
|
||||
|
|
@ -55,3 +61,63 @@ Cypress.Commands.add('deleteWebsite', (websiteId: string) => {
|
|||
expect(response.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('addUser', (username: string, password: string, role: string) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/users',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: {
|
||||
username: username,
|
||||
password: password,
|
||||
role: role,
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('deleteUser', (userId: string) => {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/users/${userId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('addTeam', (name: string) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/teams',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
body: {
|
||||
name: name,
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('deleteTeam', (teamId: string) => {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/teams/${teamId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: Cypress.env('authorization'),
|
||||
},
|
||||
}).then(response => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
32
cypress/support/index.d.ts
vendored
32
cypress/support/index.d.ts
vendored
|
|
@ -1,4 +1,5 @@
|
|||
/// <reference types="cypress" />
|
||||
/* global JQuery */
|
||||
|
||||
declare namespace Cypress {
|
||||
interface Chainable {
|
||||
|
|
@ -7,6 +8,11 @@ declare namespace Cypress {
|
|||
* @example cy.getDataTest('greeting')
|
||||
*/
|
||||
getDataTest(value: string): Chainable<JQuery<HTMLElement>>;
|
||||
/**
|
||||
* Custom command to logout through UI.
|
||||
* @example cy.logout()
|
||||
*/
|
||||
logout(): Chainable<JQuery<HTMLElement>>;
|
||||
/**
|
||||
* Custom command to login user into the app.
|
||||
* @example cy.login('admin', 'password)
|
||||
|
|
@ -18,9 +24,33 @@ declare namespace Cypress {
|
|||
*/
|
||||
addWebsite(name: string, domain: string): Chainable<JQuery<HTMLElement>>;
|
||||
/**
|
||||
* Custom command to create a website
|
||||
* Custom command to delete a website
|
||||
* @example cy.deleteWebsite('02d89813-7a72-41e1-87f0-8d668f85008b')
|
||||
*/
|
||||
deleteWebsite(websiteId: string): Chainable<JQuery<HTMLElement>>;
|
||||
/**
|
||||
* Custom command to create a website
|
||||
* @example cy.deleteWebsite('02d89813-7a72-41e1-87f0-8d668f85008b')
|
||||
*/
|
||||
/**
|
||||
* Custom command to create a user
|
||||
* @example cy.addUser('cypress', 'password', 'User')
|
||||
*/
|
||||
addUser(username: string, password: string, role: string): Chainable<JQuery<HTMLElement>>;
|
||||
/**
|
||||
* Custom command to delete a user
|
||||
* @example cy.deleteUser('02d89813-7a72-41e1-87f0-8d668f85008b')
|
||||
*/
|
||||
deleteUser(userId: string): Chainable<JQuery<HTMLElement>>;
|
||||
/**
|
||||
* Custom command to create a team
|
||||
* @example cy.addTeam('cypressTeam')
|
||||
*/
|
||||
addTeam(name: string): Chainable<JQuery<HTMLElement>>;
|
||||
/**
|
||||
* Custom command to create a website
|
||||
* @example cy.deleteTeam('02d89813-7a72-41e1-87f0-8d668f85008b')
|
||||
*/
|
||||
deleteTeam(teamId: string): Chainable<JQuery<HTMLElement>>;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
332
db/clickhouse/migrations/05_add_utm_clid.sql
Normal file
332
db/clickhouse/migrations/05_add_utm_clid.sql
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
-- Create Event
|
||||
CREATE TABLE umami.website_event_new
|
||||
(
|
||||
website_id UUID,
|
||||
session_id UUID,
|
||||
visit_id UUID,
|
||||
event_id UUID,
|
||||
--sessions
|
||||
hostname LowCardinality(String),
|
||||
browser LowCardinality(String),
|
||||
os LowCardinality(String),
|
||||
device LowCardinality(String),
|
||||
screen LowCardinality(String),
|
||||
language LowCardinality(String),
|
||||
country LowCardinality(String),
|
||||
subdivision1 LowCardinality(String),
|
||||
subdivision2 LowCardinality(String),
|
||||
city String,
|
||||
--pageviews
|
||||
url_path String,
|
||||
url_query String,
|
||||
utm_source String,
|
||||
utm_medium String,
|
||||
utm_campaign String,
|
||||
utm_content String,
|
||||
utm_term String,
|
||||
referrer_path String,
|
||||
referrer_query String,
|
||||
referrer_domain String,
|
||||
page_title String,
|
||||
--clickIDs
|
||||
gclid String,
|
||||
fbclid String,
|
||||
msclkid String,
|
||||
ttclid String,
|
||||
li_fat_id String,
|
||||
twclid String,
|
||||
--events
|
||||
event_type UInt32,
|
||||
event_name String,
|
||||
tag String,
|
||||
created_at DateTime('UTC'),
|
||||
job_id Nullable(UUID)
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
PARTITION BY toYYYYMM(created_at)
|
||||
ORDER BY (toStartOfHour(created_at), website_id, session_id, visit_id, created_at)
|
||||
PRIMARY KEY (toStartOfHour(created_at), website_id, session_id, visit_id)
|
||||
SETTINGS index_granularity = 8192;
|
||||
|
||||
-- stats hourly
|
||||
CREATE TABLE umami.website_event_stats_hourly_new
|
||||
(
|
||||
website_id UUID,
|
||||
session_id UUID,
|
||||
visit_id UUID,
|
||||
hostname LowCardinality(String),
|
||||
browser LowCardinality(String),
|
||||
os LowCardinality(String),
|
||||
device LowCardinality(String),
|
||||
screen LowCardinality(String),
|
||||
language LowCardinality(String),
|
||||
country LowCardinality(String),
|
||||
subdivision1 LowCardinality(String),
|
||||
city String,
|
||||
entry_url AggregateFunction(argMin, String, DateTime('UTC')),
|
||||
exit_url AggregateFunction(argMax, String, DateTime('UTC')),
|
||||
url_path SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
url_query SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_source SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_medium SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_campaign SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_content SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_term SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
referrer_domain SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
page_title SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
gclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
fbclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
msclkid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
ttclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
li_fat_id SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
twclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
event_type UInt32,
|
||||
event_name SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
views SimpleAggregateFunction(sum, UInt64),
|
||||
min_time SimpleAggregateFunction(min, DateTime('UTC')),
|
||||
max_time SimpleAggregateFunction(max, DateTime('UTC')),
|
||||
tag SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
created_at Datetime('UTC')
|
||||
)
|
||||
ENGINE = AggregatingMergeTree
|
||||
PARTITION BY toYYYYMM(created_at)
|
||||
ORDER BY (
|
||||
website_id,
|
||||
event_type,
|
||||
toStartOfHour(created_at),
|
||||
cityHash64(visit_id),
|
||||
visit_id
|
||||
)
|
||||
SAMPLE BY cityHash64(visit_id);
|
||||
|
||||
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv_new
|
||||
TO umami.website_event_stats_hourly_new
|
||||
AS
|
||||
SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
city,
|
||||
entry_url,
|
||||
exit_url,
|
||||
url_paths as url_path,
|
||||
url_query,
|
||||
utm_source,
|
||||
utm_medium,
|
||||
utm_campaign,
|
||||
utm_content,
|
||||
utm_term,
|
||||
referrer_domain,
|
||||
page_title,
|
||||
gclid,
|
||||
fbclid,
|
||||
msclkid,
|
||||
ttclid,
|
||||
li_fat_id,
|
||||
twclid,
|
||||
event_type,
|
||||
event_name,
|
||||
views,
|
||||
min_time,
|
||||
max_time,
|
||||
tag,
|
||||
timestamp as created_at
|
||||
FROM (SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
city,
|
||||
argMinState(url_path, created_at) entry_url,
|
||||
argMaxState(url_path, created_at) exit_url,
|
||||
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
|
||||
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
|
||||
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
|
||||
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
|
||||
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
|
||||
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
|
||||
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
|
||||
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
|
||||
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
|
||||
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
|
||||
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
|
||||
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
|
||||
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
|
||||
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
|
||||
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
|
||||
event_type,
|
||||
if(event_type = 2, groupArray(event_name), []) event_name,
|
||||
sumIf(1, event_type = 1) views,
|
||||
min(created_at) min_time,
|
||||
max(created_at) max_time,
|
||||
arrayFilter(x -> x != '', groupArray(tag)) tag,
|
||||
toStartOfHour(created_at) timestamp
|
||||
FROM umami.website_event_new
|
||||
GROUP BY website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
city,
|
||||
event_type,
|
||||
timestamp);
|
||||
|
||||
-- projections
|
||||
ALTER TABLE umami.website_event_new
|
||||
ADD PROJECTION website_event_url_path_projection (
|
||||
SELECT * ORDER BY toStartOfDay(created_at), website_id, url_path, created_at
|
||||
);
|
||||
|
||||
ALTER TABLE umami.website_event_new MATERIALIZE PROJECTION website_event_url_path_projection;
|
||||
|
||||
ALTER TABLE umami.website_event_new
|
||||
ADD PROJECTION website_event_referrer_domain_projection (
|
||||
SELECT * ORDER BY toStartOfDay(created_at), website_id, referrer_domain, created_at
|
||||
);
|
||||
|
||||
ALTER TABLE umami.website_event_new MATERIALIZE PROJECTION website_event_referrer_domain_projection;
|
||||
|
||||
-- migration
|
||||
INSERT INTO umami.website_event_new
|
||||
SELECT website_id, session_id, visit_id, event_id, hostname, browser, os, device, screen, language, country, subdivision1, subdivision2, city, url_path, url_query,
|
||||
extract(url_query, 'utm_source=([^&]*)') AS utm_source,
|
||||
extract(url_query, 'utm_medium=([^&]*)') AS utm_medium,
|
||||
extract(url_query, 'utm_campaign=([^&]*)') AS utm_campaign,
|
||||
extract(url_query, 'utm_content=([^&]*)') AS utm_content,
|
||||
extract(url_query, 'utm_term=([^&]*)') AS utm_term,referrer_path, referrer_query, referrer_domain,
|
||||
page_title,
|
||||
extract(url_query, 'gclid=([^&]*)') gclid,
|
||||
extract(url_query, 'fbclid=([^&]*)') fbclid,
|
||||
extract(url_query, 'msclkid=([^&]*)') msclkid,
|
||||
extract(url_query, 'ttclid=([^&]*)') ttclid,
|
||||
extract(url_query, 'li_fat_id=([^&]*)') li_fat_id,
|
||||
extract(url_query, 'twclid=([^&]*)') twclid,
|
||||
event_type, event_name, tag, created_at, job_id
|
||||
FROM umami.website_event
|
||||
|
||||
-- rename tables
|
||||
RENAME TABLE umami.website_event TO umami.website_event_old;
|
||||
RENAME TABLE umami.website_event_new TO umami.website_event;
|
||||
|
||||
RENAME TABLE umami.website_event_stats_hourly TO umami.website_event_stats_hourly_old;
|
||||
RENAME TABLE umami.website_event_stats_hourly_new TO umami.website_event_stats_hourly;
|
||||
|
||||
RENAME TABLE umami.website_event_stats_hourly_mv TO umami.website_event_stats_hourly_mv_old;
|
||||
RENAME TABLE umami.website_event_stats_hourly_mv_new TO umami.website_event_stats_hourly_mv;
|
||||
|
||||
-- recreate view
|
||||
DROP TABLE umami.website_event_stats_hourly_mv;
|
||||
|
||||
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
|
||||
TO umami.website_event_stats_hourly
|
||||
AS
|
||||
SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
city,
|
||||
entry_url,
|
||||
exit_url,
|
||||
url_paths as url_path,
|
||||
url_query,
|
||||
utm_source,
|
||||
utm_medium,
|
||||
utm_campaign,
|
||||
utm_content,
|
||||
utm_term,
|
||||
referrer_domain,
|
||||
page_title,
|
||||
gclid,
|
||||
fbclid,
|
||||
msclkid,
|
||||
ttclid,
|
||||
li_fat_id,
|
||||
twclid,
|
||||
event_type,
|
||||
event_name,
|
||||
views,
|
||||
min_time,
|
||||
max_time,
|
||||
tag,
|
||||
timestamp as created_at
|
||||
FROM (SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
city,
|
||||
argMinState(url_path, created_at) entry_url,
|
||||
argMaxState(url_path, created_at) exit_url,
|
||||
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
|
||||
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
|
||||
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
|
||||
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
|
||||
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
|
||||
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
|
||||
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
|
||||
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
|
||||
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
|
||||
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
|
||||
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
|
||||
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
|
||||
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
|
||||
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
|
||||
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
|
||||
event_type,
|
||||
if(event_type = 2, groupArray(event_name), []) event_name,
|
||||
sumIf(1, event_type = 1) views,
|
||||
min(created_at) min_time,
|
||||
max(created_at) max_time,
|
||||
arrayFilter(x -> x != '', groupArray(tag)) tag,
|
||||
toStartOfHour(created_at) timestamp
|
||||
FROM umami.website_event
|
||||
GROUP BY website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
city,
|
||||
event_type,
|
||||
timestamp);
|
||||
122
db/clickhouse/migrations/06_update_subdivision.sql
Normal file
122
db/clickhouse/migrations/06_update_subdivision.sql
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
-- drop projections
|
||||
ALTER TABLE umami.website_event DROP PROJECTION website_event_url_path_projection;
|
||||
ALTER TABLE umami.website_event DROP PROJECTION website_event_referrer_domain_projection;
|
||||
|
||||
--drop view
|
||||
DROP TABLE umami.website_event_stats_hourly_mv;
|
||||
|
||||
-- rename columns
|
||||
ALTER TABLE umami.website_event RENAME COLUMN "subdivision1" TO "region";
|
||||
ALTER TABLE umami.website_event_stats_hourly RENAME COLUMN "subdivision1" TO "region";
|
||||
|
||||
-- drop columns
|
||||
ALTER TABLE umami.website_event DROP COLUMN "subdivision2";
|
||||
|
||||
-- recreate projections
|
||||
ALTER TABLE umami.website_event
|
||||
ADD PROJECTION website_event_url_path_projection (
|
||||
SELECT * ORDER BY toStartOfDay(created_at), website_id, url_path, created_at
|
||||
);
|
||||
|
||||
ALTER TABLE umami.website_event MATERIALIZE PROJECTION website_event_url_path_projection;
|
||||
|
||||
ALTER TABLE umami.website_event
|
||||
ADD PROJECTION website_event_referrer_domain_projection (
|
||||
SELECT * ORDER BY toStartOfDay(created_at), website_id, referrer_domain, created_at
|
||||
);
|
||||
|
||||
ALTER TABLE umami.website_event MATERIALIZE PROJECTION website_event_referrer_domain_projection;
|
||||
|
||||
-- recreate view
|
||||
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
|
||||
TO umami.website_event_stats_hourly
|
||||
AS
|
||||
SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
entry_url,
|
||||
exit_url,
|
||||
url_paths as url_path,
|
||||
url_query,
|
||||
utm_source,
|
||||
utm_medium,
|
||||
utm_campaign,
|
||||
utm_content,
|
||||
utm_term,
|
||||
referrer_domain,
|
||||
page_title,
|
||||
gclid,
|
||||
fbclid,
|
||||
msclkid,
|
||||
ttclid,
|
||||
li_fat_id,
|
||||
twclid,
|
||||
event_type,
|
||||
event_name,
|
||||
views,
|
||||
min_time,
|
||||
max_time,
|
||||
tag,
|
||||
timestamp as created_at
|
||||
FROM (SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
argMinState(url_path, created_at) entry_url,
|
||||
argMaxState(url_path, created_at) exit_url,
|
||||
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
|
||||
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
|
||||
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
|
||||
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
|
||||
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
|
||||
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
|
||||
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
|
||||
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
|
||||
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
|
||||
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
|
||||
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
|
||||
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
|
||||
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
|
||||
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
|
||||
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
|
||||
event_type,
|
||||
if(event_type = 2, groupArray(event_name), []) event_name,
|
||||
sumIf(1, event_type = 1) views,
|
||||
min(created_at) min_time,
|
||||
max(created_at) max_time,
|
||||
arrayFilter(x -> x != '', groupArray(tag)) tag,
|
||||
toStartOfHour(created_at) timestamp
|
||||
FROM umami.website_event
|
||||
GROUP BY website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
event_type,
|
||||
timestamp);
|
||||
103
db/clickhouse/migrations/07_add_distinct_id.sql
Normal file
103
db/clickhouse/migrations/07_add_distinct_id.sql
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
-- add tag column
|
||||
ALTER TABLE umami.website_event ADD COLUMN "distinct_id" String AFTER "tag";
|
||||
ALTER TABLE umami.website_event_stats_hourly ADD COLUMN "distinct_id" String AFTER "tag";
|
||||
ALTER TABLE umami.session_data ADD COLUMN "distinct_id" String AFTER "data_type";
|
||||
|
||||
-- update materialized view
|
||||
DROP TABLE umami.website_event_stats_hourly_mv;
|
||||
|
||||
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
|
||||
TO umami.website_event_stats_hourly
|
||||
AS
|
||||
SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
entry_url,
|
||||
exit_url,
|
||||
url_paths as url_path,
|
||||
url_query,
|
||||
utm_source,
|
||||
utm_medium,
|
||||
utm_campaign,
|
||||
utm_content,
|
||||
utm_term,
|
||||
referrer_domain,
|
||||
page_title,
|
||||
gclid,
|
||||
fbclid,
|
||||
msclkid,
|
||||
ttclid,
|
||||
li_fat_id,
|
||||
twclid,
|
||||
event_type,
|
||||
event_name,
|
||||
views,
|
||||
min_time,
|
||||
max_time,
|
||||
tag,
|
||||
distinct_id,
|
||||
timestamp as created_at
|
||||
FROM (SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
argMinState(url_path, created_at) entry_url,
|
||||
argMaxState(url_path, created_at) exit_url,
|
||||
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
|
||||
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
|
||||
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
|
||||
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
|
||||
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
|
||||
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
|
||||
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
|
||||
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
|
||||
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
|
||||
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
|
||||
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
|
||||
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
|
||||
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
|
||||
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
|
||||
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
|
||||
event_type,
|
||||
if(event_type = 2, groupArray(event_name), []) event_name,
|
||||
sumIf(1, event_type = 1) views,
|
||||
min(created_at) min_time,
|
||||
max(created_at) max_time,
|
||||
arrayFilter(x -> x != '', groupArray(tag)) tag,
|
||||
distinct_id,
|
||||
toStartOfHour(created_at) timestamp
|
||||
FROM umami.website_event
|
||||
GROUP BY website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
event_type,
|
||||
distinct_id,
|
||||
timestamp);
|
||||
253
db/clickhouse/migrations/08_update_hostname_view.sql
Normal file
253
db/clickhouse/migrations/08_update_hostname_view.sql
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
-- create new hourly table
|
||||
CREATE TABLE umami.website_event_stats_hourly_new
|
||||
(
|
||||
website_id UUID,
|
||||
session_id UUID,
|
||||
visit_id UUID,
|
||||
hostname SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
browser LowCardinality(String),
|
||||
os LowCardinality(String),
|
||||
device LowCardinality(String),
|
||||
screen LowCardinality(String),
|
||||
language LowCardinality(String),
|
||||
country LowCardinality(String),
|
||||
region LowCardinality(String),
|
||||
city String,
|
||||
entry_url AggregateFunction(argMin, String, DateTime('UTC')),
|
||||
exit_url AggregateFunction(argMax, String, DateTime('UTC')),
|
||||
url_path SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
url_query SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_source SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_medium SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_campaign SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_content SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_term SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
referrer_domain SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
page_title SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
gclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
fbclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
msclkid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
ttclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
li_fat_id SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
twclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
event_type UInt32,
|
||||
event_name SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
views SimpleAggregateFunction(sum, UInt64),
|
||||
min_time SimpleAggregateFunction(min, DateTime('UTC')),
|
||||
max_time SimpleAggregateFunction(max, DateTime('UTC')),
|
||||
tag SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
distinct_id String,
|
||||
created_at Datetime('UTC')
|
||||
)
|
||||
ENGINE = AggregatingMergeTree
|
||||
PARTITION BY toYYYYMM(created_at)
|
||||
ORDER BY (
|
||||
website_id,
|
||||
event_type,
|
||||
toStartOfHour(created_at),
|
||||
cityHash64(visit_id),
|
||||
visit_id
|
||||
)
|
||||
SAMPLE BY cityHash64(visit_id);
|
||||
|
||||
-- create view
|
||||
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv_new
|
||||
TO umami.website_event_stats_hourly_new
|
||||
AS
|
||||
SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostnames as hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
entry_url,
|
||||
exit_url,
|
||||
url_paths as url_path,
|
||||
url_query,
|
||||
utm_source,
|
||||
utm_medium,
|
||||
utm_campaign,
|
||||
utm_content,
|
||||
utm_term,
|
||||
referrer_domain,
|
||||
page_title,
|
||||
gclid,
|
||||
fbclid,
|
||||
msclkid,
|
||||
ttclid,
|
||||
li_fat_id,
|
||||
twclid,
|
||||
event_type,
|
||||
event_name,
|
||||
views,
|
||||
min_time,
|
||||
max_time,
|
||||
tag,
|
||||
distinct_id,
|
||||
timestamp as created_at
|
||||
FROM (SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
arrayFilter(x -> x != '', groupArray(hostname)) hostnames,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
argMinState(url_path, created_at) entry_url,
|
||||
argMaxState(url_path, created_at) exit_url,
|
||||
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
|
||||
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
|
||||
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
|
||||
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
|
||||
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
|
||||
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
|
||||
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
|
||||
arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain,
|
||||
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
|
||||
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
|
||||
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
|
||||
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
|
||||
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
|
||||
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
|
||||
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
|
||||
event_type,
|
||||
if(event_type = 2, groupArray(event_name), []) event_name,
|
||||
sumIf(1, event_type = 1) views,
|
||||
min(created_at) min_time,
|
||||
max(created_at) max_time,
|
||||
arrayFilter(x -> x != '', groupArray(tag)) tag,
|
||||
distinct_id,
|
||||
toStartOfHour(created_at) timestamp
|
||||
FROM umami.website_event
|
||||
GROUP BY website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
event_type,
|
||||
distinct_id,
|
||||
timestamp);
|
||||
|
||||
-- rename tables
|
||||
RENAME TABLE umami.website_event_stats_hourly TO umami.website_event_stats_hourly_old;
|
||||
RENAME TABLE umami.website_event_stats_hourly_new TO umami.website_event_stats_hourly;
|
||||
|
||||
-- drop views
|
||||
DROP TABLE umami.website_event_stats_hourly_mv;
|
||||
DROP TABLE umami.website_event_stats_hourly_mv_new;
|
||||
|
||||
-- recreate view
|
||||
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
|
||||
TO umami.website_event_stats_hourly
|
||||
AS
|
||||
SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostnames as hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
entry_url,
|
||||
exit_url,
|
||||
url_paths as url_path,
|
||||
url_query,
|
||||
utm_source,
|
||||
utm_medium,
|
||||
utm_campaign,
|
||||
utm_content,
|
||||
utm_term,
|
||||
referrer_domain,
|
||||
page_title,
|
||||
gclid,
|
||||
fbclid,
|
||||
msclkid,
|
||||
ttclid,
|
||||
li_fat_id,
|
||||
twclid,
|
||||
event_type,
|
||||
event_name,
|
||||
views,
|
||||
min_time,
|
||||
max_time,
|
||||
tag,
|
||||
distinct_id,
|
||||
timestamp as created_at
|
||||
FROM (SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
arrayFilter(x -> x != '', groupArray(hostname)) hostnames,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
argMinState(url_path, created_at) entry_url,
|
||||
argMaxState(url_path, created_at) exit_url,
|
||||
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
|
||||
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
|
||||
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
|
||||
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
|
||||
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
|
||||
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
|
||||
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
|
||||
arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain,
|
||||
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
|
||||
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
|
||||
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
|
||||
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
|
||||
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
|
||||
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
|
||||
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
|
||||
event_type,
|
||||
if(event_type = 2, groupArray(event_name), []) event_name,
|
||||
sumIf(1, event_type = 1) views,
|
||||
min(created_at) min_time,
|
||||
max(created_at) max_time,
|
||||
arrayFilter(x -> x != '', groupArray(tag)) tag,
|
||||
distinct_id,
|
||||
toStartOfHour(created_at) timestamp
|
||||
FROM umami.website_event
|
||||
GROUP BY website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
region,
|
||||
city,
|
||||
event_type,
|
||||
distinct_id,
|
||||
timestamp);
|
||||
|
|
@ -13,20 +13,32 @@ CREATE TABLE umami.website_event
|
|||
screen LowCardinality(String),
|
||||
language LowCardinality(String),
|
||||
country LowCardinality(String),
|
||||
subdivision1 LowCardinality(String),
|
||||
subdivision2 LowCardinality(String),
|
||||
region LowCardinality(String),
|
||||
city String,
|
||||
--pageviews
|
||||
url_path String,
|
||||
url_query String,
|
||||
utm_source String,
|
||||
utm_medium String,
|
||||
utm_campaign String,
|
||||
utm_content String,
|
||||
utm_term String,
|
||||
referrer_path String,
|
||||
referrer_query String,
|
||||
referrer_domain String,
|
||||
page_title String,
|
||||
--clickIDs
|
||||
gclid String,
|
||||
fbclid String,
|
||||
msclkid String,
|
||||
ttclid String,
|
||||
li_fat_id String,
|
||||
twclid String,
|
||||
--events
|
||||
event_type UInt32,
|
||||
event_name String,
|
||||
tag String,
|
||||
distinct_id String,
|
||||
created_at DateTime('UTC'),
|
||||
job_id Nullable(UUID)
|
||||
)
|
||||
|
|
@ -45,7 +57,7 @@ CREATE TABLE umami.event_data
|
|||
event_name String,
|
||||
data_key String,
|
||||
string_value Nullable(String),
|
||||
number_value Nullable(Decimal64(4)),
|
||||
number_value Nullable(Decimal(22, 4)),
|
||||
date_value Nullable(DateTime('UTC')),
|
||||
data_type UInt32,
|
||||
created_at DateTime('UTC'),
|
||||
|
|
@ -61,9 +73,10 @@ CREATE TABLE umami.session_data
|
|||
session_id UUID,
|
||||
data_key String,
|
||||
string_value Nullable(String),
|
||||
number_value Nullable(Decimal64(4)),
|
||||
number_value Nullable(Decimal(22, 4)),
|
||||
date_value Nullable(DateTime('UTC')),
|
||||
data_type UInt32,
|
||||
distinct_id String,
|
||||
created_at DateTime('UTC'),
|
||||
job_id Nullable(UUID)
|
||||
)
|
||||
|
|
@ -77,27 +90,39 @@ CREATE TABLE umami.website_event_stats_hourly
|
|||
website_id UUID,
|
||||
session_id UUID,
|
||||
visit_id UUID,
|
||||
hostname LowCardinality(String),
|
||||
hostname SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
browser LowCardinality(String),
|
||||
os LowCardinality(String),
|
||||
device LowCardinality(String),
|
||||
screen LowCardinality(String),
|
||||
language LowCardinality(String),
|
||||
country LowCardinality(String),
|
||||
subdivision1 LowCardinality(String),
|
||||
region LowCardinality(String),
|
||||
city String,
|
||||
entry_url AggregateFunction(argMin, String, DateTime('UTC')),
|
||||
exit_url AggregateFunction(argMax, String, DateTime('UTC')),
|
||||
url_path SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
url_query SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_source SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_medium SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_campaign SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_content SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
utm_term SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
referrer_domain SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
page_title SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
gclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
fbclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
msclkid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
ttclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
li_fat_id SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
twclid SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
event_type UInt32,
|
||||
event_name SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
views SimpleAggregateFunction(sum, UInt64),
|
||||
min_time SimpleAggregateFunction(min, DateTime('UTC')),
|
||||
max_time SimpleAggregateFunction(max, DateTime('UTC')),
|
||||
tag SimpleAggregateFunction(groupArrayArray, Array(String)),
|
||||
distinct_id String,
|
||||
created_at Datetime('UTC')
|
||||
)
|
||||
ENGINE = AggregatingMergeTree
|
||||
|
|
@ -118,53 +143,77 @@ SELECT
|
|||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
hostnames as hostname,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
region,
|
||||
city,
|
||||
entry_url,
|
||||
exit_url,
|
||||
url_paths as url_path,
|
||||
url_query,
|
||||
utm_source,
|
||||
utm_medium,
|
||||
utm_campaign,
|
||||
utm_content,
|
||||
utm_term,
|
||||
referrer_domain,
|
||||
page_title,
|
||||
gclid,
|
||||
fbclid,
|
||||
msclkid,
|
||||
ttclid,
|
||||
li_fat_id,
|
||||
twclid,
|
||||
event_type,
|
||||
event_name,
|
||||
views,
|
||||
min_time,
|
||||
max_time,
|
||||
tag,
|
||||
distinct_id,
|
||||
timestamp as created_at
|
||||
FROM (SELECT
|
||||
website_id,
|
||||
session_id,
|
||||
visit_id,
|
||||
hostname,
|
||||
arrayFilter(x -> x != '', groupArray(hostname)) hostnames,
|
||||
browser,
|
||||
os,
|
||||
device,
|
||||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
region,
|
||||
city,
|
||||
argMinState(url_path, created_at) entry_url,
|
||||
argMaxState(url_path, created_at) exit_url,
|
||||
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
|
||||
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
|
||||
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
|
||||
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
|
||||
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
|
||||
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
|
||||
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
|
||||
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
|
||||
arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain,
|
||||
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
|
||||
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
|
||||
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
|
||||
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
|
||||
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
|
||||
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
|
||||
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
|
||||
event_type,
|
||||
if(event_type = 2, groupArray(event_name), []) event_name,
|
||||
sumIf(1, event_type = 1) views,
|
||||
sumIf(1, event_type != 2) views,
|
||||
min(created_at) min_time,
|
||||
max(created_at) max_time,
|
||||
arrayFilter(x -> x != '', groupArray(tag)) tag,
|
||||
distinct_id,
|
||||
toStartOfHour(created_at) timestamp
|
||||
FROM umami.website_event
|
||||
GROUP BY website_id,
|
||||
|
|
@ -177,9 +226,10 @@ GROUP BY website_id,
|
|||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
region,
|
||||
city,
|
||||
event_type,
|
||||
distinct_id,
|
||||
timestamp);
|
||||
|
||||
-- projections
|
||||
|
|
@ -196,3 +246,38 @@ SELECT * ORDER BY toStartOfDay(created_at), website_id, referrer_domain, created
|
|||
);
|
||||
|
||||
ALTER TABLE umami.website_event MATERIALIZE PROJECTION website_event_referrer_domain_projection;
|
||||
|
||||
-- revenue
|
||||
CREATE TABLE umami.website_revenue
|
||||
(
|
||||
website_id UUID,
|
||||
session_id UUID,
|
||||
event_id UUID,
|
||||
event_name String,
|
||||
currency String,
|
||||
revenue DECIMAL(18,4),
|
||||
created_at DateTime('UTC')
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
PARTITION BY toYYYYMM(created_at)
|
||||
ORDER BY (website_id, session_id, created_at)
|
||||
SETTINGS index_granularity = 8192;
|
||||
|
||||
|
||||
CREATE MATERIALIZED VIEW umami.website_revenue_mv
|
||||
TO umami.website_revenue
|
||||
AS
|
||||
SELECT DISTINCT
|
||||
ed.website_id,
|
||||
ed.session_id,
|
||||
ed.event_id,
|
||||
ed.event_name,
|
||||
c.currency,
|
||||
coalesce(toDecimal64(ed.number_value, 2), toDecimal64(ed.string_value, 2)) revenue,
|
||||
ed.created_at
|
||||
FROM umami.event_data ed
|
||||
JOIN (SELECT event_id, string_value as currency
|
||||
FROM umami.event_data
|
||||
WHERE positionCaseInsensitive(data_key, 'currency') > 0) c
|
||||
ON c.event_id = ed.event_id
|
||||
WHERE positionCaseInsensitive(data_key, 'revenue') > 0;
|
||||
|
|
|
|||
|
|
@ -1,143 +0,0 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE `user` (
|
||||
`user_id` VARCHAR(36) NOT NULL,
|
||||
`username` VARCHAR(255) NOT NULL,
|
||||
`password` VARCHAR(60) NOT NULL,
|
||||
`role` VARCHAR(50) NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updated_at` TIMESTAMP(0) NULL,
|
||||
`deleted_at` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `user_user_id_key`(`user_id`),
|
||||
UNIQUE INDEX `user_username_key`(`username`),
|
||||
PRIMARY KEY (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `session` (
|
||||
`session_id` VARCHAR(36) NOT NULL,
|
||||
`website_id` VARCHAR(36) NOT NULL,
|
||||
`hostname` VARCHAR(100) NULL,
|
||||
`browser` VARCHAR(20) NULL,
|
||||
`os` VARCHAR(20) NULL,
|
||||
`device` VARCHAR(20) NULL,
|
||||
`screen` VARCHAR(11) NULL,
|
||||
`language` VARCHAR(35) NULL,
|
||||
`country` CHAR(2) NULL,
|
||||
`subdivision1` CHAR(20) NULL,
|
||||
`subdivision2` VARCHAR(50) NULL,
|
||||
`city` VARCHAR(50) NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
|
||||
UNIQUE INDEX `session_session_id_key`(`session_id`),
|
||||
INDEX `session_created_at_idx`(`created_at`),
|
||||
INDEX `session_website_id_idx`(`website_id`),
|
||||
PRIMARY KEY (`session_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `website` (
|
||||
`website_id` VARCHAR(36) NOT NULL,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`domain` VARCHAR(500) NULL,
|
||||
`share_id` VARCHAR(50) NULL,
|
||||
`reset_at` TIMESTAMP(0) NULL,
|
||||
`user_id` VARCHAR(36) NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updated_at` TIMESTAMP(0) NULL,
|
||||
`deleted_at` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `website_website_id_key`(`website_id`),
|
||||
UNIQUE INDEX `website_share_id_key`(`share_id`),
|
||||
INDEX `website_user_id_idx`(`user_id`),
|
||||
INDEX `website_created_at_idx`(`created_at`),
|
||||
INDEX `website_share_id_idx`(`share_id`),
|
||||
PRIMARY KEY (`website_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `website_event` (
|
||||
`event_id` VARCHAR(36) NOT NULL,
|
||||
`website_id` VARCHAR(36) NOT NULL,
|
||||
`session_id` VARCHAR(36) NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`url_path` VARCHAR(500) NOT NULL,
|
||||
`url_query` VARCHAR(500) NULL,
|
||||
`referrer_path` VARCHAR(500) NULL,
|
||||
`referrer_query` VARCHAR(500) NULL,
|
||||
`referrer_domain` VARCHAR(500) NULL,
|
||||
`page_title` VARCHAR(500) NULL,
|
||||
`event_type` INTEGER UNSIGNED NOT NULL DEFAULT 1,
|
||||
`event_name` VARCHAR(50) NULL,
|
||||
|
||||
INDEX `website_event_created_at_idx`(`created_at`),
|
||||
INDEX `website_event_session_id_idx`(`session_id`),
|
||||
INDEX `website_event_website_id_idx`(`website_id`),
|
||||
INDEX `website_event_website_id_created_at_idx`(`website_id`, `created_at`),
|
||||
INDEX `website_event_website_id_session_id_created_at_idx`(`website_id`, `session_id`, `created_at`),
|
||||
PRIMARY KEY (`event_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `event_data` (
|
||||
`event_id` VARCHAR(36) NOT NULL,
|
||||
`website_event_id` VARCHAR(36) NOT NULL,
|
||||
`website_id` VARCHAR(36) NOT NULL,
|
||||
`event_key` VARCHAR(500) NOT NULL,
|
||||
`event_string_value` VARCHAR(500) NULL,
|
||||
`event_numeric_value` DECIMAL(19, 4) NULL,
|
||||
`event_date_value` TIMESTAMP(0) NULL,
|
||||
`event_data_type` INTEGER UNSIGNED NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
|
||||
INDEX `event_data_created_at_idx`(`created_at`),
|
||||
INDEX `event_data_website_id_idx`(`website_id`),
|
||||
INDEX `event_data_website_event_id_idx`(`website_event_id`),
|
||||
INDEX `event_data_website_id_website_event_id_created_at_idx`(`website_id`, `website_event_id`, `created_at`),
|
||||
PRIMARY KEY (`event_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `team` (
|
||||
`team_id` VARCHAR(36) NOT NULL,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`access_code` VARCHAR(50) NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updated_at` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `team_team_id_key`(`team_id`),
|
||||
UNIQUE INDEX `team_access_code_key`(`access_code`),
|
||||
INDEX `team_access_code_idx`(`access_code`),
|
||||
PRIMARY KEY (`team_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `team_user` (
|
||||
`team_user_id` VARCHAR(36) NOT NULL,
|
||||
`team_id` VARCHAR(36) NOT NULL,
|
||||
`user_id` VARCHAR(36) NOT NULL,
|
||||
`role` VARCHAR(50) NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updated_at` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `team_user_team_user_id_key`(`team_user_id`),
|
||||
INDEX `team_user_team_id_idx`(`team_id`),
|
||||
INDEX `team_user_user_id_idx`(`user_id`),
|
||||
PRIMARY KEY (`team_user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `team_website` (
|
||||
`team_website_id` VARCHAR(36) NOT NULL,
|
||||
`team_id` VARCHAR(36) NOT NULL,
|
||||
`website_id` VARCHAR(36) NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
|
||||
UNIQUE INDEX `team_website_team_website_id_key`(`team_website_id`),
|
||||
INDEX `team_website_team_id_idx`(`team_id`),
|
||||
INDEX `team_website_website_id_idx`(`website_id`),
|
||||
PRIMARY KEY (`team_website_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddSystemUser
|
||||
INSERT INTO user (user_id, username, role, password) VALUES ('41e2b680-648e-4b09-bcd7-3e2b10c06264' , 'admin', 'admin', '$2b$10$BUli0c.muyCW1ErNJc3jL.vFRFtFJWrT8/GcR4A.sUdCznaXiqFXa');
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE `event_data` CHANGE `event_data_type` `data_type` INTEGER UNSIGNED NOT NULL;
|
||||
ALTER TABLE `event_data` CHANGE `event_date_value` `date_value` TIMESTAMP(0) NULL;
|
||||
ALTER TABLE `event_data` CHANGE `event_id` `event_data_id` VARCHAR(36) NOT NULL;
|
||||
ALTER TABLE `event_data` CHANGE `event_numeric_value` `number_value` DECIMAL(19,4) NULL;
|
||||
ALTER TABLE `event_data` CHANGE `event_string_value` `string_value` VARCHAR(500) NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `session_data` (
|
||||
`session_data_id` VARCHAR(36) NOT NULL,
|
||||
`website_id` VARCHAR(36) NOT NULL,
|
||||
`session_id` VARCHAR(36) NOT NULL,
|
||||
`event_key` VARCHAR(500) NOT NULL,
|
||||
`string_value` VARCHAR(500) NULL,
|
||||
`number_value` DECIMAL(19, 4) NULL,
|
||||
`date_value` TIMESTAMP(0) NULL,
|
||||
`data_type` INTEGER UNSIGNED NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
|
||||
INDEX `session_data_created_at_idx`(`created_at`),
|
||||
INDEX `session_data_website_id_idx`(`website_id`),
|
||||
INDEX `session_data_session_id_idx`(`session_id`),
|
||||
PRIMARY KEY (`session_data_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `report` (
|
||||
`report_id` VARCHAR(36) NOT NULL,
|
||||
`user_id` VARCHAR(36) NOT NULL,
|
||||
`website_id` VARCHAR(36) NOT NULL,
|
||||
`type` VARCHAR(200) NOT NULL,
|
||||
`name` VARCHAR(200) NOT NULL,
|
||||
`description` VARCHAR(500) NOT NULL,
|
||||
`parameters` VARCHAR(6000) NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`updated_at` TIMESTAMP(0) NULL,
|
||||
|
||||
UNIQUE INDEX `report_report_id_key`(`report_id`),
|
||||
INDEX `report_user_id_idx`(`user_id`),
|
||||
INDEX `report_website_id_idx`(`website_id`),
|
||||
INDEX `report_type_idx`(`type`),
|
||||
INDEX `report_name_idx`(`name`),
|
||||
PRIMARY KEY (`report_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- EventData migration
|
||||
UPDATE event_data
|
||||
SET string_value = number_value
|
||||
WHERE data_type = 2;
|
||||
|
||||
UPDATE event_data
|
||||
SET string_value = CONCAT(REPLACE(DATE_FORMAT(date_value, '%Y-%m-%d %T'), ' ', 'T'), 'Z')
|
||||
WHERE data_type = 4;
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
-- CreateIndex
|
||||
CREATE INDEX `event_data_website_id_created_at_idx` ON `event_data`(`website_id`, `created_at`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `event_data_website_id_created_at_event_key_idx` ON `event_data`(`website_id`, `created_at`, `event_key`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_idx` ON `session`(`website_id`, `created_at`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_hostname_idx` ON `session`(`website_id`, `created_at`, `hostname`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_browser_idx` ON `session`(`website_id`, `created_at`, `browser`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_os_idx` ON `session`(`website_id`, `created_at`, `os`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_device_idx` ON `session`(`website_id`, `created_at`, `device`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_screen_idx` ON `session`(`website_id`, `created_at`, `screen`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_language_idx` ON `session`(`website_id`, `created_at`, `language`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_country_idx` ON `session`(`website_id`, `created_at`, `country`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_subdivision1_idx` ON `session`(`website_id`, `created_at`, `subdivision1`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_website_id_created_at_city_idx` ON `session`(`website_id`, `created_at`, `city`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_event_website_id_created_at_url_path_idx` ON `website_event`(`website_id`, `created_at`, `url_path`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_event_website_id_created_at_url_query_idx` ON `website_event`(`website_id`, `created_at`, `url_query`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_event_website_id_created_at_referrer_domain_idx` ON `website_event`(`website_id`, `created_at`, `referrer_domain`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_event_website_id_created_at_page_title_idx` ON `website_event`(`website_id`, `created_at`, `page_title`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_event_website_id_created_at_event_name_idx` ON `website_event`(`website_id`, `created_at`, `event_name`);
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the `team_website` table. If the table is not empty, all the data it contains will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `team` ADD COLUMN `deleted_at` TIMESTAMP(0) NULL,
|
||||
ADD COLUMN `logo_url` VARCHAR(2183) NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `user` ADD COLUMN `display_name` VARCHAR(255) NULL,
|
||||
ADD COLUMN `logo_url` VARCHAR(2183) NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `website` ADD COLUMN `created_by` VARCHAR(36) NULL,
|
||||
ADD COLUMN `team_id` VARCHAR(36) NULL;
|
||||
|
||||
-- MigrateData
|
||||
UPDATE `website` SET created_by = user_id WHERE team_id IS NULL;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE `team_website`;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_team_id_idx` ON `website`(`team_id`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_created_by_idx` ON `website`(`created_by`);
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE `website_event` ADD COLUMN `visit_id` VARCHAR(36) NULL;
|
||||
|
||||
UPDATE `website_event` we
|
||||
JOIN (SELECT DISTINCT
|
||||
s.session_id,
|
||||
s.visit_time,
|
||||
BIN_TO_UUID(RANDOM_BYTES(16) & 0xffffffffffff0fff3fffffffffffffff | 0x00000000000040008000000000000000) uuid
|
||||
FROM (SELECT DISTINCT session_id,
|
||||
DATE_FORMAT(created_at, '%Y-%m-%d %H:00:00') visit_time
|
||||
FROM `website_event`) s) a
|
||||
ON we.session_id = a.session_id and DATE_FORMAT(we.created_at, '%Y-%m-%d %H:00:00') = a.visit_time
|
||||
SET we.visit_id = a.uuid
|
||||
WHERE we.visit_id IS NULL;
|
||||
|
||||
ALTER TABLE `website_event` MODIFY `visit_id` VARCHAR(36) NOT NULL;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_event_visit_id_idx` ON `website_event`(`visit_id`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_event_website_id_visit_id_created_at_idx` ON `website_event`(`website_id`, `visit_id`, `created_at`);
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
-- DropIndex
|
||||
DROP INDEX `event_data_website_id_created_at_event_key_idx` ON `event_data`;
|
||||
|
||||
-- DropIndex
|
||||
DROP INDEX `event_data_website_id_website_event_id_created_at_idx` ON `event_data`;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `event_data` RENAME COLUMN `event_key` TO `data_key`;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `session_data` RENAME COLUMN `event_key` TO `data_key`;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `event_data_website_id_created_at_data_key_idx` ON `event_data`(`website_id`, `created_at`, `data_key`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_data_session_id_created_at_idx` ON `session_data`(`session_id`, `created_at`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `session_data_website_id_created_at_data_key_idx` ON `session_data`(`website_id`, `created_at`, `data_key`);
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE `website_event` ADD COLUMN `tag` VARCHAR(50) NULL;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `website_event_website_id_created_at_tag_idx` ON `website_event`(`website_id`, `created_at`, `tag`);
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "mysql"
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = ["native"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "mysql"
|
||||
url = env("DATABASE_URL")
|
||||
relationMode = "prisma"
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @unique @map("user_id") @db.VarChar(36)
|
||||
username String @unique @db.VarChar(255)
|
||||
password String @db.VarChar(60)
|
||||
role String @map("role") @db.VarChar(50)
|
||||
logoUrl String? @map("logo_url") @db.VarChar(2183)
|
||||
displayName String? @map("display_name") @db.VarChar(255)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
||||
|
||||
websiteUser Website[] @relation("user")
|
||||
websiteCreateUser Website[] @relation("createUser")
|
||||
teamUser TeamUser[]
|
||||
report Report[]
|
||||
|
||||
@@map("user")
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @unique @map("session_id") @db.VarChar(36)
|
||||
websiteId String @map("website_id") @db.VarChar(36)
|
||||
hostname String? @db.VarChar(100)
|
||||
browser String? @db.VarChar(20)
|
||||
os String? @db.VarChar(20)
|
||||
device String? @db.VarChar(20)
|
||||
screen String? @db.VarChar(11)
|
||||
language String? @db.VarChar(35)
|
||||
country String? @db.Char(2)
|
||||
subdivision1 String? @db.Char(20)
|
||||
subdivision2 String? @db.VarChar(50)
|
||||
city String? @db.VarChar(50)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
|
||||
websiteEvent WebsiteEvent[]
|
||||
sessionData SessionData[]
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([websiteId])
|
||||
@@index([websiteId, createdAt])
|
||||
@@index([websiteId, createdAt, hostname])
|
||||
@@index([websiteId, createdAt, browser])
|
||||
@@index([websiteId, createdAt, os])
|
||||
@@index([websiteId, createdAt, device])
|
||||
@@index([websiteId, createdAt, screen])
|
||||
@@index([websiteId, createdAt, language])
|
||||
@@index([websiteId, createdAt, country])
|
||||
@@index([websiteId, createdAt, subdivision1])
|
||||
@@index([websiteId, createdAt, city])
|
||||
@@map("session")
|
||||
}
|
||||
|
||||
model Website {
|
||||
id String @id @unique @map("website_id") @db.VarChar(36)
|
||||
name String @db.VarChar(100)
|
||||
domain String? @db.VarChar(500)
|
||||
shareId String? @unique @map("share_id") @db.VarChar(50)
|
||||
resetAt DateTime? @map("reset_at") @db.Timestamp(0)
|
||||
userId String? @map("user_id") @db.VarChar(36)
|
||||
teamId String? @map("team_id") @db.VarChar(36)
|
||||
createdBy String? @map("created_by") @db.VarChar(36)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
||||
|
||||
user User? @relation("user", fields: [userId], references: [id])
|
||||
createUser User? @relation("createUser", fields: [createdBy], references: [id])
|
||||
team Team? @relation(fields: [teamId], references: [id])
|
||||
eventData EventData[]
|
||||
report Report[]
|
||||
sessionData SessionData[]
|
||||
|
||||
@@index([userId])
|
||||
@@index([teamId])
|
||||
@@index([createdAt])
|
||||
@@index([shareId])
|
||||
@@index([createdBy])
|
||||
@@map("website")
|
||||
}
|
||||
|
||||
model WebsiteEvent {
|
||||
id String @id() @map("event_id") @db.VarChar(36)
|
||||
websiteId String @map("website_id") @db.VarChar(36)
|
||||
sessionId String @map("session_id") @db.VarChar(36)
|
||||
visitId String @map("visit_id") @db.VarChar(36)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
urlPath String @map("url_path") @db.VarChar(500)
|
||||
urlQuery String? @map("url_query") @db.VarChar(500)
|
||||
referrerPath String? @map("referrer_path") @db.VarChar(500)
|
||||
referrerQuery String? @map("referrer_query") @db.VarChar(500)
|
||||
referrerDomain String? @map("referrer_domain") @db.VarChar(500)
|
||||
pageTitle String? @map("page_title") @db.VarChar(500)
|
||||
eventType Int @default(1) @map("event_type") @db.UnsignedInt
|
||||
eventName String? @map("event_name") @db.VarChar(50)
|
||||
tag String? @db.VarChar(50)
|
||||
|
||||
eventData EventData[]
|
||||
session Session @relation(fields: [sessionId], references: [id])
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([sessionId])
|
||||
@@index([visitId])
|
||||
@@index([websiteId])
|
||||
@@index([websiteId, createdAt])
|
||||
@@index([websiteId, createdAt, urlPath])
|
||||
@@index([websiteId, createdAt, urlQuery])
|
||||
@@index([websiteId, createdAt, referrerDomain])
|
||||
@@index([websiteId, createdAt, pageTitle])
|
||||
@@index([websiteId, createdAt, eventName])
|
||||
@@index([websiteId, createdAt, tag])
|
||||
@@index([websiteId, sessionId, createdAt])
|
||||
@@index([websiteId, visitId, createdAt])
|
||||
@@map("website_event")
|
||||
}
|
||||
|
||||
model EventData {
|
||||
id String @id() @map("event_data_id") @db.VarChar(36)
|
||||
websiteId String @map("website_id") @db.VarChar(36)
|
||||
websiteEventId String @map("website_event_id") @db.VarChar(36)
|
||||
dataKey String @map("data_key") @db.VarChar(500)
|
||||
stringValue String? @map("string_value") @db.VarChar(500)
|
||||
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
|
||||
dateValue DateTime? @map("date_value") @db.Timestamp(0)
|
||||
dataType Int @map("data_type") @db.UnsignedInt
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
|
||||
website Website @relation(fields: [websiteId], references: [id])
|
||||
websiteEvent WebsiteEvent @relation(fields: [websiteEventId], references: [id])
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([websiteId])
|
||||
@@index([websiteEventId])
|
||||
@@index([websiteId, createdAt])
|
||||
@@index([websiteId, createdAt, dataKey])
|
||||
@@map("event_data")
|
||||
}
|
||||
|
||||
model SessionData {
|
||||
id String @id() @map("session_data_id") @db.VarChar(36)
|
||||
websiteId String @map("website_id") @db.VarChar(36)
|
||||
sessionId String @map("session_id") @db.VarChar(36)
|
||||
dataKey String @map("data_key") @db.VarChar(500)
|
||||
stringValue String? @map("string_value") @db.VarChar(500)
|
||||
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
|
||||
dateValue DateTime? @map("date_value") @db.Timestamp(0)
|
||||
dataType Int @map("data_type") @db.UnsignedInt
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
|
||||
website Website @relation(fields: [websiteId], references: [id])
|
||||
session Session @relation(fields: [sessionId], references: [id])
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([websiteId])
|
||||
@@index([sessionId])
|
||||
@@index([sessionId, createdAt])
|
||||
@@index([websiteId, createdAt, dataKey])
|
||||
@@map("session_data")
|
||||
}
|
||||
|
||||
model Team {
|
||||
id String @id() @unique() @map("team_id") @db.VarChar(36)
|
||||
name String @db.VarChar(50)
|
||||
accessCode String? @unique @map("access_code") @db.VarChar(50)
|
||||
logoUrl String? @map("logo_url") @db.VarChar(2183)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
||||
|
||||
website Website[]
|
||||
teamUser TeamUser[]
|
||||
|
||||
@@index([accessCode])
|
||||
@@map("team")
|
||||
}
|
||||
|
||||
model TeamUser {
|
||||
id String @id() @unique() @map("team_user_id") @db.VarChar(36)
|
||||
teamId String @map("team_id") @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
role String @map("role") @db.VarChar(50)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||
|
||||
team Team @relation(fields: [teamId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
@@index([teamId])
|
||||
@@index([userId])
|
||||
@@map("team_user")
|
||||
}
|
||||
|
||||
model Report {
|
||||
id String @id() @unique() @map("report_id") @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
websiteId String @map("website_id") @db.VarChar(36)
|
||||
type String @map("type") @db.VarChar(200)
|
||||
name String @map("name") @db.VarChar(200)
|
||||
description String @map("description") @db.VarChar(500)
|
||||
parameters String @map("parameters") @db.VarChar(6000)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
|
||||
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
website Website @relation(fields: [websiteId], references: [id])
|
||||
|
||||
@@index([userId])
|
||||
@@index([websiteId])
|
||||
@@index([type])
|
||||
@@index([name])
|
||||
@@map("report")
|
||||
}
|
||||
49
db/postgresql/data-migrations/convert-utm-clid-columns.sql
Normal file
49
db/postgresql/data-migrations/convert-utm-clid-columns.sql
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
-----------------------------------------------------
|
||||
-- PostgreSQL
|
||||
-----------------------------------------------------
|
||||
UPDATE "website_event" we
|
||||
SET fbclid = LEFT(url.fbclid, 255),
|
||||
gclid = LEFT(url.gclid, 255),
|
||||
li_fat_id = LEFT(url.li_fat_id, 255),
|
||||
msclkid = LEFT(url.msclkid, 255),
|
||||
ttclid = LEFT(url.ttclid, 255),
|
||||
twclid = LEFT(url.twclid, 255),
|
||||
utm_campaign = LEFT(url.utm_campaign, 255),
|
||||
utm_content = LEFT(url.utm_content, 255),
|
||||
utm_medium = LEFT(url.utm_medium, 255),
|
||||
utm_source = LEFT(url.utm_source, 255),
|
||||
utm_term = LEFT(url.utm_term, 255)
|
||||
FROM (SELECT event_id, website_id, session_id,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)fbclid=([^&]+)', 'i'))[1] AS fbclid,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)gclid=([^&]+)', 'i'))[1] AS gclid,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)li_fat_id=([^&]+)', 'i'))[1] AS li_fat_id,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)msclkid=([^&]+)', 'i'))[1] AS msclkid,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)ttclid=([^&]+)', 'i'))[1] AS ttclid,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)twclid=([^&]+)', 'i'))[1] AS twclid,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)utm_campaign=([^&]+)', 'i'))[1] AS utm_campaign,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)utm_content=([^&]+)', 'i'))[1] AS utm_content,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)utm_medium=([^&]+)', 'i'))[1] AS utm_medium,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)utm_source=([^&]+)', 'i'))[1] AS utm_source,
|
||||
(regexp_matches(url_query, '(?:[&?]|^)utm_term=([^&]+)', 'i'))[1] AS utm_term
|
||||
FROM "website_event"
|
||||
WHERE url_query IS NOT NULL) url
|
||||
WHERE we.event_id = url.event_id
|
||||
and we.session_id = url.session_id
|
||||
and we.website_id = url.website_id;
|
||||
|
||||
-----------------------------------------------------
|
||||
-- MySQL
|
||||
-----------------------------------------------------
|
||||
UPDATE `website_event`
|
||||
SET fbclid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)fbclid=[^&]+'), '=', -1), '&', 1), 255),
|
||||
gclid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)gclid=[^&]+'), '=', -1), '&', 1), 255),
|
||||
li_fat_id = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)li_fat_id=[^&]+'), '=', -1), '&', 1), 255),
|
||||
msclkid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)msclkid=[^&]+'), '=', -1), '&', 1), 255),
|
||||
ttclid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)ttclid=[^&]+'), '=', -1), '&', 1), 255),
|
||||
twclid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)twclid=[^&]+'), '=', -1), '&', 1), 255),
|
||||
utm_campaign = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_campaign=[^&]+'), '=', -1), '&', 1), 255),
|
||||
utm_content = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_content=[^&]+'), '=', -1), '&', 1), 255),
|
||||
utm_medium = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_medium=[^&]+'), '=', -1), '&', 1), 255),
|
||||
utm_source = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_source=[^&]+'), '=', -1), '&', 1), 255),
|
||||
utm_term = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_term=[^&]+'), '=', -1), '&', 1), 255)
|
||||
WHERE url_query IS NOT NULL;
|
||||
41
db/postgresql/data-migrations/populate-revenue-table.sql
Normal file
41
db/postgresql/data-migrations/populate-revenue-table.sql
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
-----------------------------------------------------
|
||||
-- PostgreSQL
|
||||
-----------------------------------------------------
|
||||
INSERT INTO "revenue"
|
||||
SELECT gen_random_uuid() revenue_id,
|
||||
ed.website_id,
|
||||
we.session_id,
|
||||
we.event_id,
|
||||
we.event_name,
|
||||
currency.string_value currency,
|
||||
coalesce(ed.number_value, cast(ed.string_value as numeric(19,4))) revenue,
|
||||
ed.created_at
|
||||
FROM event_data ed
|
||||
JOIN website_event we
|
||||
ON we.event_id = ed.website_event_id
|
||||
JOIN (SELECT website_event_id, string_value
|
||||
FROM event_data
|
||||
WHERE data_key ilike '%currency%') currency
|
||||
ON currency.website_event_id = ed.website_event_id
|
||||
WHERE ed.data_key ilike '%revenue%';
|
||||
|
||||
-----------------------------------------------------
|
||||
-- MySQL
|
||||
-----------------------------------------------------
|
||||
INSERT INTO `revenue`
|
||||
SELECT UUID() revenue_id,
|
||||
ed.website_id,
|
||||
we.session_id,
|
||||
we.event_id,
|
||||
we.event_name,
|
||||
currency.string_value currency,
|
||||
coalesce(ed.number_value, cast(ed.string_value as decimal(19,4))) revenue,
|
||||
ed.created_at
|
||||
FROM event_data ed
|
||||
JOIN website_event we
|
||||
ON we.event_id = ed.website_event_id
|
||||
JOIN (SELECT website_event_id, string_value
|
||||
FROM event_data
|
||||
WHERE data_key like '%currency%') currency
|
||||
ON currency.website_event_id = ed.website_event_id
|
||||
WHERE ed.data_key like '%revenue%';
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "postgresql"
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
---
|
||||
services:
|
||||
umami:
|
||||
image: ghcr.io/umami-software/umami:postgresql-latest
|
||||
image: ghcr.io/umami-software/umami:latest
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
DATABASE_URL: postgresql://umami:umami@db:5432/umami
|
||||
DATABASE_TYPE: postgresql
|
||||
APP_SECRET: replace-me-with-a-random-string
|
||||
depends_on:
|
||||
db:
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
|
||||
export const config = {
|
||||
matcher: '/:path*',
|
||||
};
|
||||
|
||||
function customCollectEndpoint(req) {
|
||||
const collectEndpoint = process.env.COLLECT_API_ENDPOINT;
|
||||
|
||||
if (collectEndpoint) {
|
||||
const url = req.nextUrl.clone();
|
||||
const { pathname } = url;
|
||||
|
||||
if (pathname.endsWith(collectEndpoint)) {
|
||||
url.pathname = '/api/send';
|
||||
return NextResponse.rewrite(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function customScriptName(req) {
|
||||
const scriptName = process.env.TRACKER_SCRIPT_NAME;
|
||||
|
||||
if (scriptName) {
|
||||
const url = req.nextUrl.clone();
|
||||
const { pathname } = url;
|
||||
const names = scriptName.split(',').map(name => name.trim().replace(/^\/+/, ''));
|
||||
|
||||
if (names.find(name => pathname.endsWith(name))) {
|
||||
url.pathname = '/script.js';
|
||||
return NextResponse.rewrite(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default function middleware(req) {
|
||||
const fns = [customCollectEndpoint, customScriptName];
|
||||
|
||||
for (const fn of fns) {
|
||||
const res = fn(req);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.next();
|
||||
}
|
||||
78
docker/middleware.ts
Normal file
78
docker/middleware.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { type NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
export const config = {
|
||||
matcher: '/:path*',
|
||||
};
|
||||
|
||||
const TRACKER_PATH = '/script.js';
|
||||
const COLLECT_PATH = '/api/send';
|
||||
const LOGIN_PATH = '/login';
|
||||
|
||||
const apiHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Headers': '*',
|
||||
'Access-Control-Allow-Methods': 'GET, DELETE, POST, PUT',
|
||||
'Access-Control-Max-Age': process.env.CORS_MAX_AGE || '86400',
|
||||
'Cache-Control': 'no-cache',
|
||||
};
|
||||
|
||||
const trackerHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Cache-Control': 'public, max-age=86400, must-revalidate',
|
||||
};
|
||||
|
||||
function customCollectEndpoint(request: NextRequest) {
|
||||
const collectEndpoint = process.env.COLLECT_API_ENDPOINT;
|
||||
|
||||
if (collectEndpoint) {
|
||||
const url = request.nextUrl.clone();
|
||||
|
||||
if (url.pathname.endsWith(collectEndpoint)) {
|
||||
url.pathname = COLLECT_PATH;
|
||||
return NextResponse.rewrite(url, { headers: apiHeaders });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function customScriptName(request: NextRequest) {
|
||||
const scriptName = process.env.TRACKER_SCRIPT_NAME;
|
||||
|
||||
if (scriptName) {
|
||||
const url = request.nextUrl.clone();
|
||||
const names = scriptName.split(',').map(name => name.trim().replace(/^\/+/, ''));
|
||||
|
||||
if (names.find(name => url.pathname.endsWith(name))) {
|
||||
url.pathname = TRACKER_PATH;
|
||||
return NextResponse.rewrite(url, { headers: trackerHeaders });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function customScriptUrl(request: NextRequest) {
|
||||
const scriptUrl = process.env.TRACKER_SCRIPT_URL;
|
||||
|
||||
if (scriptUrl && request.nextUrl.pathname.endsWith(TRACKER_PATH)) {
|
||||
return NextResponse.rewrite(scriptUrl, { headers: trackerHeaders });
|
||||
}
|
||||
}
|
||||
|
||||
function disableLogin(request: NextRequest) {
|
||||
const loginDisabled = process.env.DISABLE_LOGIN;
|
||||
|
||||
if (loginDisabled && request.nextUrl.pathname.endsWith(LOGIN_PATH)) {
|
||||
return new NextResponse('Access denied', { status: 403 });
|
||||
}
|
||||
}
|
||||
|
||||
export default function middleware(req: NextRequest) {
|
||||
const fns = [customCollectEndpoint, customScriptName, customScriptUrl, disableLogin];
|
||||
|
||||
for (const fn of fns) {
|
||||
const res = fn(req);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
|
@ -4,4 +4,7 @@ export default {
|
|||
transform: {
|
||||
'^.+\\.(ts|tsx)$': 'ts-jest',
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/src/$1',
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
{
|
||||
"cs-CZ": ["label.reset", "metrics.device.tablet"],
|
||||
"de-CH": [
|
||||
"label.admin",
|
||||
"label.analytics",
|
||||
"label.desktop",
|
||||
"label.details",
|
||||
"label.domain",
|
||||
"label.laptop",
|
||||
"label.tablet",
|
||||
"label.name",
|
||||
"label.sessions",
|
||||
"label.team",
|
||||
"label.team-id",
|
||||
"label.teams"
|
||||
],
|
||||
"de-DE": [
|
||||
"label.admin",
|
||||
"label.analytics",
|
||||
"label.desktop",
|
||||
"label.details",
|
||||
"label.domain",
|
||||
"label.laptop",
|
||||
"label.tablet",
|
||||
"label.name",
|
||||
"label.sessions",
|
||||
"label.team",
|
||||
"label.team-id",
|
||||
"label.teams"
|
||||
],
|
||||
"en-GB": "*",
|
||||
"fr-FR": ["metrics.actions", "metrics.pages"],
|
||||
"lt-LT": [
|
||||
"metrics.device.desktop",
|
||||
"metrics.device.laptop",
|
||||
"metrics.referrers",
|
||||
"message.powered-by"
|
||||
],
|
||||
"mn-MN": ["label.max", "label.min", "label.os", "label.query", "label.url", "label.urls"],
|
||||
"nb-NO": ["label.administrator", "label.dashboard"],
|
||||
"nl-NL": [
|
||||
"label.analytics",
|
||||
"label.browsers",
|
||||
"label.laptop",
|
||||
"label.tablet",
|
||||
"label.team",
|
||||
"label.team-id",
|
||||
"label.teams",
|
||||
"label.website-id",
|
||||
"label.websites"
|
||||
],
|
||||
"it-IT": [
|
||||
"label.password",
|
||||
"label.reset",
|
||||
"message.powered-by",
|
||||
"metrics.device.desktop",
|
||||
"metrics.device.tablet",
|
||||
"metrics.filter.raw"
|
||||
],
|
||||
"pt-PT": ["label.websites", "metrics.device.desktop", "metrics.device.tablet"]
|
||||
}
|
||||
3
next-env.d.ts
vendored
3
next-env.d.ts
vendored
|
|
@ -1,5 +1,6 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference path="./.next/types/routes.d.ts" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
|
|
|||
220
next.config.js
220
next.config.js
|
|
@ -1,220 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
require('dotenv').config();
|
||||
const pkg = require('./package.json');
|
||||
|
||||
const TRACKER_SCRIPT = '/script.js';
|
||||
|
||||
const basePath = process.env.BASE_PATH;
|
||||
const collectApiEndpoint = process.env.COLLECT_API_ENDPOINT;
|
||||
const cloudMode = process.env.CLOUD_MODE;
|
||||
const cloudUrl = process.env.CLOUD_URL;
|
||||
const corsMaxAge = process.env.CORS_MAX_AGE;
|
||||
const defaultLocale = process.env.DEFAULT_LOCALE;
|
||||
const disableLogin = process.env.DISABLE_LOGIN;
|
||||
const disableUI = process.env.DISABLE_UI;
|
||||
const forceSSL = process.env.FORCE_SSL;
|
||||
const frameAncestors = process.env.ALLOWED_FRAME_URLS;
|
||||
const privateMode = process.env.PRIVATE_MODE;
|
||||
const trackerScriptName = process.env.TRACKER_SCRIPT_NAME;
|
||||
const trackerScriptURL = process.env.TRACKER_SCRIPT_URL;
|
||||
|
||||
const contentSecurityPolicy = [
|
||||
`default-src 'self'`,
|
||||
`img-src * data:`,
|
||||
`script-src 'self' 'unsafe-eval' 'unsafe-inline'`,
|
||||
`style-src 'self' 'unsafe-inline'`,
|
||||
`connect-src 'self' api.umami.is cloud.umami.is`,
|
||||
`frame-ancestors 'self' ${frameAncestors}`,
|
||||
];
|
||||
|
||||
const defaultHeaders = [
|
||||
{
|
||||
key: 'X-DNS-Prefetch-Control',
|
||||
value: 'on',
|
||||
},
|
||||
{
|
||||
key: 'Content-Security-Policy',
|
||||
value: contentSecurityPolicy
|
||||
.join(';')
|
||||
.replace(/\s{2,}/g, ' ')
|
||||
.trim(),
|
||||
},
|
||||
];
|
||||
|
||||
if (forceSSL) {
|
||||
defaultHeaders.push({
|
||||
key: 'Strict-Transport-Security',
|
||||
value: 'max-age=63072000; includeSubDomains; preload',
|
||||
});
|
||||
}
|
||||
|
||||
const trackerHeaders = [
|
||||
{
|
||||
key: 'Access-Control-Allow-Origin',
|
||||
value: '*',
|
||||
},
|
||||
{
|
||||
key: 'Cache-Control',
|
||||
value: 'public, max-age=86400, must-revalidate',
|
||||
},
|
||||
];
|
||||
|
||||
const headers = [
|
||||
{
|
||||
source: '/api/:path*',
|
||||
headers: [
|
||||
{ key: 'Access-Control-Allow-Origin', value: '*' },
|
||||
{ key: 'Access-Control-Allow-Headers', value: '*' },
|
||||
{ key: 'Access-Control-Allow-Methods', value: 'GET, DELETE, POST, PUT' },
|
||||
{ key: 'Access-Control-Max-Age', value: corsMaxAge || '86400' },
|
||||
],
|
||||
},
|
||||
{
|
||||
source: '/:path*',
|
||||
headers: defaultHeaders,
|
||||
},
|
||||
{
|
||||
source: TRACKER_SCRIPT,
|
||||
headers: trackerHeaders,
|
||||
},
|
||||
];
|
||||
|
||||
const rewrites = [];
|
||||
|
||||
if (trackerScriptURL) {
|
||||
rewrites.push({
|
||||
source: TRACKER_SCRIPT,
|
||||
destination: trackerScriptURL,
|
||||
});
|
||||
}
|
||||
|
||||
if (collectApiEndpoint) {
|
||||
rewrites.push({
|
||||
source: collectApiEndpoint,
|
||||
destination: '/api/send',
|
||||
});
|
||||
}
|
||||
|
||||
const redirects = [
|
||||
{
|
||||
source: '/settings',
|
||||
destination: '/settings/websites',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: '/teams/:id',
|
||||
destination: '/teams/:id/dashboard',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: '/teams/:id/settings',
|
||||
destination: '/teams/:id/settings/team',
|
||||
permanent: true,
|
||||
},
|
||||
];
|
||||
|
||||
// Adding rewrites + headers for all alternative tracker script names.
|
||||
if (trackerScriptName) {
|
||||
const names = trackerScriptName?.split(',').map(name => name.trim());
|
||||
|
||||
if (names) {
|
||||
names.forEach(name => {
|
||||
const normalizedSource = `/${name.replace(/^\/+/, '')}`;
|
||||
|
||||
rewrites.push({
|
||||
source: normalizedSource,
|
||||
destination: TRACKER_SCRIPT,
|
||||
});
|
||||
|
||||
headers.push({
|
||||
source: normalizedSource,
|
||||
headers: trackerHeaders,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (cloudMode && cloudUrl) {
|
||||
redirects.push({
|
||||
source: '/settings/:path*',
|
||||
destination: `${cloudUrl}/settings/:path*`,
|
||||
permanent: false,
|
||||
});
|
||||
|
||||
redirects.push({
|
||||
source: '/teams/:id/settings/:path*',
|
||||
destination: `${cloudUrl}/teams/:id/settings/:path*`,
|
||||
permanent: false,
|
||||
});
|
||||
|
||||
if (disableLogin) {
|
||||
redirects.push({
|
||||
source: '/login',
|
||||
destination: cloudUrl,
|
||||
permanent: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const config = {
|
||||
reactStrictMode: false,
|
||||
env: {
|
||||
basePath,
|
||||
cloudMode,
|
||||
cloudUrl,
|
||||
configUrl: '/config',
|
||||
currentVersion: pkg.version,
|
||||
defaultLocale,
|
||||
disableLogin,
|
||||
disableUI,
|
||||
privateMode,
|
||||
},
|
||||
basePath,
|
||||
output: 'standalone',
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
typescript: {
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
experimental: {
|
||||
turbo: {
|
||||
rules: {
|
||||
'*.svg': {
|
||||
loaders: ['@svgr/webpack'],
|
||||
as: '*.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
webpack(config) {
|
||||
config.module.rules.push({
|
||||
test: /\.svg$/,
|
||||
issuer: /\.(js|ts)x?$/,
|
||||
use: ['@svgr/webpack'],
|
||||
});
|
||||
return config;
|
||||
},
|
||||
async headers() {
|
||||
return headers;
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
...rewrites,
|
||||
{
|
||||
source: '/telemetry.js',
|
||||
destination: '/api/scripts/telemetry',
|
||||
},
|
||||
{
|
||||
source: '/teams/:teamId/:path((?!settings).*)*',
|
||||
destination: '/:path*',
|
||||
},
|
||||
];
|
||||
},
|
||||
async redirects() {
|
||||
return [...redirects];
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
202
next.config.ts
Normal file
202
next.config.ts
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
import 'dotenv/config';
|
||||
import pkg from './package.json' with { type: 'json' };
|
||||
|
||||
const TRACKER_SCRIPT = '/script.js';
|
||||
|
||||
const basePath = process.env.BASE_PATH || '';
|
||||
const cloudMode = process.env.CLOUD_MODE || '';
|
||||
const cloudUrl = process.env.CLOUD_URL || '';
|
||||
const collectApiEndpoint = process.env.COLLECT_API_ENDPOINT || '';
|
||||
const corsMaxAge = process.env.CORS_MAX_AGE || '';
|
||||
const defaultLocale = process.env.DEFAULT_LOCALE || '';
|
||||
const forceSSL = process.env.FORCE_SSL || '';
|
||||
const frameAncestors = process.env.ALLOWED_FRAME_URLS || '';
|
||||
const trackerScriptName = process.env.TRACKER_SCRIPT_NAME || '';
|
||||
const trackerScriptURL = process.env.TRACKER_SCRIPT_URL || '';
|
||||
|
||||
const contentSecurityPolicy = `
|
||||
default-src 'self';
|
||||
img-src 'self' https: data:;
|
||||
script-src 'self' 'unsafe-eval' 'unsafe-inline';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
connect-src 'self' https:;
|
||||
frame-ancestors 'self' ${frameAncestors};
|
||||
`;
|
||||
|
||||
const defaultHeaders = [
|
||||
{
|
||||
key: 'X-DNS-Prefetch-Control',
|
||||
value: 'on',
|
||||
},
|
||||
{
|
||||
key: 'Content-Security-Policy',
|
||||
value: contentSecurityPolicy.replace(/\s{2,}/g, ' ').trim(),
|
||||
},
|
||||
];
|
||||
|
||||
if (forceSSL) {
|
||||
defaultHeaders.push({
|
||||
key: 'Strict-Transport-Security',
|
||||
value: 'max-age=63072000; includeSubDomains; preload',
|
||||
});
|
||||
}
|
||||
|
||||
const trackerHeaders = [
|
||||
{
|
||||
key: 'Access-Control-Allow-Origin',
|
||||
value: '*',
|
||||
},
|
||||
{
|
||||
key: 'Cache-Control',
|
||||
value: 'public, max-age=86400, must-revalidate',
|
||||
},
|
||||
];
|
||||
|
||||
const apiHeaders = [
|
||||
{
|
||||
key: 'Access-Control-Allow-Origin',
|
||||
value: '*',
|
||||
},
|
||||
{
|
||||
key: 'Access-Control-Allow-Headers',
|
||||
value: '*',
|
||||
},
|
||||
{
|
||||
key: 'Access-Control-Allow-Methods',
|
||||
value: 'GET, DELETE, POST, PUT',
|
||||
},
|
||||
{
|
||||
key: 'Access-Control-Max-Age',
|
||||
value: corsMaxAge || '86400',
|
||||
},
|
||||
{
|
||||
key: 'Cache-Control',
|
||||
value: 'no-cache',
|
||||
},
|
||||
];
|
||||
|
||||
const headers = [
|
||||
{
|
||||
source: '/api/:path*',
|
||||
headers: apiHeaders,
|
||||
},
|
||||
{
|
||||
source: '/:path*',
|
||||
headers: defaultHeaders,
|
||||
},
|
||||
{
|
||||
source: TRACKER_SCRIPT,
|
||||
headers: trackerHeaders,
|
||||
},
|
||||
];
|
||||
|
||||
const rewrites = [];
|
||||
|
||||
if (trackerScriptURL) {
|
||||
rewrites.push({
|
||||
source: TRACKER_SCRIPT,
|
||||
destination: trackerScriptURL,
|
||||
});
|
||||
}
|
||||
|
||||
if (collectApiEndpoint) {
|
||||
headers.push({
|
||||
source: collectApiEndpoint,
|
||||
headers: apiHeaders,
|
||||
});
|
||||
|
||||
rewrites.push({
|
||||
source: collectApiEndpoint,
|
||||
destination: '/api/send',
|
||||
});
|
||||
}
|
||||
|
||||
const redirects = [
|
||||
{
|
||||
source: '/settings',
|
||||
destination: '/settings/preferences',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/teams/:id',
|
||||
destination: '/teams/:id/websites',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/teams/:id/settings',
|
||||
destination: '/teams/:id/settings/preferences',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/admin',
|
||||
destination: '/admin/users',
|
||||
permanent: false,
|
||||
},
|
||||
];
|
||||
|
||||
// Adding rewrites + headers for all alternative tracker script names.
|
||||
if (trackerScriptName) {
|
||||
const names = trackerScriptName?.split(',').map(name => name.trim());
|
||||
|
||||
if (names) {
|
||||
names.forEach(name => {
|
||||
const normalizedSource = `/${name.replace(/^\/+/, '')}`;
|
||||
|
||||
rewrites.push({
|
||||
source: normalizedSource,
|
||||
destination: TRACKER_SCRIPT,
|
||||
});
|
||||
|
||||
headers.push({
|
||||
source: normalizedSource,
|
||||
headers: trackerHeaders,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (cloudMode) {
|
||||
rewrites.push({
|
||||
source: '/script.js',
|
||||
destination: 'https://cloud.umami.is/script.js',
|
||||
});
|
||||
}
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
export default {
|
||||
reactStrictMode: false,
|
||||
env: {
|
||||
basePath,
|
||||
cloudMode,
|
||||
cloudUrl,
|
||||
currentVersion: pkg.version,
|
||||
defaultLocale,
|
||||
},
|
||||
basePath,
|
||||
output: 'standalone',
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
typescript: {
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
async headers() {
|
||||
return headers;
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
...rewrites,
|
||||
{
|
||||
source: '/telemetry.js',
|
||||
destination: '/api/scripts/telemetry',
|
||||
},
|
||||
{
|
||||
source: '/teams/:teamId/:path*',
|
||||
destination: '/:path*',
|
||||
},
|
||||
];
|
||||
},
|
||||
async redirects() {
|
||||
return [...redirects];
|
||||
},
|
||||
};
|
||||
|
|
@ -1,24 +1,10 @@
|
|||
{
|
||||
"name": "@umami/components",
|
||||
"version": "0.1.0",
|
||||
"version": "0.130.0",
|
||||
"description": "Umami React components.",
|
||||
"author": "Mike Cao <mike@mikecao.com>",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "./index.js",
|
||||
"types": "./index.d.ts",
|
||||
"peerDependencies": {
|
||||
"@tanstack/react-query": "^4.33.0",
|
||||
"classnames": "^2.3.1",
|
||||
"colord": "^2.9.2",
|
||||
"date-fns-tz": "^1.1.4",
|
||||
"immer": "^9.0.12",
|
||||
"moment-timezone": "^0.5.35",
|
||||
"next": "^13.4.0",
|
||||
"next-basics": "^0.36.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-intl": "^5.24.7",
|
||||
"zustand": "^4.3.8"
|
||||
}
|
||||
"types": "./index.d.ts"
|
||||
}
|
||||
|
|
|
|||
173
package.json
173
package.json
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "umami",
|
||||
"version": "2.16.1",
|
||||
"description": "A simple, fast, privacy-focused alternative to Google Analytics.",
|
||||
"version": "3.0.2",
|
||||
"description": "A modern, privacy-focused alternative to Google Analytics.",
|
||||
"author": "Umami Software, Inc. <hello@umami.is>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://umami.is",
|
||||
|
|
@ -9,20 +9,23 @@
|
|||
"type": "git",
|
||||
"url": "https://github.com/umami-software/umami.git"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3000 --turbo",
|
||||
"dev": "next dev -p 3001 --turbo",
|
||||
"build": "npm-run-all check-env build-db check-db build-tracker build-geo build-app",
|
||||
"start": "next start",
|
||||
"build-docker": "npm-run-all build-db build-tracker build-geo build-app",
|
||||
"start-docker": "npm-run-all check-db update-tracker start-server",
|
||||
"start-env": "node scripts/start-env.js",
|
||||
"start-server": "node server.js",
|
||||
"build-app": "next build",
|
||||
"build-components": "rollup -c rollup.components.config.mjs",
|
||||
"build-tracker": "rollup -c rollup.tracker.config.mjs",
|
||||
"build-db": "npm-run-all copy-db-files build-db-client",
|
||||
"build-lang": "npm-run-all format-lang compile-lang clean-lang download-country-names download-language-names",
|
||||
"build-app": "next build --turbo",
|
||||
"build-icons": "svgr ./src/assets --out-dir src/components/svg --typescript",
|
||||
"build-components": "tsup",
|
||||
"build-tracker": "rollup -c rollup.tracker.config.js",
|
||||
"build-prisma-client": "node scripts/build-prisma-client.js",
|
||||
"build-lang": "npm-run-all format-lang compile-lang download-country-names download-language-names clean-lang",
|
||||
"build-geo": "node scripts/build-geo.js",
|
||||
"build-db": "npm-run-all build-db-client build-prisma-client",
|
||||
"build-db-schema": "prisma db pull",
|
||||
"build-db-client": "prisma generate",
|
||||
"update-tracker": "node scripts/update-tracker.js",
|
||||
|
|
@ -35,50 +38,46 @@
|
|||
"generate-lang": "npm-run-all extract-messages merge-messages",
|
||||
"format-lang": "node scripts/format-lang.js",
|
||||
"compile-lang": "formatjs compile-folder --ast build/messages public/intl/messages",
|
||||
"clean-lang": "prettier --write ./public/intl/messages/*.json",
|
||||
"check-lang": "node scripts/check-lang.js",
|
||||
"clean-lang": "prettier --write ./public/intl/**/*.json",
|
||||
"download-country-names": "node scripts/download-country-names.js",
|
||||
"download-language-names": "node scripts/download-language-names.js",
|
||||
"change-password": "node scripts/change-password.js",
|
||||
"lint": "next lint --quiet",
|
||||
"prepare": "node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install",
|
||||
"postbuild": "node scripts/postbuild.js",
|
||||
"test": "jest",
|
||||
"cypress-open": "cypress open cypress run",
|
||||
"cypress-run": "cypress run cypress run"
|
||||
"cypress-run": "cypress run cypress run",
|
||||
"seed-data": "tsx scripts/seed-data.ts",
|
||||
"lint": "biome lint .",
|
||||
"format": "biome format --write .",
|
||||
"check": "biome check --write"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.{js,jsx,ts,tsx}": [
|
||||
"prettier --write",
|
||||
"eslint"
|
||||
],
|
||||
"**/*.css": [
|
||||
"stylelint --fix",
|
||||
"prettier --write"
|
||||
],
|
||||
"**/*.json": [
|
||||
"prettier --write"
|
||||
"**/*.{js,jsx,ts,tsx,json,css}": [
|
||||
"biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"
|
||||
]
|
||||
},
|
||||
"cacheDirectories": [
|
||||
".next/cache"
|
||||
],
|
||||
"dependencies": {
|
||||
"@clickhouse/client": "^1.10.1",
|
||||
"@clickhouse/client": "^1.12.0",
|
||||
"@date-fns/utc": "^1.2.0",
|
||||
"@dicebear/collection": "^9.2.1",
|
||||
"@dicebear/core": "^9.2.1",
|
||||
"@fontsource/inter": "^4.5.15",
|
||||
"@dicebear/collection": "^9.2.3",
|
||||
"@dicebear/core": "^9.2.3",
|
||||
"@fontsource/inter": "^5.2.8",
|
||||
"@hello-pangea/dnd": "^17.0.0",
|
||||
"@prisma/client": "6.1.0",
|
||||
"@prisma/extension-read-replicas": "^0.4.0",
|
||||
"@react-spring/web": "^9.7.3",
|
||||
"@tanstack/react-query": "^5.28.6",
|
||||
"@umami/prisma-client": "^0.14.0",
|
||||
"@umami/redis-client": "^0.26.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"chalk": "^4.1.1",
|
||||
"chart.js": "^4.4.2",
|
||||
"@prisma/adapter-pg": "^6.18.0",
|
||||
"@prisma/client": "^6.18.0",
|
||||
"@prisma/extension-read-replicas": "^0.4.1",
|
||||
"@react-spring/web": "^10.0.3",
|
||||
"@svgr/cli": "^8.1.0",
|
||||
"@tanstack/react-query": "^5.90.11",
|
||||
"@umami/react-zen": "^0.211.0",
|
||||
"@umami/redis-client": "^0.29.0",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"chalk": "^5.6.2",
|
||||
"chart.js": "^4.5.1",
|
||||
"chartjs-adapter-date-fns": "^3.0.0",
|
||||
"classnames": "^2.3.1",
|
||||
"colord": "^2.9.2",
|
||||
|
|
@ -86,100 +85,90 @@
|
|||
"cross-spawn": "^7.0.3",
|
||||
"date-fns": "^2.23.0",
|
||||
"date-fns-tz": "^1.1.4",
|
||||
"debug": "^4.3.4",
|
||||
"debug": "^4.4.3",
|
||||
"del": "^6.0.0",
|
||||
"detect-browser": "^5.2.0",
|
||||
"dotenv": "^10.0.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"fs-extra": "^10.0.1",
|
||||
"immer": "^9.0.12",
|
||||
"ipaddr.js": "^2.0.1",
|
||||
"dotenv": "^17.2.3",
|
||||
"esbuild": "^0.25.11",
|
||||
"fs-extra": "^11.3.2",
|
||||
"immer": "^10.2.0",
|
||||
"ipaddr.js": "^2.3.0",
|
||||
"is-ci": "^3.0.1",
|
||||
"is-docker": "^3.0.0",
|
||||
"is-localhost-ip": "^1.4.0",
|
||||
"isbot": "^5.1.16",
|
||||
"is-localhost-ip": "^2.0.0",
|
||||
"isbot": "^5.1.31",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"jszip": "^3.10.1",
|
||||
"kafkajs": "^2.1.0",
|
||||
"maxmind": "^4.3.24",
|
||||
"md5": "^2.3.0",
|
||||
"next": "15.0.4",
|
||||
"lucide-react": "^0.543.0",
|
||||
"maxmind": "^5.0.0",
|
||||
"next": "^15.5.7",
|
||||
"node-fetch": "^3.2.8",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prisma": "6.1.0",
|
||||
"pure-rand": "^6.1.0",
|
||||
"react": "^19.0.0",
|
||||
"react-basics": "^0.126.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"papaparse": "^5.5.3",
|
||||
"pg": "^8.16.3",
|
||||
"prisma": "^6.18.0",
|
||||
"pure-rand": "^7.0.1",
|
||||
"react": "^19.2.1",
|
||||
"react-dom": "^19.2.1",
|
||||
"react-error-boundary": "^4.0.4",
|
||||
"react-intl": "^6.5.5",
|
||||
"react-intl": "^7.1.14",
|
||||
"react-simple-maps": "^2.3.0",
|
||||
"react-use-measure": "^2.0.4",
|
||||
"react-window": "^1.8.6",
|
||||
"request-ip": "^3.3.0",
|
||||
"semver": "^7.5.4",
|
||||
"semver": "^7.7.3",
|
||||
"serialize-error": "^12.0.0",
|
||||
"thenby": "^1.3.4",
|
||||
"uuid": "^9.0.0",
|
||||
"zod": "^3.24.1",
|
||||
"zustand": "^4.5.5"
|
||||
"ua-parser-js": "^2.0.6",
|
||||
"uuid": "^11.1.0",
|
||||
"zod": "^4.1.13",
|
||||
"zustand": "^5.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.3.8",
|
||||
"@formatjs/cli": "^4.2.29",
|
||||
"@netlify/plugin-nextjs": "^5.8.1",
|
||||
"@netlify/plugin-nextjs": "^5.15.1",
|
||||
"@rollup/plugin-alias": "^5.0.0",
|
||||
"@rollup/plugin-commonjs": "^25.0.4",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.2.0",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@svgr/rollup": "^8.1.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@types/cypress": "^1.1.3",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^22.13.4",
|
||||
"@types/react": "^19.0.8",
|
||||
"@types/react-dom": "^19.0.2",
|
||||
"@types/react-intl": "^3.0.0",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@rollup/plugin-typescript": "^12.3.0",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/node": "^24.9.2",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"@types/react-window": "^1.8.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||
"@typescript-eslint/parser": "^6.7.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"babel-plugin-react-compiler": "19.1.0-rc.2",
|
||||
"cross-env": "^10.1.0",
|
||||
"cypress": "^13.6.6",
|
||||
"esbuild": "^0.25.0",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint-config-next": "^14.0.4",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-plugin-css-modules": "^2.12.0",
|
||||
"eslint-plugin-cypress": "^2.15.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-jest": "^27.9.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"extract-react-intl-messages": "^4.1.1",
|
||||
"husky": "^8.0.3",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^29.7.0",
|
||||
"lint-staged": "^14.0.1",
|
||||
"postcss": "^8.4.31",
|
||||
"lint-staged": "^16.2.6",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-flexbugs-fixes": "^5.0.2",
|
||||
"postcss-import": "^15.1.0",
|
||||
"postcss-preset-env": "7.8.3",
|
||||
"postcss-rtlcss": "^4.0.1",
|
||||
"prettier": "^2.6.2",
|
||||
"prompts": "2.4.2",
|
||||
"rollup": "^3.28.0",
|
||||
"rollup": "^4.52.5",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
"rollup-plugin-delete": "^2.0.0",
|
||||
"rollup-plugin-dts": "^5.3.1",
|
||||
"rollup-plugin-esbuild": "^5.0.0",
|
||||
"rollup-plugin-node-externals": "^6.1.1",
|
||||
"rollup-plugin-delete": "^3.0.1",
|
||||
"rollup-plugin-dts": "^6.3.0",
|
||||
"rollup-plugin-node-externals": "^8.1.1",
|
||||
"rollup-plugin-peer-deps-external": "^2.2.4",
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"stylelint": "^15.10.1",
|
||||
"stylelint-config-css-modules": "^4.4.0",
|
||||
"stylelint-config-css-modules": "^4.5.1",
|
||||
"stylelint-config-prettier": "^9.0.3",
|
||||
"stylelint-config-recommended": "^14.0.0",
|
||||
"tar": "^6.1.2",
|
||||
"ts-jest": "^29.1.2",
|
||||
"ts-jest": "^29.4.6",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.5.3"
|
||||
"tsup": "^8.5.0",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15102
pnpm-lock.yaml
generated
Normal file
15102
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load diff
10
pnpm-workspace.yaml
Normal file
10
pnpm-workspace.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
packages:
|
||||
- '**'
|
||||
ignoredBuiltDependencies:
|
||||
- cypress
|
||||
- esbuild
|
||||
- sharp
|
||||
onlyBuiltDependencies:
|
||||
- '@prisma/client'
|
||||
- '@prisma/engines'
|
||||
- prisma
|
||||
50
podman/README.md
Normal file
50
podman/README.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# How to deploy umami on podman
|
||||
|
||||
|
||||
## How to use
|
||||
|
||||
1. Rename `env.sample` to `.env`
|
||||
2. Edit `.env` file. At the minimum set the passwords.
|
||||
3. Start umami by running `podman-compose up -d`.
|
||||
|
||||
If you need to stop umami, you can do so by running `podman-compose down`.
|
||||
|
||||
|
||||
### Install systemd service (optional)
|
||||
|
||||
If you want to install a systemd service to run umami, you can use the provided
|
||||
systemd service.
|
||||
|
||||
Edit `umami.service` and change these two variables:
|
||||
|
||||
|
||||
WorkingDirectory=/opt/apps/umami
|
||||
EnvironmentFile=/opt/apps/umami/.env
|
||||
|
||||
`WorkingDirectory` should be changed to the path in which `podman-compose.yml`
|
||||
is located.
|
||||
|
||||
`EnvironmentFile` should be changed to the path in which your `.env`file is
|
||||
located.
|
||||
|
||||
You can run the script `install-systemd-user-service` to install the systemd
|
||||
service under the current user.
|
||||
|
||||
|
||||
./install-systemd-user-service
|
||||
|
||||
Note: this script will enable the service and also start it. So it will assume
|
||||
that umami is not currently running. If you started it previously, bring it
|
||||
down using:
|
||||
|
||||
podman-compose down
|
||||
|
||||
|
||||
|
||||
## Compatibility
|
||||
|
||||
These files should be compatible with podman 4.3+.
|
||||
|
||||
I have tested this on Debian GNU/Linux 12 (bookworm) and with the podman that
|
||||
is distributed with the official Debian stable mirrors (podman
|
||||
v4.3.1+ds1-8+deb12u1, podman-compose v1.0.3-3).
|
||||
16
podman/env.sample
Normal file
16
podman/env.sample
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Rename this file to .env and modify the values
|
||||
#
|
||||
# Connection string for Umami’s database.
|
||||
# If you use the bundled DB container, "db" is the hostname.
|
||||
DATABASE_URL=postgresql://umami:replace-me-with-a-random-string@db:5432/umami
|
||||
|
||||
# Database type (e.g. postgresql)
|
||||
DATABASE_TYPE=postgresql
|
||||
|
||||
# A secret string used by Umami (replace with a strong random string)
|
||||
APP_SECRET=replace-me-with-a-random-string
|
||||
|
||||
# Postgres container defaults.
|
||||
POSTGRES_DB=umami
|
||||
POSTGRES_USER=umami
|
||||
POSTGRES_PASSWORD=replace-me-with-a-random-string
|
||||
10
podman/install-systemd-user-service
Executable file
10
podman/install-systemd-user-service
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
service_name="umami"
|
||||
mkdir -p ~/.config/systemd/user
|
||||
cp $service_name.service ~/.config/systemd/user
|
||||
|
||||
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable $service_name.service
|
||||
systemctl --user start $service_name.service
|
||||
41
podman/podman-compose.yml
Normal file
41
podman/podman-compose.yml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
umami:
|
||||
container_name: umami
|
||||
image: ghcr.io/umami-software/umami:postgresql-latest
|
||||
ports:
|
||||
- "127.0.0.1:3000:3000"
|
||||
environment:
|
||||
DATABASE_URL: ${DATABASE_URL}
|
||||
DATABASE_TYPE: ${DATABASE_TYPE}
|
||||
APP_SECRET: ${APP_SECRET}
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
init: true
|
||||
restart: always
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/heartbeat || exit 1"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
db:
|
||||
container_name: umami-db
|
||||
image: docker.io/library/postgres:15-alpine
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
volumes:
|
||||
- umami-db-data:/var/lib/postgresql/data:Z
|
||||
restart: always
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
volumes:
|
||||
umami-db-data:
|
||||
14
podman/umami.service
Normal file
14
podman/umami.service
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=Umami Container Stack via Podman-Compose
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/apps/umami
|
||||
EnvironmentFile=/opt/apps/umami/.env
|
||||
ExecStart=/usr/bin/podman-compose -f podman-compose.yml up -d
|
||||
ExecStop=/usr/bin/podman-compose -f podman-compose.yml down
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = {
|
||||
export default {
|
||||
plugins: [
|
||||
'postcss-flexbugs-fixes',
|
||||
[
|
||||
|
|
|
|||
8
prisma.config.ts
Normal file
8
prisma.config.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import 'dotenv/config';
|
||||
import { defineConfig, env } from 'prisma/config';
|
||||
|
||||
export default defineConfig({
|
||||
datasource: {
|
||||
url: env('DATABASE_URL'),
|
||||
},
|
||||
});
|
||||
13
prisma/migrations/08_add_utm_clid/migration.sql
Normal file
13
prisma/migrations/08_add_utm_clid/migration.sql
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "website_event"
|
||||
ADD COLUMN "fbclid" VARCHAR(255),
|
||||
ADD COLUMN "gclid" VARCHAR(255),
|
||||
ADD COLUMN "li_fat_id" VARCHAR(255),
|
||||
ADD COLUMN "msclkid" VARCHAR(255),
|
||||
ADD COLUMN "ttclid" VARCHAR(255),
|
||||
ADD COLUMN "twclid" VARCHAR(255),
|
||||
ADD COLUMN "utm_campaign" VARCHAR(255),
|
||||
ADD COLUMN "utm_content" VARCHAR(255),
|
||||
ADD COLUMN "utm_medium" VARCHAR(255),
|
||||
ADD COLUMN "utm_source" VARCHAR(255),
|
||||
ADD COLUMN "utm_term" VARCHAR(255);
|
||||
25
prisma/migrations/09_update_hostname_region/migration.sql
Normal file
25
prisma/migrations/09_update_hostname_region/migration.sql
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "website_event" ADD COLUMN "hostname" VARCHAR(100);
|
||||
|
||||
-- DataMigration
|
||||
UPDATE "website_event" w
|
||||
SET hostname = s.hostname
|
||||
FROM "session" s
|
||||
WHERE s.website_id = w.website_id
|
||||
and s.session_id = w.session_id;
|
||||
|
||||
-- DropIndex
|
||||
DROP INDEX IF EXISTS "session_website_id_created_at_hostname_idx";
|
||||
DROP INDEX IF EXISTS "session_website_id_created_at_subdivision1_idx";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "session" RENAME COLUMN "subdivision1" TO "region";
|
||||
ALTER TABLE "session" DROP COLUMN "subdivision2";
|
||||
ALTER TABLE "session" DROP COLUMN "hostname";
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "website_event_website_id_created_at_hostname_idx" ON "website_event"("website_id", "created_at", "hostname");
|
||||
CREATE INDEX "session_website_id_created_at_region_idx" ON "session"("website_id", "created_at", "region");
|
||||
|
||||
|
||||
|
||||
5
prisma/migrations/10_add_distinct_id/migration.sql
Normal file
5
prisma/migrations/10_add_distinct_id/migration.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "session" ADD COLUMN "distinct_id" VARCHAR(50);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "session_data" ADD COLUMN "distinct_id" VARCHAR(50);
|
||||
18
prisma/migrations/11_add_segment/migration.sql
Normal file
18
prisma/migrations/11_add_segment/migration.sql
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "segment" (
|
||||
"segment_id" UUID NOT NULL,
|
||||
"website_id" UUID NOT NULL,
|
||||
"type" VARCHAR(200) NOT NULL,
|
||||
"name" VARCHAR(200) NOT NULL,
|
||||
"parameters" JSONB NOT NULL,
|
||||
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMPTZ(6),
|
||||
|
||||
CONSTRAINT "segment_pkey" PRIMARY KEY ("segment_id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "segment_segment_id_key" ON "segment"("segment_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "segment_website_id_idx" ON "segment"("website_id");
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "report"
|
||||
ALTER COLUMN "parameters" SET DATA TYPE JSONB USING parameters::JSONB;
|
||||
28
prisma/migrations/13_add_revenue/migration.sql
Normal file
28
prisma/migrations/13_add_revenue/migration.sql
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "revenue" (
|
||||
"revenue_id" UUID NOT NULL,
|
||||
"website_id" UUID NOT NULL,
|
||||
"session_id" UUID NOT NULL,
|
||||
"event_id" UUID NOT NULL,
|
||||
"event_name" VARCHAR(50) NOT NULL,
|
||||
"currency" VARCHAR(100) NOT NULL,
|
||||
"revenue" DECIMAL(19,4),
|
||||
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "revenue_pkey" PRIMARY KEY ("revenue_id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "revenue_revenue_id_key" ON "revenue"("revenue_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "revenue_website_id_idx" ON "revenue"("website_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "revenue_session_id_idx" ON "revenue"("session_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "revenue_website_id_created_at_idx" ON "revenue"("website_id", "created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "revenue_website_id_session_id_created_at_idx" ON "revenue"("website_id", "session_id", "created_at");
|
||||
119
prisma/migrations/14_add_link_and_pixel/migration.sql
Normal file
119
prisma/migrations/14_add_link_and_pixel/migration.sql
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "report" ALTER COLUMN "type" SET DATA TYPE VARCHAR(50);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "revenue" ALTER COLUMN "currency" SET DATA TYPE VARCHAR(10);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "segment" ALTER COLUMN "type" SET DATA TYPE VARCHAR(50);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "link" (
|
||||
"link_id" UUID NOT NULL,
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
"url" VARCHAR(500) NOT NULL,
|
||||
"slug" VARCHAR(100) NOT NULL,
|
||||
"user_id" UUID,
|
||||
"team_id" UUID,
|
||||
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMPTZ(6),
|
||||
"deleted_at" TIMESTAMPTZ(6),
|
||||
|
||||
CONSTRAINT "link_pkey" PRIMARY KEY ("link_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "pixel" (
|
||||
"pixel_id" UUID NOT NULL,
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
"slug" VARCHAR(100) NOT NULL,
|
||||
"user_id" UUID,
|
||||
"team_id" UUID,
|
||||
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMPTZ(6),
|
||||
"deleted_at" TIMESTAMPTZ(6),
|
||||
|
||||
CONSTRAINT "pixel_pkey" PRIMARY KEY ("pixel_id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "link_link_id_key" ON "link"("link_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "link_slug_key" ON "link"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "link_slug_idx" ON "link"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "link_user_id_idx" ON "link"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "link_team_id_idx" ON "link"("team_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "link_created_at_idx" ON "link"("created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "pixel_pixel_id_key" ON "pixel"("pixel_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "pixel_slug_key" ON "pixel"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "pixel_slug_idx" ON "pixel"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "pixel_user_id_idx" ON "pixel"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "pixel_team_id_idx" ON "pixel"("team_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "pixel_created_at_idx" ON "pixel"("created_at");
|
||||
|
||||
-- DataMigration Funnel
|
||||
DELETE FROM "report" WHERE type = 'funnel' and jsonb_array_length(parameters->'steps') = 1;
|
||||
UPDATE "report" SET parameters = parameters - 'websiteId' - 'dateRange' - 'urls' WHERE type = 'funnel';
|
||||
|
||||
UPDATE "report"
|
||||
SET parameters = jsonb_set(
|
||||
parameters,
|
||||
'{steps}',
|
||||
(
|
||||
SELECT jsonb_agg(
|
||||
CASE
|
||||
WHEN step->>'type' = 'url'
|
||||
THEN jsonb_set(step, '{type}', '"path"')
|
||||
ELSE step
|
||||
END
|
||||
)
|
||||
FROM jsonb_array_elements(parameters->'steps') step
|
||||
)
|
||||
)
|
||||
WHERE type = 'funnel'
|
||||
and parameters @> '{"steps":[{"type":"url"}]}';
|
||||
|
||||
-- DataMigration Goals
|
||||
UPDATE "report" SET type = 'goal' WHERE type = 'goals';
|
||||
|
||||
INSERT INTO "report" (report_id, user_id, website_id, type, name, description, parameters, created_at, updated_at)
|
||||
SELECT gen_random_uuid(),
|
||||
user_id,
|
||||
website_id,
|
||||
'goal',
|
||||
concat(name, ' - ', elem ->> 'value'),
|
||||
description,
|
||||
jsonb_build_object(
|
||||
'type', CASE WHEN elem ->> 'type' = 'url' THEN 'path'
|
||||
ELSE elem ->> 'type' END,
|
||||
'value', elem ->> 'value'
|
||||
) AS parameters,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM "report"
|
||||
CROSS JOIN LATERAL jsonb_array_elements(parameters -> 'goals') elem
|
||||
WHERE type = 'goal'
|
||||
and elem ->> 'type' IN ('event', 'url');
|
||||
|
||||
DELETE FROM "report" WHERE type = 'goal' and parameters ? 'goals';
|
||||
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = ["native"]
|
||||
provider = "prisma-client"
|
||||
output = "../src/generated/prisma"
|
||||
engineType = "client"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
|
|
@ -20,43 +21,44 @@ model User {
|
|||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||
|
||||
websiteUser Website[] @relation("user")
|
||||
websiteCreateUser Website[] @relation("createUser")
|
||||
teamUser TeamUser[]
|
||||
report Report[]
|
||||
websites Website[] @relation("user")
|
||||
createdBy Website[] @relation("createUser")
|
||||
links Link[] @relation("user")
|
||||
pixels Pixel[] @relation("user")
|
||||
teams TeamUser[]
|
||||
reports Report[]
|
||||
|
||||
@@map("user")
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @unique @map("session_id") @db.Uuid
|
||||
websiteId String @map("website_id") @db.Uuid
|
||||
hostname String? @db.VarChar(100)
|
||||
browser String? @db.VarChar(20)
|
||||
os String? @db.VarChar(20)
|
||||
device String? @db.VarChar(20)
|
||||
screen String? @db.VarChar(11)
|
||||
language String? @db.VarChar(35)
|
||||
country String? @db.Char(2)
|
||||
subdivision1 String? @db.VarChar(20)
|
||||
subdivision2 String? @db.VarChar(50)
|
||||
city String? @db.VarChar(50)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
id String @id @unique @map("session_id") @db.Uuid
|
||||
websiteId String @map("website_id") @db.Uuid
|
||||
browser String? @db.VarChar(20)
|
||||
os String? @db.VarChar(20)
|
||||
device String? @db.VarChar(20)
|
||||
screen String? @db.VarChar(11)
|
||||
language String? @db.VarChar(35)
|
||||
country String? @db.Char(2)
|
||||
region String? @db.VarChar(20)
|
||||
city String? @db.VarChar(50)
|
||||
distinctId String? @map("distinct_id") @db.VarChar(50)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
websiteEvent WebsiteEvent[]
|
||||
sessionData SessionData[]
|
||||
websiteEvents WebsiteEvent[]
|
||||
sessionData SessionData[]
|
||||
revenue Revenue[]
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([websiteId])
|
||||
@@index([websiteId, createdAt])
|
||||
@@index([websiteId, createdAt, hostname])
|
||||
@@index([websiteId, createdAt, browser])
|
||||
@@index([websiteId, createdAt, os])
|
||||
@@index([websiteId, createdAt, device])
|
||||
@@index([websiteId, createdAt, screen])
|
||||
@@index([websiteId, createdAt, language])
|
||||
@@index([websiteId, createdAt, country])
|
||||
@@index([websiteId, createdAt, subdivision1])
|
||||
@@index([websiteId, createdAt, region])
|
||||
@@index([websiteId, createdAt, city])
|
||||
@@map("session")
|
||||
}
|
||||
|
|
@ -78,7 +80,9 @@ model Website {
|
|||
createUser User? @relation("createUser", fields: [createdBy], references: [id])
|
||||
team Team? @relation(fields: [teamId], references: [id])
|
||||
eventData EventData[]
|
||||
report Report[]
|
||||
reports Report[]
|
||||
revenue Revenue[]
|
||||
segments Segment[]
|
||||
sessionData SessionData[]
|
||||
|
||||
@@index([userId])
|
||||
|
|
@ -97,13 +101,25 @@ model WebsiteEvent {
|
|||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
urlPath String @map("url_path") @db.VarChar(500)
|
||||
urlQuery String? @map("url_query") @db.VarChar(500)
|
||||
utmSource String? @map("utm_source") @db.VarChar(255)
|
||||
utmMedium String? @map("utm_medium") @db.VarChar(255)
|
||||
utmCampaign String? @map("utm_campaign") @db.VarChar(255)
|
||||
utmContent String? @map("utm_content") @db.VarChar(255)
|
||||
utmTerm String? @map("utm_term") @db.VarChar(255)
|
||||
referrerPath String? @map("referrer_path") @db.VarChar(500)
|
||||
referrerQuery String? @map("referrer_query") @db.VarChar(500)
|
||||
referrerDomain String? @map("referrer_domain") @db.VarChar(500)
|
||||
pageTitle String? @map("page_title") @db.VarChar(500)
|
||||
gclid String? @db.VarChar(255)
|
||||
fbclid String? @db.VarChar(255)
|
||||
msclkid String? @db.VarChar(255)
|
||||
ttclid String? @db.VarChar(255)
|
||||
lifatid String? @map("li_fat_id") @db.VarChar(255)
|
||||
twclid String? @db.VarChar(255)
|
||||
eventType Int @default(1) @map("event_type") @db.Integer
|
||||
eventName String? @map("event_name") @db.VarChar(50)
|
||||
tag String? @db.VarChar(50)
|
||||
hostname String? @db.VarChar(100)
|
||||
|
||||
eventData EventData[]
|
||||
session Session @relation(fields: [sessionId], references: [id])
|
||||
|
|
@ -121,6 +137,7 @@ model WebsiteEvent {
|
|||
@@index([websiteId, createdAt, tag])
|
||||
@@index([websiteId, sessionId, createdAt])
|
||||
@@index([websiteId, visitId, createdAt])
|
||||
@@index([websiteId, createdAt, hostname])
|
||||
@@map("website_event")
|
||||
}
|
||||
|
||||
|
|
@ -155,6 +172,7 @@ model SessionData {
|
|||
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
|
||||
dateValue DateTime? @map("date_value") @db.Timestamptz(6)
|
||||
dataType Int @map("data_type") @db.Integer
|
||||
distinctId String? @map("distinct_id") @db.VarChar(50)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
website Website @relation(fields: [websiteId], references: [id])
|
||||
|
|
@ -177,8 +195,10 @@ model Team {
|
|||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||
|
||||
website Website[]
|
||||
teamUser TeamUser[]
|
||||
websites Website[]
|
||||
members TeamUser[]
|
||||
links Link[]
|
||||
pixels Pixel[]
|
||||
|
||||
@@index([accessCode])
|
||||
@@map("team")
|
||||
|
|
@ -188,7 +208,7 @@ model TeamUser {
|
|||
id String @id() @unique() @map("team_user_id") @db.Uuid
|
||||
teamId String @map("team_id") @db.Uuid
|
||||
userId String @map("user_id") @db.Uuid
|
||||
role String @map("role") @db.VarChar(50)
|
||||
role String @db.VarChar(50)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
|
|
@ -204,10 +224,10 @@ model Report {
|
|||
id String @id() @unique() @map("report_id") @db.Uuid
|
||||
userId String @map("user_id") @db.Uuid
|
||||
websiteId String @map("website_id") @db.Uuid
|
||||
type String @map("type") @db.VarChar(200)
|
||||
name String @map("name") @db.VarChar(200)
|
||||
description String @map("description") @db.VarChar(500)
|
||||
parameters String @map("parameters") @db.VarChar(6000)
|
||||
type String @db.VarChar(50)
|
||||
name String @db.VarChar(200)
|
||||
description String @db.VarChar(500)
|
||||
parameters Json
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
|
|
@ -220,3 +240,79 @@ model Report {
|
|||
@@index([name])
|
||||
@@map("report")
|
||||
}
|
||||
|
||||
model Segment {
|
||||
id String @id() @unique() @map("segment_id") @db.Uuid
|
||||
websiteId String @map("website_id") @db.Uuid
|
||||
type String @db.VarChar(50)
|
||||
name String @db.VarChar(200)
|
||||
parameters Json
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
website Website @relation(fields: [websiteId], references: [id])
|
||||
|
||||
@@index([websiteId])
|
||||
@@map("segment")
|
||||
}
|
||||
|
||||
model Revenue {
|
||||
id String @id() @unique() @map("revenue_id") @db.Uuid
|
||||
websiteId String @map("website_id") @db.Uuid
|
||||
sessionId String @map("session_id") @db.Uuid
|
||||
eventId String @map("event_id") @db.Uuid
|
||||
eventName String @map("event_name") @db.VarChar(50)
|
||||
currency String @db.VarChar(10)
|
||||
revenue Decimal? @db.Decimal(19, 4)
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
website Website @relation(fields: [websiteId], references: [id])
|
||||
session Session @relation(fields: [sessionId], references: [id])
|
||||
|
||||
@@index([websiteId])
|
||||
@@index([sessionId])
|
||||
@@index([websiteId, createdAt])
|
||||
@@index([websiteId, sessionId, createdAt])
|
||||
@@map("revenue")
|
||||
}
|
||||
|
||||
model Link {
|
||||
id String @id() @unique() @map("link_id") @db.Uuid
|
||||
name String @db.VarChar(100)
|
||||
url String @db.VarChar(500)
|
||||
slug String @unique() @db.VarChar(100)
|
||||
userId String? @map("user_id") @db.Uuid
|
||||
teamId String? @map("team_id") @db.Uuid
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||
|
||||
user User? @relation("user", fields: [userId], references: [id])
|
||||
team Team? @relation(fields: [teamId], references: [id])
|
||||
|
||||
@@index([slug])
|
||||
@@index([userId])
|
||||
@@index([teamId])
|
||||
@@index([createdAt])
|
||||
@@map("link")
|
||||
}
|
||||
|
||||
model Pixel {
|
||||
id String @id() @unique() @map("pixel_id") @db.Uuid
|
||||
name String @db.VarChar(100)
|
||||
slug String @unique() @db.VarChar(100)
|
||||
userId String? @map("user_id") @db.Uuid
|
||||
teamId String? @map("team_id") @db.Uuid
|
||||
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||
|
||||
user User? @relation("user", fields: [userId], references: [id])
|
||||
team Team? @relation(fields: [teamId], references: [id])
|
||||
|
||||
@@index([slug])
|
||||
@@index([userId])
|
||||
@@index([teamId])
|
||||
@@index([createdAt])
|
||||
@@map("pixel")
|
||||
}
|
||||
|
|
@ -7202,7 +7202,7 @@
|
|||
]
|
||||
]
|
||||
},
|
||||
"id": "-99"
|
||||
"id": "XKX"
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2.3 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -97,6 +97,7 @@
|
|||
"CN": "\u041a\u0438\u0442\u0430\u0439",
|
||||
"CC": "\u041a\u043e\u043a\u043e\u0441\u043e\u0432\u0438 \u043e\u0441\u0442\u0440\u043e\u0432\u0438 (\u043e\u0441\u0442\u0440\u043e\u0432\u0438 \u041a\u0438\u0439\u043b\u0438\u043d\u0433)",
|
||||
"CO": "\u041a\u043e\u043b\u0443\u043c\u0431\u0438\u044f",
|
||||
"XK": "\u041a\u043e\u0441\u043e\u0432\u043e",
|
||||
"KM": "\u041a\u043e\u043c\u043e\u0440\u0441\u043a\u0438 \u043e\u0441\u0442\u0440\u043e\u0432\u0438",
|
||||
"CG": "\u041a\u043e\u043d\u0433\u043e (\u0411\u0440\u0430\u0437\u0430\u0432\u0438\u043b)",
|
||||
"CD": "\u041a\u043e\u043d\u0433\u043e (\u041a\u0438\u043d\u0448\u0430\u0441\u0430)",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -119,6 +119,7 @@
|
|||
"CO": "Kolumbija",
|
||||
"KM": "Komori",
|
||||
"CG": "Kongo",
|
||||
"XK": "Kosovo",
|
||||
"CR": "Kostarika",
|
||||
"CU": "Kuba",
|
||||
"CK": "Kukova ostrva",
|
||||
|
|
|
|||
|
|
@ -1 +1,252 @@
|
|||
{"AF":"Afganistan","AL":"Alb\u00e0nia","DE":"Alemanya","DZ":"Alg\u00e8ria","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Ant\u00e0rtida","AG":"Antigua i Barbuda","SA":"Ar\u00e0bia Saudita","AR":"Argentina","AM":"Arm\u00e8nia","AW":"Aruba","AU":"Austr\u00e0lia","AT":"\u00c0ustria","AZ":"Azerbaidjan","BS":"Bahames","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BY":"Belar\u00fas","BE":"B\u00e8lgica","BZ":"Belize","BJ":"Ben\u00edn","BM":"Bermudes","BT":"Bhutan","BO":"Bol\u00edvia","BA":"B\u00f2snia i Hercegovina","BW":"Botswana","BV":"Bouvet","BR":"Brasil","BN":"Brunei","BG":"Bulg\u00e0ria","BF":"Burkina Faso","BI":"Burundi","KH":"Cambodja","CM":"Camerun","CA":"Canad\u00e0","CV":"Cap Verd","BQ":"Carib Neerland\u00e8s","VA":"Ciutat del Vatic\u00e0","CO":"Col\u00f2mbia","KM":"Comores","CG":"Congo - Brazzaville","CD":"Congo - Kinshasa","KP":"Corea del Nord","KR":"Corea del Sud","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","HR":"Cro\u00e0cia","CU":"Cuba","CW":"Cura\u00e7ao","DK":"Dinamarca","DJ":"Djibouti","DM":"Dominica","EG":"Egipte","SV":"El Salvador","AE":"Emirats \u00c0rabs Units","EC":"Equador","ER":"Eritrea","SK":"Eslov\u00e0quia","SI":"Eslov\u00e8nia","ES":"Espanya","US":"Estats Units","EE":"Est\u00f2nia","SZ":"eSwatini","ET":"Eti\u00f2pia","FJ":"Fiji","PH":"Filipines","FI":"Finl\u00e0ndia","FR":"Fran\u00e7a","GA":"Gabon","GM":"G\u00e0mbia","GE":"Ge\u00f2rgia","GH":"Ghana","GI":"Gibraltar","GR":"Gr\u00e8cia","GD":"Grenada","GL":"Groenl\u00e0ndia","GP":"Guadeloupe","GF":"Guaiana Francesa","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea Bissau","GQ":"Guinea Equatorial","GY":"Guyana","HT":"Hait\u00ed","HN":"Hondures","HK":"Hong Kong (RAE Xina)","HU":"Hongria","YE":"Iemen","CX":"Illa Christmas","RE":"Illa de la Reuni\u00f3","IM":"Illa de Man","HM":"Illa Heard i Illes McDonald","AX":"Illes \u00c5land","KY":"Illes Caiman","CC":"Illes Cocos","CK":"Illes Cook","FO":"Illes F\u00e8roe","GS":"Illes Ge\u00f2rgia del Sud i Sandwich del Sud","FK":"Illes Malvines","MP":"Illes Mariannes del Nord","MH":"Illes Marshall","UM":"Illes Perif\u00e8riques Menors dels EUA","PN":"Illes Pitcairn","SB":"Illes Salom\u00f3","TC":"Illes Turks i Caicos","VG":"Illes Verges Brit\u00e0niques","VI":"Illes Verges Nord-americanes","IN":"\u00cdndia","ID":"Indon\u00e8sia","IR":"Iran","IQ":"Iraq","IE":"Irlanda","IS":"Isl\u00e0ndia","IL":"Israel","IT":"It\u00e0lia","JM":"Jamaica","JP":"Jap\u00f3","JE":"Jersey","JO":"Jord\u00e0nia","KZ":"Kazakhstan","KE":"Kenya","KG":"Kirguizistan","KI":"Kiribati","KW":"Kuwait","LA":"Laos","LS":"Lesotho","LV":"Let\u00f2nia","LB":"L\u00edban","LR":"Lib\u00e8ria","LY":"L\u00edbia","LI":"Liechtenstein","LT":"Litu\u00e0nia","LU":"Luxemburg","MO":"Macau (RAE Xina)","MK":"Maced\u00f2nia del Nord","MG":"Madagascar","MY":"Mal\u00e0isia","MW":"Malawi","MV":"Maldives","ML":"Mali","MT":"Malta","MA":"Marroc","MQ":"Martinica","MU":"Maurici","MR":"Maurit\u00e0nia","YT":"Mayotte","MX":"M\u00e8xic","FM":"Micron\u00e8sia","MZ":"Mo\u00e7ambic","MD":"Mold\u00e0via","MC":"M\u00f2naco","MN":"Mong\u00f2lia","ME":"Montenegro","MS":"Montserrat","MM":"Myanmar (Birm\u00e0nia)","NA":"Nam\u00edbia","NR":"Nauru","NP":"Nepal","NI":"Nicaragua","NE":"N\u00edger","NG":"Nig\u00e8ria","NU":"Niue","NF":"Norfolk","NO":"Noruega","NC":"Nova Caled\u00f2nia","NZ":"Nova Zelanda","OM":"Oman","NL":"Pa\u00efsos Baixos","PK":"Pakistan","PW":"Palau","PA":"Panam\u00e0","PG":"Papua Nova Guinea","PY":"Paraguai","PE":"Per\u00fa","PF":"Polin\u00e8sia Francesa","PL":"Pol\u00f2nia","PT":"Portugal","PR":"Puerto Rico","QA":"Qatar","GB":"Regne Unit","CF":"Rep\u00fablica Centreafricana","ZA":"Rep\u00fablica de Sud-\u00e0frica","DO":"Rep\u00fablica Dominicana","RO":"Romania","RW":"Ruanda","RU":"R\u00fassia","EH":"S\u00e0hara Occidental","BL":"Saint Barth\u00e9lemy","KN":"Saint Christopher i Nevis","SH":"Saint Helena","LC":"Saint Lucia","MF":"Saint Martin","VC":"Saint Vincent i les Grenadines","PM":"Saint-Pierre-et-Miquelon","WS":"Samoa","AS":"Samoa Nord-americana","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 i Pr\u00edncipe","SN":"Senegal","RS":"S\u00e8rbia","SC":"Seychelles","SL":"Sierra Leone","SG":"Singapur","SX":"Sint Maarten","SY":"S\u00edria","SO":"Som\u00e0lia","LK":"Sri Lanka","SD":"Sudan","SS":"Sudan del Sud","SE":"Su\u00e8cia","CH":"Su\u00efssa","SR":"Surinam","SJ":"Svalbard i Jan Mayen","TJ":"Tadjikistan","TH":"Tail\u00e0ndia","TW":"Taiwan","TZ":"Tanz\u00e0nia","IO":"Territori Brit\u00e0nic de l\u2019Oce\u00e0 \u00cdndic","TF":"Territoris Australs Francesos","PS":"Territoris palestins","TL":"Timor Oriental","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinitat i Tobago","TN":"Tun\u00edsia","TM":"Turkmenistan","TR":"Turquia","TV":"Tuvalu","TD":"Txad","CZ":"Tx\u00e8quia","UA":"Ucra\u00efna","UG":"Uganda","UY":"Uruguai","UZ":"Uzbekistan","VU":"Vanuatu","VE":"Vene\u00e7uela","VN":"Vietnam","WF":"Wallis i Futuna","CL":"Xile","CN":"Xina","CY":"Xipre","ZM":"Z\u00e0mbia","ZW":"Zimb\u00e0bue"}
|
||||
{
|
||||
"AF": "Afganistan",
|
||||
"AL": "Alb\u00e0nia",
|
||||
"DE": "Alemanya",
|
||||
"DZ": "Alg\u00e8ria",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Ant\u00e0rtida",
|
||||
"AG": "Antigua i Barbuda",
|
||||
"SA": "Ar\u00e0bia Saudita",
|
||||
"AR": "Argentina",
|
||||
"AM": "Arm\u00e8nia",
|
||||
"AW": "Aruba",
|
||||
"AU": "Austr\u00e0lia",
|
||||
"AT": "\u00c0ustria",
|
||||
"AZ": "Azerbaidjan",
|
||||
"BS": "Bahames",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesh",
|
||||
"BB": "Barbados",
|
||||
"BY": "Belar\u00fas",
|
||||
"BE": "B\u00e8lgica",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Ben\u00edn",
|
||||
"BM": "Bermudes",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bol\u00edvia",
|
||||
"BA": "B\u00f2snia i Hercegovina",
|
||||
"BW": "Botswana",
|
||||
"BV": "Bouvet",
|
||||
"BR": "Brasil",
|
||||
"BN": "Brunei",
|
||||
"BG": "Bulg\u00e0ria",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"KH": "Cambodja",
|
||||
"CM": "Camerun",
|
||||
"CA": "Canad\u00e0",
|
||||
"CV": "Cap Verd",
|
||||
"BQ": "Carib Neerland\u00e8s",
|
||||
"VA": "Ciutat del Vatic\u00e0",
|
||||
"CO": "Col\u00f2mbia",
|
||||
"KM": "Comores",
|
||||
"CG": "Congo - Brazzaville",
|
||||
"CD": "Congo - Kinshasa",
|
||||
"KP": "Corea del Nord",
|
||||
"KR": "Corea del Sud",
|
||||
"CR": "Costa Rica",
|
||||
"CI": "C\u00f4te d\u2019Ivoire",
|
||||
"HR": "Cro\u00e0cia",
|
||||
"CU": "Cuba",
|
||||
"CW": "Cura\u00e7ao",
|
||||
"DK": "Dinamarca",
|
||||
"DJ": "Djibouti",
|
||||
"DM": "Dominica",
|
||||
"EG": "Egipte",
|
||||
"SV": "El Salvador",
|
||||
"AE": "Emirats \u00c0rabs Units",
|
||||
"EC": "Equador",
|
||||
"ER": "Eritrea",
|
||||
"SK": "Eslov\u00e0quia",
|
||||
"SI": "Eslov\u00e8nia",
|
||||
"ES": "Espanya",
|
||||
"US": "Estats Units",
|
||||
"EE": "Est\u00f2nia",
|
||||
"SZ": "eSwatini",
|
||||
"ET": "Eti\u00f2pia",
|
||||
"FJ": "Fiji",
|
||||
"PH": "Filipines",
|
||||
"FI": "Finl\u00e0ndia",
|
||||
"FR": "Fran\u00e7a",
|
||||
"GA": "Gabon",
|
||||
"GM": "G\u00e0mbia",
|
||||
"GE": "Ge\u00f2rgia",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GR": "Gr\u00e8cia",
|
||||
"GD": "Grenada",
|
||||
"GL": "Groenl\u00e0ndia",
|
||||
"GP": "Guadeloupe",
|
||||
"GF": "Guaiana Francesa",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea Bissau",
|
||||
"GQ": "Guinea Equatorial",
|
||||
"GY": "Guyana",
|
||||
"HT": "Hait\u00ed",
|
||||
"HN": "Hondures",
|
||||
"HK": "Hong Kong (RAE Xina)",
|
||||
"HU": "Hongria",
|
||||
"YE": "Iemen",
|
||||
"CX": "Illa Christmas",
|
||||
"RE": "Illa de la Reuni\u00f3",
|
||||
"IM": "Illa de Man",
|
||||
"HM": "Illa Heard i Illes McDonald",
|
||||
"AX": "Illes \u00c5land",
|
||||
"KY": "Illes Caiman",
|
||||
"CC": "Illes Cocos",
|
||||
"CK": "Illes Cook",
|
||||
"FO": "Illes F\u00e8roe",
|
||||
"GS": "Illes Ge\u00f2rgia del Sud i Sandwich del Sud",
|
||||
"FK": "Illes Malvines",
|
||||
"MP": "Illes Mariannes del Nord",
|
||||
"MH": "Illes Marshall",
|
||||
"UM": "Illes Perif\u00e8riques Menors dels EUA",
|
||||
"PN": "Illes Pitcairn",
|
||||
"SB": "Illes Salom\u00f3",
|
||||
"TC": "Illes Turks i Caicos",
|
||||
"VG": "Illes Verges Brit\u00e0niques",
|
||||
"VI": "Illes Verges Nord-americanes",
|
||||
"IN": "\u00cdndia",
|
||||
"ID": "Indon\u00e8sia",
|
||||
"IR": "Iran",
|
||||
"IQ": "Iraq",
|
||||
"IE": "Irlanda",
|
||||
"IS": "Isl\u00e0ndia",
|
||||
"IL": "Israel",
|
||||
"IT": "It\u00e0lia",
|
||||
"JM": "Jamaica",
|
||||
"JP": "Jap\u00f3",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jord\u00e0nia",
|
||||
"KZ": "Kazakhstan",
|
||||
"KE": "Kenya",
|
||||
"KG": "Kirguizistan",
|
||||
"KI": "Kiribati",
|
||||
"XK": "Kosovo",
|
||||
"KW": "Kuwait",
|
||||
"LA": "Laos",
|
||||
"LS": "Lesotho",
|
||||
"LV": "Let\u00f2nia",
|
||||
"LB": "L\u00edban",
|
||||
"LR": "Lib\u00e8ria",
|
||||
"LY": "L\u00edbia",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Litu\u00e0nia",
|
||||
"LU": "Luxemburg",
|
||||
"MO": "Macau (RAE Xina)",
|
||||
"MK": "Maced\u00f2nia del Nord",
|
||||
"MG": "Madagascar",
|
||||
"MY": "Mal\u00e0isia",
|
||||
"MW": "Malawi",
|
||||
"MV": "Maldives",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MA": "Marroc",
|
||||
"MQ": "Martinica",
|
||||
"MU": "Maurici",
|
||||
"MR": "Maurit\u00e0nia",
|
||||
"YT": "Mayotte",
|
||||
"MX": "M\u00e8xic",
|
||||
"FM": "Micron\u00e8sia",
|
||||
"MZ": "Mo\u00e7ambic",
|
||||
"MD": "Mold\u00e0via",
|
||||
"MC": "M\u00f2naco",
|
||||
"MN": "Mong\u00f2lia",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MM": "Myanmar (Birm\u00e0nia)",
|
||||
"NA": "Nam\u00edbia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NI": "Nicaragua",
|
||||
"NE": "N\u00edger",
|
||||
"NG": "Nig\u00e8ria",
|
||||
"NU": "Niue",
|
||||
"NF": "Norfolk",
|
||||
"NO": "Noruega",
|
||||
"NC": "Nova Caled\u00f2nia",
|
||||
"NZ": "Nova Zelanda",
|
||||
"OM": "Oman",
|
||||
"NL": "Pa\u00efsos Baixos",
|
||||
"PK": "Pakistan",
|
||||
"PW": "Palau",
|
||||
"PA": "Panam\u00e0",
|
||||
"PG": "Papua Nova Guinea",
|
||||
"PY": "Paraguai",
|
||||
"PE": "Per\u00fa",
|
||||
"PF": "Polin\u00e8sia Francesa",
|
||||
"PL": "Pol\u00f2nia",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"QA": "Qatar",
|
||||
"GB": "Regne Unit",
|
||||
"CF": "Rep\u00fablica Centreafricana",
|
||||
"ZA": "Rep\u00fablica de Sud-\u00e0frica",
|
||||
"DO": "Rep\u00fablica Dominicana",
|
||||
"RO": "Romania",
|
||||
"RW": "Ruanda",
|
||||
"RU": "R\u00fassia",
|
||||
"EH": "S\u00e0hara Occidental",
|
||||
"BL": "Saint Barth\u00e9lemy",
|
||||
"KN": "Saint Christopher i Nevis",
|
||||
"SH": "Saint Helena",
|
||||
"LC": "Saint Lucia",
|
||||
"MF": "Saint Martin",
|
||||
"VC": "Saint Vincent i les Grenadines",
|
||||
"PM": "Saint-Pierre-et-Miquelon",
|
||||
"WS": "Samoa",
|
||||
"AS": "Samoa Nord-americana",
|
||||
"SM": "San Marino",
|
||||
"ST": "S\u00e3o Tom\u00e9 i Pr\u00edncipe",
|
||||
"SN": "Senegal",
|
||||
"RS": "S\u00e8rbia",
|
||||
"SC": "Seychelles",
|
||||
"SL": "Sierra Leone",
|
||||
"SG": "Singapur",
|
||||
"SX": "Sint Maarten",
|
||||
"SY": "S\u00edria",
|
||||
"SO": "Som\u00e0lia",
|
||||
"LK": "Sri Lanka",
|
||||
"SD": "Sudan",
|
||||
"SS": "Sudan del Sud",
|
||||
"SE": "Su\u00e8cia",
|
||||
"CH": "Su\u00efssa",
|
||||
"SR": "Surinam",
|
||||
"SJ": "Svalbard i Jan Mayen",
|
||||
"TJ": "Tadjikistan",
|
||||
"TH": "Tail\u00e0ndia",
|
||||
"TW": "Taiwan",
|
||||
"TZ": "Tanz\u00e0nia",
|
||||
"IO": "Territori Brit\u00e0nic de l\u2019Oce\u00e0 \u00cdndic",
|
||||
"TF": "Territoris Australs Francesos",
|
||||
"PS": "Territoris palestins",
|
||||
"TL": "Timor Oriental",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinitat i Tobago",
|
||||
"TN": "Tun\u00edsia",
|
||||
"TM": "Turkmenistan",
|
||||
"TR": "Turquia",
|
||||
"TV": "Tuvalu",
|
||||
"TD": "Txad",
|
||||
"CZ": "Tx\u00e8quia",
|
||||
"UA": "Ucra\u00efna",
|
||||
"UG": "Uganda",
|
||||
"UY": "Uruguai",
|
||||
"UZ": "Uzbekistan",
|
||||
"VU": "Vanuatu",
|
||||
"VE": "Vene\u00e7uela",
|
||||
"VN": "Vietnam",
|
||||
"WF": "Wallis i Futuna",
|
||||
"CL": "Xile",
|
||||
"CN": "Xina",
|
||||
"CY": "Xipre",
|
||||
"ZM": "Z\u00e0mbia",
|
||||
"ZW": "Zimb\u00e0bue"
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1,252 @@
|
|||
{"AF":"Afghanistan","AL":"Albanien","DZ":"Algeriet","AS":"Amerikansk Samoa","UM":"Amerikanske overs\u00f8iske \u00f8er","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarktis","AG":"Antigua og Barbuda","AR":"Argentina","AM":"Armenien","AW":"Aruba","AZ":"Aserbajdsjan","AU":"Australien","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BE":"Belgien","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivia","BA":"Bosnien-Hercegovina","BW":"Botswana","BV":"Bouvet\u00f8en","BR":"Brasilien","BN":"Brunei","BG":"Bulgarien","BF":"Burkina Faso","BI":"Burundi","KH":"Cambodja","CM":"Cameroun","CA":"Canada","KY":"Cayman\u00f8erne","CL":"Chile","CC":"Cocos\u00f8erne","CO":"Colombia","KM":"Comorerne","CG":"Congo-Brazzaville","CD":"Congo-Kinshasa","CK":"Cook\u00f8erne","CR":"Costa Rica","CU":"Cuba","CW":"Cura\u00e7ao","CY":"Cypern","DK":"Danmark","VI":"De Amerikanske Jomfru\u00f8er","VG":"De Britiske Jomfru\u00f8er","AE":"De Forenede Arabiske Emirater","TF":"De Franske Besiddelser i Det Sydlige Indiske Ocean og Antarktis","PS":"De pal\u00e6stinensiske omr\u00e5der","BQ":"De tidligere Nederlandske Antiller","CF":"Den Centralafrikanske Republik","DO":"Den Dominikanske Republik","IO":"Det Britiske Territorium i Det Indiske Ocean","DJ":"Djibouti","DM":"Dominica","EC":"Ecuador","EG":"Egypten","SV":"El Salvador","CI":"Elfenbenskysten","ER":"Eritrea","EE":"Estland","SZ":"Eswatini","ET":"Etiopien","FK":"Falklands\u00f8erne","FJ":"Fiji","PH":"Filippinerne","FI":"Finland","FR":"Frankrig","GF":"Fransk Guyana","PF":"Fransk Polynesien","FO":"F\u00e6r\u00f8erne","GA":"Gabon","GM":"Gambia","GE":"Georgien","GH":"Ghana","GI":"Gibraltar","GD":"Grenada","GR":"Gr\u00e6kenland","GL":"Gr\u00f8nland","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard Island og McDonald Islands","NL":"Holland","HN":"Honduras","BY":"Hviderusland","IN":"Indien","ID":"Indonesien","IQ":"Irak","IR":"Iran","IE":"Irland","IS":"Island","IM":"Isle of Man","IL":"Israel","IT":"Italien","JM":"Jamaica","JP":"Japan","JE":"Jersey","JO":"Jordan","CX":"Jule\u00f8en","CV":"Kap Verde","KZ":"Kasakhstan","KE":"Kenya","CN":"Kina","KG":"Kirgisistan","KI":"Kiribati","HR":"Kroatien","KW":"Kuwait","LA":"Laos","LS":"Lesotho","LV":"Letland","LB":"Libanon","LR":"Liberia","LY":"Libyen","LI":"Liechtenstein","LT":"Litauen","LU":"Luxembourg","MG":"Madagaskar","MW":"Malawi","MY":"Malaysia","MV":"Maldiverne","ML":"Mali","MT":"Malta","MA":"Marokko","MH":"Marshall\u00f8erne","MQ":"Martinique","MR":"Mauretanien","MU":"Mauritius","YT":"Mayotte","MX":"Mexico","FM":"Mikronesien","MD":"Moldova","MC":"Monaco","MN":"Mongoliet","ME":"Montenegro","MS":"Montserrat","MZ":"Mozambique","MM":"Myanmar (Burma)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NZ":"New Zealand","NI":"Nicaragua","NE":"Niger","NG":"Nigeria","NU":"Niue","KP":"Nordkorea","MK":"Nordmakedonien","MP":"Nordmarianerne","NF":"Norfolk Island","NO":"Norge","NC":"Ny Kaledonien","OM":"Oman","PK":"Pakistan","PW":"Palau","PA":"Panama","PG":"Papua Ny Guinea","PY":"Paraguay","PE":"Peru","PN":"Pitcairn","PL":"Polen","PT":"Portugal","PR":"Puerto Rico","QA":"Qatar","RE":"R\u00e9union","RO":"Rum\u00e6nien","RU":"Rusland","RW":"Rwanda","BL":"Saint Barth\u00e9lemy","KN":"Saint Kitts og Nevis","LC":"Saint Lucia","MF":"Saint Martin","PM":"Saint Pierre og Miquelon","VC":"Saint Vincent og Grenadinerne","SB":"Salomon\u00f8erne","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 og Pr\u00edncipe","HK":"SAR Hongkong","MO":"SAR Macao","SA":"Saudi-Arabien","CH":"Schweiz","SN":"Senegal","RS":"Serbien","SC":"Seychellerne","SL":"Sierra Leone","SG":"Singapore","SX":"Sint Maarten","SK":"Slovakiet","SI":"Slovenien","SO":"Somalia","GS":"South Georgia og De Sydlige Sandwich\u00f8er","ES":"Spanien","LK":"Sri Lanka","SH":"St. Helena","GB":"Storbritannien","SD":"Sudan","SR":"Surinam","SJ":"Svalbard og Jan Mayen","SE":"Sverige","ZA":"Sydafrika","KR":"Sydkorea","SS":"Sydsudan","SY":"Syrien","TJ":"Tadsjikistan","TW":"Taiwan","TZ":"Tanzania","TD":"Tchad","TH":"Thailand","TL":"Timor-Leste","CZ":"Tjekkiet","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad og Tobago","TN":"Tunesien","TM":"Turkmenistan","TC":"Turks- og Caicos\u00f8erne","TV":"Tuvalu","TR":"Tyrkiet","DE":"Tyskland","UG":"Uganda","UA":"Ukraine","HU":"Ungarn","UY":"Uruguay","US":"USA","UZ":"Usbekistan","VU":"Vanuatu","VA":"Vatikanstaten","VE":"Venezuela","EH":"Vestsahara","VN":"Vietnam","WF":"Wallis og Futuna","YE":"Yemen","ZM":"Zambia","ZW":"Zimbabwe","GQ":"\u00c6kvatorialguinea","AT":"\u00d8strig","AX":"\u00c5land"}
|
||||
{
|
||||
"AF": "Afghanistan",
|
||||
"AL": "Albanien",
|
||||
"DZ": "Algeriet",
|
||||
"AS": "Amerikansk Samoa",
|
||||
"UM": "Amerikanske overs\u00f8iske \u00f8er",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Antarktis",
|
||||
"AG": "Antigua og Barbuda",
|
||||
"AR": "Argentina",
|
||||
"AM": "Armenien",
|
||||
"AW": "Aruba",
|
||||
"AZ": "Aserbajdsjan",
|
||||
"AU": "Australien",
|
||||
"BS": "Bahamas",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesh",
|
||||
"BB": "Barbados",
|
||||
"BE": "Belgien",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Benin",
|
||||
"BM": "Bermuda",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bolivia",
|
||||
"BA": "Bosnien-Hercegovina",
|
||||
"BW": "Botswana",
|
||||
"BV": "Bouvet\u00f8en",
|
||||
"BR": "Brasilien",
|
||||
"BN": "Brunei",
|
||||
"BG": "Bulgarien",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"KH": "Cambodja",
|
||||
"CM": "Cameroun",
|
||||
"CA": "Canada",
|
||||
"KY": "Cayman\u00f8erne",
|
||||
"CL": "Chile",
|
||||
"CC": "Cocos\u00f8erne",
|
||||
"CO": "Colombia",
|
||||
"KM": "Comorerne",
|
||||
"CG": "Congo-Brazzaville",
|
||||
"CD": "Congo-Kinshasa",
|
||||
"CK": "Cook\u00f8erne",
|
||||
"CR": "Costa Rica",
|
||||
"CU": "Cuba",
|
||||
"CW": "Cura\u00e7ao",
|
||||
"CY": "Cypern",
|
||||
"DK": "Danmark",
|
||||
"VI": "De Amerikanske Jomfru\u00f8er",
|
||||
"VG": "De Britiske Jomfru\u00f8er",
|
||||
"AE": "De Forenede Arabiske Emirater",
|
||||
"TF": "De Franske Besiddelser i Det Sydlige Indiske Ocean og Antarktis",
|
||||
"PS": "De pal\u00e6stinensiske omr\u00e5der",
|
||||
"BQ": "De tidligere Nederlandske Antiller",
|
||||
"CF": "Den Centralafrikanske Republik",
|
||||
"DO": "Den Dominikanske Republik",
|
||||
"IO": "Det Britiske Territorium i Det Indiske Ocean",
|
||||
"DJ": "Djibouti",
|
||||
"DM": "Dominica",
|
||||
"EC": "Ecuador",
|
||||
"EG": "Egypten",
|
||||
"SV": "El Salvador",
|
||||
"CI": "Elfenbenskysten",
|
||||
"ER": "Eritrea",
|
||||
"EE": "Estland",
|
||||
"SZ": "Eswatini",
|
||||
"ET": "Etiopien",
|
||||
"FK": "Falklands\u00f8erne",
|
||||
"FJ": "Fiji",
|
||||
"PH": "Filippinerne",
|
||||
"FI": "Finland",
|
||||
"FR": "Frankrig",
|
||||
"GF": "Fransk Guyana",
|
||||
"PF": "Fransk Polynesien",
|
||||
"FO": "F\u00e6r\u00f8erne",
|
||||
"GA": "Gabon",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgien",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GD": "Grenada",
|
||||
"GR": "Gr\u00e6kenland",
|
||||
"GL": "Gr\u00f8nland",
|
||||
"GP": "Guadeloupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea-Bissau",
|
||||
"GY": "Guyana",
|
||||
"HT": "Haiti",
|
||||
"HM": "Heard Island og McDonald Islands",
|
||||
"NL": "Holland",
|
||||
"HN": "Honduras",
|
||||
"BY": "Hviderusland",
|
||||
"IN": "Indien",
|
||||
"ID": "Indonesien",
|
||||
"IQ": "Irak",
|
||||
"IR": "Iran",
|
||||
"IE": "Irland",
|
||||
"IS": "Island",
|
||||
"IM": "Isle of Man",
|
||||
"IL": "Israel",
|
||||
"IT": "Italien",
|
||||
"JM": "Jamaica",
|
||||
"JP": "Japan",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordan",
|
||||
"CX": "Jule\u00f8en",
|
||||
"CV": "Kap Verde",
|
||||
"KZ": "Kasakhstan",
|
||||
"KE": "Kenya",
|
||||
"CN": "Kina",
|
||||
"KG": "Kirgisistan",
|
||||
"KI": "Kiribati",
|
||||
"XK": "Kosovo",
|
||||
"HR": "Kroatien",
|
||||
"KW": "Kuwait",
|
||||
"LA": "Laos",
|
||||
"LS": "Lesotho",
|
||||
"LV": "Letland",
|
||||
"LB": "Libanon",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libyen",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Litauen",
|
||||
"LU": "Luxembourg",
|
||||
"MG": "Madagaskar",
|
||||
"MW": "Malawi",
|
||||
"MY": "Malaysia",
|
||||
"MV": "Maldiverne",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MA": "Marokko",
|
||||
"MH": "Marshall\u00f8erne",
|
||||
"MQ": "Martinique",
|
||||
"MR": "Mauretanien",
|
||||
"MU": "Mauritius",
|
||||
"YT": "Mayotte",
|
||||
"MX": "Mexico",
|
||||
"FM": "Mikronesien",
|
||||
"MD": "Moldova",
|
||||
"MC": "Monaco",
|
||||
"MN": "Mongoliet",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MZ": "Mozambique",
|
||||
"MM": "Myanmar (Burma)",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NZ": "New Zealand",
|
||||
"NI": "Nicaragua",
|
||||
"NE": "Niger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"KP": "Nordkorea",
|
||||
"MK": "Nordmakedonien",
|
||||
"MP": "Nordmarianerne",
|
||||
"NF": "Norfolk Island",
|
||||
"NO": "Norge",
|
||||
"NC": "Ny Kaledonien",
|
||||
"OM": "Oman",
|
||||
"PK": "Pakistan",
|
||||
"PW": "Palau",
|
||||
"PA": "Panama",
|
||||
"PG": "Papua Ny Guinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Peru",
|
||||
"PN": "Pitcairn",
|
||||
"PL": "Polen",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"QA": "Qatar",
|
||||
"RE": "R\u00e9union",
|
||||
"RO": "Rum\u00e6nien",
|
||||
"RU": "Rusland",
|
||||
"RW": "Rwanda",
|
||||
"BL": "Saint Barth\u00e9lemy",
|
||||
"KN": "Saint Kitts og Nevis",
|
||||
"LC": "Saint Lucia",
|
||||
"MF": "Saint Martin",
|
||||
"PM": "Saint Pierre og Miquelon",
|
||||
"VC": "Saint Vincent og Grenadinerne",
|
||||
"SB": "Salomon\u00f8erne",
|
||||
"WS": "Samoa",
|
||||
"SM": "San Marino",
|
||||
"ST": "S\u00e3o Tom\u00e9 og Pr\u00edncipe",
|
||||
"HK": "SAR Hongkong",
|
||||
"MO": "SAR Macao",
|
||||
"SA": "Saudi-Arabien",
|
||||
"CH": "Schweiz",
|
||||
"SN": "Senegal",
|
||||
"RS": "Serbien",
|
||||
"SC": "Seychellerne",
|
||||
"SL": "Sierra Leone",
|
||||
"SG": "Singapore",
|
||||
"SX": "Sint Maarten",
|
||||
"SK": "Slovakiet",
|
||||
"SI": "Slovenien",
|
||||
"SO": "Somalia",
|
||||
"GS": "South Georgia og De Sydlige Sandwich\u00f8er",
|
||||
"ES": "Spanien",
|
||||
"LK": "Sri Lanka",
|
||||
"SH": "St. Helena",
|
||||
"GB": "Storbritannien",
|
||||
"SD": "Sudan",
|
||||
"SR": "Surinam",
|
||||
"SJ": "Svalbard og Jan Mayen",
|
||||
"SE": "Sverige",
|
||||
"ZA": "Sydafrika",
|
||||
"KR": "Sydkorea",
|
||||
"SS": "Sydsudan",
|
||||
"SY": "Syrien",
|
||||
"TJ": "Tadsjikistan",
|
||||
"TW": "Taiwan",
|
||||
"TZ": "Tanzania",
|
||||
"TD": "Tchad",
|
||||
"TH": "Thailand",
|
||||
"TL": "Timor-Leste",
|
||||
"CZ": "Tjekkiet",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad og Tobago",
|
||||
"TN": "Tunesien",
|
||||
"TM": "Turkmenistan",
|
||||
"TC": "Turks- og Caicos\u00f8erne",
|
||||
"TV": "Tuvalu",
|
||||
"TR": "Tyrkiet",
|
||||
"DE": "Tyskland",
|
||||
"UG": "Uganda",
|
||||
"UA": "Ukraine",
|
||||
"HU": "Ungarn",
|
||||
"UY": "Uruguay",
|
||||
"US": "USA",
|
||||
"UZ": "Usbekistan",
|
||||
"VU": "Vanuatu",
|
||||
"VA": "Vatikanstaten",
|
||||
"VE": "Venezuela",
|
||||
"EH": "Vestsahara",
|
||||
"VN": "Vietnam",
|
||||
"WF": "Wallis og Futuna",
|
||||
"YE": "Yemen",
|
||||
"ZM": "Zambia",
|
||||
"ZW": "Zimbabwe",
|
||||
"GQ": "\u00c6kvatorialguinea",
|
||||
"AT": "\u00d8strig",
|
||||
"AX": "\u00c5land"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,252 @@
|
|||
{"AF":"Afghanistan","EG":"\u00c4gypten","AX":"\u00c5landinseln","AL":"Albanien","DZ":"Algerien","AS":"Amerikanisch-Samoa","VI":"Amerikanische Jungferninseln","UM":"Amerikanische \u00dcberseeinseln","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarktis","AG":"Antigua und Barbuda","GQ":"\u00c4quatorialguinea","AR":"Argentinien","AM":"Armenien","AW":"Aruba","AZ":"Aserbaidschan","ET":"\u00c4thiopien","AU":"Australien","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesch","BB":"Barbados","BE":"Belgien","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivien","BQ":"Bonaire, Sint Eustatius und Saba","BA":"Bosnien und Herzegowina","BW":"Botswana","BV":"Bouvetinsel","BR":"Brasilien","VG":"Britische Jungferninseln","IO":"Britisches Territorium im Indischen Ozean","BN":"Brunei","BG":"Bulgarien","BF":"Burkina Faso","BI":"Burundi","CL":"Chile","CN":"China","CK":"Cookinseln","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","CW":"Cura\u00e7ao","DK":"D\u00e4nemark","DE":"Deutschland","DM":"Dominica","DO":"Dominikanische Republik","DJ":"Dschibuti","EC":"Ecuador","SV":"El Salvador","ER":"Eritrea","EE":"Estland","SZ":"Eswatini","FK":"Falklandinseln","FO":"F\u00e4r\u00f6er","FJ":"Fidschi","FI":"Finnland","FR":"Frankreich","GF":"Franz\u00f6sisch-Guayana","PF":"Franz\u00f6sisch-Polynesien","TF":"Franz\u00f6sische S\u00fcd- und Antarktisgebiete","GA":"Gabun","GM":"Gambia","GE":"Georgien","GH":"Ghana","GI":"Gibraltar","GD":"Grenada","GR":"Griechenland","GL":"Gr\u00f6nland","GB":"Grossbritannien","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard und McDonaldinseln","HN":"Honduras","IN":"Indien","ID":"Indonesien","IQ":"Irak","IR":"Iran","IE":"Irland","IS":"Island","IM":"Isle of Man","IL":"Israel","IT":"Italien","JM":"Jamaika","JP":"Japan","YE":"Jemen","JE":"Jersey","JO":"Jordanien","KY":"Kaimaninseln","KH":"Kambodscha","CM":"Kamerun","CA":"Kanada","CV":"Kapverden","KZ":"Kasachstan","QA":"Katar","KE":"Kenia","KG":"Kirgisistan","KI":"Kiribati","CC":"Kokosinseln","CO":"Kolumbien","KM":"Komoren","CG":"Kongo-Brazzaville","CD":"Kongo-Kinshasa","HR":"Kroatien","CU":"Kuba","KW":"Kuwait","LA":"Laos","LS":"Lesotho","LV":"Lettland","LB":"Libanon","LR":"Liberia","LY":"Libyen","LI":"Liechtenstein","LT":"Litauen","LU":"Luxemburg","MG":"Madagaskar","MW":"Malawi","MY":"Malaysia","MV":"Malediven","ML":"Mali","MT":"Malta","MA":"Marokko","MH":"Marshallinseln","MQ":"Martinique","MR":"Mauretanien","MU":"Mauritius","YT":"Mayotte","MX":"Mexiko","FM":"Mikronesien","MC":"Monaco","MN":"Mongolei","ME":"Montenegro","MS":"Montserrat","MZ":"Mosambik","MM":"Myanmar","NA":"Namibia","NR":"Nauru","NP":"Nepal","NC":"Neukaledonien","NZ":"Neuseeland","NI":"Nicaragua","NL":"Niederlande","NE":"Niger","NG":"Nigeria","NU":"Niue","KP":"Nordkorea","MP":"N\u00f6rdliche Marianen","MK":"Nordmazedonien","NF":"Norfolkinsel","NO":"Norwegen","OM":"Oman","AT":"\u00d6sterreich","TL":"Osttimor","PK":"Pakistan","PS":"Pal\u00e4stinensische Autonomiegebiete","PW":"Palau","PA":"Panama","PG":"Papua-Neuguinea","PY":"Paraguay","PE":"Peru","PH":"Philippinen","PN":"Pitcairninseln","PL":"Polen","PT":"Portugal","PR":"Puerto Rico","MD":"Republik Moldau","RE":"R\u00e9union","RW":"Ruanda","RO":"Rum\u00e4nien","RU":"Russland","SB":"Salomon-Inseln","ZM":"Sambia","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 und Pr\u00edncipe","SA":"Saudi-Arabien","SE":"Schweden","CH":"Schweiz","SN":"Senegal","RS":"Serbien","SC":"Seychellen","SL":"Sierra Leone","SG":"Singapur","SX":"Sint Maarten","SK":"Slowakei","SI":"Slowenien","SO":"Somalia","HK":"Sonderverwaltungsregion Hongkong","MO":"Sonderverwaltungsregion Macau","ES":"Spanien","SJ":"Spitzbergen und Jan Mayen","LK":"Sri Lanka","BL":"St. Barth\u00e9lemy","SH":"St. Helena","KN":"St. Kitts und Nevis","LC":"St. Lucia","MF":"St. Martin","PM":"St. Pierre und Miquelon","VC":"St. Vincent und die Grenadinen","ZA":"S\u00fcdafrika","SD":"Sudan","GS":"S\u00fcdgeorgien und die S\u00fcdlichen Sandwichinseln","KR":"S\u00fcdkorea","SS":"S\u00fcdsudan","SR":"Suriname","SY":"Syrien","TJ":"Tadschikistan","TW":"Taiwan","TZ":"Tansania","TH":"Thailand","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad und Tobago","TD":"Tschad","CZ":"Tschechien","TN":"Tunesien","TR":"T\u00fcrkei","TM":"Turkmenistan","TC":"Turks- und Caicosinseln","TV":"Tuvalu","UG":"Uganda","UA":"Ukraine","HU":"Ungarn","UY":"Uruguay","UZ":"Usbekistan","VU":"Vanuatu","VA":"Vatikanstadt","VE":"Venezuela","AE":"Vereinigte Arabische Emirate","US":"Vereinigte Staaten","VN":"Vietnam","WF":"Wallis und Futuna","CX":"Weihnachtsinsel","BY":"Weissrussland","EH":"Westsahara","CF":"Zentralafrikanische Republik","ZW":"Zimbabwe","CY":"Zypern"}
|
||||
{
|
||||
"AF": "Afghanistan",
|
||||
"EG": "\u00c4gypten",
|
||||
"AX": "\u00c5landinseln",
|
||||
"AL": "Albanien",
|
||||
"DZ": "Algerien",
|
||||
"AS": "Amerikanisch-Samoa",
|
||||
"VI": "Amerikanische Jungferninseln",
|
||||
"UM": "Amerikanische \u00dcberseeinseln",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Antarktis",
|
||||
"AG": "Antigua und Barbuda",
|
||||
"GQ": "\u00c4quatorialguinea",
|
||||
"AR": "Argentinien",
|
||||
"AM": "Armenien",
|
||||
"AW": "Aruba",
|
||||
"AZ": "Aserbaidschan",
|
||||
"ET": "\u00c4thiopien",
|
||||
"AU": "Australien",
|
||||
"BS": "Bahamas",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesch",
|
||||
"BB": "Barbados",
|
||||
"BE": "Belgien",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Benin",
|
||||
"BM": "Bermuda",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bolivien",
|
||||
"BQ": "Bonaire, Sint Eustatius und Saba",
|
||||
"BA": "Bosnien und Herzegowina",
|
||||
"BW": "Botswana",
|
||||
"BV": "Bouvetinsel",
|
||||
"BR": "Brasilien",
|
||||
"VG": "Britische Jungferninseln",
|
||||
"IO": "Britisches Territorium im Indischen Ozean",
|
||||
"BN": "Brunei",
|
||||
"BG": "Bulgarien",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"CL": "Chile",
|
||||
"CN": "China",
|
||||
"CK": "Cookinseln",
|
||||
"CR": "Costa Rica",
|
||||
"CI": "C\u00f4te d\u2019Ivoire",
|
||||
"CW": "Cura\u00e7ao",
|
||||
"DK": "D\u00e4nemark",
|
||||
"DE": "Deutschland",
|
||||
"DM": "Dominica",
|
||||
"DO": "Dominikanische Republik",
|
||||
"DJ": "Dschibuti",
|
||||
"EC": "Ecuador",
|
||||
"SV": "El Salvador",
|
||||
"ER": "Eritrea",
|
||||
"EE": "Estland",
|
||||
"SZ": "Eswatini",
|
||||
"FK": "Falklandinseln",
|
||||
"FO": "F\u00e4r\u00f6er",
|
||||
"FJ": "Fidschi",
|
||||
"FI": "Finnland",
|
||||
"FR": "Frankreich",
|
||||
"GF": "Franz\u00f6sisch-Guayana",
|
||||
"PF": "Franz\u00f6sisch-Polynesien",
|
||||
"TF": "Franz\u00f6sische S\u00fcd- und Antarktisgebiete",
|
||||
"GA": "Gabun",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgien",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GD": "Grenada",
|
||||
"GR": "Griechenland",
|
||||
"GL": "Gr\u00f6nland",
|
||||
"GB": "Grossbritannien",
|
||||
"GP": "Guadeloupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea-Bissau",
|
||||
"GY": "Guyana",
|
||||
"HT": "Haiti",
|
||||
"HM": "Heard und McDonaldinseln",
|
||||
"HN": "Honduras",
|
||||
"IN": "Indien",
|
||||
"ID": "Indonesien",
|
||||
"IQ": "Irak",
|
||||
"IR": "Iran",
|
||||
"IE": "Irland",
|
||||
"IS": "Island",
|
||||
"IM": "Isle of Man",
|
||||
"IL": "Israel",
|
||||
"IT": "Italien",
|
||||
"JM": "Jamaika",
|
||||
"JP": "Japan",
|
||||
"YE": "Jemen",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordanien",
|
||||
"KY": "Kaimaninseln",
|
||||
"KH": "Kambodscha",
|
||||
"CM": "Kamerun",
|
||||
"CA": "Kanada",
|
||||
"CV": "Kapverden",
|
||||
"KZ": "Kasachstan",
|
||||
"QA": "Katar",
|
||||
"KE": "Kenia",
|
||||
"KG": "Kirgisistan",
|
||||
"KI": "Kiribati",
|
||||
"CC": "Kokosinseln",
|
||||
"CO": "Kolumbien",
|
||||
"KM": "Komoren",
|
||||
"CG": "Kongo-Brazzaville",
|
||||
"CD": "Kongo-Kinshasa",
|
||||
"XK": "Kosovo",
|
||||
"HR": "Kroatien",
|
||||
"CU": "Kuba",
|
||||
"KW": "Kuwait",
|
||||
"LA": "Laos",
|
||||
"LS": "Lesotho",
|
||||
"LV": "Lettland",
|
||||
"LB": "Libanon",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libyen",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Litauen",
|
||||
"LU": "Luxemburg",
|
||||
"MG": "Madagaskar",
|
||||
"MW": "Malawi",
|
||||
"MY": "Malaysia",
|
||||
"MV": "Malediven",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MA": "Marokko",
|
||||
"MH": "Marshallinseln",
|
||||
"MQ": "Martinique",
|
||||
"MR": "Mauretanien",
|
||||
"MU": "Mauritius",
|
||||
"YT": "Mayotte",
|
||||
"MX": "Mexiko",
|
||||
"FM": "Mikronesien",
|
||||
"MC": "Monaco",
|
||||
"MN": "Mongolei",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MZ": "Mosambik",
|
||||
"MM": "Myanmar",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NC": "Neukaledonien",
|
||||
"NZ": "Neuseeland",
|
||||
"NI": "Nicaragua",
|
||||
"NL": "Niederlande",
|
||||
"NE": "Niger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"KP": "Nordkorea",
|
||||
"MP": "N\u00f6rdliche Marianen",
|
||||
"MK": "Nordmazedonien",
|
||||
"NF": "Norfolkinsel",
|
||||
"NO": "Norwegen",
|
||||
"OM": "Oman",
|
||||
"AT": "\u00d6sterreich",
|
||||
"TL": "Osttimor",
|
||||
"PK": "Pakistan",
|
||||
"PS": "Pal\u00e4stinensische Autonomiegebiete",
|
||||
"PW": "Palau",
|
||||
"PA": "Panama",
|
||||
"PG": "Papua-Neuguinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Peru",
|
||||
"PH": "Philippinen",
|
||||
"PN": "Pitcairninseln",
|
||||
"PL": "Polen",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"MD": "Republik Moldau",
|
||||
"RE": "R\u00e9union",
|
||||
"RW": "Ruanda",
|
||||
"RO": "Rum\u00e4nien",
|
||||
"RU": "Russland",
|
||||
"SB": "Salomon-Inseln",
|
||||
"ZM": "Sambia",
|
||||
"WS": "Samoa",
|
||||
"SM": "San Marino",
|
||||
"ST": "S\u00e3o Tom\u00e9 und Pr\u00edncipe",
|
||||
"SA": "Saudi-Arabien",
|
||||
"SE": "Schweden",
|
||||
"CH": "Schweiz",
|
||||
"SN": "Senegal",
|
||||
"RS": "Serbien",
|
||||
"SC": "Seychellen",
|
||||
"SL": "Sierra Leone",
|
||||
"SG": "Singapur",
|
||||
"SX": "Sint Maarten",
|
||||
"SK": "Slowakei",
|
||||
"SI": "Slowenien",
|
||||
"SO": "Somalia",
|
||||
"HK": "Sonderverwaltungsregion Hongkong",
|
||||
"MO": "Sonderverwaltungsregion Macau",
|
||||
"ES": "Spanien",
|
||||
"SJ": "Spitzbergen und Jan Mayen",
|
||||
"LK": "Sri Lanka",
|
||||
"BL": "St. Barth\u00e9lemy",
|
||||
"SH": "St. Helena",
|
||||
"KN": "St. Kitts und Nevis",
|
||||
"LC": "St. Lucia",
|
||||
"MF": "St. Martin",
|
||||
"PM": "St. Pierre und Miquelon",
|
||||
"VC": "St. Vincent und die Grenadinen",
|
||||
"ZA": "S\u00fcdafrika",
|
||||
"SD": "Sudan",
|
||||
"GS": "S\u00fcdgeorgien und die S\u00fcdlichen Sandwichinseln",
|
||||
"KR": "S\u00fcdkorea",
|
||||
"SS": "S\u00fcdsudan",
|
||||
"SR": "Suriname",
|
||||
"SY": "Syrien",
|
||||
"TJ": "Tadschikistan",
|
||||
"TW": "Taiwan",
|
||||
"TZ": "Tansania",
|
||||
"TH": "Thailand",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad und Tobago",
|
||||
"TD": "Tschad",
|
||||
"CZ": "Tschechien",
|
||||
"TN": "Tunesien",
|
||||
"TR": "T\u00fcrkei",
|
||||
"TM": "Turkmenistan",
|
||||
"TC": "Turks- und Caicosinseln",
|
||||
"TV": "Tuvalu",
|
||||
"UG": "Uganda",
|
||||
"UA": "Ukraine",
|
||||
"HU": "Ungarn",
|
||||
"UY": "Uruguay",
|
||||
"UZ": "Usbekistan",
|
||||
"VU": "Vanuatu",
|
||||
"VA": "Vatikanstadt",
|
||||
"VE": "Venezuela",
|
||||
"AE": "Vereinigte Arabische Emirate",
|
||||
"US": "Vereinigte Staaten",
|
||||
"VN": "Vietnam",
|
||||
"WF": "Wallis und Futuna",
|
||||
"CX": "Weihnachtsinsel",
|
||||
"BY": "Weissrussland",
|
||||
"EH": "Westsahara",
|
||||
"CF": "Zentralafrikanische Republik",
|
||||
"ZW": "Zimbabwe",
|
||||
"CY": "Zypern"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,252 @@
|
|||
{"AF":"Afghanistan","EG":"\u00c4gypten","AX":"\u00c5landinseln","AL":"Albanien","DZ":"Algerien","AS":"Amerikanisch-Samoa","VI":"Amerikanische Jungferninseln","UM":"Amerikanische \u00dcberseeinseln","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarktis","AG":"Antigua und Barbuda","GQ":"\u00c4quatorialguinea","AR":"Argentinien","AM":"Armenien","AW":"Aruba","AZ":"Aserbaidschan","ET":"\u00c4thiopien","AU":"Australien","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesch","BB":"Barbados","BY":"Belarus","BE":"Belgien","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivien","BQ":"Bonaire, Sint Eustatius und Saba","BA":"Bosnien und Herzegowina","BW":"Botsuana","BV":"Bouvetinsel","BR":"Brasilien","VG":"Britische Jungferninseln","IO":"Britisches Territorium im Indischen Ozean","BN":"Brunei Darussalam","BG":"Bulgarien","BF":"Burkina Faso","BI":"Burundi","CV":"Cabo Verde","CL":"Chile","CN":"China","CK":"Cookinseln","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","CW":"Cura\u00e7ao","DK":"D\u00e4nemark","DE":"Deutschland","DM":"Dominica","DO":"Dominikanische Republik","DJ":"Dschibuti","EC":"Ecuador","SV":"El Salvador","ER":"Eritrea","EE":"Estland","SZ":"Eswatini","FK":"Falklandinseln","FO":"F\u00e4r\u00f6er","FJ":"Fidschi","FI":"Finnland","FR":"Frankreich","GF":"Franz\u00f6sisch-Guayana","PF":"Franz\u00f6sisch-Polynesien","TF":"Franz\u00f6sische S\u00fcd- und Antarktisgebiete","GA":"Gabun","GM":"Gambia","GE":"Georgien","GH":"Ghana","GI":"Gibraltar","GD":"Grenada","GR":"Griechenland","GL":"Gr\u00f6nland","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard und McDonaldinseln","HN":"Honduras","IN":"Indien","ID":"Indonesien","IQ":"Irak","IR":"Iran","IE":"Irland","IS":"Island","IM":"Isle of Man","IL":"Israel","IT":"Italien","JM":"Jamaika","JP":"Japan","YE":"Jemen","JE":"Jersey","JO":"Jordanien","KY":"Kaimaninseln","KH":"Kambodscha","CM":"Kamerun","CA":"Kanada","KZ":"Kasachstan","QA":"Katar","KE":"Kenia","KG":"Kirgisistan","KI":"Kiribati","CC":"Kokosinseln","CO":"Kolumbien","KM":"Komoren","CG":"Kongo-Brazzaville","CD":"Kongo-Kinshasa","HR":"Kroatien","CU":"Kuba","KW":"Kuwait","LA":"Laos","LS":"Lesotho","LV":"Lettland","LB":"Libanon","LR":"Liberia","LY":"Libyen","LI":"Liechtenstein","LT":"Litauen","LU":"Luxemburg","MG":"Madagaskar","MW":"Malawi","MY":"Malaysia","MV":"Malediven","ML":"Mali","MT":"Malta","MA":"Marokko","MH":"Marshallinseln","MQ":"Martinique","MR":"Mauretanien","MU":"Mauritius","YT":"Mayotte","MX":"Mexiko","FM":"Mikronesien","MC":"Monaco","MN":"Mongolei","ME":"Montenegro","MS":"Montserrat","MZ":"Mosambik","MM":"Myanmar","NA":"Namibia","NR":"Nauru","NP":"Nepal","NC":"Neukaledonien","NZ":"Neuseeland","NI":"Nicaragua","NL":"Niederlande","NE":"Niger","NG":"Nigeria","NU":"Niue","KP":"Nordkorea","MP":"N\u00f6rdliche Marianen","MK":"Nordmazedonien","NF":"Norfolkinsel","NO":"Norwegen","OM":"Oman","AT":"\u00d6sterreich","PK":"Pakistan","PS":"Pal\u00e4stinensische Autonomiegebiete","PW":"Palau","PA":"Panama","PG":"Papua-Neuguinea","PY":"Paraguay","PE":"Peru","PH":"Philippinen","PN":"Pitcairninseln","PL":"Polen","PT":"Portugal","PR":"Puerto Rico","MD":"Republik Moldau","RE":"R\u00e9union","RW":"Ruanda","RO":"Rum\u00e4nien","RU":"Russland","SB":"Salomonen","ZM":"Sambia","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 und Pr\u00edncipe","SA":"Saudi-Arabien","SE":"Schweden","CH":"Schweiz","SN":"Senegal","RS":"Serbien","SC":"Seychellen","SL":"Sierra Leone","ZW":"Simbabwe","SG":"Singapur","SX":"Sint Maarten","SK":"Slowakei","SI":"Slowenien","SO":"Somalia","HK":"Sonderverwaltungsregion Hongkong","MO":"Sonderverwaltungsregion Macau","ES":"Spanien","SJ":"Spitzbergen und Jan Mayen","LK":"Sri Lanka","BL":"St. Barth\u00e9lemy","SH":"St. Helena","KN":"St. Kitts und Nevis","LC":"St. Lucia","MF":"St. Martin","PM":"St. Pierre und Miquelon","VC":"St. Vincent und die Grenadinen","ZA":"S\u00fcdafrika","SD":"Sudan","GS":"S\u00fcdgeorgien und die S\u00fcdlichen Sandwichinseln","KR":"S\u00fcdkorea","SS":"S\u00fcdsudan","SR":"Suriname","SY":"Syrien","TJ":"Tadschikistan","TW":"Taiwan","TZ":"Tansania","TH":"Thailand","TL":"Timor-Leste","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad und Tobago","TD":"Tschad","CZ":"Tschechien","TN":"Tunesien","TR":"T\u00fcrkei","TM":"Turkmenistan","TC":"Turks- und Caicosinseln","TV":"Tuvalu","UG":"Uganda","UA":"Ukraine","HU":"Ungarn","UY":"Uruguay","UZ":"Usbekistan","VU":"Vanuatu","VA":"Vatikanstadt","VE":"Venezuela","AE":"Vereinigte Arabische Emirate","US":"Vereinigte Staaten","GB":"Vereinigtes K\u00f6nigreich","VN":"Vietnam","WF":"Wallis und Futuna","CX":"Weihnachtsinsel","EH":"Westsahara","CF":"Zentralafrikanische Republik","CY":"Zypern"}
|
||||
{
|
||||
"AF": "Afghanistan",
|
||||
"EG": "\u00c4gypten",
|
||||
"AX": "\u00c5landinseln",
|
||||
"AL": "Albanien",
|
||||
"DZ": "Algerien",
|
||||
"AS": "Amerikanisch-Samoa",
|
||||
"VI": "Amerikanische Jungferninseln",
|
||||
"UM": "Amerikanische \u00dcberseeinseln",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Antarktis",
|
||||
"AG": "Antigua und Barbuda",
|
||||
"GQ": "\u00c4quatorialguinea",
|
||||
"AR": "Argentinien",
|
||||
"AM": "Armenien",
|
||||
"AW": "Aruba",
|
||||
"AZ": "Aserbaidschan",
|
||||
"ET": "\u00c4thiopien",
|
||||
"AU": "Australien",
|
||||
"BS": "Bahamas",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesch",
|
||||
"BB": "Barbados",
|
||||
"BY": "Belarus",
|
||||
"BE": "Belgien",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Benin",
|
||||
"BM": "Bermuda",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bolivien",
|
||||
"BQ": "Bonaire, Sint Eustatius und Saba",
|
||||
"BA": "Bosnien und Herzegowina",
|
||||
"BW": "Botsuana",
|
||||
"BV": "Bouvetinsel",
|
||||
"BR": "Brasilien",
|
||||
"VG": "Britische Jungferninseln",
|
||||
"IO": "Britisches Territorium im Indischen Ozean",
|
||||
"BN": "Brunei Darussalam",
|
||||
"BG": "Bulgarien",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"CV": "Cabo Verde",
|
||||
"CL": "Chile",
|
||||
"CN": "China",
|
||||
"CK": "Cookinseln",
|
||||
"CR": "Costa Rica",
|
||||
"CI": "C\u00f4te d\u2019Ivoire",
|
||||
"CW": "Cura\u00e7ao",
|
||||
"DK": "D\u00e4nemark",
|
||||
"DE": "Deutschland",
|
||||
"DM": "Dominica",
|
||||
"DO": "Dominikanische Republik",
|
||||
"DJ": "Dschibuti",
|
||||
"EC": "Ecuador",
|
||||
"SV": "El Salvador",
|
||||
"ER": "Eritrea",
|
||||
"EE": "Estland",
|
||||
"SZ": "Eswatini",
|
||||
"FK": "Falklandinseln",
|
||||
"FO": "F\u00e4r\u00f6er",
|
||||
"FJ": "Fidschi",
|
||||
"FI": "Finnland",
|
||||
"FR": "Frankreich",
|
||||
"GF": "Franz\u00f6sisch-Guayana",
|
||||
"PF": "Franz\u00f6sisch-Polynesien",
|
||||
"TF": "Franz\u00f6sische S\u00fcd- und Antarktisgebiete",
|
||||
"GA": "Gabun",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgien",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GD": "Grenada",
|
||||
"GR": "Griechenland",
|
||||
"GL": "Gr\u00f6nland",
|
||||
"GP": "Guadeloupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea-Bissau",
|
||||
"GY": "Guyana",
|
||||
"HT": "Haiti",
|
||||
"HM": "Heard und McDonaldinseln",
|
||||
"HN": "Honduras",
|
||||
"IN": "Indien",
|
||||
"ID": "Indonesien",
|
||||
"IQ": "Irak",
|
||||
"IR": "Iran",
|
||||
"IE": "Irland",
|
||||
"IS": "Island",
|
||||
"IM": "Isle of Man",
|
||||
"IL": "Israel",
|
||||
"IT": "Italien",
|
||||
"JM": "Jamaika",
|
||||
"JP": "Japan",
|
||||
"YE": "Jemen",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordanien",
|
||||
"KY": "Kaimaninseln",
|
||||
"KH": "Kambodscha",
|
||||
"CM": "Kamerun",
|
||||
"CA": "Kanada",
|
||||
"KZ": "Kasachstan",
|
||||
"QA": "Katar",
|
||||
"KE": "Kenia",
|
||||
"KG": "Kirgisistan",
|
||||
"KI": "Kiribati",
|
||||
"CC": "Kokosinseln",
|
||||
"CO": "Kolumbien",
|
||||
"KM": "Komoren",
|
||||
"CG": "Kongo-Brazzaville",
|
||||
"CD": "Kongo-Kinshasa",
|
||||
"XK": "Kosovo",
|
||||
"HR": "Kroatien",
|
||||
"CU": "Kuba",
|
||||
"KW": "Kuwait",
|
||||
"LA": "Laos",
|
||||
"LS": "Lesotho",
|
||||
"LV": "Lettland",
|
||||
"LB": "Libanon",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libyen",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Litauen",
|
||||
"LU": "Luxemburg",
|
||||
"MG": "Madagaskar",
|
||||
"MW": "Malawi",
|
||||
"MY": "Malaysia",
|
||||
"MV": "Malediven",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MA": "Marokko",
|
||||
"MH": "Marshallinseln",
|
||||
"MQ": "Martinique",
|
||||
"MR": "Mauretanien",
|
||||
"MU": "Mauritius",
|
||||
"YT": "Mayotte",
|
||||
"MX": "Mexiko",
|
||||
"FM": "Mikronesien",
|
||||
"MC": "Monaco",
|
||||
"MN": "Mongolei",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MZ": "Mosambik",
|
||||
"MM": "Myanmar",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NC": "Neukaledonien",
|
||||
"NZ": "Neuseeland",
|
||||
"NI": "Nicaragua",
|
||||
"NL": "Niederlande",
|
||||
"NE": "Niger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"KP": "Nordkorea",
|
||||
"MP": "N\u00f6rdliche Marianen",
|
||||
"MK": "Nordmazedonien",
|
||||
"NF": "Norfolkinsel",
|
||||
"NO": "Norwegen",
|
||||
"OM": "Oman",
|
||||
"AT": "\u00d6sterreich",
|
||||
"PK": "Pakistan",
|
||||
"PS": "Pal\u00e4stinensische Autonomiegebiete",
|
||||
"PW": "Palau",
|
||||
"PA": "Panama",
|
||||
"PG": "Papua-Neuguinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Peru",
|
||||
"PH": "Philippinen",
|
||||
"PN": "Pitcairninseln",
|
||||
"PL": "Polen",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"MD": "Republik Moldau",
|
||||
"RE": "R\u00e9union",
|
||||
"RW": "Ruanda",
|
||||
"RO": "Rum\u00e4nien",
|
||||
"RU": "Russland",
|
||||
"SB": "Salomonen",
|
||||
"ZM": "Sambia",
|
||||
"WS": "Samoa",
|
||||
"SM": "San Marino",
|
||||
"ST": "S\u00e3o Tom\u00e9 und Pr\u00edncipe",
|
||||
"SA": "Saudi-Arabien",
|
||||
"SE": "Schweden",
|
||||
"CH": "Schweiz",
|
||||
"SN": "Senegal",
|
||||
"RS": "Serbien",
|
||||
"SC": "Seychellen",
|
||||
"SL": "Sierra Leone",
|
||||
"ZW": "Simbabwe",
|
||||
"SG": "Singapur",
|
||||
"SX": "Sint Maarten",
|
||||
"SK": "Slowakei",
|
||||
"SI": "Slowenien",
|
||||
"SO": "Somalia",
|
||||
"HK": "Sonderverwaltungsregion Hongkong",
|
||||
"MO": "Sonderverwaltungsregion Macau",
|
||||
"ES": "Spanien",
|
||||
"SJ": "Spitzbergen und Jan Mayen",
|
||||
"LK": "Sri Lanka",
|
||||
"BL": "St. Barth\u00e9lemy",
|
||||
"SH": "St. Helena",
|
||||
"KN": "St. Kitts und Nevis",
|
||||
"LC": "St. Lucia",
|
||||
"MF": "St. Martin",
|
||||
"PM": "St. Pierre und Miquelon",
|
||||
"VC": "St. Vincent und die Grenadinen",
|
||||
"ZA": "S\u00fcdafrika",
|
||||
"SD": "Sudan",
|
||||
"GS": "S\u00fcdgeorgien und die S\u00fcdlichen Sandwichinseln",
|
||||
"KR": "S\u00fcdkorea",
|
||||
"SS": "S\u00fcdsudan",
|
||||
"SR": "Suriname",
|
||||
"SY": "Syrien",
|
||||
"TJ": "Tadschikistan",
|
||||
"TW": "Taiwan",
|
||||
"TZ": "Tansania",
|
||||
"TH": "Thailand",
|
||||
"TL": "Timor-Leste",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad und Tobago",
|
||||
"TD": "Tschad",
|
||||
"CZ": "Tschechien",
|
||||
"TN": "Tunesien",
|
||||
"TR": "T\u00fcrkei",
|
||||
"TM": "Turkmenistan",
|
||||
"TC": "Turks- und Caicosinseln",
|
||||
"TV": "Tuvalu",
|
||||
"UG": "Uganda",
|
||||
"UA": "Ukraine",
|
||||
"HU": "Ungarn",
|
||||
"UY": "Uruguay",
|
||||
"UZ": "Usbekistan",
|
||||
"VU": "Vanuatu",
|
||||
"VA": "Vatikanstadt",
|
||||
"VE": "Venezuela",
|
||||
"AE": "Vereinigte Arabische Emirate",
|
||||
"US": "Vereinigte Staaten",
|
||||
"GB": "Vereinigtes K\u00f6nigreich",
|
||||
"VN": "Vietnam",
|
||||
"WF": "Wallis und Futuna",
|
||||
"CX": "Weihnachtsinsel",
|
||||
"EH": "Westsahara",
|
||||
"CF": "Zentralafrikanische Republik",
|
||||
"CY": "Zypern"
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1,252 @@
|
|||
{"AF":"Afghanistan","AX":"\u00c5land Islands","AL":"Albania","DZ":"Algeria","AS":"American Samoa","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarctica","AG":"Antigua & Barbuda","AR":"Argentina","AM":"Armenia","AW":"Aruba","AU":"Australia","AT":"Austria","AZ":"Azerbaijan","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BY":"Belarus","BE":"Belgium","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivia","BA":"Bosnia & Herzegovina","BW":"Botswana","BV":"Bouvet Island","BR":"Brazil","IO":"British Indian Ocean Territory","VG":"British Virgin Islands","BN":"Brunei","BG":"Bulgaria","BF":"Burkina Faso","BI":"Burundi","KH":"Cambodia","CM":"Cameroon","CA":"Canada","CV":"Cape Verde","BQ":"Caribbean Netherlands","KY":"Cayman Islands","CF":"Central African Republic","TD":"Chad","CL":"Chile","CN":"China","CX":"Christmas Island","CC":"Cocos (Keeling) Islands","CO":"Colombia","KM":"Comoros","CG":"Congo - Brazzaville","CD":"Congo - Kinshasa","CK":"Cook Islands","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","HR":"Croatia","CU":"Cuba","CW":"Cura\u00e7ao","CY":"Cyprus","CZ":"Czechia","DK":"Denmark","DJ":"Djibouti","DM":"Dominica","DO":"Dominican Republic","EC":"Ecuador","EG":"Egypt","SV":"El Salvador","GQ":"Equatorial Guinea","ER":"Eritrea","EE":"Estonia","SZ":"Eswatini","ET":"Ethiopia","FK":"Falkland Islands","FO":"Faroe Islands","FJ":"Fiji","FI":"Finland","FR":"France","GF":"French Guiana","PF":"French Polynesia","TF":"French Southern Territories","GA":"Gabon","GM":"Gambia","GE":"Georgia","DE":"Germany","GH":"Ghana","GI":"Gibraltar","GR":"Greece","GL":"Greenland","GD":"Grenada","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard & McDonald Islands","HN":"Honduras","HK":"Hong Kong SAR China","HU":"Hungary","IS":"Iceland","IN":"India","ID":"Indonesia","IR":"Iran","IQ":"Iraq","IE":"Ireland","IM":"Isle of Man","IL":"Israel","IT":"Italy","JM":"Jamaica","JP":"Japan","JE":"Jersey","JO":"Jordan","KZ":"Kazakhstan","KE":"Kenya","KI":"Kiribati","KW":"Kuwait","KG":"Kyrgyzstan","LA":"Laos","LV":"Latvia","LB":"Lebanon","LS":"Lesotho","LR":"Liberia","LY":"Libya","LI":"Liechtenstein","LT":"Lithuania","LU":"Luxembourg","MO":"Macao SAR China","MG":"Madagascar","MW":"Malawi","MY":"Malaysia","MV":"Maldives","ML":"Mali","MT":"Malta","MH":"Marshall Islands","MQ":"Martinique","MR":"Mauritania","MU":"Mauritius","YT":"Mayotte","MX":"Mexico","FM":"Micronesia","MD":"Moldova","MC":"Monaco","MN":"Mongolia","ME":"Montenegro","MS":"Montserrat","MA":"Morocco","MZ":"Mozambique","MM":"Myanmar (Burma)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NL":"Netherlands","NC":"New Caledonia","NZ":"New Zealand","NI":"Nicaragua","NE":"Niger","NG":"Nigeria","NU":"Niue","NF":"Norfolk Island","KP":"North Korea","MK":"North Macedonia","MP":"Northern Mariana Islands","NO":"Norway","OM":"Oman","PK":"Pakistan","PW":"Palau","PS":"Palestinian Territories","PA":"Panama","PG":"Papua New Guinea","PY":"Paraguay","PE":"Peru","PH":"Philippines","PN":"Pitcairn Islands","PL":"Poland","PT":"Portugal","PR":"Puerto Rico","QA":"Qatar","RE":"R\u00e9union","RO":"Romania","RU":"Russia","RW":"Rwanda","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 & Pr\u00edncipe","SA":"Saudi Arabia","SN":"Senegal","RS":"Serbia","SC":"Seychelles","SL":"Sierra Leone","SG":"Singapore","SX":"Sint Maarten","SK":"Slovakia","SI":"Slovenia","SB":"Solomon Islands","SO":"Somalia","ZA":"South Africa","GS":"South Georgia & South Sandwich Islands","KR":"South Korea","SS":"South Sudan","ES":"Spain","LK":"Sri Lanka","BL":"St. Barth\u00e9lemy","SH":"St. Helena","KN":"St. Kitts & Nevis","LC":"St. Lucia","MF":"St. Martin","PM":"St. Pierre & Miquelon","VC":"St. Vincent & Grenadines","SD":"Sudan","SR":"Suriname","SJ":"Svalbard & Jan Mayen","SE":"Sweden","CH":"Switzerland","SY":"Syria","TW":"Taiwan","TJ":"Tajikistan","TZ":"Tanzania","TH":"Thailand","TL":"Timor-Leste","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad & Tobago","TN":"Tunisia","TR":"Turkey","TM":"Turkmenistan","TC":"Turks & Caicos Islands","TV":"Tuvalu","UM":"U.S. Outlying Islands","VI":"U.S. Virgin Islands","UG":"Uganda","UA":"Ukraine","AE":"United Arab Emirates","GB":"United Kingdom","US":"United States","UY":"Uruguay","UZ":"Uzbekistan","VU":"Vanuatu","VA":"Vatican City","VE":"Venezuela","VN":"Vietnam","WF":"Wallis & Futuna","EH":"Western Sahara","YE":"Yemen","ZM":"Zambia","ZW":"Zimbabwe"}
|
||||
{
|
||||
"AF": "Afghanistan",
|
||||
"AX": "\u00c5land Islands",
|
||||
"AL": "Albania",
|
||||
"DZ": "Algeria",
|
||||
"AS": "American Samoa",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Antarctica",
|
||||
"AG": "Antigua & Barbuda",
|
||||
"AR": "Argentina",
|
||||
"AM": "Armenia",
|
||||
"AW": "Aruba",
|
||||
"AU": "Australia",
|
||||
"AT": "Austria",
|
||||
"AZ": "Azerbaijan",
|
||||
"BS": "Bahamas",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesh",
|
||||
"BB": "Barbados",
|
||||
"BY": "Belarus",
|
||||
"BE": "Belgium",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Benin",
|
||||
"BM": "Bermuda",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bolivia",
|
||||
"BA": "Bosnia & Herzegovina",
|
||||
"BW": "Botswana",
|
||||
"BV": "Bouvet Island",
|
||||
"BR": "Brazil",
|
||||
"IO": "British Indian Ocean Territory",
|
||||
"VG": "British Virgin Islands",
|
||||
"BN": "Brunei",
|
||||
"BG": "Bulgaria",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"KH": "Cambodia",
|
||||
"CM": "Cameroon",
|
||||
"CA": "Canada",
|
||||
"CV": "Cape Verde",
|
||||
"BQ": "Caribbean Netherlands",
|
||||
"KY": "Cayman Islands",
|
||||
"CF": "Central African Republic",
|
||||
"TD": "Chad",
|
||||
"CL": "Chile",
|
||||
"CN": "China",
|
||||
"CX": "Christmas Island",
|
||||
"CC": "Cocos (Keeling) Islands",
|
||||
"CO": "Colombia",
|
||||
"KM": "Comoros",
|
||||
"CG": "Congo - Brazzaville",
|
||||
"CD": "Congo - Kinshasa",
|
||||
"CK": "Cook Islands",
|
||||
"CR": "Costa Rica",
|
||||
"CI": "C\u00f4te d\u2019Ivoire",
|
||||
"HR": "Croatia",
|
||||
"CU": "Cuba",
|
||||
"CW": "Cura\u00e7ao",
|
||||
"CY": "Cyprus",
|
||||
"CZ": "Czechia",
|
||||
"DK": "Denmark",
|
||||
"DJ": "Djibouti",
|
||||
"DM": "Dominica",
|
||||
"DO": "Dominican Republic",
|
||||
"EC": "Ecuador",
|
||||
"EG": "Egypt",
|
||||
"SV": "El Salvador",
|
||||
"GQ": "Equatorial Guinea",
|
||||
"ER": "Eritrea",
|
||||
"EE": "Estonia",
|
||||
"SZ": "Eswatini",
|
||||
"ET": "Ethiopia",
|
||||
"FK": "Falkland Islands",
|
||||
"FO": "Faroe Islands",
|
||||
"FJ": "Fiji",
|
||||
"FI": "Finland",
|
||||
"FR": "France",
|
||||
"GF": "French Guiana",
|
||||
"PF": "French Polynesia",
|
||||
"TF": "French Southern Territories",
|
||||
"GA": "Gabon",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgia",
|
||||
"DE": "Germany",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GR": "Greece",
|
||||
"GL": "Greenland",
|
||||
"GD": "Grenada",
|
||||
"GP": "Guadeloupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea-Bissau",
|
||||
"GY": "Guyana",
|
||||
"HT": "Haiti",
|
||||
"HM": "Heard & McDonald Islands",
|
||||
"HN": "Honduras",
|
||||
"HK": "Hong Kong SAR China",
|
||||
"HU": "Hungary",
|
||||
"IS": "Iceland",
|
||||
"IN": "India",
|
||||
"ID": "Indonesia",
|
||||
"IR": "Iran",
|
||||
"IQ": "Iraq",
|
||||
"IE": "Ireland",
|
||||
"IM": "Isle of Man",
|
||||
"IL": "Israel",
|
||||
"IT": "Italy",
|
||||
"JM": "Jamaica",
|
||||
"JP": "Japan",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordan",
|
||||
"KZ": "Kazakhstan",
|
||||
"KE": "Kenya",
|
||||
"KI": "Kiribati",
|
||||
"XK": "Kosovo",
|
||||
"KW": "Kuwait",
|
||||
"KG": "Kyrgyzstan",
|
||||
"LA": "Laos",
|
||||
"LV": "Latvia",
|
||||
"LB": "Lebanon",
|
||||
"LS": "Lesotho",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libya",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Lithuania",
|
||||
"LU": "Luxembourg",
|
||||
"MO": "Macao SAR China",
|
||||
"MG": "Madagascar",
|
||||
"MW": "Malawi",
|
||||
"MY": "Malaysia",
|
||||
"MV": "Maldives",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MH": "Marshall Islands",
|
||||
"MQ": "Martinique",
|
||||
"MR": "Mauritania",
|
||||
"MU": "Mauritius",
|
||||
"YT": "Mayotte",
|
||||
"MX": "Mexico",
|
||||
"FM": "Micronesia",
|
||||
"MD": "Moldova",
|
||||
"MC": "Monaco",
|
||||
"MN": "Mongolia",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MA": "Morocco",
|
||||
"MZ": "Mozambique",
|
||||
"MM": "Myanmar (Burma)",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NL": "Netherlands",
|
||||
"NC": "New Caledonia",
|
||||
"NZ": "New Zealand",
|
||||
"NI": "Nicaragua",
|
||||
"NE": "Niger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"NF": "Norfolk Island",
|
||||
"KP": "North Korea",
|
||||
"MK": "North Macedonia",
|
||||
"MP": "Northern Mariana Islands",
|
||||
"NO": "Norway",
|
||||
"OM": "Oman",
|
||||
"PK": "Pakistan",
|
||||
"PW": "Palau",
|
||||
"PS": "Palestinian Territories",
|
||||
"PA": "Panama",
|
||||
"PG": "Papua New Guinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Peru",
|
||||
"PH": "Philippines",
|
||||
"PN": "Pitcairn Islands",
|
||||
"PL": "Poland",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"QA": "Qatar",
|
||||
"RE": "R\u00e9union",
|
||||
"RO": "Romania",
|
||||
"RU": "Russia",
|
||||
"RW": "Rwanda",
|
||||
"WS": "Samoa",
|
||||
"SM": "San Marino",
|
||||
"ST": "S\u00e3o Tom\u00e9 & Pr\u00edncipe",
|
||||
"SA": "Saudi Arabia",
|
||||
"SN": "Senegal",
|
||||
"RS": "Serbia",
|
||||
"SC": "Seychelles",
|
||||
"SL": "Sierra Leone",
|
||||
"SG": "Singapore",
|
||||
"SX": "Sint Maarten",
|
||||
"SK": "Slovakia",
|
||||
"SI": "Slovenia",
|
||||
"SB": "Solomon Islands",
|
||||
"SO": "Somalia",
|
||||
"ZA": "South Africa",
|
||||
"GS": "South Georgia & South Sandwich Islands",
|
||||
"KR": "South Korea",
|
||||
"SS": "South Sudan",
|
||||
"ES": "Spain",
|
||||
"LK": "Sri Lanka",
|
||||
"BL": "St. Barth\u00e9lemy",
|
||||
"SH": "St. Helena",
|
||||
"KN": "St. Kitts & Nevis",
|
||||
"LC": "St. Lucia",
|
||||
"MF": "St. Martin",
|
||||
"PM": "St. Pierre & Miquelon",
|
||||
"VC": "St. Vincent & Grenadines",
|
||||
"SD": "Sudan",
|
||||
"SR": "Suriname",
|
||||
"SJ": "Svalbard & Jan Mayen",
|
||||
"SE": "Sweden",
|
||||
"CH": "Switzerland",
|
||||
"SY": "Syria",
|
||||
"TW": "Taiwan",
|
||||
"TJ": "Tajikistan",
|
||||
"TZ": "Tanzania",
|
||||
"TH": "Thailand",
|
||||
"TL": "Timor-Leste",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad & Tobago",
|
||||
"TN": "Tunisia",
|
||||
"TR": "Turkey",
|
||||
"TM": "Turkmenistan",
|
||||
"TC": "Turks & Caicos Islands",
|
||||
"TV": "Tuvalu",
|
||||
"UM": "U.S. Outlying Islands",
|
||||
"VI": "U.S. Virgin Islands",
|
||||
"UG": "Uganda",
|
||||
"UA": "Ukraine",
|
||||
"AE": "United Arab Emirates",
|
||||
"GB": "United Kingdom",
|
||||
"US": "United States",
|
||||
"UY": "Uruguay",
|
||||
"UZ": "Uzbekistan",
|
||||
"VU": "Vanuatu",
|
||||
"VA": "Vatican City",
|
||||
"VE": "Venezuela",
|
||||
"VN": "Vietnam",
|
||||
"WF": "Wallis & Futuna",
|
||||
"EH": "Western Sahara",
|
||||
"YE": "Yemen",
|
||||
"ZM": "Zambia",
|
||||
"ZW": "Zimbabwe"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,252 @@
|
|||
{"AF":"Afghanistan","AX":"\u00c5land Islands","AL":"Albania","DZ":"Algeria","AS":"American Samoa","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarctica","AG":"Antigua & Barbuda","AR":"Argentina","AM":"Armenia","AW":"Aruba","AU":"Australia","AT":"Austria","AZ":"Azerbaijan","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BY":"Belarus","BE":"Belgium","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivia","BA":"Bosnia & Herzegovina","BW":"Botswana","BV":"Bouvet Island","BR":"Brazil","IO":"British Indian Ocean Territory","VG":"British Virgin Islands","BN":"Brunei","BG":"Bulgaria","BF":"Burkina Faso","BI":"Burundi","KH":"Cambodia","CM":"Cameroon","CA":"Canada","CV":"Cape Verde","BQ":"Caribbean Netherlands","KY":"Cayman Islands","CF":"Central African Republic","TD":"Chad","CL":"Chile","CN":"China","CX":"Christmas Island","CC":"Cocos (Keeling) Islands","CO":"Colombia","KM":"Comoros","CG":"Congo - Brazzaville","CD":"Congo - Kinshasa","CK":"Cook Islands","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","HR":"Croatia","CU":"Cuba","CW":"Cura\u00e7ao","CY":"Cyprus","CZ":"Czechia","DK":"Denmark","DJ":"Djibouti","DM":"Dominica","DO":"Dominican Republic","EC":"Ecuador","EG":"Egypt","SV":"El Salvador","GQ":"Equatorial Guinea","ER":"Eritrea","EE":"Estonia","SZ":"Eswatini","ET":"Ethiopia","FK":"Falkland Islands","FO":"Faroe Islands","FJ":"Fiji","FI":"Finland","FR":"France","GF":"French Guiana","PF":"French Polynesia","TF":"French Southern Territories","GA":"Gabon","GM":"Gambia","GE":"Georgia","DE":"Germany","GH":"Ghana","GI":"Gibraltar","GR":"Greece","GL":"Greenland","GD":"Grenada","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard & McDonald Islands","HN":"Honduras","HK":"Hong Kong SAR China","HU":"Hungary","IS":"Iceland","IN":"India","ID":"Indonesia","IR":"Iran","IQ":"Iraq","IE":"Ireland","IM":"Isle of Man","IL":"Israel","IT":"Italy","JM":"Jamaica","JP":"Japan","JE":"Jersey","JO":"Jordan","KZ":"Kazakhstan","KE":"Kenya","KI":"Kiribati","KW":"Kuwait","KG":"Kyrgyzstan","LA":"Laos","LV":"Latvia","LB":"Lebanon","LS":"Lesotho","LR":"Liberia","LY":"Libya","LI":"Liechtenstein","LT":"Lithuania","LU":"Luxembourg","MO":"Macao SAR China","MG":"Madagascar","MW":"Malawi","MY":"Malaysia","MV":"Maldives","ML":"Mali","MT":"Malta","MH":"Marshall Islands","MQ":"Martinique","MR":"Mauritania","MU":"Mauritius","YT":"Mayotte","MX":"Mexico","FM":"Micronesia","MD":"Moldova","MC":"Monaco","MN":"Mongolia","ME":"Montenegro","MS":"Montserrat","MA":"Morocco","MZ":"Mozambique","MM":"Myanmar (Burma)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NL":"Netherlands","NC":"New Caledonia","NZ":"New Zealand","NI":"Nicaragua","NE":"Niger","NG":"Nigeria","NU":"Niue","NF":"Norfolk Island","KP":"North Korea","MK":"North Macedonia","MP":"Northern Mariana Islands","NO":"Norway","OM":"Oman","PK":"Pakistan","PW":"Palau","PS":"Palestinian Territories","PA":"Panama","PG":"Papua New Guinea","PY":"Paraguay","PE":"Peru","PH":"Philippines","PN":"Pitcairn Islands","PL":"Poland","PT":"Portugal","PR":"Puerto Rico","QA":"Qatar","RE":"R\u00e9union","RO":"Romania","RU":"Russia","RW":"Rwanda","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 & Pr\u00edncipe","SA":"Saudi Arabia","SN":"Senegal","RS":"Serbia","SC":"Seychelles","SL":"Sierra Leone","SG":"Singapore","SX":"Sint Maarten","SK":"Slovakia","SI":"Slovenia","SB":"Solomon Islands","SO":"Somalia","ZA":"South Africa","GS":"South Georgia & South Sandwich Islands","KR":"South Korea","SS":"South Sudan","ES":"Spain","LK":"Sri Lanka","BL":"St. Barth\u00e9lemy","SH":"St. Helena","KN":"St. Kitts & Nevis","LC":"St. Lucia","MF":"St. Martin","PM":"St. Pierre & Miquelon","VC":"St. Vincent & Grenadines","SD":"Sudan","SR":"Suriname","SJ":"Svalbard & Jan Mayen","SE":"Sweden","CH":"Switzerland","SY":"Syria","TW":"Taiwan","TJ":"Tajikistan","TZ":"Tanzania","TH":"Thailand","TL":"Timor-Leste","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad & Tobago","TN":"Tunisia","TR":"Turkey","TM":"Turkmenistan","TC":"Turks & Caicos Islands","TV":"Tuvalu","UM":"U.S. Outlying Islands","VI":"U.S. Virgin Islands","UG":"Uganda","UA":"Ukraine","AE":"United Arab Emirates","GB":"United Kingdom","US":"United States","UY":"Uruguay","UZ":"Uzbekistan","VU":"Vanuatu","VA":"Vatican City","VE":"Venezuela","VN":"Vietnam","WF":"Wallis & Futuna","EH":"Western Sahara","YE":"Yemen","ZM":"Zambia","ZW":"Zimbabwe"}
|
||||
{
|
||||
"AF": "Afghanistan",
|
||||
"AX": "\u00c5land Islands",
|
||||
"AL": "Albania",
|
||||
"DZ": "Algeria",
|
||||
"AS": "American Samoa",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Antarctica",
|
||||
"AG": "Antigua & Barbuda",
|
||||
"AR": "Argentina",
|
||||
"AM": "Armenia",
|
||||
"AW": "Aruba",
|
||||
"AU": "Australia",
|
||||
"AT": "Austria",
|
||||
"AZ": "Azerbaijan",
|
||||
"BS": "Bahamas",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesh",
|
||||
"BB": "Barbados",
|
||||
"BY": "Belarus",
|
||||
"BE": "Belgium",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Benin",
|
||||
"BM": "Bermuda",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bolivia",
|
||||
"BA": "Bosnia & Herzegovina",
|
||||
"BW": "Botswana",
|
||||
"BV": "Bouvet Island",
|
||||
"BR": "Brazil",
|
||||
"IO": "British Indian Ocean Territory",
|
||||
"VG": "British Virgin Islands",
|
||||
"BN": "Brunei",
|
||||
"BG": "Bulgaria",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"KH": "Cambodia",
|
||||
"CM": "Cameroon",
|
||||
"CA": "Canada",
|
||||
"CV": "Cape Verde",
|
||||
"BQ": "Caribbean Netherlands",
|
||||
"KY": "Cayman Islands",
|
||||
"CF": "Central African Republic",
|
||||
"TD": "Chad",
|
||||
"CL": "Chile",
|
||||
"CN": "China",
|
||||
"CX": "Christmas Island",
|
||||
"CC": "Cocos (Keeling) Islands",
|
||||
"CO": "Colombia",
|
||||
"KM": "Comoros",
|
||||
"CG": "Congo - Brazzaville",
|
||||
"CD": "Congo - Kinshasa",
|
||||
"CK": "Cook Islands",
|
||||
"CR": "Costa Rica",
|
||||
"CI": "C\u00f4te d\u2019Ivoire",
|
||||
"HR": "Croatia",
|
||||
"CU": "Cuba",
|
||||
"CW": "Cura\u00e7ao",
|
||||
"CY": "Cyprus",
|
||||
"CZ": "Czechia",
|
||||
"DK": "Denmark",
|
||||
"DJ": "Djibouti",
|
||||
"DM": "Dominica",
|
||||
"DO": "Dominican Republic",
|
||||
"EC": "Ecuador",
|
||||
"EG": "Egypt",
|
||||
"SV": "El Salvador",
|
||||
"GQ": "Equatorial Guinea",
|
||||
"ER": "Eritrea",
|
||||
"EE": "Estonia",
|
||||
"SZ": "Eswatini",
|
||||
"ET": "Ethiopia",
|
||||
"FK": "Falkland Islands",
|
||||
"FO": "Faroe Islands",
|
||||
"FJ": "Fiji",
|
||||
"FI": "Finland",
|
||||
"FR": "France",
|
||||
"GF": "French Guiana",
|
||||
"PF": "French Polynesia",
|
||||
"TF": "French Southern Territories",
|
||||
"GA": "Gabon",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgia",
|
||||
"DE": "Germany",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GR": "Greece",
|
||||
"GL": "Greenland",
|
||||
"GD": "Grenada",
|
||||
"GP": "Guadeloupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea-Bissau",
|
||||
"GY": "Guyana",
|
||||
"HT": "Haiti",
|
||||
"HM": "Heard & McDonald Islands",
|
||||
"HN": "Honduras",
|
||||
"HK": "Hong Kong SAR China",
|
||||
"HU": "Hungary",
|
||||
"IS": "Iceland",
|
||||
"IN": "India",
|
||||
"ID": "Indonesia",
|
||||
"IR": "Iran",
|
||||
"IQ": "Iraq",
|
||||
"IE": "Ireland",
|
||||
"IM": "Isle of Man",
|
||||
"IL": "Israel",
|
||||
"IT": "Italy",
|
||||
"JM": "Jamaica",
|
||||
"JP": "Japan",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordan",
|
||||
"KZ": "Kazakhstan",
|
||||
"KE": "Kenya",
|
||||
"KI": "Kiribati",
|
||||
"XK": "Kosovo",
|
||||
"KW": "Kuwait",
|
||||
"KG": "Kyrgyzstan",
|
||||
"LA": "Laos",
|
||||
"LV": "Latvia",
|
||||
"LB": "Lebanon",
|
||||
"LS": "Lesotho",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libya",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Lithuania",
|
||||
"LU": "Luxembourg",
|
||||
"MO": "Macao SAR China",
|
||||
"MG": "Madagascar",
|
||||
"MW": "Malawi",
|
||||
"MY": "Malaysia",
|
||||
"MV": "Maldives",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MH": "Marshall Islands",
|
||||
"MQ": "Martinique",
|
||||
"MR": "Mauritania",
|
||||
"MU": "Mauritius",
|
||||
"YT": "Mayotte",
|
||||
"MX": "Mexico",
|
||||
"FM": "Micronesia",
|
||||
"MD": "Moldova",
|
||||
"MC": "Monaco",
|
||||
"MN": "Mongolia",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MA": "Morocco",
|
||||
"MZ": "Mozambique",
|
||||
"MM": "Myanmar (Burma)",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NL": "Netherlands",
|
||||
"NC": "New Caledonia",
|
||||
"NZ": "New Zealand",
|
||||
"NI": "Nicaragua",
|
||||
"NE": "Niger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"NF": "Norfolk Island",
|
||||
"KP": "North Korea",
|
||||
"MK": "North Macedonia",
|
||||
"MP": "Northern Mariana Islands",
|
||||
"NO": "Norway",
|
||||
"OM": "Oman",
|
||||
"PK": "Pakistan",
|
||||
"PW": "Palau",
|
||||
"PS": "Palestinian Territories",
|
||||
"PA": "Panama",
|
||||
"PG": "Papua New Guinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Peru",
|
||||
"PH": "Philippines",
|
||||
"PN": "Pitcairn Islands",
|
||||
"PL": "Poland",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"QA": "Qatar",
|
||||
"RE": "R\u00e9union",
|
||||
"RO": "Romania",
|
||||
"RU": "Russia",
|
||||
"RW": "Rwanda",
|
||||
"WS": "Samoa",
|
||||
"SM": "San Marino",
|
||||
"ST": "S\u00e3o Tom\u00e9 & Pr\u00edncipe",
|
||||
"SA": "Saudi Arabia",
|
||||
"SN": "Senegal",
|
||||
"RS": "Serbia",
|
||||
"SC": "Seychelles",
|
||||
"SL": "Sierra Leone",
|
||||
"SG": "Singapore",
|
||||
"SX": "Sint Maarten",
|
||||
"SK": "Slovakia",
|
||||
"SI": "Slovenia",
|
||||
"SB": "Solomon Islands",
|
||||
"SO": "Somalia",
|
||||
"ZA": "South Africa",
|
||||
"GS": "South Georgia & South Sandwich Islands",
|
||||
"KR": "South Korea",
|
||||
"SS": "South Sudan",
|
||||
"ES": "Spain",
|
||||
"LK": "Sri Lanka",
|
||||
"BL": "St. Barth\u00e9lemy",
|
||||
"SH": "St. Helena",
|
||||
"KN": "St. Kitts & Nevis",
|
||||
"LC": "St. Lucia",
|
||||
"MF": "St. Martin",
|
||||
"PM": "St. Pierre & Miquelon",
|
||||
"VC": "St. Vincent & Grenadines",
|
||||
"SD": "Sudan",
|
||||
"SR": "Suriname",
|
||||
"SJ": "Svalbard & Jan Mayen",
|
||||
"SE": "Sweden",
|
||||
"CH": "Switzerland",
|
||||
"SY": "Syria",
|
||||
"TW": "Taiwan",
|
||||
"TJ": "Tajikistan",
|
||||
"TZ": "Tanzania",
|
||||
"TH": "Thailand",
|
||||
"TL": "Timor-Leste",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad & Tobago",
|
||||
"TN": "Tunisia",
|
||||
"TR": "Turkey",
|
||||
"TM": "Turkmenistan",
|
||||
"TC": "Turks & Caicos Islands",
|
||||
"TV": "Tuvalu",
|
||||
"UM": "U.S. Outlying Islands",
|
||||
"VI": "U.S. Virgin Islands",
|
||||
"UG": "Uganda",
|
||||
"UA": "Ukraine",
|
||||
"AE": "United Arab Emirates",
|
||||
"GB": "United Kingdom",
|
||||
"US": "United States",
|
||||
"UY": "Uruguay",
|
||||
"UZ": "Uzbekistan",
|
||||
"VU": "Vanuatu",
|
||||
"VA": "Vatican City",
|
||||
"VE": "Venezuela",
|
||||
"VN": "Vietnam",
|
||||
"WF": "Wallis & Futuna",
|
||||
"EH": "Western Sahara",
|
||||
"YE": "Yemen",
|
||||
"ZM": "Zambia",
|
||||
"ZW": "Zimbabwe"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@
|
|||
"KE": "Kenia",
|
||||
"KG": "Kirguist\u00e1n",
|
||||
"KI": "Kiribati",
|
||||
"XK": "Kosovo",
|
||||
"KW": "Kuwait",
|
||||
"LA": "Laos",
|
||||
"LS": "Lesoto",
|
||||
|
|
|
|||
|
|
@ -1 +1,252 @@
|
|||
{"AF":"Afganist\u00e1n","AL":"Albania","DE":"Alemania","AD":"Andorra","AO":"Angola","AI":"Anguila","AQ":"Ant\u00e1rtida","AG":"Antigua y Barbuda","SA":"Arabia Saudita","DZ":"Argelia","AR":"Argentina","AM":"Armenia","AW":"Aruba","AU":"Australia","AT":"Austria","AZ":"Azerbaiy\u00e1n","BS":"Bahamas","BD":"Banglad\u00e9s","BB":"Barbados","BH":"Bar\u00e9in","BE":"B\u00e9lgica","BZ":"Belice","BJ":"Ben\u00edn","BM":"Bermudas","BY":"Bielorrusia","BO":"Bolivia","BA":"Bosnia y Herzegovina","BW":"Botsuana","BR":"Brasil","BN":"Brun\u00e9i","BG":"Bulgaria","BF":"Burkina Faso","BI":"Burundi","BT":"But\u00e1n","CV":"Cabo Verde","KH":"Camboya","CM":"Camer\u00fan","CA":"Canad\u00e1","BQ":"Caribe neerland\u00e9s","QA":"Catar","TD":"Chad","CZ":"Chequia","CL":"Chile","CN":"China","CY":"Chipre","VA":"Ciudad del Vaticano","CO":"Colombia","KM":"Comoras","CG":"Congo","KP":"Corea del Norte","KR":"Corea del Sur","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","HR":"Croacia","CU":"Cuba","CW":"Curazao","DK":"Dinamarca","DM":"Dominica","EC":"Ecuador","EG":"Egipto","SV":"El Salvador","AE":"Emiratos \u00c1rabes Unidos","ER":"Eritrea","SK":"Eslovaquia","SI":"Eslovenia","ES":"Espa\u00f1a","US":"Estados Unidos","EE":"Estonia","SZ":"Eswatini","ET":"Etiop\u00eda","PH":"Filipinas","FI":"Finlandia","FJ":"Fiyi","FR":"Francia","GA":"Gab\u00f3n","GM":"Gambia","GE":"Georgia","GH":"Ghana","GI":"Gibraltar","GD":"Granada","GR":"Grecia","GL":"Groenlandia","GP":"Guadalupe","GU":"Guam","GT":"Guatemala","GF":"Guayana Francesa","GG":"Guernsey","GN":"Guinea","GQ":"Guinea Ecuatorial","GW":"Guinea-Bis\u00e1u","GY":"Guyana","HT":"Hait\u00ed","HN":"Honduras","HU":"Hungr\u00eda","IN":"India","ID":"Indonesia","IQ":"Irak","IR":"Ir\u00e1n","IE":"Irlanda","BV":"Isla Bouvet","IM":"Isla de Man","CX":"Isla de Navidad","NF":"Isla Norfolk","IS":"Islandia","AX":"Islas \u00c5land","KY":"Islas Caim\u00e1n","CC":"Islas Cocos","CK":"Islas Cook","FO":"Islas Feroe","GS":"Islas Georgia del Sur y Sandwich del Sur","HM":"Islas Heard y McDonald","FK":"Islas Malvinas","MP":"Islas Marianas del Norte","MH":"Islas Marshall","UM":"Islas menores alejadas de EE. UU.","PN":"Islas Pitcairn","SB":"Islas Salom\u00f3n","TC":"Islas Turcas y Caicos","VG":"Islas V\u00edrgenes Brit\u00e1nicas","VI":"Islas V\u00edrgenes de EE. UU.","IL":"Israel","IT":"Italia","JM":"Jamaica","JP":"Jap\u00f3n","JE":"Jersey","JO":"Jordania","KZ":"Kazajist\u00e1n","KE":"Kenia","KG":"Kirguist\u00e1n","KI":"Kiribati","KW":"Kuwait","LA":"Laos","LS":"Lesoto","LV":"Letonia","LB":"L\u00edbano","LR":"Liberia","LY":"Libia","LI":"Liechtenstein","LT":"Lituania","LU":"Luxemburgo","MK":"Macedonia del Norte","MG":"Madagascar","MY":"Malasia","MW":"Malaui","MV":"Maldivas","ML":"Mali","MT":"Malta","MA":"Marruecos","MQ":"Martinica","MU":"Mauricio","MR":"Mauritania","YT":"Mayotte","MX":"M\u00e9xico","FM":"Micronesia","MD":"Moldavia","MC":"M\u00f3naco","MN":"Mongolia","ME":"Montenegro","MS":"Montserrat","MZ":"Mozambique","MM":"Myanmar (Birmania)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NI":"Nicaragua","NE":"N\u00edger","NG":"Nigeria","NU":"Niue","NO":"Noruega","NC":"Nueva Caledonia","NZ":"Nueva Zelanda","OM":"Om\u00e1n","NL":"Pa\u00edses Bajos","PK":"Pakist\u00e1n","PW":"Palaos","PA":"Panam\u00e1","PG":"Pap\u00faa Nueva Guinea","PY":"Paraguay","PE":"Per\u00fa","PF":"Polinesia Francesa","PL":"Polonia","PT":"Portugal","PR":"Puerto Rico","HK":"RAE de Hong Kong (China)","MO":"RAE de Macao (China)","GB":"Reino Unido","CF":"Rep\u00fablica Centroafricana","CD":"Rep\u00fablica Democr\u00e1tica del Congo","DO":"Rep\u00fablica Dominicana","RE":"Reuni\u00f3n","RW":"Ruanda","RO":"Rumania","RU":"Rusia","EH":"S\u00e1hara Occidental","WS":"Samoa","AS":"Samoa Americana","BL":"San Bartolom\u00e9","KN":"San Crist\u00f3bal y Nieves","SM":"San Marino","MF":"San Mart\u00edn","PM":"San Pedro y Miquel\u00f3n","VC":"San Vicente y las Granadinas","SH":"Santa Elena","LC":"Santa Luc\u00eda","ST":"Santo Tom\u00e9 y Pr\u00edncipe","SN":"Senegal","RS":"Serbia","SC":"Seychelles","SL":"Sierra Leona","SG":"Singapur","SX":"Sint Maarten","SY":"Siria","SO":"Somalia","LK":"Sri Lanka","ZA":"Sud\u00e1frica","SD":"Sud\u00e1n","SS":"Sud\u00e1n del Sur","SE":"Suecia","CH":"Suiza","SR":"Surinam","SJ":"Svalbard y Jan Mayen","TH":"Tailandia","TW":"Taiw\u00e1n","TZ":"Tanzania","TJ":"Tayikist\u00e1n","IO":"Territorio Brit\u00e1nico del Oc\u00e9ano \u00cdndico","TF":"Territorios Australes Franceses","PS":"Territorios Palestinos","TL":"Timor-Leste","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad y Tobago","TN":"T\u00fanez","TM":"Turkmenist\u00e1n","TR":"Turqu\u00eda","TV":"Tuvalu","UA":"Ucrania","UG":"Uganda","UY":"Uruguay","UZ":"Uzbekist\u00e1n","VU":"Vanuatu","VE":"Venezuela","VN":"Vietnam","WF":"Wallis y Futuna","YE":"Yemen","DJ":"Yibuti","ZM":"Zambia","ZW":"Zimbabue"}
|
||||
{
|
||||
"AF": "Afganist\u00e1n",
|
||||
"AL": "Albania",
|
||||
"DE": "Alemania",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguila",
|
||||
"AQ": "Ant\u00e1rtida",
|
||||
"AG": "Antigua y Barbuda",
|
||||
"SA": "Arabia Saudita",
|
||||
"DZ": "Argelia",
|
||||
"AR": "Argentina",
|
||||
"AM": "Armenia",
|
||||
"AW": "Aruba",
|
||||
"AU": "Australia",
|
||||
"AT": "Austria",
|
||||
"AZ": "Azerbaiy\u00e1n",
|
||||
"BS": "Bahamas",
|
||||
"BD": "Banglad\u00e9s",
|
||||
"BB": "Barbados",
|
||||
"BH": "Bar\u00e9in",
|
||||
"BE": "B\u00e9lgica",
|
||||
"BZ": "Belice",
|
||||
"BJ": "Ben\u00edn",
|
||||
"BM": "Bermudas",
|
||||
"BY": "Bielorrusia",
|
||||
"BO": "Bolivia",
|
||||
"BA": "Bosnia y Herzegovina",
|
||||
"BW": "Botsuana",
|
||||
"BR": "Brasil",
|
||||
"BN": "Brun\u00e9i",
|
||||
"BG": "Bulgaria",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"BT": "But\u00e1n",
|
||||
"CV": "Cabo Verde",
|
||||
"KH": "Camboya",
|
||||
"CM": "Camer\u00fan",
|
||||
"CA": "Canad\u00e1",
|
||||
"BQ": "Caribe neerland\u00e9s",
|
||||
"QA": "Catar",
|
||||
"TD": "Chad",
|
||||
"CZ": "Chequia",
|
||||
"CL": "Chile",
|
||||
"CN": "China",
|
||||
"CY": "Chipre",
|
||||
"VA": "Ciudad del Vaticano",
|
||||
"CO": "Colombia",
|
||||
"KM": "Comoras",
|
||||
"CG": "Congo",
|
||||
"KP": "Corea del Norte",
|
||||
"KR": "Corea del Sur",
|
||||
"CR": "Costa Rica",
|
||||
"CI": "C\u00f4te d\u2019Ivoire",
|
||||
"HR": "Croacia",
|
||||
"CU": "Cuba",
|
||||
"CW": "Curazao",
|
||||
"DK": "Dinamarca",
|
||||
"DM": "Dominica",
|
||||
"EC": "Ecuador",
|
||||
"EG": "Egipto",
|
||||
"SV": "El Salvador",
|
||||
"AE": "Emiratos \u00c1rabes Unidos",
|
||||
"ER": "Eritrea",
|
||||
"SK": "Eslovaquia",
|
||||
"SI": "Eslovenia",
|
||||
"ES": "Espa\u00f1a",
|
||||
"US": "Estados Unidos",
|
||||
"EE": "Estonia",
|
||||
"SZ": "Eswatini",
|
||||
"ET": "Etiop\u00eda",
|
||||
"PH": "Filipinas",
|
||||
"FI": "Finlandia",
|
||||
"FJ": "Fiyi",
|
||||
"FR": "Francia",
|
||||
"GA": "Gab\u00f3n",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgia",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GD": "Granada",
|
||||
"GR": "Grecia",
|
||||
"GL": "Groenlandia",
|
||||
"GP": "Guadalupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GF": "Guayana Francesa",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GQ": "Guinea Ecuatorial",
|
||||
"GW": "Guinea-Bis\u00e1u",
|
||||
"GY": "Guyana",
|
||||
"HT": "Hait\u00ed",
|
||||
"HN": "Honduras",
|
||||
"HU": "Hungr\u00eda",
|
||||
"IN": "India",
|
||||
"ID": "Indonesia",
|
||||
"IQ": "Irak",
|
||||
"IR": "Ir\u00e1n",
|
||||
"IE": "Irlanda",
|
||||
"BV": "Isla Bouvet",
|
||||
"IM": "Isla de Man",
|
||||
"CX": "Isla de Navidad",
|
||||
"NF": "Isla Norfolk",
|
||||
"IS": "Islandia",
|
||||
"AX": "Islas \u00c5land",
|
||||
"KY": "Islas Caim\u00e1n",
|
||||
"CC": "Islas Cocos",
|
||||
"CK": "Islas Cook",
|
||||
"FO": "Islas Feroe",
|
||||
"GS": "Islas Georgia del Sur y Sandwich del Sur",
|
||||
"HM": "Islas Heard y McDonald",
|
||||
"FK": "Islas Malvinas",
|
||||
"MP": "Islas Marianas del Norte",
|
||||
"MH": "Islas Marshall",
|
||||
"UM": "Islas menores alejadas de EE. UU.",
|
||||
"PN": "Islas Pitcairn",
|
||||
"SB": "Islas Salom\u00f3n",
|
||||
"TC": "Islas Turcas y Caicos",
|
||||
"VG": "Islas V\u00edrgenes Brit\u00e1nicas",
|
||||
"VI": "Islas V\u00edrgenes de EE. UU.",
|
||||
"IL": "Israel",
|
||||
"IT": "Italia",
|
||||
"JM": "Jamaica",
|
||||
"JP": "Jap\u00f3n",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordania",
|
||||
"KZ": "Kazajist\u00e1n",
|
||||
"KE": "Kenia",
|
||||
"KG": "Kirguist\u00e1n",
|
||||
"KI": "Kiribati",
|
||||
"XK": "Kosovo",
|
||||
"KW": "Kuwait",
|
||||
"LA": "Laos",
|
||||
"LS": "Lesoto",
|
||||
"LV": "Letonia",
|
||||
"LB": "L\u00edbano",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libia",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Lituania",
|
||||
"LU": "Luxemburgo",
|
||||
"MK": "Macedonia del Norte",
|
||||
"MG": "Madagascar",
|
||||
"MY": "Malasia",
|
||||
"MW": "Malaui",
|
||||
"MV": "Maldivas",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MA": "Marruecos",
|
||||
"MQ": "Martinica",
|
||||
"MU": "Mauricio",
|
||||
"MR": "Mauritania",
|
||||
"YT": "Mayotte",
|
||||
"MX": "M\u00e9xico",
|
||||
"FM": "Micronesia",
|
||||
"MD": "Moldavia",
|
||||
"MC": "M\u00f3naco",
|
||||
"MN": "Mongolia",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MZ": "Mozambique",
|
||||
"MM": "Myanmar (Birmania)",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NI": "Nicaragua",
|
||||
"NE": "N\u00edger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"NO": "Noruega",
|
||||
"NC": "Nueva Caledonia",
|
||||
"NZ": "Nueva Zelanda",
|
||||
"OM": "Om\u00e1n",
|
||||
"NL": "Pa\u00edses Bajos",
|
||||
"PK": "Pakist\u00e1n",
|
||||
"PW": "Palaos",
|
||||
"PA": "Panam\u00e1",
|
||||
"PG": "Pap\u00faa Nueva Guinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Per\u00fa",
|
||||
"PF": "Polinesia Francesa",
|
||||
"PL": "Polonia",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"HK": "RAE de Hong Kong (China)",
|
||||
"MO": "RAE de Macao (China)",
|
||||
"GB": "Reino Unido",
|
||||
"CF": "Rep\u00fablica Centroafricana",
|
||||
"CD": "Rep\u00fablica Democr\u00e1tica del Congo",
|
||||
"DO": "Rep\u00fablica Dominicana",
|
||||
"RE": "Reuni\u00f3n",
|
||||
"RW": "Ruanda",
|
||||
"RO": "Rumania",
|
||||
"RU": "Rusia",
|
||||
"EH": "S\u00e1hara Occidental",
|
||||
"WS": "Samoa",
|
||||
"AS": "Samoa Americana",
|
||||
"BL": "San Bartolom\u00e9",
|
||||
"KN": "San Crist\u00f3bal y Nieves",
|
||||
"SM": "San Marino",
|
||||
"MF": "San Mart\u00edn",
|
||||
"PM": "San Pedro y Miquel\u00f3n",
|
||||
"VC": "San Vicente y las Granadinas",
|
||||
"SH": "Santa Elena",
|
||||
"LC": "Santa Luc\u00eda",
|
||||
"ST": "Santo Tom\u00e9 y Pr\u00edncipe",
|
||||
"SN": "Senegal",
|
||||
"RS": "Serbia",
|
||||
"SC": "Seychelles",
|
||||
"SL": "Sierra Leona",
|
||||
"SG": "Singapur",
|
||||
"SX": "Sint Maarten",
|
||||
"SY": "Siria",
|
||||
"SO": "Somalia",
|
||||
"LK": "Sri Lanka",
|
||||
"ZA": "Sud\u00e1frica",
|
||||
"SD": "Sud\u00e1n",
|
||||
"SS": "Sud\u00e1n del Sur",
|
||||
"SE": "Suecia",
|
||||
"CH": "Suiza",
|
||||
"SR": "Surinam",
|
||||
"SJ": "Svalbard y Jan Mayen",
|
||||
"TH": "Tailandia",
|
||||
"TW": "Taiw\u00e1n",
|
||||
"TZ": "Tanzania",
|
||||
"TJ": "Tayikist\u00e1n",
|
||||
"IO": "Territorio Brit\u00e1nico del Oc\u00e9ano \u00cdndico",
|
||||
"TF": "Territorios Australes Franceses",
|
||||
"PS": "Territorios Palestinos",
|
||||
"TL": "Timor-Leste",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad y Tobago",
|
||||
"TN": "T\u00fanez",
|
||||
"TM": "Turkmenist\u00e1n",
|
||||
"TR": "Turqu\u00eda",
|
||||
"TV": "Tuvalu",
|
||||
"UA": "Ucrania",
|
||||
"UG": "Uganda",
|
||||
"UY": "Uruguay",
|
||||
"UZ": "Uzbekist\u00e1n",
|
||||
"VU": "Vanuatu",
|
||||
"VE": "Venezuela",
|
||||
"VN": "Vietnam",
|
||||
"WF": "Wallis y Futuna",
|
||||
"YE": "Yemen",
|
||||
"DJ": "Yibuti",
|
||||
"ZM": "Zambia",
|
||||
"ZW": "Zimbabue"
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1,252 @@
|
|||
{"AF":"Afganistan","AX":"Ahvenanmaa","NL":"Alankomaat","AL":"Albania","DZ":"Algeria","AS":"Amerikan Samoa","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarktis","AG":"Antigua ja Barbuda","AE":"Arabiemiirikunnat","AR":"Argentiina","AM":"Armenia","AW":"Aruba","AU":"Australia","AZ":"Azerbaid\u017ean","BS":"Bahama","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BE":"Belgia","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivia","BA":"Bosnia ja Hertsegovina","BW":"Botswana","BV":"Bouvet\u2019nsaari","BR":"Brasilia","IO":"Brittil\u00e4inen Intian valtameren alue","VG":"Brittil\u00e4iset Neitsytsaaret","BN":"Brunei","BG":"Bulgaria","BF":"Burkina Faso","BI":"Burundi","KY":"Caymansaaret","CL":"Chile","CK":"Cookinsaaret","CR":"Costa Rica","CW":"Cura\u00e7ao","DJ":"Djibouti","DM":"Dominica","DO":"Dominikaaninen tasavalta","EC":"Ecuador","EG":"Egypti","SV":"El Salvador","ER":"Eritrea","ES":"Espanja","ZA":"Etel\u00e4-Afrikka","GS":"Etel\u00e4-Georgia ja Etel\u00e4iset Sandwichsaaret","KR":"Etel\u00e4-Korea","SS":"Etel\u00e4-Sudan","ET":"Etiopia","FK":"Falklandinsaaret","FJ":"Fid\u017ei","PH":"Filippiinit","FO":"F\u00e4rsaaret","GA":"Gabon","GM":"Gambia","GE":"Georgia","GH":"Ghana","GI":"Gibraltar","GD":"Grenada","GL":"Gr\u00f6nlanti","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard ja McDonaldinsaaret","HN":"Honduras","HK":"Hongkong \u2013 Kiinan e.h.a.","SJ":"Huippuvuoret ja Jan Mayen","ID":"Indonesia","IN":"Intia","IQ":"Irak","IR":"Iran","IE":"Irlanti","IS":"Islanti","GB":"Iso-Britannia","IL":"Israel","IT":"Italia","TL":"It\u00e4-Timor","AT":"It\u00e4valta","JM":"Jamaika","JP":"Japani","YE":"Jemen","JE":"Jersey","JO":"Jordania","CX":"Joulusaari","KH":"Kambod\u017ea","CM":"Kamerun","CA":"Kanada","CV":"Kap Verde","BQ":"Karibian Alankomaat","KZ":"Kazakstan","KE":"Kenia","CF":"Keski-Afrikan tasavalta","CN":"Kiina","KG":"Kirgisia","KI":"Kiribati","CO":"Kolumbia","KM":"Komorit","CD":"Kongon demokraattinen tasavalta","CG":"Kongon tasavalta","CC":"Kookossaaret (Keelingsaaret)","GR":"Kreikka","HR":"Kroatia","CU":"Kuuba","KW":"Kuwait","CY":"Kypros","LA":"Laos","LV":"Latvia","LS":"Lesotho","LB":"Libanon","LR":"Liberia","LY":"Libya","LI":"Liechtenstein","LT":"Liettua","LU":"Luxemburg","EH":"L\u00e4nsi-Sahara","MO":"Macao \u2013 Kiinan e.h.a.","MG":"Madagaskar","MW":"Malawi","MV":"Malediivit","MY":"Malesia","ML":"Mali","MT":"Malta","IM":"Mansaari","MA":"Marokko","MH":"Marshallinsaaret","MQ":"Martinique","MR":"Mauritania","MU":"Mauritius","YT":"Mayotte","MX":"Meksiko","FM":"Mikronesian liittovaltio","MD":"Moldova","MC":"Monaco","MN":"Mongolia","ME":"Montenegro","MS":"Montserrat","MZ":"Mosambik","MM":"Myanmar (Burma)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NI":"Nicaragua","NE":"Niger","NG":"Nigeria","NU":"Niue","NF":"Norfolkinsaari","NO":"Norja","CI":"Norsunluurannikko","OM":"Oman","PK":"Pakistan","PW":"Palau","PS":"Palestiinalaisalueet","PA":"Panama","PG":"Papua-Uusi-Guinea","PY":"Paraguay","PE":"Peru","PN":"Pitcairn","KP":"Pohjois-Korea","MK":"Pohjois-Makedonia","MP":"Pohjois-Mariaanit","PT":"Portugali","PR":"Puerto Rico","PL":"Puola","GQ":"P\u00e4iv\u00e4ntasaajan Guinea","QA":"Qatar","FR":"Ranska","TF":"Ranskan etel\u00e4iset alueet","GF":"Ranskan Guayana","PF":"Ranskan Polynesia","RE":"R\u00e9union","RO":"Romania","RW":"Ruanda","SE":"Ruotsi","SH":"Saint Helena","KN":"Saint Kitts ja Nevis","LC":"Saint Lucia","VC":"Saint Vincent ja Grenadiinit","BL":"Saint-Barth\u00e9lemy","MF":"Saint-Martin","PM":"Saint-Pierre ja Miquelon","DE":"Saksa","SB":"Salomonsaaret","ZM":"Sambia","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 ja Pr\u00edncipe","SA":"Saudi-Arabia","SN":"Senegal","RS":"Serbia","SC":"Seychellit","SL":"Sierra Leone","SG":"Singapore","SX":"Sint Maarten","SK":"Slovakia","SI":"Slovenia","SO":"Somalia","LK":"Sri Lanka","SD":"Sudan","FI":"Suomi","SR":"Suriname","CH":"Sveitsi","SZ":"Swazimaa","SY":"Syyria","TJ":"Tad\u017eikistan","TW":"Taiwan","TZ":"Tansania","DK":"Tanska","TH":"Thaimaa","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad ja Tobago","TD":"T\u0161ad","CZ":"T\u0161ekki","TN":"Tunisia","TR":"Turkki","TM":"Turkmenistan","TC":"Turks- ja Caicossaaret","TV":"Tuvalu","UG":"Uganda","UA":"Ukraina","HU":"Unkari","UY":"Uruguay","NC":"Uusi-Kaledonia","NZ":"Uusi-Seelanti","UZ":"Uzbekistan","BY":"Valko-Ven\u00e4j\u00e4","VU":"Vanuatu","VA":"Vatikaani","VE":"Venezuela","RU":"Ven\u00e4j\u00e4","VN":"Vietnam","EE":"Viro","WF":"Wallis ja Futuna","US":"Yhdysvallat","UM":"Yhdysvaltain erillissaaret","VI":"Yhdysvaltain Neitsytsaaret","ZW":"Zimbabwe"}
|
||||
{
|
||||
"AF": "Afganistan",
|
||||
"AX": "Ahvenanmaa",
|
||||
"NL": "Alankomaat",
|
||||
"AL": "Albania",
|
||||
"DZ": "Algeria",
|
||||
"AS": "Amerikan Samoa",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Antarktis",
|
||||
"AG": "Antigua ja Barbuda",
|
||||
"AE": "Arabiemiirikunnat",
|
||||
"AR": "Argentiina",
|
||||
"AM": "Armenia",
|
||||
"AW": "Aruba",
|
||||
"AU": "Australia",
|
||||
"AZ": "Azerbaid\u017ean",
|
||||
"BS": "Bahama",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesh",
|
||||
"BB": "Barbados",
|
||||
"BE": "Belgia",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Benin",
|
||||
"BM": "Bermuda",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bolivia",
|
||||
"BA": "Bosnia ja Hertsegovina",
|
||||
"BW": "Botswana",
|
||||
"BV": "Bouvet\u2019nsaari",
|
||||
"BR": "Brasilia",
|
||||
"IO": "Brittil\u00e4inen Intian valtameren alue",
|
||||
"VG": "Brittil\u00e4iset Neitsytsaaret",
|
||||
"BN": "Brunei",
|
||||
"BG": "Bulgaria",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"KY": "Caymansaaret",
|
||||
"CL": "Chile",
|
||||
"CK": "Cookinsaaret",
|
||||
"CR": "Costa Rica",
|
||||
"CW": "Cura\u00e7ao",
|
||||
"DJ": "Djibouti",
|
||||
"DM": "Dominica",
|
||||
"DO": "Dominikaaninen tasavalta",
|
||||
"EC": "Ecuador",
|
||||
"EG": "Egypti",
|
||||
"SV": "El Salvador",
|
||||
"ER": "Eritrea",
|
||||
"ES": "Espanja",
|
||||
"ZA": "Etel\u00e4-Afrikka",
|
||||
"GS": "Etel\u00e4-Georgia ja Etel\u00e4iset Sandwichsaaret",
|
||||
"KR": "Etel\u00e4-Korea",
|
||||
"SS": "Etel\u00e4-Sudan",
|
||||
"ET": "Etiopia",
|
||||
"FK": "Falklandinsaaret",
|
||||
"FJ": "Fid\u017ei",
|
||||
"PH": "Filippiinit",
|
||||
"FO": "F\u00e4rsaaret",
|
||||
"GA": "Gabon",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgia",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GD": "Grenada",
|
||||
"GL": "Gr\u00f6nlanti",
|
||||
"GP": "Guadeloupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea-Bissau",
|
||||
"GY": "Guyana",
|
||||
"HT": "Haiti",
|
||||
"HM": "Heard ja McDonaldinsaaret",
|
||||
"HN": "Honduras",
|
||||
"HK": "Hongkong \u2013 Kiinan e.h.a.",
|
||||
"SJ": "Huippuvuoret ja Jan Mayen",
|
||||
"ID": "Indonesia",
|
||||
"IN": "Intia",
|
||||
"IQ": "Irak",
|
||||
"IR": "Iran",
|
||||
"IE": "Irlanti",
|
||||
"IS": "Islanti",
|
||||
"GB": "Iso-Britannia",
|
||||
"IL": "Israel",
|
||||
"IT": "Italia",
|
||||
"TL": "It\u00e4-Timor",
|
||||
"AT": "It\u00e4valta",
|
||||
"JM": "Jamaika",
|
||||
"JP": "Japani",
|
||||
"YE": "Jemen",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordania",
|
||||
"CX": "Joulusaari",
|
||||
"KH": "Kambod\u017ea",
|
||||
"CM": "Kamerun",
|
||||
"CA": "Kanada",
|
||||
"CV": "Kap Verde",
|
||||
"BQ": "Karibian Alankomaat",
|
||||
"KZ": "Kazakstan",
|
||||
"KE": "Kenia",
|
||||
"CF": "Keski-Afrikan tasavalta",
|
||||
"CN": "Kiina",
|
||||
"KG": "Kirgisia",
|
||||
"KI": "Kiribati",
|
||||
"CO": "Kolumbia",
|
||||
"KM": "Komorit",
|
||||
"CD": "Kongon demokraattinen tasavalta",
|
||||
"CG": "Kongon tasavalta",
|
||||
"CC": "Kookossaaret (Keelingsaaret)",
|
||||
"XK": "Kosovo",
|
||||
"GR": "Kreikka",
|
||||
"HR": "Kroatia",
|
||||
"CU": "Kuuba",
|
||||
"KW": "Kuwait",
|
||||
"CY": "Kypros",
|
||||
"LA": "Laos",
|
||||
"LV": "Latvia",
|
||||
"LS": "Lesotho",
|
||||
"LB": "Libanon",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libya",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Liettua",
|
||||
"LU": "Luxemburg",
|
||||
"EH": "L\u00e4nsi-Sahara",
|
||||
"MO": "Macao \u2013 Kiinan e.h.a.",
|
||||
"MG": "Madagaskar",
|
||||
"MW": "Malawi",
|
||||
"MV": "Malediivit",
|
||||
"MY": "Malesia",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"IM": "Mansaari",
|
||||
"MA": "Marokko",
|
||||
"MH": "Marshallinsaaret",
|
||||
"MQ": "Martinique",
|
||||
"MR": "Mauritania",
|
||||
"MU": "Mauritius",
|
||||
"YT": "Mayotte",
|
||||
"MX": "Meksiko",
|
||||
"FM": "Mikronesian liittovaltio",
|
||||
"MD": "Moldova",
|
||||
"MC": "Monaco",
|
||||
"MN": "Mongolia",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MZ": "Mosambik",
|
||||
"MM": "Myanmar (Burma)",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NI": "Nicaragua",
|
||||
"NE": "Niger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"NF": "Norfolkinsaari",
|
||||
"NO": "Norja",
|
||||
"CI": "Norsunluurannikko",
|
||||
"OM": "Oman",
|
||||
"PK": "Pakistan",
|
||||
"PW": "Palau",
|
||||
"PS": "Palestiinalaisalueet",
|
||||
"PA": "Panama",
|
||||
"PG": "Papua-Uusi-Guinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Peru",
|
||||
"PN": "Pitcairn",
|
||||
"KP": "Pohjois-Korea",
|
||||
"MK": "Pohjois-Makedonia",
|
||||
"MP": "Pohjois-Mariaanit",
|
||||
"PT": "Portugali",
|
||||
"PR": "Puerto Rico",
|
||||
"PL": "Puola",
|
||||
"GQ": "P\u00e4iv\u00e4ntasaajan Guinea",
|
||||
"QA": "Qatar",
|
||||
"FR": "Ranska",
|
||||
"TF": "Ranskan etel\u00e4iset alueet",
|
||||
"GF": "Ranskan Guayana",
|
||||
"PF": "Ranskan Polynesia",
|
||||
"RE": "R\u00e9union",
|
||||
"RO": "Romania",
|
||||
"RW": "Ruanda",
|
||||
"SE": "Ruotsi",
|
||||
"SH": "Saint Helena",
|
||||
"KN": "Saint Kitts ja Nevis",
|
||||
"LC": "Saint Lucia",
|
||||
"VC": "Saint Vincent ja Grenadiinit",
|
||||
"BL": "Saint-Barth\u00e9lemy",
|
||||
"MF": "Saint-Martin",
|
||||
"PM": "Saint-Pierre ja Miquelon",
|
||||
"DE": "Saksa",
|
||||
"SB": "Salomonsaaret",
|
||||
"ZM": "Sambia",
|
||||
"WS": "Samoa",
|
||||
"SM": "San Marino",
|
||||
"ST": "S\u00e3o Tom\u00e9 ja Pr\u00edncipe",
|
||||
"SA": "Saudi-Arabia",
|
||||
"SN": "Senegal",
|
||||
"RS": "Serbia",
|
||||
"SC": "Seychellit",
|
||||
"SL": "Sierra Leone",
|
||||
"SG": "Singapore",
|
||||
"SX": "Sint Maarten",
|
||||
"SK": "Slovakia",
|
||||
"SI": "Slovenia",
|
||||
"SO": "Somalia",
|
||||
"LK": "Sri Lanka",
|
||||
"SD": "Sudan",
|
||||
"FI": "Suomi",
|
||||
"SR": "Suriname",
|
||||
"CH": "Sveitsi",
|
||||
"SZ": "Swazimaa",
|
||||
"SY": "Syyria",
|
||||
"TJ": "Tad\u017eikistan",
|
||||
"TW": "Taiwan",
|
||||
"TZ": "Tansania",
|
||||
"DK": "Tanska",
|
||||
"TH": "Thaimaa",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad ja Tobago",
|
||||
"TD": "T\u0161ad",
|
||||
"CZ": "T\u0161ekki",
|
||||
"TN": "Tunisia",
|
||||
"TR": "Turkki",
|
||||
"TM": "Turkmenistan",
|
||||
"TC": "Turks- ja Caicossaaret",
|
||||
"TV": "Tuvalu",
|
||||
"UG": "Uganda",
|
||||
"UA": "Ukraina",
|
||||
"HU": "Unkari",
|
||||
"UY": "Uruguay",
|
||||
"NC": "Uusi-Kaledonia",
|
||||
"NZ": "Uusi-Seelanti",
|
||||
"UZ": "Uzbekistan",
|
||||
"BY": "Valko-Ven\u00e4j\u00e4",
|
||||
"VU": "Vanuatu",
|
||||
"VA": "Vatikaani",
|
||||
"VE": "Venezuela",
|
||||
"RU": "Ven\u00e4j\u00e4",
|
||||
"VN": "Vietnam",
|
||||
"EE": "Viro",
|
||||
"WF": "Wallis ja Futuna",
|
||||
"US": "Yhdysvallat",
|
||||
"UM": "Yhdysvaltain erillissaaret",
|
||||
"VI": "Yhdysvaltain Neitsytsaaret",
|
||||
"ZW": "Zimbabwe"
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue