mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-29 14:45:07 +03:00
1. added multipath protocol and schema suport
2. added SCTP protocol and schema support 3. added set of NAS models support (Asustor, ReadyNAS, Drobo, QNAP, WD, Synology, Terramaster) 4. moved to fc00::/7 private segment 5. added Windows, MacOS and Linux UI for peers edit and current status
This commit is contained in:
parent
cfa293d189
commit
d8a4000141
198 changed files with 8589 additions and 697 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
|
||||
This file generates crypto keys for [ansible-yggdrasil](https://github.com/jcgruenhage/ansible-yggdrasil/)
|
||||
This file generates crypto keys for [ansible-mesh](https://github.com/jcgruenhage/ansible-mesh/)
|
||||
|
||||
*/
|
||||
package main
|
||||
|
@ -14,7 +14,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/cheggaaa/pb/v3"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||
"github.com/RiV-chain/RiV-mesh/src/address"
|
||||
)
|
||||
|
||||
var numHosts = flag.Int("hosts", 1, "number of host vars to generate")
|
||||
|
@ -57,8 +57,8 @@ func main() {
|
|||
return
|
||||
}
|
||||
defer file.Close()
|
||||
file.WriteString(fmt.Sprintf("yggdrasil_public_key: %v\n", hex.EncodeToString(keys[i].pub)))
|
||||
file.WriteString("yggdrasil_private_key: \"{{ vault_yggdrasil_private_key }}\"\n")
|
||||
file.WriteString(fmt.Sprintf("mesh_public_key: %v\n", hex.EncodeToString(keys[i].pub)))
|
||||
file.WriteString("mesh_private_key: \"{{ vault_mesh_private_key }}\"\n")
|
||||
file.WriteString(fmt.Sprintf("ansible_host: %v\n", keys[i].ip))
|
||||
|
||||
file, err = os.Create(fmt.Sprintf("host_vars/%x/vault", i))
|
||||
|
@ -66,7 +66,7 @@ func main() {
|
|||
return
|
||||
}
|
||||
defer file.Close()
|
||||
file.WriteString(fmt.Sprintf("vault_yggdrasil_private_key: %v\n", hex.EncodeToString(keys[i].priv)))
|
||||
file.WriteString(fmt.Sprintf("vault_mesh_private_key: %v\n", hex.EncodeToString(keys[i].priv)))
|
||||
bar.Increment()
|
||||
}
|
||||
bar.Finish()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Last Modified: Fri Oct 30 11:33:31 2020
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/bin/yggdrasil {
|
||||
/usr/bin/mesh {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/nameservice>
|
||||
|
||||
|
@ -12,6 +12,6 @@
|
|||
/proc/sys/net/core/somaxconn r,
|
||||
/sys/kernel/mm/transparent_hugepage/hpage_pmd_size r,
|
||||
|
||||
/etc/yggdrasil.conf rw,
|
||||
/run/yggdrasil.sock rw,
|
||||
/etc/mesh.conf rw,
|
||||
/run/mesh.sock rw,
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
CONFFILE="/etc/yggdrasil.conf"
|
||||
CONFFILE="/etc/mesh.conf"
|
||||
|
||||
genconf() {
|
||||
/usr/bin/yggdrasil -genconf > "$1"
|
||||
/usr/bin/mesh -genconf > "$1"
|
||||
return $?
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,8 @@ start() {
|
|||
fi
|
||||
fi
|
||||
|
||||
printf 'Starting yggdrasil: '
|
||||
if start-stop-daemon -S -q -b -x /usr/bin/yggdrasil \
|
||||
printf 'Starting mesh: '
|
||||
if start-stop-daemon -S -q -b -x /usr/bin/mesh \
|
||||
-- -useconffile "$CONFFILE"; then
|
||||
echo "OK"
|
||||
else
|
||||
|
@ -43,8 +43,8 @@ start() {
|
|||
}
|
||||
|
||||
stop() {
|
||||
printf "Stopping yggdrasil: "
|
||||
if start-stop-daemon -K -q -x /usr/bin/yggdrasil; then
|
||||
printf "Stopping mesh: "
|
||||
if start-stop-daemon -K -q -x /usr/bin/mesh; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL"
|
||||
|
@ -52,8 +52,8 @@ stop() {
|
|||
}
|
||||
|
||||
reload() {
|
||||
printf "Reloading yggdrasil: "
|
||||
if start-stop-daemon -K -q -s HUP -x /usr/bin/yggdrasil; then
|
||||
printf "Reloading mesh: "
|
||||
if start-stop-daemon -K -q -s HUP -x /usr/bin/mesh; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL"
|
165
contrib/deb/generate-gui.sh
Executable file
165
contrib/deb/generate-gui.sh
Executable file
|
@ -0,0 +1,165 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .deb for Debian/Ubuntu. It installs
|
||||
# mesh and enables it in systemd. You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=i386 sh contrib/deb/generate.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGNAME=$PKG-$PKGVERSION-$PKGARCH
|
||||
PKGFILE=$PKGNAME.deb
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build
|
||||
elif [ $PKGARCH = "i386" ]; then GOARCH=386 GOOS=linux ./build
|
||||
else
|
||||
echo "Specify PKGARCH=amd64,i386,mips,mipsel,armhf,arm64,armel"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGFILE"
|
||||
|
||||
mkdir -p /tmp/$PKGNAME/
|
||||
mkdir -p /tmp/$PKGNAME/debian/
|
||||
mkdir -p /tmp/$PKGNAME/DEBIAN/
|
||||
mkdir -p /tmp/$PKGNAME/usr/bin/
|
||||
mkdir -p /tmp/$PKGNAME/usr/local/bin/
|
||||
mkdir -p /tmp/$PKGNAME/etc/systemd/system/
|
||||
mkdir -p /tmp/$PKGNAME/usr/share/applications/
|
||||
mkdir -p /tmp/$PKGNAME/etc/
|
||||
mkdir -p /tmp/$PKGNAME/etc/xdg/autostart
|
||||
chmod 0775 /tmp/$PKGNAME/ -R
|
||||
|
||||
for resolution in 16x16 24x24 32x32 48x48 64x64 192x192 256x256 512x512; do
|
||||
echo "Converting icon for: $resolution"
|
||||
mkdir -p /tmp/$PKGNAME/usr/share/icons/hicolor/$resolution/apps && \
|
||||
convert -colorspace sRGB ./riv.png -resize $resolution PNG8:/tmp/$PKGNAME/usr/share/icons/hicolor/$resolution/apps/riv.png && \
|
||||
chmod 644 /tmp/$PKGNAME/usr/share/icons/hicolor/$resolution/apps/riv.png
|
||||
done
|
||||
|
||||
cp contrib/ui/mesh-ui/index.html /tmp/$PKGNAME/etc/
|
||||
|
||||
cat > /tmp/$PKGNAME/usr/share/applications/riv.desktop << EOF
|
||||
[Desktop Entry]
|
||||
Name=RiV mesh
|
||||
GenericName=Mesh network
|
||||
Comment=RiV-mesh is an early-stage implementation of a fully end-to-end encrypted IPv6 network
|
||||
Exec=sh -c "/usr/bin/mesh-ui /etc/index.html"
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=riv
|
||||
Categories=Network;FileTransfer;
|
||||
StartupNotify=false
|
||||
EOF
|
||||
|
||||
cat > /tmp/$PKGNAME/debian/changelog << EOF
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
echo 9 > /tmp/$PKGNAME/debian/compat
|
||||
cat > /tmp/$PKGNAME/DEBIAN/control << EOF
|
||||
Package: mesh
|
||||
Version: $PKGVERSION
|
||||
Section: contrib/net
|
||||
Priority: extra
|
||||
Architecture: $PKGARCH
|
||||
Replaces: $PKGREPLACES
|
||||
Conflicts: $PKGREPLACES
|
||||
Maintainer: Vadym Vikulin <vadym.vikulin@rivchain.org>
|
||||
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
|
||||
It is lightweight, self-arranging, supported on multiple platforms and
|
||||
allows pretty much any IPv6-capable application to communicate securely with
|
||||
other RiV-mesh nodes.
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/copyright << EOF
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/docs << EOF
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/install << EOF
|
||||
usr/bin/mesh usr/bin
|
||||
usr/bin/meshctl usr/bin
|
||||
usr/bin/mesh-ui usr/bin
|
||||
usr/local/bin/meshctl usr/local/bin
|
||||
etc/index.html etc
|
||||
etc/xdg/autostart/riv.desktop etc/xdg/autostart
|
||||
etc/systemd/system/*.service etc/systemd/system
|
||||
usr/share/applications/riv.desktop usr/share/applications
|
||||
usr/share/icons/hicolor/16x16/apps/riv.png usr/share/icons/hicolor/16x16/apps
|
||||
usr/share/icons/hicolor/24x24/apps/riv.png usr/share/icons/hicolor/24x24/apps
|
||||
usr/share/icons/hicolor/32x32/apps/riv.png usr/share/icons/hicolor/32x32/apps
|
||||
usr/share/icons/hicolor/48x48/apps/riv.png usr/share/icons/hicolor/48x48/apps
|
||||
usr/share/icons/hicolor/64x64/apps/riv.png usr/share/icons/hicolor/64x64/apps
|
||||
usr/share/icons/hicolor/192x192/apps/riv.png usr/share/icons/hicolor/192x192/apps
|
||||
usr/share/icons/hicolor/256x256/apps/riv.png usr/share/icons/hicolor/256x256/apps
|
||||
usr/share/icons/hicolor/512x512/apps/riv.png usr/share/icons/hicolor/512x512/apps
|
||||
EOF
|
||||
|
||||
cat > /tmp/$PKGNAME/DEBIAN/postinst << EOF
|
||||
#!/bin/sh
|
||||
|
||||
if ! getent group mesh 2>&1 > /dev/null; then
|
||||
groupadd --system --force mesh || echo "Failed to create group 'mesh' - please create it manually and reinstall"
|
||||
fi
|
||||
|
||||
if [ -f /etc/mesh.conf ]; then
|
||||
mkdir -p /var/backups
|
||||
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
|
||||
cp /etc/mesh.conf /var/backups/mesh.conf.`date +%Y%m%d`
|
||||
echo "Normalising and updating /etc/mesh.conf"
|
||||
/usr/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > /etc/mesh.conf
|
||||
else
|
||||
echo "Generating initial configuration file /etc/mesh.conf"
|
||||
echo "Please familiarise yourself with this file before starting Mesh"
|
||||
sh -c 'umask 0027 && /usr/bin/mesh -genconf > /etc/mesh.conf'
|
||||
fi
|
||||
chgrp mesh /etc/mesh.conf
|
||||
chmod 755 /etc/mesh.conf
|
||||
if command -v systemctl >/dev/null; then
|
||||
systemctl daemon-reload || echo -n "daemon not reloaded!"
|
||||
systemctl enable mesh || echo -n "systemctl enable failed!"
|
||||
systemctl restart mesh || echo -n "systemctl restart failed!"
|
||||
fi
|
||||
update-icon-caches /usr/share/icons/*
|
||||
update-desktop-database /usr/share/applications
|
||||
EOF
|
||||
|
||||
cat > /tmp/$PKGNAME/DEBIAN/prerm << EOF
|
||||
#!/bin/sh
|
||||
if command -v systemctl >/dev/null; then
|
||||
if systemctl is-active --quiet mesh; then
|
||||
systemctl stop mesh || true
|
||||
fi
|
||||
systemctl disable mesh || true
|
||||
fi
|
||||
EOF
|
||||
|
||||
cp mesh /tmp/$PKGNAME/usr/bin/
|
||||
cp meshctl /tmp/$PKGNAME/usr/bin/
|
||||
cp mesh-ui /tmp/$PKGNAME/usr/bin/
|
||||
ln -s /usr/bin/meshctl /tmp/$PKGNAME/usr/local/bin/meshctl
|
||||
cp contrib/systemd/*.service /tmp/$PKGNAME/etc/systemd/system/
|
||||
cp /tmp/$PKGNAME/usr/share/applications/riv.desktop /tmp/$PKGNAME/etc/xdg/autostart
|
||||
chmod 0775 /tmp/$PKGNAME/DEBIAN/*
|
||||
chmod 644 /tmp/$PKGNAME/etc/systemd/system/*
|
||||
chmod 644 /tmp/$PKGNAME/usr/share/applications/riv.desktop
|
||||
chmod 644 /tmp/$PKGNAME/etc/xdg/autostart/*
|
||||
chmod 755 /tmp/$PKGNAME/usr/bin/*
|
||||
chmod 755 /tmp/$PKGNAME/etc/index.html
|
||||
|
||||
dpkg-deb --build --root-owner-group /tmp/$PKGNAME
|
||||
cp /tmp/$PKGFILE .
|
||||
|
||||
rm -rf /tmp/$PKGNAME
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .deb for Debian/Ubuntu. It installs
|
||||
# yggdrasil and enables it in systemd. You can give it the PKGARCH= argument
|
||||
# mesh and enables it in systemd. You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=i386 sh contrib/deb/generate.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
|
@ -11,14 +11,15 @@ then
|
|||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKGNAME=$(sh contrib/semver/name.sh)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGFILE=$PKGNAME-$PKGVERSION-$PKGARCH.deb
|
||||
PKGREPLACES=yggdrasil
|
||||
PKGNAME=$PKG-$PKGVERSION-$PKGARCH-nogui
|
||||
PKGFILE=$PKGNAME.deb
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=yggdrasil-develop
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build
|
||||
|
@ -37,91 +38,92 @@ echo "Building $PKGFILE"
|
|||
|
||||
mkdir -p /tmp/$PKGNAME/
|
||||
mkdir -p /tmp/$PKGNAME/debian/
|
||||
mkdir -p /tmp/$PKGNAME/DEBIAN/
|
||||
mkdir -p /tmp/$PKGNAME/usr/bin/
|
||||
mkdir -p /tmp/$PKGNAME/usr/local/bin/
|
||||
mkdir -p /tmp/$PKGNAME/etc/systemd/system/
|
||||
chmod 0775 /tmp/$PKGNAME/ -R
|
||||
|
||||
cat > /tmp/$PKGNAME/debian/changelog << EOF
|
||||
Please see https://github.com/yggdrasil-network/yggdrasil-go/
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
echo 9 > /tmp/$PKGNAME/debian/compat
|
||||
cat > /tmp/$PKGNAME/debian/control << EOF
|
||||
Package: $PKGNAME
|
||||
cat > /tmp/$PKGNAME/DEBIAN/control << EOF
|
||||
Package: mesh
|
||||
Version: $PKGVERSION
|
||||
Section: contrib/net
|
||||
Priority: extra
|
||||
Architecture: $PKGARCH
|
||||
Replaces: $PKGREPLACES
|
||||
Conflicts: $PKGREPLACES
|
||||
Maintainer: Neil Alexander <neilalexander@users.noreply.github.com>
|
||||
Description: Yggdrasil Network
|
||||
Yggdrasil is an early-stage implementation of a fully end-to-end encrypted IPv6
|
||||
network. It is lightweight, self-arranging, supported on multiple platforms and
|
||||
Maintainer: Vadym Vikulin <vadym.vikulin@rivchain.org>
|
||||
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
|
||||
It is lightweight, self-arranging, supported on multiple platforms and
|
||||
allows pretty much any IPv6-capable application to communicate securely with
|
||||
other Yggdrasil nodes.
|
||||
other RiV-mesh nodes.
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/copyright << EOF
|
||||
Please see https://github.com/yggdrasil-network/yggdrasil-go/
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/docs << EOF
|
||||
Please see https://github.com/yggdrasil-network/yggdrasil-go/
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/install << EOF
|
||||
usr/bin/yggdrasil usr/bin
|
||||
usr/bin/yggdrasilctl usr/bin
|
||||
usr/bin/mesh usr/bin
|
||||
usr/bin/meshctl usr/bin
|
||||
usr/local/bin/meshctl usr/local/bin
|
||||
etc/systemd/system/*.service etc/systemd/system
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/postinst << EOF
|
||||
cat > /tmp/$PKGNAME/DEBIAN/postinst << EOF
|
||||
#!/bin/sh
|
||||
|
||||
if ! getent group yggdrasil 2>&1 > /dev/null; then
|
||||
groupadd --system --force yggdrasil || echo "Failed to create group 'yggdrasil' - please create it manually and reinstall"
|
||||
if ! getent group mesh 2>&1 > /dev/null; then
|
||||
groupadd --system --force mesh || echo "Failed to create group 'mesh' - please create it manually and reinstall"
|
||||
fi
|
||||
|
||||
if [ -f /etc/yggdrasil.conf ];
|
||||
then
|
||||
if [ -f /etc/mesh.conf ]; then
|
||||
mkdir -p /var/backups
|
||||
echo "Backing up configuration file to /var/backups/yggdrasil.conf.`date +%Y%m%d`"
|
||||
cp /etc/yggdrasil.conf /var/backups/yggdrasil.conf.`date +%Y%m%d`
|
||||
echo "Normalising and updating /etc/yggdrasil.conf"
|
||||
/usr/bin/yggdrasil -useconf -normaliseconf < /var/backups/yggdrasil.conf.`date +%Y%m%d` > /etc/yggdrasil.conf
|
||||
chgrp yggdrasil /etc/yggdrasil.conf
|
||||
|
||||
if command -v systemctl >/dev/null; then
|
||||
systemctl daemon-reload >/dev/null || true
|
||||
systemctl enable yggdrasil || true
|
||||
systemctl start yggdrasil || true
|
||||
fi
|
||||
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
|
||||
cp /etc/mesh.conf /var/backups/mesh.conf.`date +%Y%m%d`
|
||||
echo "Normalising and updating /etc/mesh.conf"
|
||||
/usr/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > /etc/mesh.conf
|
||||
else
|
||||
echo "Generating initial configuration file /etc/yggdrasil.conf"
|
||||
echo "Please familiarise yourself with this file before starting Yggdrasil"
|
||||
sh -c 'umask 0027 && /usr/bin/yggdrasil -genconf > /etc/yggdrasil.conf'
|
||||
chgrp yggdrasil /etc/yggdrasil.conf
|
||||
echo "Generating initial configuration file /etc/mesh.conf"
|
||||
echo "Please familiarise yourself with this file before starting RiV-mesh"
|
||||
sh -c 'umask 0027 && /usr/bin/mesh -genconf > /etc/mesh.conf'
|
||||
fi
|
||||
chgrp mesh /etc/mesh.conf
|
||||
chmod 755 /etc/mesh.conf
|
||||
if command -v systemctl >/dev/null; then
|
||||
systemctl daemon-reload || echo -n "daemon not reloaded!"
|
||||
systemctl enable mesh || echo -n "systemctl enable failed!"
|
||||
systemctl restart mesh || echo -n "systemctl restart failed!"
|
||||
fi
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/prerm << EOF
|
||||
cat > /tmp/$PKGNAME/DEBIAN/prerm << EOF
|
||||
#!/bin/sh
|
||||
if command -v systemctl >/dev/null; then
|
||||
if systemctl is-active --quiet yggdrasil; then
|
||||
systemctl stop yggdrasil || true
|
||||
if systemctl is-active --quiet mesh; then
|
||||
systemctl stop mesh || true
|
||||
fi
|
||||
systemctl disable yggdrasil || true
|
||||
systemctl disable mesh || true
|
||||
fi
|
||||
EOF
|
||||
|
||||
cp yggdrasil /tmp/$PKGNAME/usr/bin/
|
||||
cp yggdrasilctl /tmp/$PKGNAME/usr/bin/
|
||||
cp contrib/systemd/*.service /tmp/$PKGNAME/etc/systemd/system/
|
||||
cp mesh /tmp/$PKGNAME/usr/bin/
|
||||
cp meshctl /tmp/$PKGNAME/usr/bin/
|
||||
ln -s /usr/bin/meshctl /tmp/$PKGNAME/usr/local/bin/meshctl
|
||||
if [ $LOGLEVEL = "DEBUG" ]; then cp contrib/systemd/mesh-debug.service /tmp/$PKGNAME/etc/systemd/system/mesh.service
|
||||
else
|
||||
cp contrib/systemd/mesh.service /tmp/$PKGNAME/etc/systemd/system/
|
||||
fi
|
||||
|
||||
tar -czvf /tmp/$PKGNAME/data.tar.gz -C /tmp/$PKGNAME/ \
|
||||
usr/bin/yggdrasil usr/bin/yggdrasilctl \
|
||||
etc/systemd/system/yggdrasil.service \
|
||||
etc/systemd/system/yggdrasil-default-config.service
|
||||
tar -czvf /tmp/$PKGNAME/control.tar.gz -C /tmp/$PKGNAME/debian .
|
||||
echo 2.0 > /tmp/$PKGNAME/debian-binary
|
||||
cp contrib/systemd/mesh-default-config.service /tmp/$PKGNAME/etc/systemd/system/
|
||||
chmod 0775 /tmp/$PKGNAME/DEBIAN/*
|
||||
chmod 644 /tmp/$PKGNAME/etc/systemd/system/*
|
||||
chmod 755 /tmp/$PKGNAME/usr/bin/*
|
||||
|
||||
ar -r $PKGFILE \
|
||||
/tmp/$PKGNAME/debian-binary \
|
||||
/tmp/$PKGNAME/control.tar.gz \
|
||||
/tmp/$PKGNAME/data.tar.gz
|
||||
dpkg-deb --build --root-owner-group /tmp/$PKGNAME
|
||||
cp /tmp/$PKGFILE .
|
||||
|
||||
rm -rf /tmp/$PKGNAME
|
||||
|
|
|
@ -9,17 +9,17 @@ RUN apk add git && ./build && go build -o /src/genkeys cmd/genkeys/main.go
|
|||
|
||||
FROM docker.io/alpine
|
||||
|
||||
COPY --from=builder /src/yggdrasil /usr/bin/yggdrasil
|
||||
COPY --from=builder /src/yggdrasilctl /usr/bin/yggdrasilctl
|
||||
COPY --from=builder /src/mesh /usr/bin/mesh
|
||||
COPY --from=builder /src/meshctl /usr/bin/meshctl
|
||||
COPY --from=builder /src/genkeys /usr/bin/genkeys
|
||||
COPY contrib/docker/entrypoint.sh /usr/bin/entrypoint.sh
|
||||
|
||||
# RUN addgroup -g 1000 -S yggdrasil-network \
|
||||
# && adduser -u 1000 -S -g 1000 --home /etc/yggdrasil-network yggdrasil-network
|
||||
# RUN addgroup -g 1000 -S RiV-chain \
|
||||
# && adduser -u 1000 -S -g 1000 --home /etc/RiV-chain RiV-chain
|
||||
#
|
||||
# USER yggdrasil-network
|
||||
# USER RiV-chain
|
||||
# TODO: Make running unprivileged work
|
||||
|
||||
VOLUME [ "/etc/yggdrasil-network" ]
|
||||
VOLUME [ "/etc/RiV-chain" ]
|
||||
|
||||
ENTRYPOINT [ "/usr/bin/entrypoint.sh" ]
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
set -e
|
||||
|
||||
CONF_DIR="/etc/yggdrasil-network"
|
||||
CONF_DIR="/etc/RiV-chain"
|
||||
|
||||
if [ ! -f "$CONF_DIR/config.conf" ]; then
|
||||
echo "generate $CONF_DIR/config.conf"
|
||||
yggdrasil --genconf > "$CONF_DIR/config.conf"
|
||||
mesh --genconf > "$CONF_DIR/config.conf"
|
||||
fi
|
||||
|
||||
yggdrasil --useconf < "$CONF_DIR/config.conf"
|
||||
mesh --useconf < "$CONF_DIR/config.conf"
|
||||
exit $?
|
||||
|
|
72
contrib/freebsd/mesh
Normal file
72
contrib/freebsd/mesh
Normal file
|
@ -0,0 +1,72 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Put the mesh and meshctl binaries into /usr/local/bin
|
||||
# Then copy this script into /etc/rc.d/mesh
|
||||
# Finally, run:
|
||||
# 1. chmod +x /etc/rc.d/mesh /usr/local/bin/{mesh,meshctl}
|
||||
# 2. echo "mesh_enable=yes" >> /etc/rc.d
|
||||
# 3. service mesh start
|
||||
#
|
||||
# PROVIDE: mesh
|
||||
# REQUIRE: networking
|
||||
# KEYWORD:
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name="mesh"
|
||||
rcvar="mesh_enable"
|
||||
|
||||
start_cmd="${name}_start"
|
||||
stop_cmd="${name}_stop"
|
||||
|
||||
pidfile="/var/run/mesh/${name}.pid"
|
||||
command="/usr/sbin/daemon"
|
||||
command_args="-P ${pidfile} -r -f ${mesh_command}"
|
||||
|
||||
mesh_start()
|
||||
{
|
||||
test ! -x /usr/local/bin/mesh && (
|
||||
logger -s -t mesh "Warning: /usr/local/bin/mesh is missing or not executable"
|
||||
logger -s -t mesh "Copy the mesh binary into /usr/local/bin and then chmod +x /usr/local/bin/mesh"
|
||||
return 1
|
||||
)
|
||||
|
||||
test ! -f /etc/mesh.conf && (
|
||||
logger -s -t mesh "Generating new configuration file into /etc/mesh.conf"
|
||||
/usr/local/bin/mesh -genconf > /etc/mesh.conf
|
||||
)
|
||||
|
||||
tap_path="$(cat /etc/mesh.conf | egrep -o '/dev/tap[0-9]{1,2}$')"
|
||||
tap_name="$(echo -n ${tap_path} | tr -d '/dev/')"
|
||||
|
||||
/sbin/ifconfig ${tap_name} >/dev/null 2>&1 || (
|
||||
logger -s -t mesh "Creating ${tap_name} adapter"
|
||||
/sbin/ifconfig ${tap_name} create || logger -s -t mesh "Failed to create ${tap_name} adapter"
|
||||
)
|
||||
|
||||
test ! -d /var/run/mesh && mkdir -p /var/run/mesh
|
||||
|
||||
logger -s -t mesh "Starting mesh"
|
||||
${command} ${command_args} /usr/local/bin/mesh -useconffile /etc/mesh.conf \
|
||||
1>/var/log/mesh.stdout.log \
|
||||
2>/var/log/mesh.stderr.log &
|
||||
}
|
||||
|
||||
mesh_stop()
|
||||
{
|
||||
logger -s -t mesh "Stopping mesh"
|
||||
test -f /var/run/mesh/${name}.pid && kill -TERM $(cat /var/run/mesh/${name}.pid)
|
||||
|
||||
tap_path="$(cat /etc/mesh.conf | grep /dev/tap | egrep -o '/dev/.*$')"
|
||||
tap_name="$(echo -n ${tap_path} | tr -d '/dev/')"
|
||||
|
||||
/sbin/ifconfig ${tap_name} >/dev/null 2>&1 && (
|
||||
logger -s -t mesh "Destroying ${tap_name} adapter"
|
||||
/sbin/ifconfig ${tap_name} destroy || logger -s -t mesh "Failed to destroy ${tap_name} adapter"
|
||||
)
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
: ${mesh_enable:=no}
|
||||
|
||||
run_rc_command "$1"
|
|
@ -1,72 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Put the yggdrasil and yggdrasilctl binaries into /usr/local/bin
|
||||
# Then copy this script into /etc/rc.d/yggdrasil
|
||||
# Finally, run:
|
||||
# 1. chmod +x /etc/rc.d/yggdrasil /usr/local/bin/{yggdrasil,yggdrasilctl}
|
||||
# 2. echo "yggdrasil_enable=yes" >> /etc/rc.d
|
||||
# 3. service yggdrasil start
|
||||
#
|
||||
# PROVIDE: yggdrasil
|
||||
# REQUIRE: networking
|
||||
# KEYWORD:
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name="yggdrasil"
|
||||
rcvar="yggdrasil_enable"
|
||||
|
||||
start_cmd="${name}_start"
|
||||
stop_cmd="${name}_stop"
|
||||
|
||||
pidfile="/var/run/yggdrasil/${name}.pid"
|
||||
command="/usr/sbin/daemon"
|
||||
command_args="-P ${pidfile} -r -f ${yggdrasil_command}"
|
||||
|
||||
yggdrasil_start()
|
||||
{
|
||||
test ! -x /usr/local/bin/yggdrasil && (
|
||||
logger -s -t yggdrasil "Warning: /usr/local/bin/yggdrasil is missing or not executable"
|
||||
logger -s -t yggdrasil "Copy the yggdrasil binary into /usr/local/bin and then chmod +x /usr/local/bin/yggdrasil"
|
||||
return 1
|
||||
)
|
||||
|
||||
test ! -f /etc/yggdrasil.conf && (
|
||||
logger -s -t yggdrasil "Generating new configuration file into /etc/yggdrasil.conf"
|
||||
/usr/local/bin/yggdrasil -genconf > /etc/yggdrasil.conf
|
||||
)
|
||||
|
||||
tap_path="$(cat /etc/yggdrasil.conf | egrep -o '/dev/tap[0-9]{1,2}$')"
|
||||
tap_name="$(echo -n ${tap_path} | tr -d '/dev/')"
|
||||
|
||||
/sbin/ifconfig ${tap_name} >/dev/null 2>&1 || (
|
||||
logger -s -t yggdrasil "Creating ${tap_name} adapter"
|
||||
/sbin/ifconfig ${tap_name} create || logger -s -t yggdrasil "Failed to create ${tap_name} adapter"
|
||||
)
|
||||
|
||||
test ! -d /var/run/yggdrasil && mkdir -p /var/run/yggdrasil
|
||||
|
||||
logger -s -t yggdrasil "Starting yggdrasil"
|
||||
${command} ${command_args} /usr/local/bin/yggdrasil -useconffile /etc/yggdrasil.conf \
|
||||
1>/var/log/yggdrasil.stdout.log \
|
||||
2>/var/log/yggdrasil.stderr.log &
|
||||
}
|
||||
|
||||
yggdrasil_stop()
|
||||
{
|
||||
logger -s -t yggdrasil "Stopping yggdrasil"
|
||||
test -f /var/run/yggdrasil/${name}.pid && kill -TERM $(cat /var/run/yggdrasil/${name}.pid)
|
||||
|
||||
tap_path="$(cat /etc/yggdrasil.conf | grep /dev/tap | egrep -o '/dev/.*$')"
|
||||
tap_name="$(echo -n ${tap_path} | tr -d '/dev/')"
|
||||
|
||||
/sbin/ifconfig ${tap_name} >/dev/null 2>&1 && (
|
||||
logger -s -t yggdrasil "Destroying ${tap_name} adapter"
|
||||
/sbin/ifconfig ${tap_name} destroy || logger -s -t yggdrasil "Failed to destroy ${tap_name} adapter"
|
||||
)
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
: ${yggdrasil_enable:=no}
|
||||
|
||||
run_rc_command "$1"
|
176
contrib/macos/create-pkg-gui.sh
Normal file
176
contrib/macos/create-pkg-gui.sh
Normal file
|
@ -0,0 +1,176 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Check if xar and mkbom are available
|
||||
command -v xar >/dev/null 2>&1 || (
|
||||
echo "Building xar"
|
||||
sudo apt-get install libxml2-dev libssl1.0-dev zlib1g-dev autoconf -y
|
||||
rm -rf /tmp/xar && mkdir -p /tmp/xar && cd /tmp/xar
|
||||
#git clone https://github.com/mackyle/xar && cd xar/xar
|
||||
git clone https://github.com/RiV-chain/xar.git && cd xar/xar
|
||||
(sh autogen.sh && make && sudo make install) || (echo "Failed to build xar"; exit 1)
|
||||
)
|
||||
command -v mkbom >/dev/null 2>&1 || (
|
||||
echo "Building mkbom"
|
||||
mkdir -p /tmp/mkbom && cd /tmp/mkbom
|
||||
git clone https://github.com/hogliux/bomutils && cd bomutils
|
||||
sudo make install || (echo "Failed to build mkbom"; exit 1)
|
||||
)
|
||||
|
||||
# Build RiV-mesh
|
||||
echo "running GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build"
|
||||
GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build
|
||||
|
||||
# Check if we can find the files we need - they should
|
||||
# exist if you are running this script from the root of
|
||||
# the RiV-mesh repo and you have ran ./build
|
||||
test -f mesh || (echo "mesh binary not found"; exit 1)
|
||||
test -f meshctl || (echo "meshctl binary not found"; exit 1)
|
||||
test -f mesh-ui || (echo "mesh-ui binary not found"; exit 1)
|
||||
test -f contrib/macos/mesh.plist || (echo "contrib/macos/mesh.plist not found"; exit 1)
|
||||
test -f contrib/semver/version.sh || (echo "contrib/semver/version.sh not found"; exit 1)
|
||||
|
||||
# Delete the pkgbuild folder if it already exists
|
||||
test -d pkgbuild && rm -rf pkgbuild
|
||||
|
||||
# Create our folder structure
|
||||
|
||||
mkdir -p pkgbuild/scripts
|
||||
mkdir -p pkgbuild/flat/base.pkg
|
||||
mkdir -p pkgbuild/flat/Resources/en.lproj
|
||||
mkdir -p pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
|
||||
mkdir -p pkgbuild/root/Applications/RiV-mesh.app/Contents/Resources
|
||||
mkdir -p pkgbuild/root/usr/local/bin
|
||||
mkdir -p pkgbuild/root/Library/LaunchDaemons
|
||||
|
||||
# Copy package contents into the pkgbuild root
|
||||
cp meshctl pkgbuild/root/usr/local/bin
|
||||
cp mesh pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
|
||||
cp mesh-ui pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
|
||||
cp riv.icns pkgbuild/root/Applications/RiV-mesh.app/Contents/Resources
|
||||
cp contrib/ui/mesh-ui/index.html pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
|
||||
cp contrib/macos/mesh.plist pkgbuild/root/Library/LaunchDaemons
|
||||
|
||||
# Create the postinstall script
|
||||
cat > pkgbuild/scripts/postinstall << EOF
|
||||
#!/bin/sh
|
||||
|
||||
# Normalise the config if it exists, generate it if it doesn't
|
||||
if [ -f /etc/mesh.conf ];
|
||||
then
|
||||
mkdir -p /Library/Preferences/RiV-mesh
|
||||
echo "Backing up configuration file to /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d`"
|
||||
cp /etc/mesh.conf /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d`
|
||||
echo "Normalising /etc/mesh.conf"
|
||||
/Applications/RiV-mesh.app/Contents/MacOS/mesh -useconffile /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d` -normaliseconf > /etc/mesh.conf
|
||||
else
|
||||
/Applications/RiV-mesh.app/Contents/MacOS/mesh -genconf > /etc/mesh.conf
|
||||
fi
|
||||
|
||||
chmod 755 /etc/mesh.conf
|
||||
|
||||
# Unload existing RiV-mesh launchd service, if possible
|
||||
test -f /Library/LaunchDaemons/mesh.plist && (launchctl unload /Library/LaunchDaemons/mesh.plist || true)
|
||||
|
||||
# Load RiV-mesh launchd service and start RiV-mesh
|
||||
launchctl load /Library/LaunchDaemons/mesh.plist
|
||||
EOF
|
||||
|
||||
# Set execution permissions
|
||||
chmod 755 pkgbuild/scripts/postinstall
|
||||
chmod 755 pkgbuild/root/usr/local/bin/meshctl
|
||||
chmod 755 pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS/mesh
|
||||
chmod 755 pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS/mesh-ui
|
||||
chmod 755 pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS/index.html
|
||||
|
||||
# Work out metadata for the package info
|
||||
PKGNAME=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
|
||||
# Create the Info.plist file
|
||||
cat > pkgbuild/root/Applications/RiV-mesh.app/Contents/Info.plist << EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>org.riv-mesh.ui</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>RiV-mesh</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<string>True</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>riv.icns</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${PKGVERSION}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${PKGVERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${PKGVERSION}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>mesh-ui</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.github.RiV-mesh.pkg</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/tmp/mesh-ui.stdout.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/tmp/mesh-ui.stderr.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
|
||||
# Pack payload and scripts
|
||||
( cd pkgbuild/scripts && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > pkgbuild/flat/base.pkg/Scripts
|
||||
( cd pkgbuild/root && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > pkgbuild/flat/base.pkg/Payload
|
||||
|
||||
PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 ))
|
||||
|
||||
# Create the PackageInfo file
|
||||
cat > pkgbuild/flat/base.pkg/PackageInfo << EOF
|
||||
<pkg-info format-version="2" identifier="io.github.RiV-mesh.pkg" version="${PKGVERSION}" install-location="/" auth="root">
|
||||
<payload installKBytes="${PAYLOADSIZE}" numberOfFiles="6"/>
|
||||
<scripts>
|
||||
<postinstall file="./postinstall"/>
|
||||
</scripts>
|
||||
</pkg-info>
|
||||
EOF
|
||||
|
||||
# Create the BOM
|
||||
( cd pkgbuild && mkbom root flat/base.pkg/Bom )
|
||||
|
||||
# Create the Distribution file
|
||||
cat > pkgbuild/flat/Distribution << EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<installer-script minSpecVersion="1.000000" authoringTool="com.apple.PackageMaker" authoringToolVersion="3.0.3" authoringToolBuild="174">
|
||||
<title>RiV-mesh (${PKGNAME}-${PKGVERSION})</title>
|
||||
<options customize="never" allow-external-scripts="no"/>
|
||||
<domains enable_anywhere="true"/>
|
||||
<installation-check script="pm_install_check();"/>
|
||||
<script>
|
||||
function pm_install_check() {
|
||||
if(!(system.compareVersions(system.version.ProductVersion,'10.10') >= 0)) {
|
||||
my.result.title = 'Failure';
|
||||
my.result.message = 'You need at least Mac OS X 10.10 to install RiV-mesh.';
|
||||
my.result.type = 'Fatal';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
<choices-outline>
|
||||
<line choice="choice1"/>
|
||||
</choices-outline>
|
||||
<choice id="choice1" title="base">
|
||||
<pkg-ref id="io.github.RiV-mesh.pkg"/>
|
||||
</choice>
|
||||
<pkg-ref id="io.github.RiV-mesh.pkg" installKBytes="${PAYLOADSIZE}" version="${VERSION}" auth="Root">#base.pkg</pkg-ref>
|
||||
</installer-script>
|
||||
EOF
|
||||
|
||||
# Finally pack the .pkg
|
||||
( cd pkgbuild/flat && xar --compression none -cf "../../${PKGNAME}-${PKGVERSION}-macos-${PKGARCH}.pkg" * )
|
|
@ -15,16 +15,12 @@ command -v mkbom >/dev/null 2>&1 || (
|
|||
sudo make install || (echo "Failed to build mkbom"; exit 1)
|
||||
)
|
||||
|
||||
# Build Yggdrasil
|
||||
echo "running GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build"
|
||||
GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build
|
||||
|
||||
# Check if we can find the files we need - they should
|
||||
# exist if you are running this script from the root of
|
||||
# the yggdrasil-go repo and you have ran ./build
|
||||
test -f yggdrasil || (echo "yggdrasil binary not found"; exit 1)
|
||||
test -f yggdrasilctl || (echo "yggdrasilctl binary not found"; exit 1)
|
||||
test -f contrib/macos/yggdrasil.plist || (echo "contrib/macos/yggdrasil.plist not found"; exit 1)
|
||||
# the RiV-mesh repo and you have ran ./build
|
||||
test -f mesh || (echo "mesh binary not found"; exit 1)
|
||||
test -f meshctl || (echo "meshctl binary not found"; exit 1)
|
||||
test -f contrib/macos/mesh.plist || (echo "contrib/macos/mesh.plist not found"; exit 1)
|
||||
test -f contrib/semver/version.sh || (echo "contrib/semver/version.sh not found"; exit 1)
|
||||
|
||||
# Delete the pkgbuild folder if it already exists
|
||||
|
@ -35,40 +31,43 @@ mkdir -p pkgbuild/scripts
|
|||
mkdir -p pkgbuild/flat/base.pkg
|
||||
mkdir -p pkgbuild/flat/Resources/en.lproj
|
||||
mkdir -p pkgbuild/root/usr/local/bin
|
||||
mkdir -p pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
|
||||
mkdir -p pkgbuild/root/Library/LaunchDaemons
|
||||
|
||||
# Copy package contents into the pkgbuild root
|
||||
cp yggdrasil pkgbuild/root/usr/local/bin
|
||||
cp yggdrasilctl pkgbuild/root/usr/local/bin
|
||||
cp contrib/macos/yggdrasil.plist pkgbuild/root/Library/LaunchDaemons
|
||||
cp mesh pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS
|
||||
cp meshctl pkgbuild/root/usr/local/bin
|
||||
cp contrib/macos/mesh.plist pkgbuild/root/Library/LaunchDaemons
|
||||
|
||||
# Create the postinstall script
|
||||
cat > pkgbuild/scripts/postinstall << EOF
|
||||
#!/bin/sh
|
||||
|
||||
# Normalise the config if it exists, generate it if it doesn't
|
||||
if [ -f /etc/yggdrasil.conf ];
|
||||
if [ -f /etc/mesh.conf ];
|
||||
then
|
||||
mkdir -p /Library/Preferences/Yggdrasil
|
||||
echo "Backing up configuration file to /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d`"
|
||||
cp /etc/yggdrasil.conf /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d`
|
||||
echo "Normalising /etc/yggdrasil.conf"
|
||||
/usr/local/bin/yggdrasil -useconffile /Library/Preferences/Yggdrasil/yggdrasil.conf.`date +%Y%m%d` -normaliseconf > /etc/yggdrasil.conf
|
||||
mkdir -p /Library/Preferences/RiV-mesh
|
||||
echo "Backing up configuration file to /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d`"
|
||||
cp /etc/mesh.conf /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d`
|
||||
echo "Normalising /etc/mesh.conf"
|
||||
/Applications/RiV-mesh.app/Contents/MacOS/mesh -useconffile /Library/Preferences/RiV-mesh/mesh.conf.`date +%Y%m%d` -normaliseconf > /etc/mesh.conf
|
||||
else
|
||||
/usr/local/bin/yggdrasil -genconf > /etc/yggdrasil.conf
|
||||
/Applications/RiV-mesh.app/Contents/MacOS/mesh -genconf > /etc/mesh.conf
|
||||
fi
|
||||
|
||||
# Unload existing Yggdrasil launchd service, if possible
|
||||
test -f /Library/LaunchDaemons/yggdrasil.plist && (launchctl unload /Library/LaunchDaemons/yggdrasil.plist || true)
|
||||
chmod 755 /etc/mesh.conf
|
||||
|
||||
# Load Yggdrasil launchd service and start Yggdrasil
|
||||
launchctl load /Library/LaunchDaemons/yggdrasil.plist
|
||||
# Unload existing RiV-mesh launchd service, if possible
|
||||
test -f /Library/LaunchDaemons/mesh.plist && (launchctl unload /Library/LaunchDaemons/mesh.plist || true)
|
||||
|
||||
# Load RiV-mesh launchd service and start RiV-mesh
|
||||
launchctl load /Library/LaunchDaemons/mesh.plist
|
||||
EOF
|
||||
|
||||
# Set execution permissions
|
||||
chmod +x pkgbuild/scripts/postinstall
|
||||
chmod +x pkgbuild/root/usr/local/bin/yggdrasil
|
||||
chmod +x pkgbuild/root/usr/local/bin/yggdrasilctl
|
||||
chmod 755 pkgbuild/scripts/postinstall
|
||||
chmod 755 pkgbuild/root/Applications/RiV-mesh.app/Contents/MacOS/mesh
|
||||
chmod 755 pkgbuild/root/usr/local/bin/meshctl
|
||||
|
||||
# Pack payload and scripts
|
||||
( cd pkgbuild/scripts && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > pkgbuild/flat/base.pkg/Scripts
|
||||
|
@ -79,11 +78,10 @@ PKGNAME=$(sh contrib/semver/name.sh)
|
|||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 ))
|
||||
[ "$PKGARCH" = "amd64" ] && PKGHOSTARCH="x86_64" || PKGHOSTARCH=${PKGARCH}
|
||||
|
||||
# Create the PackageInfo file
|
||||
cat > pkgbuild/flat/base.pkg/PackageInfo << EOF
|
||||
<pkg-info format-version="2" identifier="io.github.yggdrasil-network.pkg" version="${PKGVERSION}" install-location="/" auth="root">
|
||||
<pkg-info format-version="2" identifier="io.github.RiV-chain.pkg" version="${PKGVERSION}" install-location="/" auth="root">
|
||||
<payload installKBytes="${PAYLOADSIZE}" numberOfFiles="3"/>
|
||||
<scripts>
|
||||
<postinstall file="./postinstall"/>
|
||||
|
@ -98,15 +96,15 @@ EOF
|
|||
cat > pkgbuild/flat/Distribution << EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<installer-script minSpecVersion="1.000000" authoringTool="com.apple.PackageMaker" authoringToolVersion="3.0.3" authoringToolBuild="174">
|
||||
<title>Yggdrasil (${PKGNAME}-${PKGVERSION})</title>
|
||||
<options customize="never" allow-external-scripts="no" hostArchitectures="${PKGHOSTARCH}" />
|
||||
<title>RiV-mesh (${PKGNAME}-${PKGVERSION})</title>
|
||||
<options customize="never" allow-external-scripts="no"/>
|
||||
<domains enable_anywhere="true"/>
|
||||
<installation-check script="pm_install_check();"/>
|
||||
<script>
|
||||
function pm_install_check() {
|
||||
if(!(system.compareVersions(system.version.ProductVersion,'10.10') >= 0)) {
|
||||
my.result.title = 'Failure';
|
||||
my.result.message = 'You need at least Mac OS X 10.10 to install Yggdrasil.';
|
||||
my.result.message = 'You need at least Mac OS X 10.10 to install RiV-mesh.';
|
||||
my.result.type = 'Fatal';
|
||||
return false;
|
||||
}
|
||||
|
@ -117,11 +115,11 @@ cat > pkgbuild/flat/Distribution << EOF
|
|||
<line choice="choice1"/>
|
||||
</choices-outline>
|
||||
<choice id="choice1" title="base">
|
||||
<pkg-ref id="io.github.yggdrasil-network.pkg"/>
|
||||
<pkg-ref id="io.github.RiV-mesh.pkg"/>
|
||||
</choice>
|
||||
<pkg-ref id="io.github.yggdrasil-network.pkg" installKBytes="${PAYLOADSIZE}" version="${VERSION}" auth="Root">#base.pkg</pkg-ref>
|
||||
<pkg-ref id="io.github.RiV-mesh.pkg" installKBytes="${PAYLOADSIZE}" version="${VERSION}" auth="Root">#base.pkg</pkg-ref>
|
||||
</installer-script>
|
||||
EOF
|
||||
|
||||
# Finally pack the .pkg
|
||||
( cd pkgbuild/flat && xar --compression none -cf "../../${PKGNAME}-${PKGVERSION}-macos-${PKGARCH}.pkg" * )
|
||||
( cd pkgbuild/flat && xar --compression none -cf "../../${PKGNAME}-${PKGVERSION}-macos-${PKGARCH}-nogui.pkg" * )
|
||||
|
|
26
contrib/macos/mesh.plist
Normal file
26
contrib/macos/mesh.plist
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>org.riv-mesh.service</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Applications/RiV-mesh.app/Contents/MacOS/mesh</string>
|
||||
<string>-useconffile</string>
|
||||
<string>/etc/mesh.conf</string>
|
||||
</array>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>ProcessType</key>
|
||||
<string>Interactive</string>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/Applications/RiV-mesh.app/Contents/MacOS</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/tmp/mesh.stdout.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/tmp/mesh.stderr.log</string>
|
||||
</dict>
|
||||
</plist>
|
12
contrib/mesh-brute-simple/Makefile
Normal file
12
contrib/mesh-brute-simple/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
.PHONY: all
|
||||
|
||||
all: util mesh-brute-multi-curve25519 mesh-brute-multi-ed25519
|
||||
|
||||
util: util.c
|
||||
gcc -Wall -std=c89 -O3 -c -o util.o util.c
|
||||
|
||||
mesh-brute-multi-ed25519: mesh-brute-multi-ed25519.c util.o
|
||||
gcc -Wall -std=c89 -O3 -o mesh-brute-multi-ed25519 -lsodium mesh-brute-multi-ed25519.c util.o
|
||||
|
||||
mesh-brute-multi-curve25519: mesh-brute-multi-curve25519.c util.o
|
||||
gcc -Wall -std=c89 -O3 -o mesh-brute-multi-curve25519 -lsodium mesh-brute-multi-curve25519.c util.o
|
|
@ -1,4 +1,4 @@
|
|||
# yggdrasil-brute-simple
|
||||
# mesh-brute-simple
|
||||
|
||||
Simple program for finding curve25519 and ed25519 public keys whose sha512 hash has many leading ones.
|
||||
Because ed25519 private keys consist of a seed that is hashed to find the secret part of the keypair,
|
|
@ -13,7 +13,7 @@ if besthash:
|
|||
besthash = hash
|
||||
*/
|
||||
|
||||
#include "yggdrasil-brute.h"
|
||||
#include "mesh-brute.h"
|
||||
|
||||
|
||||
void seed(unsigned char sk[32]) {
|
||||
|
@ -43,7 +43,7 @@ int main(int argc, char **argv) {
|
|||
int where;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: ./yggdrasil-brute-multi-curve25519 <seconds>\n");
|
||||
fprintf(stderr, "usage: ./mesh-brute-multi-curve25519 <seconds>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ int main(int argc, char **argv) {
|
|||
requestedtime = atoi(argv[1]);
|
||||
|
||||
if (requestedtime < 0) requestedtime = 0;
|
||||
fprintf(stderr, "Searching for yggdrasil curve25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime);
|
||||
fprintf(stderr, "Searching for mesh curve25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime);
|
||||
|
||||
sodium_memzero(bestsklist, NUMKEYS * 32);
|
||||
sodium_memzero(bestpklist, NUMKEYS * 32);
|
|
@ -20,7 +20,7 @@ if besthash:
|
|||
besthash = hash
|
||||
*/
|
||||
|
||||
#include "yggdrasil-brute.h"
|
||||
#include "mesh-brute.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -41,7 +41,7 @@ int main(int argc, char **argv) {
|
|||
int where;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: ./yggdrasil-brute-multi-curve25519 <seconds>\n");
|
||||
fprintf(stderr, "usage: ./mesh-brute-multi-curve25519 <seconds>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ int main(int argc, char **argv) {
|
|||
requestedtime = atoi(argv[1]);
|
||||
|
||||
if (requestedtime < 0) requestedtime = 0;
|
||||
fprintf(stderr, "Searching for yggdrasil ed25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime);
|
||||
fprintf(stderr, "Searching for mesh ed25519 keys (this will take slightly longer than %ld seconds)\n", requestedtime);
|
||||
|
||||
sodium_memzero(bestsklist, NUMKEYS * 64);
|
||||
sodium_memzero(besthashlist, NUMKEYS * 64);
|
|
@ -1,4 +1,4 @@
|
|||
#include "yggdrasil-brute.h"
|
||||
#include "mesh-brute.h"
|
||||
|
||||
int find_where(unsigned char hash[64], unsigned char besthashlist[NUMKEYS][64]) {
|
||||
/* Where to insert hash into sorted hashlist */
|
||||
|
@ -28,7 +28,7 @@ void insert_32(unsigned char itemlist[NUMKEYS][32], unsigned char item[32], int
|
|||
}
|
||||
|
||||
void make_addr(unsigned char addr[32], unsigned char hash[64]) {
|
||||
/* Public key hash to yggdrasil ipv6 address */
|
||||
/* Public key hash to mesh ipv6 address */
|
||||
int i;
|
||||
int offset;
|
||||
unsigned char mask;
|
|
@ -4,7 +4,7 @@ set -ef
|
|||
|
||||
[ ! -d contrib/mobile ] && (echo "Must run ./contrib/mobile/build [-i] [-a] from the repository top level folder"; exit 1)
|
||||
|
||||
PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/version}
|
||||
PKGSRC=${PKGSRC:-github.com/RiV-chain/RiV-mesh/src/version}
|
||||
PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)}
|
||||
PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)}
|
||||
|
||||
|
@ -37,7 +37,7 @@ if [ $IOS ]; then
|
|||
echo "Building framework for iOS"
|
||||
go get golang.org/x/mobile/bind
|
||||
gomobile bind \
|
||||
-target ios -tags mobile -o Yggdrasil.xcframework \
|
||||
-target ios -tags mobile -o Mesh.xcframework \
|
||||
-ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
|
||||
./contrib/mobile ./src/config;
|
||||
fi
|
||||
|
@ -46,7 +46,7 @@ if [ $ANDROID ]; then
|
|||
echo "Building aar for Android"
|
||||
go get golang.org/x/mobile/bind
|
||||
gomobile bind \
|
||||
-target android -tags mobile -o yggdrasil.aar \
|
||||
-target android -tags mobile -o mesh.aar \
|
||||
-ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
|
||||
./contrib/mobile ./src/config;
|
||||
fi
|
||||
|
|
|
@ -9,23 +9,23 @@ import (
|
|||
|
||||
"github.com/gologme/log"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/core"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/version"
|
||||
"github.com/RiV-chain/RiV-mesh/src/address"
|
||||
"github.com/RiV-chain/RiV-mesh/src/config"
|
||||
"github.com/RiV-chain/RiV-mesh/src/core"
|
||||
"github.com/RiV-chain/RiV-mesh/src/defaults"
|
||||
"github.com/RiV-chain/RiV-mesh/src/ipv6rwc"
|
||||
"github.com/RiV-chain/RiV-mesh/src/multicast"
|
||||
"github.com/RiV-chain/RiV-mesh/src/version"
|
||||
|
||||
_ "golang.org/x/mobile/bind"
|
||||
)
|
||||
|
||||
// Yggdrasil mobile package is meant to "plug the gap" for mobile support, as
|
||||
// RiV-mesh mobile package is meant to "plug the gap" for mobile support, as
|
||||
// Gomobile will not create headers for Swift/Obj-C etc if they have complex
|
||||
// (non-native) types. Therefore for iOS we will expose some nice simple
|
||||
// functions. Note that in the case of iOS we handle reading/writing to/from TUN
|
||||
// in Swift therefore we use the "dummy" TUN interface instead.
|
||||
type Yggdrasil struct {
|
||||
type Mesh struct {
|
||||
core *core.Core
|
||||
iprwc *ipv6rwc.ReadWriteCloser
|
||||
config *config.NodeConfig
|
||||
|
@ -34,13 +34,13 @@ type Yggdrasil struct {
|
|||
}
|
||||
|
||||
// StartAutoconfigure starts a node with a randomly generated config
|
||||
func (m *Yggdrasil) StartAutoconfigure() error {
|
||||
func (m *Mesh) StartAutoconfigure() error {
|
||||
return m.StartJSON([]byte("{}"))
|
||||
}
|
||||
|
||||
// StartJSON starts a node with the given JSON config. You can get JSON config
|
||||
// (rather than HJSON) by using the GenerateConfigJSON() function
|
||||
func (m *Yggdrasil) StartJSON(configjson []byte) error {
|
||||
func (m *Mesh) StartJSON(configjson []byte) error {
|
||||
logger := log.New(m.log, "", 0)
|
||||
logger.EnableLevel("error")
|
||||
logger.EnableLevel("warn")
|
||||
|
@ -83,10 +83,10 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error {
|
|||
options := []multicast.SetupOption{}
|
||||
for _, intf := range m.config.MulticastInterfaces {
|
||||
options = append(options, multicast.MulticastInterface{
|
||||
Regex: regexp.MustCompile(intf.Regex),
|
||||
Beacon: intf.Beacon,
|
||||
Listen: intf.Listen,
|
||||
Port: intf.Port,
|
||||
Regex: regexp.MustCompile(intf.Regex),
|
||||
Beacon: intf.Beacon,
|
||||
Listen: intf.Listen,
|
||||
Port: intf.Port,
|
||||
Priority: intf.Priority,
|
||||
})
|
||||
}
|
||||
|
@ -105,9 +105,9 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Send sends a packet to Yggdrasil. It should be a fully formed
|
||||
// Send sends a packet to Mesh. It should be a fully formed
|
||||
// IPv6 packet
|
||||
func (m *Yggdrasil) Send(p []byte) error {
|
||||
func (m *Mesh) Send(p []byte) error {
|
||||
if m.iprwc == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -115,9 +115,9 @@ func (m *Yggdrasil) Send(p []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Recv waits for and reads a packet coming from Yggdrasil. It
|
||||
// Recv waits for and reads a packet coming from Mesh. It
|
||||
// will be a fully formed IPv6 packet
|
||||
func (m *Yggdrasil) Recv() ([]byte, error) {
|
||||
func (m *Mesh) Recv() ([]byte, error) {
|
||||
if m.iprwc == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -126,11 +126,11 @@ func (m *Yggdrasil) Recv() ([]byte, error) {
|
|||
return buf[:n], nil
|
||||
}
|
||||
|
||||
// Stop the mobile Yggdrasil instance
|
||||
func (m *Yggdrasil) Stop() error {
|
||||
// Stop the mobile Mesh instance
|
||||
func (m *Mesh) Stop() error {
|
||||
logger := log.New(m.log, "", 0)
|
||||
logger.EnableLevel("info")
|
||||
logger.Infof("Stop the mobile Yggdrasil instance %s", "")
|
||||
logger.Infof("Stop the mobile Mesh instance %s", "")
|
||||
if err := m.multicast.Stop(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -149,28 +149,28 @@ func GenerateConfigJSON() []byte {
|
|||
}
|
||||
|
||||
// GetAddressString gets the node's IPv6 address
|
||||
func (m *Yggdrasil) GetAddressString() string {
|
||||
func (m *Mesh) GetAddressString() string {
|
||||
ip := m.core.Address()
|
||||
return ip.String()
|
||||
}
|
||||
|
||||
// GetSubnetString gets the node's IPv6 subnet in CIDR notation
|
||||
func (m *Yggdrasil) GetSubnetString() string {
|
||||
func (m *Mesh) GetSubnetString() string {
|
||||
subnet := m.core.Subnet()
|
||||
return subnet.String()
|
||||
}
|
||||
|
||||
// GetPublicKeyString gets the node's public key in hex form
|
||||
func (m *Yggdrasil) GetPublicKeyString() string {
|
||||
func (m *Mesh) GetPublicKeyString() string {
|
||||
return hex.EncodeToString(m.core.GetSelf().Key)
|
||||
}
|
||||
|
||||
// GetCoordsString gets the node's coordinates
|
||||
func (m *Yggdrasil) GetCoordsString() string {
|
||||
func (m *Mesh) GetCoordsString() string {
|
||||
return fmt.Sprintf("%v", m.core.GetSelf().Coords)
|
||||
}
|
||||
|
||||
func (m *Yggdrasil) GetPeersJSON() (result string) {
|
||||
func (m *Mesh) GetPeersJSON() (result string) {
|
||||
peers := []struct {
|
||||
core.PeerInfo
|
||||
IP string
|
||||
|
@ -193,7 +193,7 @@ func (m *Yggdrasil) GetPeersJSON() (result string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *Yggdrasil) GetDHTJSON() (result string) {
|
||||
func (m *Mesh) GetDHTJSON() (result string) {
|
||||
if res, err := json.Marshal(m.core.GetDHT()); err == nil {
|
||||
return string(res)
|
||||
} else {
|
||||
|
@ -202,7 +202,7 @@ func (m *Yggdrasil) GetDHTJSON() (result string) {
|
|||
}
|
||||
|
||||
// GetMTU returns the configured node MTU. This must be called AFTER Start.
|
||||
func (m *Yggdrasil) GetMTU() int {
|
||||
func (m *Mesh) GetMTU() int {
|
||||
return int(m.core.MTU())
|
||||
}
|
||||
|
||||
|
|
|
@ -3,14 +3,14 @@ package mobile
|
|||
import "testing"
|
||||
|
||||
func TestStartYggdrasil(t *testing.T) {
|
||||
ygg := &Yggdrasil{}
|
||||
if err := ygg.StartAutoconfigure(); err != nil {
|
||||
t.Fatalf("Failed to start Yggdrasil: %s", err)
|
||||
ygg := &Mesh{}
|
||||
if err := mesh.StartAutoconfigure(); err != nil {
|
||||
t.Fatalf("Failed to start Mesh: %s", err)
|
||||
}
|
||||
t.Log("Address:", ygg.GetAddressString())
|
||||
t.Log("Subnet:", ygg.GetSubnetString())
|
||||
t.Log("Coords:", ygg.GetCoordsString())
|
||||
if err := ygg.Stop(); err != nil {
|
||||
t.Log("Address:", mesh.GetAddressString())
|
||||
t.Log("Subnet:", mesh.GetSubnetString())
|
||||
t.Log("Coords:", mesh.GetCoordsString())
|
||||
if err := mesh.Stop(); err != nil {
|
||||
t.Fatalf("Failed to stop Yggdrasil: %s", err)
|
||||
}
|
||||
}
|
||||
|
|
313
contrib/msi/build-msi-gui.sh
Normal file
313
contrib/msi/build-msi-gui.sh
Normal file
|
@ -0,0 +1,313 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script generates an MSI file for Mesh for a given architecture. It
|
||||
# needs to run on Windows within MSYS2 and Go 1.13 or later must be installed on
|
||||
# the system and within the PATH. This is ran currently by Appveyor or GitHub Actions (see
|
||||
# appveyor.yml in the repository root) for both x86 and x64.
|
||||
#
|
||||
# Author: Neil Alexander <neilalexander@users.noreply.github.com>, Vadym Vikulin <vadym.vikulin@rivchain.org>
|
||||
|
||||
# Get arch from command line if given
|
||||
PKGARCH=$1
|
||||
if [ "${PKGARCH}" == "" ];
|
||||
then
|
||||
echo "tell me the architecture: x86, x64 or arm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the rest of the repository history. This is needed within Appveyor because
|
||||
# otherwise we don't get all of the branch histories and therefore the semver
|
||||
# scripts don't work properly.
|
||||
if [ "${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}" != "" ];
|
||||
then
|
||||
git fetch --all
|
||||
git checkout ${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}
|
||||
elif [ "${APPVEYOR_REPO_BRANCH}" != "" ];
|
||||
then
|
||||
git fetch --all
|
||||
git checkout ${APPVEYOR_REPO_BRANCH}
|
||||
fi
|
||||
|
||||
# Install prerequisites within MSYS2
|
||||
pacman -S --needed --noconfirm unzip git curl
|
||||
|
||||
# Download the wix tools!
|
||||
if [ ! -d wixbin ];
|
||||
then
|
||||
curl -LO https://wixtoolset.org/downloads/v3.14.0.3910/wix314-binaries.zip
|
||||
if [ `md5sum wix314-binaries.zip | cut -f 1 -d " "` != "34f655cf108086838dd5a76d4318063b" ];
|
||||
then
|
||||
echo "wix package didn't match expected checksum"
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p wixbin
|
||||
unzip -o wix311-binaries.zip -d wixbin || (
|
||||
echo "failed to unzip WiX"
|
||||
exit 1
|
||||
)
|
||||
fi
|
||||
|
||||
# Work out metadata for the package info
|
||||
PKGNAME=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/msi/msversion.sh --bare)
|
||||
PKGVERSIONMS=$(echo $PKGVERSION | tr - .)
|
||||
PKGINDEXFILE=contrib/ui/mesh-ui/index.html
|
||||
PKGLICENSEFILE=LICENSE.rtf
|
||||
|
||||
#Build winres
|
||||
go-winres simply --icon riv.ico --file-version $PKGVERSION --file-description "RiV-mesh (c) service, 2021 RIV CHAIN" \
|
||||
--product-version $PKGVERSION --product-name "RiV-mesh" --copyright "Copyright (c) 2021, RIV CHAIN"
|
||||
cp *.syso cmd/mesh
|
||||
go-winres simply --icon riv.ico --file-version $PKGVERSION --file-description "RiV-mesh (c) GUI, 2021 RIV CHAIN" \
|
||||
--product-version $PKGVERSION --product-name "RiV-mesh" --copyright "Copyright (c) 2021, RIV CHAIN" --manifest gui
|
||||
cp *.syso contrib/ui/mesh-ui
|
||||
go-winres simply --file-version $PKGVERSION --file-description "RiV-mesh (c) CLI, 2021 RIV CHAIN" \
|
||||
--product-version $PKGVERSION --product-name "RiV-mesh" --copyright "Copyright (c) 2021, RIV CHAIN" --manifest cli
|
||||
cp *.syso cmd/meshctl
|
||||
|
||||
# Build Mesh!
|
||||
[ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ LDFLAGS="-H windowsgui" ./build
|
||||
[ "${PKGARCH}" == "x86" ] && GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ LDFLAGS="-H windowsgui" ./build
|
||||
[ "${PKGARCH}" == "arm" ] && GOOS=windows GOARCH=arm CGO_ENABLED=0 ./build
|
||||
|
||||
#[ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ ./build
|
||||
#[ "${PKGARCH}" == "x86" ] && GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ ./build
|
||||
#[ "${PKGARCH}" == "arm" ] && GOOS=windows GOARCH=arm CGO_ENABLED=0 ./build
|
||||
#[ "${PKGARCH}" == "arm64" ] && GOOS=windows GOARCH=arm64 CGO_ENABLED=0 ./build
|
||||
|
||||
# Create the postinstall script
|
||||
cat > updateconfig.bat << EOF
|
||||
if not exist %ALLUSERSPROFILE%\\RiV-mesh (
|
||||
mkdir %ALLUSERSPROFILE%\\RiV-mesh
|
||||
)
|
||||
if not exist %ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf (
|
||||
if exist mesh.exe (
|
||||
mesh.exe -genconf > %ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf
|
||||
)
|
||||
)
|
||||
EOF
|
||||
|
||||
[ "${PKGARCH}" == "x64" ] && \
|
||||
PKGGUID="5bcfdddd-66a7-4eb7-b5f7-4a7500dcc65d" PKGINSTFOLDER="ProgramFiles64Folder" || \
|
||||
PKGGUID="cbf6ffa1-219e-4bb2-a0e5-74dbf1b58a45" PKGINSTFOLDER="ProgramFilesFolder"
|
||||
|
||||
# Download the Wintun driver
|
||||
if [ ! -d wintun ];
|
||||
then
|
||||
curl -o wintun.zip https://www.wintun.net/builds/wintun-0.14.1.zip
|
||||
unzip wintun.zip
|
||||
fi
|
||||
if [ $PKGARCH = "x64" ]; then
|
||||
PKGWINTUNDLL=wintun/bin/amd64/wintun.dll
|
||||
PKGWEBVIEWFILE=contrib/ui/mesh-ui/dll/x64/webview.dll
|
||||
PKGWEBVIEWFILELOADER=contrib/ui/mesh-ui/dll/x64/WebView2Loader.dll
|
||||
elif [ $PKGARCH = "x86" ]; then
|
||||
PKGWINTUNDLL=wintun/bin/x86/wintun.dll
|
||||
PKGWEBVIEWFILE=contrib/ui/mesh-ui/dll/x86/webview.dll
|
||||
PKGWEBVIEWFILELOADER=contrib/ui/mesh-ui/dll/x86/WebView2Loader.dll
|
||||
elif [ $PKGARCH = "arm" ]; then
|
||||
PKGWINTUNDLL=wintun/bin/arm/wintun.dll
|
||||
#elif [ $PKGARCH = "arm64" ]; then
|
||||
# PKGWINTUNDLL=wintun/bin/arm64/wintun.dll
|
||||
else
|
||||
echo "wasn't sure which architecture to get wintun for"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $PKGNAME != "master" ]; then
|
||||
PKGDISPLAYNAME="RiV-mesh Network (${PKGNAME} branch)"
|
||||
else
|
||||
PKGDISPLAYNAME="RiV-mesh Network"
|
||||
fi
|
||||
|
||||
# Generate the wix.xml file
|
||||
cat > wix.xml << EOF
|
||||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Product
|
||||
Name="${PKGDISPLAYNAME}"
|
||||
Id="*"
|
||||
UpgradeCode="${PKGGUID}"
|
||||
Language="1033"
|
||||
Codepage="1252"
|
||||
Version="${PKGVERSIONMS}"
|
||||
Manufacturer="RiV-chain">
|
||||
|
||||
<Package
|
||||
Id="*"
|
||||
Keywords="Installer"
|
||||
Description="RiV-mesh Network Installer"
|
||||
Comments="RiV-mesh Network standalone router for Windows."
|
||||
Manufacturer="RiV-chain"
|
||||
InstallerVersion="200"
|
||||
InstallScope="perMachine"
|
||||
Languages="1033"
|
||||
Compressed="yes"
|
||||
SummaryCodepage="1252" />
|
||||
|
||||
<MajorUpgrade
|
||||
AllowDowngrades="yes" />
|
||||
|
||||
<Media
|
||||
Id="1"
|
||||
Cabinet="Media.cab"
|
||||
EmbedCab="yes"
|
||||
CompressionLevel="high" />
|
||||
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="DesktopFolder" SourceName="Desktop"/>
|
||||
<Directory Id="${PKGINSTFOLDER}" Name="PFiles">
|
||||
<Directory Id="MeshInstallFolder" Name="RiV-mesh">
|
||||
<Component Id="MainExecutable" Guid="c2119231-2aa3-4962-867a-9759c87beb24">
|
||||
<File
|
||||
Id="Mesh"
|
||||
Name="mesh.exe"
|
||||
DiskId="1"
|
||||
Source="mesh.exe"
|
||||
KeyPath="yes" />
|
||||
|
||||
<File
|
||||
Id="Wintun"
|
||||
Name="wintun.dll"
|
||||
DiskId="1"
|
||||
Source="${PKGWINTUNDLL}" />
|
||||
|
||||
<ServiceInstall
|
||||
Id="MeshServiceInstaller"
|
||||
Account="LocalSystem"
|
||||
Description="RiV-mesh Network router process"
|
||||
DisplayName="RiV-mesh Service"
|
||||
ErrorControl="normal"
|
||||
LoadOrderGroup="NetworkProvider"
|
||||
Name="Mesh"
|
||||
Start="auto"
|
||||
Type="ownProcess"
|
||||
Arguments='-useconffile "%ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf" -logto "%ALLUSERSPROFILE%\\RiV-mesh\\mesh.log"'
|
||||
Vital="yes" />
|
||||
|
||||
<ServiceControl
|
||||
Id="MeshServiceControl"
|
||||
Name="Mesh"
|
||||
Start="install"
|
||||
Stop="both"
|
||||
Remove="uninstall" />
|
||||
</Component>
|
||||
|
||||
<Component Id="CtrlExecutable" Guid="a916b730-974d-42a1-b687-d9d504cbb86a">
|
||||
<File
|
||||
Id="Meshctl"
|
||||
Name="meshctl.exe"
|
||||
DiskId="1"
|
||||
Source="meshctl.exe"
|
||||
KeyPath="yes"/>
|
||||
</Component>
|
||||
|
||||
<Component Id="UIExecutable" Guid="ef9f30e0-8274-4526-835b-51bc09b5b1b7">
|
||||
|
||||
<File
|
||||
Id="MeshUI"
|
||||
Name="mesh-ui.exe"
|
||||
DiskId="1"
|
||||
Source="mesh-ui.exe"
|
||||
KeyPath="yes" />
|
||||
|
||||
<File
|
||||
Id="WebViewHtmlFile"
|
||||
Name="index.html"
|
||||
DiskId="1"
|
||||
Source="${PKGINDEXFILE}" />
|
||||
|
||||
<File
|
||||
Id="WebViewDllFile"
|
||||
Name="webview.dll"
|
||||
DiskId="1"
|
||||
Source="${PKGWEBVIEWFILE}" />
|
||||
|
||||
<File
|
||||
Id="WebViewLoaderFile"
|
||||
Name="WebView2Loader.dll"
|
||||
DiskId="1"
|
||||
Source="${PKGWEBVIEWFILELOADER}" />
|
||||
|
||||
</Component>
|
||||
|
||||
<Component Id="ConfigScript" Guid="64a3733b-c98a-4732-85f3-20cd7da1a785">
|
||||
<File
|
||||
Id="Configbat"
|
||||
Name="updateconfig.bat"
|
||||
DiskId="1"
|
||||
Source="updateconfig.bat"
|
||||
KeyPath="yes"/>
|
||||
</Component>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
<Feature Id="MeshFeature" Title="Mesh" Level="1">
|
||||
<ComponentRef Id="MainExecutable" />
|
||||
<ComponentRef Id="UIExecutable" />
|
||||
<ComponentRef Id="CtrlExecutable" />
|
||||
<ComponentRef Id="cmpDesktopShortcut" />
|
||||
<ComponentRef Id="ConfigScript" />
|
||||
</Feature>
|
||||
|
||||
<CustomAction
|
||||
Id="UpdateGenerateConfig"
|
||||
Directory="MeshInstallFolder"
|
||||
ExeCommand="cmd.exe /c updateconfig.bat"
|
||||
Execute="deferred"
|
||||
Return="check"
|
||||
Impersonate="yes" />
|
||||
|
||||
<!-- Step 2: Add UI to your installer / Step 4: Trigger the custom action -->
|
||||
<UI>
|
||||
<UIRef Id="WixUI_Minimal" />
|
||||
<Publish Dialog="ExitDialog"
|
||||
Control="Finish"
|
||||
Event="DoAction"
|
||||
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
|
||||
</UI>
|
||||
<WixVariable Id="WixUILicenseRtf" Value="${PKGLICENSEFILE}" />
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch RiV-mesh" />
|
||||
|
||||
<!-- Step 3: Include the custom action -->
|
||||
<Property Id="WixShellExecTarget" Value="[#MeshUI]" />
|
||||
<Property Id="ASSISTANCE_START_VIA_REGISTRY">1</Property>
|
||||
<CustomAction Id="LaunchApplication"
|
||||
BinaryKey="WixCA"
|
||||
DllEntry="WixShellExec"
|
||||
Impersonate="yes" />
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom
|
||||
Action="UpdateGenerateConfig"
|
||||
Before="StartServices">
|
||||
NOT Installed AND NOT REMOVE
|
||||
</Custom>
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<Component Id="cmpDesktopShortcut" Guid="e32e4d07-abf8-4c37-a2c3-1ca4b4f98adc" Directory="DesktopFolder" >
|
||||
<Shortcut Id="RiVMeshDesktopShortcut"
|
||||
Name="RiV-mesh"
|
||||
Description="RiV-mesh is IoT E2E encrypted network"
|
||||
Directory="DesktopFolder"
|
||||
Target="[MeshInstallFolder]mesh-ui.exe"
|
||||
WorkingDirectory="MeshInstallFolder"/>
|
||||
<RegistryValue Root="HKCU" Key="Software\RiV-chain\RiV-mesh" Name="installed" Type="integer" Value="1" KeyPath="yes" />
|
||||
<RegistryValue Id="MerAs.rst" Root="HKMU" Action="write"
|
||||
Key="Software\Microsoft\Windows\CurrentVersion\Run"
|
||||
Name="RiV-mesh client"
|
||||
Value="[MeshInstallFolder]mesh-ui.exe"
|
||||
Type="string" />
|
||||
<Condition>ASSISTANCE_START_VIA_REGISTRY</Condition>
|
||||
</Component>
|
||||
|
||||
</Product>
|
||||
</Wix>
|
||||
EOF
|
||||
|
||||
# Generate the MSI
|
||||
CANDLEFLAGS="-nologo"
|
||||
LIGHTFLAGS="-nologo -spdb -sice:ICE71 -sice:ICE61"
|
||||
wixbin/candle $CANDLEFLAGS -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj -arch ${PKGARCH} wix.xml && \
|
||||
wixbin/light $LIGHTFLAGS -ext WixUIExtension -ext WixUtilExtension -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj
|
|
@ -1,9 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script generates an MSI file for Yggdrasil for a given architecture. It
|
||||
# needs to run on Windows within MSYS2 and Go 1.17 or later must be installed on
|
||||
# the system and within the PATH. This is ran currently by GitHub Actions (see
|
||||
# the workflows in the repository).
|
||||
# This script generates an MSI file for Mesh for a given architecture. It
|
||||
# needs to run on Windows within MSYS2 and Go 1.13 or later must be installed on
|
||||
# the system and within the PATH. This is ran currently by Appveyor or GitHub Actions (see
|
||||
# appveyor.yml in the repository root) for both x86 and x64.
|
||||
#
|
||||
# Author: Neil Alexander <neilalexander@users.noreply.github.com>
|
||||
|
||||
|
@ -15,6 +15,22 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Get the rest of the repository history. This is needed within Appveyor because
|
||||
# otherwise we don't get all of the branch histories and therefore the semver
|
||||
# scripts don't work properly.
|
||||
if [ "${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}" != "" ];
|
||||
then
|
||||
git fetch --all
|
||||
git checkout ${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}
|
||||
elif [ "${APPVEYOR_REPO_BRANCH}" != "" ];
|
||||
then
|
||||
git fetch --all
|
||||
git checkout ${APPVEYOR_REPO_BRANCH}
|
||||
fi
|
||||
|
||||
# Install prerequisites within MSYS2
|
||||
pacman -S --needed --noconfirm unzip git curl
|
||||
|
||||
# Download the wix tools!
|
||||
if [ ! -d wixbin ];
|
||||
then
|
||||
|
@ -31,7 +47,7 @@ then
|
|||
)
|
||||
fi
|
||||
|
||||
# Build Yggdrasil!
|
||||
# Build Mesh!
|
||||
[ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 ./build
|
||||
[ "${PKGARCH}" == "x86" ] && GOOS=windows GOARCH=386 CGO_ENABLED=0 ./build
|
||||
[ "${PKGARCH}" == "arm" ] && GOOS=windows GOARCH=arm CGO_ENABLED=0 ./build
|
||||
|
@ -39,12 +55,12 @@ fi
|
|||
|
||||
# Create the postinstall script
|
||||
cat > updateconfig.bat << EOF
|
||||
if not exist %ALLUSERSPROFILE%\\Yggdrasil (
|
||||
mkdir %ALLUSERSPROFILE%\\Yggdrasil
|
||||
if not exist %ALLUSERSPROFILE%\\RiV-mesh (
|
||||
mkdir %ALLUSERSPROFILE%\\RiV-mesh
|
||||
)
|
||||
if not exist %ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.conf (
|
||||
if exist yggdrasil.exe (
|
||||
yggdrasil.exe -genconf > %ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.conf
|
||||
if not exist %ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf (
|
||||
if exist mesh.exe (
|
||||
mesh.exe -genconf > %ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf
|
||||
)
|
||||
)
|
||||
EOF
|
||||
|
@ -53,9 +69,9 @@ EOF
|
|||
PKGNAME=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/msi/msversion.sh --bare)
|
||||
PKGVERSIONMS=$(echo $PKGVERSION | tr - .)
|
||||
([ "${PKGARCH}" == "x64" ] || [ "${PKGARCH}" == "arm64" ]) && \
|
||||
PKGGUID="77757838-1a23-40a5-a720-c3b43e0260cc" PKGINSTFOLDER="ProgramFiles64Folder" || \
|
||||
PKGGUID="54a3294e-a441-4322-aefb-3bb40dd022bb" PKGINSTFOLDER="ProgramFilesFolder"
|
||||
[ "${PKGARCH}" == "x64" ] && \
|
||||
PKGGUID="5bcfdddd-66a7-4eb7-b5f7-4a7500dcc65d" PKGINSTFOLDER="ProgramFiles64Folder" || \
|
||||
PKGGUID="cbf6ffa1-219e-4bb2-a0e5-74dbf1b58a45" PKGINSTFOLDER="ProgramFilesFolder"
|
||||
|
||||
# Download the Wintun driver
|
||||
if [ ! -d wintun ];
|
||||
|
@ -77,9 +93,9 @@ else
|
|||
fi
|
||||
|
||||
if [ $PKGNAME != "master" ]; then
|
||||
PKGDISPLAYNAME="Yggdrasil Network (${PKGNAME} branch)"
|
||||
PKGDISPLAYNAME="RiV-mesh Network (${PKGNAME} branch)"
|
||||
else
|
||||
PKGDISPLAYNAME="Yggdrasil Network"
|
||||
PKGDISPLAYNAME="RiV-mesh Network"
|
||||
fi
|
||||
|
||||
# Generate the wix.xml file
|
||||
|
@ -93,14 +109,14 @@ cat > wix.xml << EOF
|
|||
Language="1033"
|
||||
Codepage="1252"
|
||||
Version="${PKGVERSIONMS}"
|
||||
Manufacturer="github.com/yggdrasil-network">
|
||||
Manufacturer="RiV-chain">
|
||||
|
||||
<Package
|
||||
Id="*"
|
||||
Keywords="Installer"
|
||||
Description="Yggdrasil Network Installer"
|
||||
Comments="Yggdrasil Network standalone router for Windows."
|
||||
Manufacturer="github.com/yggdrasil-network"
|
||||
Description="RiV-mesh Network Installer"
|
||||
Comments="RiV-mesh Network standalone router for Windows."
|
||||
Manufacturer="RiV-chain"
|
||||
InstallerVersion="200"
|
||||
InstallScope="perMachine"
|
||||
Languages="1033"
|
||||
|
@ -118,14 +134,14 @@ cat > wix.xml << EOF
|
|||
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="${PKGINSTFOLDER}" Name="PFiles">
|
||||
<Directory Id="YggdrasilInstallFolder" Name="Yggdrasil">
|
||||
<Directory Id="MeshInstallFolder" Name="Mesh">
|
||||
|
||||
<Component Id="MainExecutable" Guid="c2119231-2aa3-4962-867a-9759c87beb24">
|
||||
<File
|
||||
Id="Yggdrasil"
|
||||
Name="yggdrasil.exe"
|
||||
Id="Mesh"
|
||||
Name="mesh.exe"
|
||||
DiskId="1"
|
||||
Source="yggdrasil.exe"
|
||||
Source="mesh.exe"
|
||||
KeyPath="yes" />
|
||||
|
||||
<File
|
||||
|
@ -137,19 +153,19 @@ cat > wix.xml << EOF
|
|||
<ServiceInstall
|
||||
Id="ServiceInstaller"
|
||||
Account="LocalSystem"
|
||||
Description="Yggdrasil Network router process"
|
||||
DisplayName="Yggdrasil Service"
|
||||
Description="RiV-mesh Network router process"
|
||||
DisplayName="RiV-mesh Service"
|
||||
ErrorControl="normal"
|
||||
LoadOrderGroup="NetworkProvider"
|
||||
Name="Yggdrasil"
|
||||
Name="Mesh"
|
||||
Start="auto"
|
||||
Type="ownProcess"
|
||||
Arguments='-useconffile "%ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.conf" -logto "%ALLUSERSPROFILE%\\Yggdrasil\\yggdrasil.log"'
|
||||
Arguments='-useconffile "%ALLUSERSPROFILE%\\RiV-mesh\\mesh.conf" -logto "%ALLUSERSPROFILE%\\RiV-mesh\\mesh.log"'
|
||||
Vital="yes" />
|
||||
|
||||
<ServiceControl
|
||||
Id="ServiceControl"
|
||||
Name="yggdrasil"
|
||||
Id="MeshServiceControl"
|
||||
Name="Mesh"
|
||||
Start="install"
|
||||
Stop="both"
|
||||
Remove="uninstall" />
|
||||
|
@ -157,10 +173,10 @@ cat > wix.xml << EOF
|
|||
|
||||
<Component Id="CtrlExecutable" Guid="a916b730-974d-42a1-b687-d9d504cbb86a">
|
||||
<File
|
||||
Id="Yggdrasilctl"
|
||||
Name="yggdrasilctl.exe"
|
||||
Id="Meshctl"
|
||||
Name="meshctl.exe"
|
||||
DiskId="1"
|
||||
Source="yggdrasilctl.exe"
|
||||
Source="meshctl.exe"
|
||||
KeyPath="yes"/>
|
||||
</Component>
|
||||
|
||||
|
@ -176,7 +192,7 @@ cat > wix.xml << EOF
|
|||
</Directory>
|
||||
</Directory>
|
||||
|
||||
<Feature Id="YggdrasilFeature" Title="Yggdrasil" Level="1">
|
||||
<Feature Id="MeshFeature" Title="Mesh" Level="1">
|
||||
<ComponentRef Id="MainExecutable" />
|
||||
<ComponentRef Id="CtrlExecutable" />
|
||||
<ComponentRef Id="ConfigScript" />
|
||||
|
@ -184,7 +200,7 @@ cat > wix.xml << EOF
|
|||
|
||||
<CustomAction
|
||||
Id="UpdateGenerateConfig"
|
||||
Directory="YggdrasilInstallFolder"
|
||||
Directory="MeshInstallFolder"
|
||||
ExeCommand="cmd.exe /c updateconfig.bat"
|
||||
Execute="deferred"
|
||||
Return="check"
|
||||
|
@ -206,4 +222,4 @@ EOF
|
|||
CANDLEFLAGS="-nologo"
|
||||
LIGHTFLAGS="-nologo -spdb -sice:ICE71 -sice:ICE61"
|
||||
wixbin/candle $CANDLEFLAGS -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj -arch ${PKGARCH} wix.xml && \
|
||||
wixbin/light $LIGHTFLAGS -ext WixUtilExtension.dll -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj
|
||||
wixbin/light $LIGHTFLAGS -ext WixUtilExtension.dll -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}-nogui.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj
|
||||
|
|
|
@ -17,30 +17,6 @@ if [ $? != 0 ] || [ -z "$BRANCH" ]; then
|
|||
BRANCH="master"
|
||||
fi
|
||||
|
||||
# Split out into major, minor and patch numbers
|
||||
MAJOR=$(echo $TAG | cut -c 2- | cut -d "." -f 1)
|
||||
MINOR=$(echo $TAG | cut -c 2- | cut -d "." -f 2)
|
||||
PATCH=$(echo $TAG | cut -c 2- | cut -d "." -f 3 | awk -F"rc" '{print $1}')
|
||||
STAG=$(echo $TAG | sed 's/v//' | sed 's/[^0123456789.].//')
|
||||
|
||||
# Output in the desired format
|
||||
if [ $((PATCH)) -eq 0 ]; then
|
||||
printf '%s%d.%d' "$PREPEND" "$((MAJOR))" "$((MINOR))"
|
||||
else
|
||||
printf '%s%d.%d.%d' "$PREPEND" "$((MAJOR))" "$((MINOR))" "$((PATCH))"
|
||||
fi
|
||||
|
||||
# Add the build tag on non-master branches
|
||||
if [ "$BRANCH" != "master" ]; then
|
||||
BUILD=$(git rev-list --count $TAG..HEAD 2>/dev/null)
|
||||
|
||||
# Did getting the count of commits since the tag succeed?
|
||||
if [ $? != 0 ] || [ -z "$BUILD" ]; then
|
||||
printf -- "-unknown"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Is the build greater than zero?
|
||||
if [ $((BUILD)) -gt 0 ]; then
|
||||
printf -- "-%04d" "$((BUILD))"
|
||||
fi
|
||||
fi
|
||||
printf '%s' "$STAG"
|
||||
|
|
108
contrib/nas/nas-asustor.sh
Normal file
108
contrib/nas/nas-asustor.sh
Normal file
|
@ -0,0 +1,108 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .bin for WD NAS build.
|
||||
# You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=x86_64 contrib/nas/nas-asustor.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGFOLDER=$ENV_TAG-$PKGARCH-$PKGVERSION
|
||||
PKGFILE=mesh-$PKGFOLDER.apk
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "x86-64" ]; then GOOS=linux GOARCH=amd64 ./build
|
||||
elif [ $PKGARCH = "armv7" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
|
||||
else
|
||||
echo "Specify PKGARCH=x86-64 or armv7"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGFOLDER"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER
|
||||
|
||||
mkdir -p /tmp/$PKGFOLDER/bin
|
||||
mkdir -p /tmp/$PKGFOLDER/var/log
|
||||
chmod 0775 /tmp/$PKGFOLDER/ -R
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-asustor/* /tmp/$PKGFOLDER/ -r
|
||||
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
|
||||
|
||||
echo "Converting icon for: 90x90"
|
||||
convert -colorspace sRGB ./riv.png -resize 90x90 PNG32:/tmp/$PKGFOLDER/CONTROL/icon.png
|
||||
chmod 644 /tmp/$PKGFOLDER/CONTROL/icon.png
|
||||
|
||||
cat > /tmp/$PKGFOLDER/CONTROL/config.json << EOF
|
||||
{
|
||||
"general": {
|
||||
"package": "mesh-$ENV_TAG",
|
||||
"name": "RiV Mesh",
|
||||
"version": "$PKGVERSION",
|
||||
"depends": [],
|
||||
"conflicts": [],
|
||||
"developer": "Riv Chain ltd",
|
||||
"maintainer": "Riv Chain ltd",
|
||||
"email": "vadym.vikulin@rivchain.org",
|
||||
"website": "https://github.com/RiV-chain/RiV-mesh",
|
||||
"architecture": "$PKGARCH",
|
||||
"firmware": "2.4.0"
|
||||
},
|
||||
"adm-desktop": {
|
||||
"app": {
|
||||
"type":"custom",
|
||||
"protocol":"http",
|
||||
"port": 19019,
|
||||
"url": "/"
|
||||
},
|
||||
"privilege": {
|
||||
"accessible": "administrators",
|
||||
"customizable": true
|
||||
}
|
||||
},
|
||||
"register": {
|
||||
"share-folder": [
|
||||
],
|
||||
"prerequisites": {
|
||||
"enable-service": [],
|
||||
"restart-service": []
|
||||
},
|
||||
"boot-priority": {
|
||||
"start-order": 95,
|
||||
"stop-order": 5
|
||||
},
|
||||
"port": []
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
cat > /tmp/$PKGFOLDER/CHANGELOG.md << EOF
|
||||
See https://github.com/RiV-chain/RiV-mesh
|
||||
EOF
|
||||
|
||||
cat > /tmp/$PKGFOLDER/CONTROL/changelog.txt << EOF
|
||||
See https://github.com/RiV-chain/RiV-mesh
|
||||
EOF
|
||||
|
||||
cp mesh /tmp/$PKGFOLDER/bin
|
||||
cp meshctl /tmp/$PKGFOLDER/bin
|
||||
cp LICENSE /tmp/$PKGFOLDER/CONTROL/license.txt
|
||||
chmod +x /tmp/$PKGFOLDER/bin/*
|
||||
chmod 0775 /tmp/$PKGFOLDER/www -R
|
||||
|
||||
fakeroot python2 ./contrib/nas/tool/asustor_apkg_tools.py create /tmp/$PKGFOLDER
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER/
|
||||
#mv *.apk $PKGFILE
|
90
contrib/nas/nas-drobo.sh
Normal file
90
contrib/nas/nas-drobo.sh
Normal file
|
@ -0,0 +1,90 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .bin for WD NAS build.
|
||||
# You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=x86_64 contrib/nas/nas-asustor.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGNAME=$ENV_TAG-$PKGARCH-$PKGVERSION
|
||||
PKGFOLDER=$PKGNAME/mesh
|
||||
PKGFILE=mesh-$PKGNAME.tar.gz
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "armv7" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
|
||||
else
|
||||
echo "Specify PKGARCH=armv7"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGFOLDER"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER
|
||||
|
||||
mkdir -p /tmp/$PKGFOLDER/bin
|
||||
mkdir -p /tmp/$PKGFOLDER/config
|
||||
mkdir -p /tmp/$PKGFOLDER/var/log
|
||||
mkdir -p /tmp/$PKGFOLDER/lib/modules
|
||||
|
||||
if [ $ENV_TAG = "nas-drobo-5n" ]; then
|
||||
for kernel in 3.2.96-3 3.2.58-2 3.2.58-1 3.2.58 3.2.27; do
|
||||
echo "Loading tun module for Linux kernel $kernel"
|
||||
wget -N ftp://updates.drobo.com/droboapps/kernelmodules/5N/3.2.96-3/tun.ko -P /tmp/$PKGFOLDER/lib/modules/$kernel
|
||||
done
|
||||
elif [ $ENV_TAG = "nas-drobo-5n2" ]; then
|
||||
for kernel in 3.2.96-3 3.2.58-2; do
|
||||
echo "Loading tun module for Linux kernel $kernel"
|
||||
wget -N ftp://updates.drobo.com/droboapps/kernelmodules/5N2/3.2.96-3/tun.ko -P /tmp/$PKGFOLDER/lib/modules/$kernel
|
||||
done
|
||||
elif [ $ENV_TAG = "nas-drobo-b810n" ]; then
|
||||
for kernel in 3.2.96-3 3.2.58-2 3.2.58-1 3.2.58; do
|
||||
echo "Loading tun module for Linux kernel $kernel"
|
||||
wget -N ftp://updates.drobo.com/droboapps/kernelmodules/B810n/3.2.96-3/tun.ko -P /tmp/$PKGFOLDER/lib/modules/$kernel
|
||||
done
|
||||
else
|
||||
echo "Specify ENV_TAG=nas-drobo-5n or nas-drobo-5n2 or nas-drobo-b810n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p /tmp/$PKGFOLDER/tmp
|
||||
chmod 0775 /tmp/$PKGFOLDER/ -R
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-drobo/Content/* /tmp/$PKGFOLDER/ -r
|
||||
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
|
||||
|
||||
cat > /tmp/$PKGFOLDER/version.txt << EOF
|
||||
$PKGVERSION
|
||||
EOF
|
||||
|
||||
cp mesh /tmp/$PKGFOLDER/bin
|
||||
cp meshctl /tmp/$PKGFOLDER/bin
|
||||
cp LICENSE /tmp/$PKGFOLDER/
|
||||
chmod +x /tmp/$PKGFOLDER/*.sh
|
||||
chmod +x /tmp/$PKGFOLDER/bin/*
|
||||
chmod 0775 /tmp/$PKGFOLDER/www -R
|
||||
|
||||
current_dir=$(pwd)
|
||||
|
||||
cd /tmp/$PKGFOLDER && tar czf ../mesh.tgz $(ls .)
|
||||
cd ../ && md5sum mesh.tgz > mesh.tgz.md5
|
||||
tar czf $PKGFILE mesh.tgz mesh.tgz.md5
|
||||
|
||||
mv $PKGFILE "$current_dir"
|
||||
|
||||
cd "$current_dir"
|
||||
|
||||
rm -rf /tmp/$PKGNAME/
|
||||
|
108
contrib/nas/nas-netgear-os6.sh
Normal file
108
contrib/nas/nas-netgear-os6.sh
Normal file
|
@ -0,0 +1,108 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .deb for Debian/Ubuntu. It installs
|
||||
# mesh and enables it in systemd. You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=i386 sh contrib/deb/generate.sh
|
||||
|
||||
if [ $(pwd) != $(git rev-parse --show-toplevel) ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGNAME=$ENV_TAG-$PKGVERSION
|
||||
PKGFILE=$PKGNAME.deb
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build
|
||||
elif [ $PKGARCH = "armel" ]; then GOARCH=arm GOARM=5 GOOS=linux ./build
|
||||
else
|
||||
echo "Specify PKGARCH=amd64,armel"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGFILE"
|
||||
|
||||
mkdir -p /tmp/$PKGNAME/usr/bin
|
||||
mkdir -p /tmp/$PKGNAME/debian/
|
||||
mkdir -p /tmp/$PKGNAME/DEBIAN/
|
||||
mkdir -p /tmp/$PKGNAME/apps/mesh/bin
|
||||
mkdir -p /tmp/$PKGNAME/apps/mesh/www
|
||||
mkdir -p /tmp/$PKGNAME/apps/mesh/var/log
|
||||
mkdir -p /tmp/$PKGNAME/apps/mesh/var/lib/mesh/hooks
|
||||
mkdir -p /tmp/$PKGNAME/usr/share/doc/mesh
|
||||
|
||||
chmod 0775 /tmp/$PKGNAME/ -R
|
||||
|
||||
for resolution in 150x150; do
|
||||
echo "Converting icon for: $resolution"
|
||||
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGNAME/apps/mesh/logo.png && \
|
||||
chmod 644 /tmp/$PKGNAME/apps/mesh/logo.png
|
||||
done
|
||||
|
||||
cat > /tmp/$PKGNAME/apps/mesh/config.xml << EOF
|
||||
<Application resource-id="mesh"><!-- 'resource-id' must be AppName -->
|
||||
<Name>RiV Mesh</Name><!-- Any desciptive name, upto 48 chars -->
|
||||
<Author>Riv Chain Ltd</Author><!-- Authors name. upto 48 chars -->
|
||||
<Version>$PKGVERSION</Version><!-- Version -->
|
||||
<RequireReboot>0</RequireReboot><!-- If non-zero, it indicates reboot is required. -->
|
||||
<ConfigURL></ConfigURL><!-- 'localhost' will be replaced by framework JS. -->
|
||||
<LaunchURL>https://localhost/apps/mesh/</LaunchURL><!-- 'localhost' will be replaced by framework JS. -->
|
||||
<ReservePort>19019</ReservePort>
|
||||
<DebianPackage>mesh</DebianPackage>
|
||||
<ServiceName>fvapp-mesh.service</ServiceName><!-- If start/stop need to start/stop service, specify service name -->
|
||||
<Description lang="en-us">RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.</Description>
|
||||
</Application>
|
||||
EOF
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-netgear-os6/package/apps /tmp/$PKGNAME/ -r
|
||||
cp contrib/ui/www/* /tmp/$PKGNAME/apps/mesh/www/ -r
|
||||
|
||||
cat > /tmp/$PKGNAME/debian/changelog << EOF
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
|
||||
echo 9 > /tmp/$PKGNAME/debian/compat
|
||||
|
||||
cat > /tmp/$PKGNAME/DEBIAN/control << EOF
|
||||
Package: mesh
|
||||
Version: $PKGVERSION
|
||||
Section: contrib/net
|
||||
Priority: extra
|
||||
Architecture: $PKGARCH
|
||||
Replaces: $PKGREPLACES
|
||||
Conflicts: $PKGREPLACES
|
||||
Maintainer: Vadym Vikulin <vadym.vikulin@rivchain.org>
|
||||
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
|
||||
It is lightweight, self-arranging, supported on multiple platforms and
|
||||
allows pretty much any IPv6-capable application to communicate securely with
|
||||
other RiV-mesh nodes.
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/copyright << EOF
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
cat > /tmp/$PKGNAME/debian/docs << EOF
|
||||
Please see https://github.com/RiV-chain/RiV-mesh/
|
||||
EOF
|
||||
|
||||
cp mesh /tmp/$PKGNAME/apps/mesh/bin
|
||||
cp meshctl /tmp/$PKGNAME/apps/mesh/bin
|
||||
ln -s /apps/mesh/bin/meshctl /tmp/$PKGNAME/usr/bin/meshctl
|
||||
ln -s /apps/mesh/var/log/mesh.log /tmp/$PKGNAME/apps/mesh/www/log
|
||||
chmod 0775 /tmp/$PKGNAME/DEBIAN/*
|
||||
chmod 755 /tmp/$PKGNAME/apps/mesh/bin/*
|
||||
|
||||
dpkg-deb -Zxz --build --root-owner-group /tmp/$PKGNAME
|
||||
|
||||
cp /tmp/$PKGFILE .
|
||||
|
||||
rm -rf /tmp/$PKGNAME
|
84
contrib/nas/nas-qnap.sh
Normal file
84
contrib/nas/nas-qnap.sh
Normal file
|
@ -0,0 +1,84 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .bin for WD NAS build.
|
||||
# You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=x86_64 contrib/nas/nas-asustor.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semmsiver/name.sh)
|
||||
PKGVERSION=$(sh contrib/msi/msversion.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGFOLDER=$ENV_TAG-$PKGARCH-$PKGVERSION
|
||||
PKGFILE=mesh-$PKGFOLDER.qpkg
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "x86-64" ]; then GOOS=linux GOARCH=amd64 ./build
|
||||
elif [ $PKGARCH = "arm-x31" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
|
||||
else
|
||||
echo "Specify PKGARCH=x86-64 or arm-x31"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGFOLDER"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER
|
||||
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/icons
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/shared/bin
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/shared/tmp
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/shared/lib
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/shared/www
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/shared/var/log
|
||||
chmod 0775 /tmp/$PKGFOLDER/ -R
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-qnap/package/* /tmp/$PKGFOLDER/mesh -r
|
||||
cp contrib/ui/nas-qnap/au/* /tmp/$PKGFOLDER/mesh/shared -r
|
||||
cp contrib/ui/www/* /tmp/$PKGFOLDER/mesh/shared/www/ -r
|
||||
|
||||
echo "Converting icon for: 64x64"
|
||||
convert -colorspace sRGB ./riv.png -resize 64x64 /tmp/$PKGFOLDER/mesh/icons/mesh.gif
|
||||
echo "Converting icon for: 80x80"
|
||||
convert -colorspace sRGB ./riv.png -resize 80x80 /tmp/$PKGFOLDER/mesh/icons/mesh_80.gif
|
||||
convert -colorspace sRGB ./riv.png -resize 64x64 /tmp/$PKGFOLDER/mesh/icons/mesh_gray.gif
|
||||
|
||||
cat > /tmp/$PKGFOLDER/mesh/qpkg.cfg << EOF
|
||||
QPKG_DISPLAY_NAME="RiV Mesh"
|
||||
QPKG_NAME="mesh"
|
||||
QPKG_VER="$PKGVERSION"
|
||||
QPKG_AUTHOR="Riv Chain ltd"
|
||||
QPKG_SUMMARY="RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network."
|
||||
QPKG_RC_NUM="198"
|
||||
QPKG_SERVICE_PROGRAM="mesh.sh"
|
||||
QPKG_WEBUI="/mesh"
|
||||
QPKG_WEB_PORT=
|
||||
QPKG_LICENSE="LGPLv3"
|
||||
QDK_BUILD_ARCH="$PKGARCH"
|
||||
EOF
|
||||
|
||||
touch /tmp/$PKGFOLDER/mesh/qdk.conf
|
||||
|
||||
cp mesh /tmp/$PKGFOLDER/mesh/shared/bin
|
||||
cp meshctl /tmp/$PKGFOLDER/mesh/shared/bin
|
||||
chmod +x /tmp/$PKGFOLDER/mesh/shared/bin/*
|
||||
chmod 0775 /tmp/$PKGFOLDER/mesh/shared/www -R
|
||||
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
|
||||
|
||||
curent_dir=$(pwd)
|
||||
|
||||
cd /tmp/$PKGFOLDER/mesh && /opt/tomcat/tool/Qnap/bin/qbuild --force-config -v
|
||||
|
||||
mv build/*.qpkg "$curent_dir"/$PKGFILE
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER/
|
92
contrib/nas/nas-synology-dsm6.0.sh
Normal file
92
contrib/nas/nas-synology-dsm6.0.sh
Normal file
|
@ -0,0 +1,92 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .bin for WD NAS build.
|
||||
# You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=armv7hf contrib/nas/nas-westerndigital-os5.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/nas/tool/synology_version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGNAME=$ENV_TAG-$PKGARCH-$PKGVERSION
|
||||
PKGFOLDER=${PKGNAME}/package
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "x86_64" ]; then GOOS=linux GOARCH=amd64 ./build
|
||||
elif [ $PKGARCH = "armv7" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
|
||||
else
|
||||
echo "Specify PKGARCH=x86_64"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGNAME"
|
||||
|
||||
rm -rf /tmp/${PKGNAME}
|
||||
mkdir -p /tmp/$PKGFOLDER/bin/
|
||||
mkdir -p /tmp/$PKGFOLDER/lib/
|
||||
mkdir -p /tmp/$PKGFOLDER/tmp/
|
||||
mkdir -p /tmp/$PKGFOLDER/ui/
|
||||
mkdir -p /tmp/$PKGFOLDER/var/log/
|
||||
mkdir -p /tmp/$PKGFOLDER/var/lib/mesh
|
||||
|
||||
chmod 0775 /tmp/$PKGFOLDER/ -R
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-synology-dsm6.0/package/* /tmp/$PKGFOLDER/ -r
|
||||
cp contrib/ui/nas-synology-dsm6.0/spk/* /tmp/$PKGNAME/ -r
|
||||
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
|
||||
|
||||
for res in 16 24 32 48 64 72 256; do
|
||||
resolution="${res}x${res}"
|
||||
echo "Converting icon for: $resolution"
|
||||
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGFOLDER/ui/mesh-$res.png && \
|
||||
chmod 644 /tmp/$PKGFOLDER/ui/mesh-$res.png
|
||||
done
|
||||
|
||||
echo "Converting icon for: 72x72"
|
||||
convert -colorspace sRGB ./riv.png -resize 72x72 PNG32:/tmp/$PKGNAME/PACKAGE_ICON.PNG
|
||||
echo "Converting icon for: 256x256"
|
||||
convert -colorspace sRGB ./riv.png -resize 256x256 PNG32:/tmp/$PKGNAME/PACKAGE_ICON_256.PNG
|
||||
|
||||
cat > /tmp/$PKGNAME/INFO << EOF
|
||||
package="mesh"
|
||||
displayname="RiV Mesh"
|
||||
version="$PKGVERSION"
|
||||
description="RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network. \
|
||||
It is lightweight, self-arranging, supported on multiple platforms and \
|
||||
allows pretty much any IPv6-capable application to communicate securely with \
|
||||
other RiV-mesh nodes."
|
||||
maintainer="Riv Chain ltd"
|
||||
maintainer_url="https://github.com/RiV-chain/RiV-mesh"
|
||||
support_url="https://github.com/RiV-chain/RiV-mesh"
|
||||
dsmappname="org.mesh"
|
||||
arch="$PKGARCH"
|
||||
dsmuidir="ui"
|
||||
silent_upgrade="yes"
|
||||
os_min_ver="6.0-7320"
|
||||
EOF
|
||||
|
||||
echo $PKGVERSION > /tmp/$PKGNAME/VERSION
|
||||
|
||||
cp mesh /tmp/$PKGFOLDER/bin
|
||||
cp meshctl /tmp/$PKGFOLDER/bin
|
||||
cp LICENSE /tmp/$PKGNAME/
|
||||
|
||||
chmod -R 0755 /tmp/$PKGFOLDER/www/assets
|
||||
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
|
||||
chmod -R +x /tmp/$PKGNAME/scripts
|
||||
|
||||
fakeroot ./contrib/nas/tool/synology_pkg_util.sh make_package /tmp/$PKGFOLDER /tmp/$PKGNAME
|
||||
rm -rf /tmp/$PKGFOLDER/
|
||||
fakeroot ./contrib/nas/tool/synology_pkg_util.sh make_spk /tmp/$PKGNAME . $PKGNAME.spk
|
||||
|
95
contrib/nas/nas-synology-dsm7.0.sh
Normal file
95
contrib/nas/nas-synology-dsm7.0.sh
Normal file
|
@ -0,0 +1,95 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .bin for WD NAS build.
|
||||
# You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=armv7hf contrib/nas/nas-westerndigital-os5.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/nas/tool/synology_version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGNAME=$ENV_TAG-$PKGARCH-$PKGVERSION
|
||||
PKGFOLDER=${PKGNAME}/package
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "x86_64" ]; then GOOS=linux GOARCH=amd64 ./build
|
||||
elif [ $PKGARCH = "armv7" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
|
||||
else
|
||||
echo "Specify PKGARCH=x86_64 or armv7"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGNAME"
|
||||
|
||||
rm -rf /tmp/${PKGNAME}
|
||||
mkdir -p /tmp/$PKGFOLDER/bin/
|
||||
mkdir -p /tmp/$PKGFOLDER/lib/
|
||||
mkdir -p /tmp/$PKGFOLDER/tmp/
|
||||
mkdir -p /tmp/$PKGFOLDER/ui/
|
||||
mkdir -p /tmp/$PKGFOLDER/var/log/
|
||||
mkdir -p /tmp/$PKGFOLDER/var/lib/mesh
|
||||
|
||||
chmod 0775 /tmp/$PKGFOLDER/ -R
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-synology-dsm6.0/package/* /tmp/$PKGFOLDER/ -r
|
||||
cp contrib/ui/nas-synology-dsm6.0/spk/* /tmp/$PKGNAME/ -r
|
||||
cp contrib/ui/nas-synology-dsm7.0/package/* /tmp/$PKGFOLDER/ -r
|
||||
cp contrib/ui/nas-synology-dsm7.0/spk/* /tmp/$PKGNAME/ -r
|
||||
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
|
||||
|
||||
for res in 16 24 32 48 64 72 256; do
|
||||
resolution="${res}x${res}"
|
||||
echo "Converting icon for: $resolution"
|
||||
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGFOLDER/ui/mesh-$res.png && \
|
||||
chmod 644 /tmp/$PKGFOLDER/ui/mesh-$res.png
|
||||
done
|
||||
|
||||
echo "Converting icon for: 64x64"
|
||||
convert -colorspace sRGB ./riv.png -resize 64x64 PNG32:/tmp/$PKGNAME/PACKAGE_ICON.PNG
|
||||
echo "Converting icon for: 256x256"
|
||||
convert -colorspace sRGB ./riv.png -resize 256x256 PNG32:/tmp/$PKGNAME/PACKAGE_ICON_256.PNG
|
||||
|
||||
cat > /tmp/$PKGNAME/INFO << EOF
|
||||
package="mesh"
|
||||
displayname="RiV Mesh"
|
||||
version="$PKGVERSION"
|
||||
description="RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network. \
|
||||
It is lightweight, self-arranging, supported on multiple platforms and \
|
||||
allows pretty much any IPv6-capable application to communicate securely with \
|
||||
other RiV-mesh nodes."
|
||||
maintainer="Riv Chain ltd"
|
||||
maintainer_url="https://github.com/RiV-chain/RiV-mesh"
|
||||
support_url="https://github.com/RiV-chain/RiV-mesh"
|
||||
dsmappname="org.mesh"
|
||||
arch="$PKGARCH"
|
||||
dsmuidir="ui"
|
||||
silent_upgrade="yes"
|
||||
os_min_ver="7.0-40000"
|
||||
EOF
|
||||
|
||||
echo $PKGVERSION > /tmp/$PKGNAME/VERSION
|
||||
|
||||
cp mesh /tmp/$PKGFOLDER/bin
|
||||
cp meshctl /tmp/$PKGFOLDER/bin
|
||||
cp LICENSE /tmp/$PKGNAME/
|
||||
|
||||
chmod -R 0755 /tmp/$PKGFOLDER/www/assets
|
||||
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
|
||||
chmod -R 0755 /tmp/$PKGNAME/scripts
|
||||
chmod -R 0755 /tmp/$PKGNAME/conf
|
||||
|
||||
fakeroot ./contrib/nas/tool/synology_pkg_util.sh make_package /tmp/$PKGFOLDER /tmp/$PKGNAME
|
||||
rm -rf /tmp/$PKGFOLDER/
|
||||
fakeroot ./contrib/nas/tool/synology_pkg_util.sh make_spk /tmp/$PKGNAME . $PKGNAME.spk
|
||||
|
91
contrib/nas/nas-terramaster.sh
Normal file
91
contrib/nas/nas-terramaster.sh
Normal file
|
@ -0,0 +1,91 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .bin for Terramaster NAS build.
|
||||
# You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=x86_64 contrib/nas/nas-terramaster.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semmsiver/name.sh)
|
||||
PKGVERSION=$(sh contrib/msi/msversion.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGFOLDER=$ENV_TAG-$PKGARCH-$PKGVERSION
|
||||
PKGFILE=mesh-$PKGFOLDER.tpk
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ -z $TERRAMASTER_TOOLS ]; then
|
||||
echo "Specify TERRAMASTER_TOOLS path"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "x86-64" ]; then GOOS=linux GOARCH=amd64 ./build
|
||||
elif [ $PKGARCH = "arm-x31" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
|
||||
else
|
||||
echo "Specify PKGARCH=x86-64 or arm-x31"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGFOLDER"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER
|
||||
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/usr/bin
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/var/log
|
||||
mkdir -p /tmp/$PKGFOLDER/mesh/usr/www/images/icons
|
||||
chmod 0775 /tmp/$PKGFOLDER/ -R
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-terramaster/mesh /tmp/$PKGFOLDER/ -r
|
||||
cp contrib/ui/www/* /tmp/$PKGFOLDER/mesh/usr/local/mesh/www -r
|
||||
|
||||
echo "Converting icon for: 120x120"
|
||||
convert -colorspace sRGB ./riv.png -resize 120x120 PNG32:/tmp/$PKGFOLDER/mesh/usr/www/images/icons/mesh.png
|
||||
|
||||
echo "$PKGVERSION" > /tmp/$PKGFOLDER/mesh/version
|
||||
|
||||
cat > /tmp/$PKGFOLDER/mesh/mesh.lang << EOF
|
||||
[zh-cn]
|
||||
name = "RiV Mesh"
|
||||
auth = "mesh"
|
||||
version = "$PKGVERSION"
|
||||
descript = "RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network."
|
||||
|
||||
[en-us]
|
||||
name = "RiV Mesh"
|
||||
auth = "mesh"
|
||||
version = "$PKGVERSION"
|
||||
descript = "RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network."
|
||||
EOF
|
||||
|
||||
cp mesh /tmp/$PKGFOLDER/mesh/usr/bin
|
||||
cp meshctl /tmp/$PKGFOLDER/mesh/usr/bin
|
||||
cp riv.svg /tmp/$PKGFOLDER/mesh/usr/www/images/icons/mesh.svg
|
||||
ln -s /usr/mesh/var/log/mesh.log /tmp/$PKGFOLDER/mesh/usr/local/mesh/www/log
|
||||
chmod +x /tmp/$PKGFOLDER/mesh/usr/bin/*
|
||||
chmod 0775 /tmp/$PKGFOLDER/mesh/usr/www -R
|
||||
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
|
||||
|
||||
curent_dir=$(pwd)
|
||||
|
||||
cd /tmp/$PKGFOLDER/
|
||||
|
||||
cp $TERRAMASTER_TOOLS/makeapp .
|
||||
cp $TERRAMASTER_TOOLS/install-* .
|
||||
cp -r $TERRAMASTER_TOOLS/phpencode .
|
||||
|
||||
./makeapp mesh
|
||||
|
||||
cd dist/$PKGFOLDER && mv *.tpk "$curent_dir"/$PKGFILE
|
||||
|
||||
cd "$curent_dir"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER/
|
92
contrib/nas/nas-westerndigital-os3.sh
Normal file
92
contrib/nas/nas-westerndigital-os3.sh
Normal file
|
@ -0,0 +1,92 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .bin for WD NAS build.
|
||||
# You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=armv7hf contrib/nas/nas-westerndigital-os5.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGNAME=$PKG-$PKGVERSION-$PKGARCH
|
||||
PKGFOLDER=mesh
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "arm" ]; then GOOS=linux GOARCH=arm GOARM=5 ./build
|
||||
else
|
||||
echo "Specify PKGARCH=arm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGNAME"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER
|
||||
mkdir -p /tmp/$PKGFOLDER/bin/
|
||||
mkdir -p /tmp/$PKGFOLDER/tmp/
|
||||
mkdir -p /tmp/$PKGFOLDER/lib/
|
||||
mkdir -p /tmp/$PKGFOLDER/var/log/
|
||||
mkdir -p /tmp/$PKGFOLDER/var/lib/mesh
|
||||
|
||||
chmod 0775 /tmp/$PKGFOLDER/ -R
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-westerndigital/package/mesh/* /tmp/$PKGFOLDER/ -r
|
||||
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
|
||||
|
||||
for resolution in 256x256; do
|
||||
echo "Converting icon for: $resolution"
|
||||
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGFOLDER/www/mesh.png && \
|
||||
chmod 644 /tmp/$PKGFOLDER/www/mesh.png
|
||||
done
|
||||
|
||||
cat > /tmp/$PKGFOLDER/apkg.rc << EOF
|
||||
Package: mesh
|
||||
Section: Apps
|
||||
Version: $PKGVERSION
|
||||
Packager: RiV Chain
|
||||
Email: vadym.vikulin@rivchain.org
|
||||
Homepage: https://github.com/RiV-chain/RiV-mesh
|
||||
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
|
||||
It is lightweight, self-arranging, supported on multiple platforms and
|
||||
allows pretty much any IPv6-capable application to communicate securely with
|
||||
other RiV-mesh nodes.
|
||||
Icon: mesh.png
|
||||
AddonShowName: RiV Mesh
|
||||
AddonIndexPage: index.html?v=$PKGVERSION
|
||||
AddonUsedPort:
|
||||
InstDepend:
|
||||
InstConflict:
|
||||
StartDepend:
|
||||
StartConflict:
|
||||
CenterType: 0
|
||||
UserControl: 1
|
||||
MinFWVer:
|
||||
MaxFWVer:
|
||||
IndividualFlag:
|
||||
EOF
|
||||
|
||||
cp mesh /tmp/$PKGFOLDER/bin
|
||||
cp meshctl /tmp/$PKGFOLDER/bin
|
||||
chmod -R 0755 /tmp/$PKGFOLDER/www/assets
|
||||
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
|
||||
chmod +x /tmp/$PKGFOLDER/*.sh
|
||||
curent_dir=$(pwd)
|
||||
echo "current folder=$curent_dir"
|
||||
|
||||
cd /tmp/$PKGFOLDER/ && mksapkg -E -s -m WDMyCloudEX4
|
||||
|
||||
cp /tmp/WDMyCloudEX4_mesh_$PKGVERSION.bin* "$curent_dir"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER
|
||||
|
||||
cd "$curent_dir"
|
92
contrib/nas/nas-westerndigital-os5.sh
Normal file
92
contrib/nas/nas-westerndigital-os5.sh
Normal file
|
@ -0,0 +1,92 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This is a lazy script to create a .bin for WD NAS build.
|
||||
# You can give it the PKGARCH= argument
|
||||
# i.e. PKGARCH=armv7hf contrib/nas/nas-westerndigital-os5.sh
|
||||
|
||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||
then
|
||||
echo "You should run this script from the top-level directory of the git repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||
PKG=$(sh contrib/semver/name.sh)
|
||||
PKGVERSION=$(sh contrib/semver/version.sh --bare)
|
||||
PKGARCH=${PKGARCH-amd64}
|
||||
PKGNAME=$PKG-$PKGVERSION-$PKGARCH
|
||||
PKGFOLDER=mesh
|
||||
PKGREPLACES=mesh
|
||||
|
||||
if [ $PKGBRANCH = "master" ]; then
|
||||
PKGREPLACES=mesh-develop
|
||||
fi
|
||||
|
||||
if [ $PKGARCH = "armv7hf" ]; then GOOS=linux GOARCH=arm GOARM=7 ./build
|
||||
else
|
||||
echo "Specify PKGARCH=armv7hf"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building $PKGNAME"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER
|
||||
mkdir -p /tmp/$PKGFOLDER/bin/
|
||||
mkdir -p /tmp/$PKGFOLDER/tmp/
|
||||
mkdir -p /tmp/$PKGFOLDER/lib/
|
||||
mkdir -p /tmp/$PKGFOLDER/var/log/
|
||||
mkdir -p /tmp/$PKGFOLDER/var/lib/mesh
|
||||
|
||||
chmod 0775 /tmp/$PKGFOLDER/ -R
|
||||
|
||||
echo "coping ui package..."
|
||||
cp contrib/ui/nas-westerndigital/package/mesh/* /tmp/$PKGFOLDER/ -r
|
||||
cp contrib/ui/www/* /tmp/$PKGFOLDER/www/ -r
|
||||
|
||||
for resolution in 256x256; do
|
||||
echo "Converting icon for: $resolution"
|
||||
convert -colorspace sRGB ./riv.png -resize $resolution PNG32:/tmp/$PKGFOLDER/www/mesh.png && \
|
||||
chmod 644 /tmp/$PKGFOLDER/www/mesh.png
|
||||
done
|
||||
|
||||
cat > /tmp/$PKGFOLDER/apkg.rc << EOF
|
||||
Package: mesh
|
||||
Section: Apps
|
||||
Version: $PKGVERSION
|
||||
Packager: RiV Chain
|
||||
Email: vadym.vikulin@rivchain.org
|
||||
Homepage: https://github.com/RiV-chain/RiV-mesh
|
||||
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
|
||||
It is lightweight, self-arranging, supported on multiple platforms and
|
||||
allows pretty much any IPv6-capable application to communicate securely with
|
||||
other RiV-mesh nodes.
|
||||
Icon: mesh.png
|
||||
AddonShowName: RiV Mesh
|
||||
AddonIndexPage: index.html?v=$PKGVERSION
|
||||
AddonUsedPort:
|
||||
InstDepend:
|
||||
InstConflict:
|
||||
StartDepend:
|
||||
StartConflict:
|
||||
CenterType: 0
|
||||
UserControl: 1
|
||||
MinFWVer:
|
||||
MaxFWVer:
|
||||
IndividualFlag:
|
||||
EOF
|
||||
|
||||
cp mesh /tmp/$PKGFOLDER/bin
|
||||
cp meshctl /tmp/$PKGFOLDER/bin
|
||||
chmod -R 0755 /tmp/$PKGFOLDER/www/assets
|
||||
chmod -R u+rwX,go+rX,g-w /tmp/$PKGFOLDER
|
||||
chmod +x /tmp/$PKGFOLDER/*.sh
|
||||
curent_dir=$(pwd)
|
||||
echo "current folder=$curent_dir"
|
||||
|
||||
cd /tmp/$PKGFOLDER/ && MyCloudOS5_mksapkg -E -s -m WDMyCloudEX4100
|
||||
|
||||
cp /tmp/WDMyCloudEX4100_mesh_$PKGVERSION.bin* "$curent_dir"
|
||||
|
||||
rm -rf /tmp/$PKGFOLDER
|
||||
|
||||
cd "$curent_dir"
|
574
contrib/nas/tool/asustor_apkg_tools.py
Executable file
574
contrib/nas/tool/asustor_apkg_tools.py
Executable file
|
@ -0,0 +1,574 @@
|
|||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2011-2013 Asustor Systems, Inc. All Rights Reserved.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import zipfile
|
||||
import tarfile
|
||||
import tempfile
|
||||
import shutil
|
||||
import json
|
||||
import glob
|
||||
import re
|
||||
import csv
|
||||
|
||||
__author__ = 'Walker Lee <walkerlee@asustor.com>'
|
||||
__copyright__ = 'Copyright (C) 2011-2013 ASUSTOR Systems, Inc. All Rights Reserved.'
|
||||
__version__ = '0.1'
|
||||
__abs_path__ = os.path.abspath(sys.argv[0])
|
||||
__program__ = os.path.basename(__abs_path__)
|
||||
|
||||
def find_developer(app):
|
||||
developer = None
|
||||
|
||||
if os.path.exists('apkg-developer-mapping.csv'):
|
||||
with open('apkg-developer-mapping.csv', 'r') as f:
|
||||
for row in csv.reader(f):
|
||||
if row[0] == app:
|
||||
developer = row[1]
|
||||
break;
|
||||
|
||||
return developer
|
||||
|
||||
class Chdir:
|
||||
def __init__(self, newPath):
|
||||
self.newPath = newPath
|
||||
|
||||
def __enter__(self):
|
||||
self.savedPath = os.getcwd()
|
||||
os.chdir(self.newPath)
|
||||
|
||||
def __exit__(self, etype, value, traceback):
|
||||
os.chdir(self.savedPath)
|
||||
|
||||
class Apkg:
|
||||
umask = 0022
|
||||
tmp_dir = '/tmp'
|
||||
|
||||
tmp_prefix = 'APKG-'
|
||||
|
||||
apk_format = {
|
||||
'version' : '2.0',
|
||||
'format' : 'zip',
|
||||
'suffix' : 'apk'
|
||||
}
|
||||
|
||||
apk_file_contents = {
|
||||
'version' : 'apkg-version',
|
||||
'data' : 'data.tar.gz',
|
||||
'control' : 'control.tar.gz'
|
||||
}
|
||||
|
||||
apk_special_folders = {
|
||||
'control' : 'CONTROL',
|
||||
'webman' : 'webman',
|
||||
'web' : 'www'
|
||||
}
|
||||
|
||||
apk_control_files = {
|
||||
'pkg-config' : 'config.json',
|
||||
'changlog' : 'changelog.txt',
|
||||
'description' : 'description.txt',
|
||||
'icon' : 'icon.png',
|
||||
'script-pre-install' : 'pre-install.sh',
|
||||
'script-pre-uninstall' : 'pre-uninstall.sh',
|
||||
'script-post-install' : 'post-install.sh',
|
||||
'script-post-uninstall' : 'post-uninstall.sh',
|
||||
'script-start-stop' : 'start-stop.sh',
|
||||
}
|
||||
|
||||
apk_web_settings = {
|
||||
'user' : 'admin',
|
||||
'group' : 'administrators',
|
||||
'uid' : 999,
|
||||
'gid' : 999,
|
||||
'perms' : 0770
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.pid = os.getpid()
|
||||
self.cwd = os.getcwd()
|
||||
self.pkg_tmp_dir = self.tmp_dir + '/APKG.' + str(self.pid)
|
||||
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
def pkg_misc_check(self):
|
||||
pass
|
||||
|
||||
def compress_pkg(self):
|
||||
pass
|
||||
|
||||
def __check_apk_format(self, apk_file):
|
||||
file_list = []
|
||||
|
||||
# check apk file format
|
||||
try:
|
||||
with zipfile.ZipFile(apk_file, 'r') as apk_zip:
|
||||
file_list = apk_zip.namelist()
|
||||
except zipfile.BadZipfile:
|
||||
print 'File is not a apk file: %s' % (apk_file)
|
||||
return False
|
||||
|
||||
# check apk file contents
|
||||
if not file_list:
|
||||
print 'File is empty: %s' % (apk_file)
|
||||
return False
|
||||
|
||||
result = True
|
||||
for (key, value) in self.apk_file_contents.items():
|
||||
if value not in file_list:
|
||||
print 'Can\'t found file in apk file: %s' % (value)
|
||||
result = False
|
||||
|
||||
return result
|
||||
|
||||
# return True for files we want to exclude
|
||||
def __excluded_files(self, file):
|
||||
_return = False
|
||||
# here we're checking to see if the file is 'CONTROL' -
|
||||
# a file don't want included in our tar archive.
|
||||
if file.find('CONTROL') > -1:
|
||||
_return = True
|
||||
return _return
|
||||
|
||||
def __zip_archive(self, apk_file, file_list):
|
||||
with zipfile.ZipFile(apk_file, 'w') as apk_zip:
|
||||
for one_file in file_list:
|
||||
apk_zip.write(one_file)
|
||||
|
||||
def __zip_extract(self, apk_file, member, path):
|
||||
with zipfile.ZipFile(apk_file, 'r') as apk_zip:
|
||||
apk_zip.extract(member, path)
|
||||
|
||||
def __tar_archive(self, tar_file, path):
|
||||
# create a tar archive of directory
|
||||
with tarfile.open(tar_file, 'w:gz') as tar:
|
||||
if os.path.basename(tar_file) == self.apk_file_contents['data']:
|
||||
tar.add(path, exclude=self.__excluded_files)
|
||||
else:
|
||||
tar.add(path)
|
||||
|
||||
def __tar_extract(self, tar_file, path):
|
||||
with tarfile.open(tar_file, 'r:gz') as tar:
|
||||
tar.extractall(path)
|
||||
|
||||
def __get_apkg_version(self, version_file):
|
||||
with file(version_file) as f:
|
||||
version = f.read().rstrip()
|
||||
return version
|
||||
|
||||
def __get_app_info_v1(self, control_dir):
|
||||
with open(control_dir + '/' + self.apk_control_files['pkg-config']) as data_file:
|
||||
data = json.load(data_file)
|
||||
return data
|
||||
|
||||
def __get_app_info_v2(self, control_dir):
|
||||
with open(control_dir + '/' + self.apk_control_files['pkg-config']) as data_file:
|
||||
data = json.load(data_file)
|
||||
return data
|
||||
|
||||
def __get_app_info(self, control_dir, apkg_version):
|
||||
if apkg_version == '1.0':
|
||||
return self.__get_app_info_v1(control_dir)
|
||||
elif apkg_version == '2.0':
|
||||
return self.__get_app_info_v2(control_dir)
|
||||
else:
|
||||
return None
|
||||
|
||||
def __check_app_layout(self, app_dir):
|
||||
control_dir = app_dir + '/' + self.apk_special_folders['control']
|
||||
|
||||
if not os.path.isdir(control_dir):
|
||||
print '[Not found] CONTROL folder: %s' % (control_dir)
|
||||
return False
|
||||
|
||||
config_file = control_dir + '/' + self.apk_control_files['pkg-config']
|
||||
|
||||
if not os.path.isfile(config_file):
|
||||
print '[Not found] config file: %s' % (config_file)
|
||||
return False
|
||||
|
||||
# TODO: check icon exist?
|
||||
icon_file = control_dir + '/' + self.apk_control_files['icon']
|
||||
|
||||
pass
|
||||
|
||||
return True
|
||||
|
||||
def __check_app_info_fields(self, app_info):
|
||||
require_fields = ['package', 'version', 'architecture', 'firmware']
|
||||
|
||||
for field in require_fields:
|
||||
try:
|
||||
if app_info['general'][field].strip() == '':
|
||||
print 'Empty field: %s' % (field)
|
||||
return False
|
||||
except KeyError:
|
||||
print 'Missing field: %s' % (field)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def __filter_special_chars(self, string, pattern):
|
||||
filter_string = re.sub(pattern, '', string)
|
||||
return filter_string
|
||||
|
||||
def __check_app_package_name(self, package):
|
||||
return True if self.__filter_special_chars(package, '[a-zA-Z0-9.+-]') == '' else False
|
||||
|
||||
def create(self, folder, dest_dir=None):
|
||||
# check folder is exist
|
||||
app_dir = os.path.abspath(folder)
|
||||
if not os.path.isdir(app_dir):
|
||||
print 'Not a directory: %s' % (app_dir)
|
||||
return -1
|
||||
|
||||
control_dir = app_dir + '/' + self.apk_special_folders['control']
|
||||
config_file = control_dir + '/' + self.apk_control_files['pkg-config']
|
||||
|
||||
# check package layout is correct
|
||||
if not self.__check_app_layout(app_dir):
|
||||
print 'Invalid App layout: %s' % (app_dir)
|
||||
return -1
|
||||
|
||||
# change file mode and owner
|
||||
os.chmod(control_dir, 0755)
|
||||
os.chown(control_dir, 0, 0)
|
||||
|
||||
all_files = glob.glob(control_dir + '/*')
|
||||
sh_files = glob.glob(control_dir + '/*.sh')
|
||||
py_files = glob.glob(control_dir + '/*.py')
|
||||
|
||||
for one_file in all_files:
|
||||
os.chmod(one_file, 0644)
|
||||
os.chown(one_file, 0, 0)
|
||||
|
||||
for one_file in sh_files:
|
||||
os.chmod(one_file, 0755)
|
||||
os.system('dos2unix %s > /dev/null 2>&1' % (one_file))
|
||||
|
||||
for one_file in py_files:
|
||||
os.chmod(one_file, 0755)
|
||||
|
||||
app_info = self.__get_app_info(control_dir, self.apk_format['version'])
|
||||
|
||||
# check config.json fields
|
||||
if not self.__check_app_info_fields(app_info):
|
||||
print 'Invalid App config: %s' % (config_file)
|
||||
return -1
|
||||
|
||||
# check package field value
|
||||
if not self.__check_app_package_name(app_info['general']['package']):
|
||||
print 'Invalid App package field: %s (valid characters [a-zA-Z0-9.+-])' % ('package')
|
||||
return -1
|
||||
|
||||
# prepare tmp dir
|
||||
tmp_dir = tempfile.mkdtemp(prefix=self.tmp_prefix)
|
||||
|
||||
version_file = tmp_dir + '/' + self.apk_file_contents['version']
|
||||
control_tar_gz = tmp_dir + '/' + self.apk_file_contents['control']
|
||||
data_tar_gz = tmp_dir + '/' + self.apk_file_contents['data']
|
||||
|
||||
if dest_dir == None:
|
||||
dest_dir = os.getcwd()
|
||||
else:
|
||||
dest_dir = os.path.abspath(dest_dir)
|
||||
|
||||
apk_file = dest_dir + '/' + app_info['general']['package'] + '_' + app_info['general']['version'] + '_' + app_info['general']['architecture'] + '.' + self.apk_format['suffix']
|
||||
|
||||
# write apkg version
|
||||
with open(version_file, 'w') as apkg_version:
|
||||
apkg_version.write(self.apk_format['version'] + '\n')
|
||||
|
||||
# archive data files
|
||||
with Chdir(app_dir):
|
||||
self.__tar_archive(data_tar_gz, '.')
|
||||
|
||||
# archive control files
|
||||
with Chdir(control_dir):
|
||||
self.__tar_archive(control_tar_gz, '.')
|
||||
|
||||
# archive apk file
|
||||
with Chdir(tmp_dir):
|
||||
self.__zip_archive(apk_file, [self.apk_file_contents['version'], self.apk_file_contents['control'], self.apk_file_contents['data']])
|
||||
|
||||
# cleanup temp folder
|
||||
shutil.rmtree(tmp_dir, ignore_errors=True)
|
||||
|
||||
return apk_file
|
||||
|
||||
def extract(self, package, dest_dir=None):
|
||||
# check file is exist
|
||||
apk_file = os.path.abspath(package)
|
||||
if not os.path.isfile(apk_file):
|
||||
print 'Not a file: %s' % (apk_file)
|
||||
return -1
|
||||
|
||||
# check package format (apk: zip format; contain files: apkg-version, control.tar.gz, data.tar.gz)
|
||||
if not self.__check_apk_format(apk_file):
|
||||
return -1
|
||||
|
||||
# unpack package phase 1
|
||||
tmp_dir = tempfile.mkdtemp(prefix=self.tmp_prefix)
|
||||
tmp_contents_dir = tmp_dir + '/@contents@'
|
||||
os.mkdir(tmp_contents_dir)
|
||||
|
||||
self.__zip_extract(apk_file, self.apk_file_contents['version'], tmp_contents_dir)
|
||||
self.__zip_extract(apk_file, self.apk_file_contents['control'], tmp_contents_dir)
|
||||
self.__zip_extract(apk_file, self.apk_file_contents['data'], tmp_contents_dir)
|
||||
|
||||
# unpack package phase 2
|
||||
tmp_control_dir = tmp_dir + '/' + self.apk_special_folders['control']
|
||||
os.mkdir(tmp_control_dir)
|
||||
|
||||
self.__tar_extract(tmp_contents_dir + '/' + self.apk_file_contents['control'], tmp_control_dir)
|
||||
self.__tar_extract(tmp_contents_dir + '/' + self.apk_file_contents['data'], tmp_dir)
|
||||
|
||||
# get apkg version
|
||||
apkg_version = self.__get_apkg_version(tmp_contents_dir + '/' + self.apk_file_contents['version'])
|
||||
|
||||
# clean tmp contents dir
|
||||
shutil.rmtree(tmp_contents_dir, ignore_errors=True)
|
||||
|
||||
# get apk information
|
||||
apk_info = self.__get_app_info(tmp_control_dir, apkg_version)
|
||||
|
||||
# error handle
|
||||
if apk_info is None:
|
||||
print 'Extract error: %s' % (apk_file)
|
||||
shutil.rmtree(tmp_dir, ignore_errors=True)
|
||||
return -1
|
||||
|
||||
if dest_dir == None:
|
||||
dest_dir = os.getcwd()
|
||||
else:
|
||||
dest_dir = os.path.abspath(dest_dir)
|
||||
|
||||
# move dir
|
||||
if apkg_version == '1.0':
|
||||
app_dir = dest_dir + '/' + apk_info['app']['name'] + '_' + apk_info['app']['version'] + '_' + apk_info['app']['architecture']
|
||||
elif apkg_version == '2.0':
|
||||
app_dir = dest_dir + '/' + apk_info['general']['name'] + '_' + apk_info['general']['version'] + '_' + apk_info['general']['architecture']
|
||||
|
||||
if os.path.isdir(app_dir):
|
||||
print 'The folder is exist, please remove it: %s' % (app_dir)
|
||||
shutil.rmtree(tmp_dir, ignore_errors=True)
|
||||
return -1
|
||||
else:
|
||||
shutil.move(tmp_dir, app_dir)
|
||||
return app_dir
|
||||
|
||||
def convert(self, package):
|
||||
app_dir = self.extract(package, dest_dir='/tmp')
|
||||
|
||||
if app_dir == -1:
|
||||
print 'Convert error'
|
||||
return -1
|
||||
|
||||
control_dir = app_dir + '/' + self.apk_special_folders['control']
|
||||
config_file = control_dir + '/' + self.apk_control_files['pkg-config']
|
||||
changelog_file = control_dir + '/' + self.apk_control_files['changlog']
|
||||
description_file = control_dir + '/' + self.apk_control_files['description']
|
||||
|
||||
# get old format app information
|
||||
app_old_info = self.__get_app_info(control_dir, self.apk_format['version'])
|
||||
|
||||
app_new_info = {}
|
||||
|
||||
developer = find_developer(app_old_info['app']['package'])
|
||||
|
||||
app_new_info['general'] = {}
|
||||
app_new_info['general']['package'] = app_old_info['app']['package']
|
||||
app_new_info['general']['name'] = app_old_info['app']['name']
|
||||
app_new_info['general']['version'] = app_old_info['app']['version']
|
||||
app_new_info['general']['depends'] = app_old_info['app']['depends']
|
||||
app_new_info['general']['conflicts'] = app_old_info['app']['conflicts']
|
||||
app_new_info['general']['developer'] = app_old_info['app']['website'] if (developer is None) else developer
|
||||
app_new_info['general']['maintainer'] = app_old_info['app']['maintainer']
|
||||
app_new_info['general']['email'] = app_old_info['app']['email']
|
||||
app_new_info['general']['website'] = app_old_info['app']['website']
|
||||
app_new_info['general']['architecture'] = app_old_info['app']['architecture']
|
||||
app_new_info['general']['firmware'] = '2.0'
|
||||
|
||||
try:
|
||||
app_old_info['desktop']
|
||||
except KeyError:
|
||||
app_old_info['desktop'] = {}
|
||||
|
||||
try:
|
||||
app_old_info['desktop']['icon']
|
||||
except KeyError:
|
||||
app_old_info['desktop']['icon'] = {}
|
||||
|
||||
# remove unused field
|
||||
app_old_info['desktop']['icon'].pop('title', None)
|
||||
|
||||
try:
|
||||
app_old_info['desktop']['privilege']
|
||||
except KeyError:
|
||||
app_old_info['desktop']['privilege'] = {}
|
||||
|
||||
app_new_info['adm-desktop'] = {}
|
||||
app_new_info['adm-desktop']['app'] = app_old_info['desktop']['icon']
|
||||
app_new_info['adm-desktop']['privilege'] = app_old_info['desktop']['privilege']
|
||||
|
||||
try:
|
||||
app_old_info['install']['link']
|
||||
except KeyError:
|
||||
app_old_info['install']['link'] = {}
|
||||
|
||||
try:
|
||||
app_old_info['install']['share']
|
||||
except KeyError:
|
||||
app_old_info['install']['share'] = []
|
||||
|
||||
try:
|
||||
app_old_info['install']['service-reg']
|
||||
except KeyError:
|
||||
app_old_info['install']['service-reg'] = {}
|
||||
|
||||
try:
|
||||
app_old_info['install']['service-reg']['priority']
|
||||
except KeyError:
|
||||
app_old_info['install']['service-reg']['priority'] = {}
|
||||
|
||||
try:
|
||||
app_old_info['install']['service-reg']['port']
|
||||
except KeyError:
|
||||
app_old_info['install']['service-reg']['port'] = []
|
||||
|
||||
try:
|
||||
app_old_info['install']['dep-service']
|
||||
except KeyError:
|
||||
app_old_info['install']['dep-service'] = {}
|
||||
|
||||
try:
|
||||
app_old_info['install']['dep-service']['start']
|
||||
except KeyError:
|
||||
app_old_info['install']['dep-service']['start'] = []
|
||||
|
||||
try:
|
||||
app_old_info['install']['dep-service']['restart']
|
||||
except KeyError:
|
||||
app_old_info['install']['dep-service']['restart'] = []
|
||||
|
||||
app_new_info['register'] = {}
|
||||
app_new_info['register']['symbolic-link'] = app_old_info['install']['link']
|
||||
app_new_info['register']['share-folder'] = app_old_info['install']['share']
|
||||
app_new_info['register']['port'] = app_old_info['install']['service-reg']['port']
|
||||
app_new_info['register']['boot-priority'] = {}
|
||||
|
||||
try:
|
||||
app_new_info['register']['boot-priority']['start-order'] = app_old_info['install']['service-reg']['priority']['start']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
app_new_info['register']['boot-priority']['stop-order'] = app_old_info['install']['service-reg']['priority']['stop']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
app_new_info['register']['prerequisites'] = {}
|
||||
app_new_info['register']['prerequisites']['enable-service'] = app_old_info['install']['dep-service']['start']
|
||||
app_new_info['register']['prerequisites']['restart-service'] = app_old_info['install']['dep-service']['restart']
|
||||
|
||||
# get changelog and description
|
||||
changelog = app_old_info['app'].pop('changes', None).strip()
|
||||
description = app_old_info['app'].pop('description', None).strip()
|
||||
|
||||
# convert json object to string
|
||||
json_string = json.dumps(app_new_info, indent=3)
|
||||
|
||||
# set new format app information
|
||||
with open(config_file, 'w') as new_file:
|
||||
new_file.write(json_string + '\n')
|
||||
|
||||
# write changelog.txt
|
||||
if changelog is not None and changelog != '':
|
||||
with open(changelog_file, 'w') as new_file:
|
||||
new_file.write(changelog + '\n')
|
||||
|
||||
# write description.txt
|
||||
if description is not None and description != '':
|
||||
with open(description_file, 'w') as new_file:
|
||||
new_file.write(description + '\n')
|
||||
|
||||
# convert icon
|
||||
icon_enable_file = control_dir + '/icon-enable.png'
|
||||
icon_disable_file = control_dir + '/icon-disable.png'
|
||||
icon_file = control_dir + '/' + self.apk_control_files['icon']
|
||||
|
||||
os.unlink(icon_disable_file)
|
||||
os.rename(icon_enable_file, icon_file)
|
||||
|
||||
convert_dir = os.getcwd() + '/apk-2.0'
|
||||
if not os.path.exists(convert_dir):
|
||||
os.mkdir(convert_dir)
|
||||
|
||||
# re-pack apk
|
||||
apk_file = self.create(app_dir, dest_dir=convert_dir)
|
||||
|
||||
# cleanup app folder
|
||||
shutil.rmtree(app_dir, ignore_errors=True)
|
||||
|
||||
print 'Convert success: %s' % (apk_file)
|
||||
|
||||
def upload(self, package):
|
||||
# check file is exist
|
||||
abs_path = os.path.abspath(package)
|
||||
if not os.path.isfile(abs_path):
|
||||
print 'Not a file: %s' % (abs_path)
|
||||
return -1
|
||||
|
||||
print 'function not support: %s' % ('upload')
|
||||
|
||||
# main
|
||||
if __name__ == "__main__":
|
||||
# create the top-level parser
|
||||
parser = argparse.ArgumentParser(description='asustor package helper.')
|
||||
|
||||
subparsers = parser.add_subparsers(help='sub-commands')
|
||||
|
||||
# create the parser for the "create" commad
|
||||
parser_create = subparsers.add_parser('create', help='create package from folder')
|
||||
parser_create.add_argument('folder', help='select a package layout folder to pack')
|
||||
parser_create.add_argument('--destination', help='move apk to destination folder')
|
||||
parser_create.set_defaults(command='create')
|
||||
|
||||
# create the parser for the "extract" commad
|
||||
parser_extract = subparsers.add_parser('extract', help='extract package to folder')
|
||||
parser_extract.add_argument('package', help='select a package to extract')
|
||||
parser_extract.add_argument('--destination', help='extract apk to destination folder')
|
||||
parser_extract.set_defaults(command='extract')
|
||||
|
||||
# create the parser for the "convert" commad
|
||||
# parser_convert = subparsers.add_parser('convert', help='convert package format to 2.0')
|
||||
# parser_convert.add_argument('package', help='select a package to convert')
|
||||
# parser_convert.set_defaults(command='convert')
|
||||
|
||||
# create the parser for the "upload" commad
|
||||
# parser_upload = subparsers.add_parser('upload', help='upload package to file server')
|
||||
# parser_upload.add_argument('package', help='select a package to upload')
|
||||
# parser_upload.set_defaults(command='upload')
|
||||
|
||||
# parsing arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
# process commands
|
||||
apkg = Apkg()
|
||||
|
||||
if args.command == 'create':
|
||||
apkg.create(args.folder, args.destination)
|
||||
|
||||
elif args.command == 'extract':
|
||||
apkg.extract(args.package, args.destination)
|
||||
|
||||
# elif args.command == 'convert':
|
||||
# apkg.convert(args.package)
|
||||
|
||||
# elif args.command == 'upload':
|
||||
# apkg.upload(args.package)
|
436
contrib/nas/tool/synology_pkg_util.sh
Executable file
436
contrib/nas/tool/synology_pkg_util.sh
Executable file
|
@ -0,0 +1,436 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) 2000-2015 Synology Inc. All rights reserved.
|
||||
|
||||
pkg_warn ()
|
||||
{
|
||||
local ret=$?;
|
||||
echo "Error: $@" 1>&2;
|
||||
return $?
|
||||
}
|
||||
pkg_log ()
|
||||
{
|
||||
local ret=$?;
|
||||
echo "$@" 1>&2;
|
||||
return $ret
|
||||
}
|
||||
pkg_get_string ()
|
||||
{
|
||||
local file="$1";
|
||||
local sec="$2";
|
||||
local key="$3";
|
||||
local text="$(sed -n '/^\['$sec'\]/,/^'$key'/s/'$key'.*=[^"]*"\(.*\)"/\1/p' "$file")";
|
||||
local product_name_original="_DISKSTATION_";
|
||||
local product_name=$(pkg_get_product_name);
|
||||
local os_name_original="_OSNAME_";
|
||||
local os_name=$(pkg_get_os_name);
|
||||
local idx=0;
|
||||
shift 3;
|
||||
for val in "$@";
|
||||
do
|
||||
text="${text/\{$idx\}/$val}";
|
||||
let idx=1+$idx;
|
||||
done;
|
||||
echo "$text" | sed -e "s/${product_name_original}/${product_name}/g" | sed -e "s/${os_name_original}/${os_name}/g"
|
||||
}
|
||||
pkg_dump_info ()
|
||||
{
|
||||
local fields="package version maintainer maintainer_url distributor distributor_url arch exclude_arch model
|
||||
adminprotocol adminurl adminport firmware dsmuidir dsmappname checkport allow_altport
|
||||
startable helpurl report_url support_center install_reboot install_dep_packages install_conflict_packages install_dep_services
|
||||
instuninst_restart_services startstop_restart_services start_dep_services silent_install silent_upgrade silent_uninstall install_type
|
||||
checksum package_icon package_icon_120 package_icon_128 package_icon_144 package_icon_256 thirdparty support_conf_folder log_collector
|
||||
support_aaprofile auto_upgrade_from offline_install precheckstartstop";
|
||||
local f= lan= file= sec= key=;
|
||||
for f in $fields;
|
||||
do
|
||||
if [ -n "${!f}" ]; then
|
||||
echo $f=\"${!f}\";
|
||||
fi;
|
||||
done;
|
||||
if [ -e "$UISTRING_PATH" -a "$description_sec" -a "$description_key" ]; then
|
||||
sec=$description_sec;
|
||||
key=$description_key;
|
||||
for lan in $UISTRING_PATH/*;
|
||||
do
|
||||
lan=$(basename "$lan");
|
||||
file="$UISTRING_PATH/$lan/strings";
|
||||
if [ -r "$file" ]; then
|
||||
echo description_$lan=\"$(pkg_get_string "$file" "$sec" "$key")\";
|
||||
if [ "x$lan" = "xenu" ]; then
|
||||
echo description=\"$(pkg_get_string "$file" "$sec" "$key")\";
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
else
|
||||
if [ "x" != "x$description" ]; then
|
||||
echo "description=\"${description}\"";
|
||||
fi;
|
||||
fi;
|
||||
if [ -e "$UISTRING_PATH" -a "$displayname_sec" -a "$displayname_key" ]; then
|
||||
sec=$displayname_sec;
|
||||
key=$displayname_key;
|
||||
for lan in $UISTRING_PATH/*;
|
||||
do
|
||||
lan=$(basename "$lan");
|
||||
file="$UISTRING_PATH/$lan/strings";
|
||||
if [ -r "$file" ]; then
|
||||
echo displayname_$lan=\"$(pkg_get_string "$file" "$sec" "$key")\";
|
||||
if [ "x$lan" = "xenu" ]; then
|
||||
echo displayname=\"$(pkg_get_string "$file" "$sec" "$key")\";
|
||||
fi;
|
||||
fi;
|
||||
done;
|
||||
else
|
||||
if [ "x" != "x$displayname" ]; then
|
||||
echo "displayname=\"${displayname}\"";
|
||||
fi;
|
||||
fi
|
||||
}
|
||||
plat_to_unified_plat() {
|
||||
local plat="$1"
|
||||
local unified_plat=
|
||||
|
||||
case "$plat" in
|
||||
x86 | bromolow | cedarview | avoton )
|
||||
unified_plat="x86 bromolow cedarview avoton"
|
||||
;;
|
||||
# alpine and alpine4k use same define.
|
||||
alpine )
|
||||
unified_plat="alpine"
|
||||
;;
|
||||
*)
|
||||
unified_plat="$plat"
|
||||
;;
|
||||
esac
|
||||
echo "$unified_plat"
|
||||
}
|
||||
|
||||
get_var_from_envmak() {
|
||||
return 1
|
||||
local var="$1"
|
||||
shift
|
||||
local envmaks="$@"
|
||||
local ret=
|
||||
local defaultSearchPath="/env.mak /env32.mak"
|
||||
|
||||
for f in "${envmaks[@]}" $defaultSearchPath; do
|
||||
if [ ! -r "$f" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
ret=$(grep "^$var=" "$f" | cut -d= -f2)
|
||||
|
||||
if [ -n "$ret" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$ret" ]; then
|
||||
pkg_warn "get_var_from_envmak: can not extract $var from '[$envmaks $defaultSearchPath]'"
|
||||
return 1
|
||||
else
|
||||
echo "$ret"
|
||||
fi
|
||||
}
|
||||
|
||||
pkg_get_platform ()
|
||||
{
|
||||
local arch=;
|
||||
local PLATFORM_ABBR=$(get_var_from_envmak PLATFORM_ABBR "$1" 2> /dev/null) || return 1;
|
||||
if [ -n "$PLATFORM_ABBR" ]; then
|
||||
case "$PLATFORM_ABBR" in
|
||||
6180)
|
||||
arch="88f6180"
|
||||
;;
|
||||
6281)
|
||||
arch="88f6281"
|
||||
;;
|
||||
816x)
|
||||
arch="ti816x"
|
||||
;;
|
||||
ppc)
|
||||
arch="powerpc"
|
||||
;;
|
||||
824x)
|
||||
arch="ppc824x"
|
||||
;;
|
||||
853x)
|
||||
arch="ppc853x"
|
||||
;;
|
||||
854x)
|
||||
arch="ppc854x"
|
||||
;;
|
||||
x64)
|
||||
arch="x86"
|
||||
;;
|
||||
*)
|
||||
arch="$PLATFORM_ABBR"
|
||||
;;
|
||||
esac;
|
||||
fi;
|
||||
if [ -z "$arch" ]; then
|
||||
local SYNO_PLATFORM=$(get_var_from_envmak SYNO_PLATFORM "$1") || return 1;
|
||||
case "$SYNO_PLATFORM" in
|
||||
MARVELL_88F6180)
|
||||
arch="88f6180"
|
||||
;;
|
||||
MARVELL_88F6281)
|
||||
arch="88f6281"
|
||||
;;
|
||||
TI_816X)
|
||||
arch="ti816x"
|
||||
;;
|
||||
POWERPC)
|
||||
arch="powerpc"
|
||||
;;
|
||||
PPC_824X)
|
||||
arch="ppc824x"
|
||||
;;
|
||||
PPC_853X)
|
||||
arch="ppc853x"
|
||||
;;
|
||||
PPC_854X)
|
||||
arch="ppc854x"
|
||||
;;
|
||||
PPC_QORIQ)
|
||||
arch="qoriq"
|
||||
;;
|
||||
X64)
|
||||
arch="x86"
|
||||
;;
|
||||
BROMOLOW)
|
||||
arch="bromolow"
|
||||
;;
|
||||
CEDARVIEW)
|
||||
arch="cedarview"
|
||||
;;
|
||||
AVOTON)
|
||||
arch="avoton"
|
||||
;;
|
||||
MARVELL_ARMADAXP)
|
||||
arch="armadaxp"
|
||||
;;
|
||||
MARVELL_ARMADA370)
|
||||
arch="armada370"
|
||||
;;
|
||||
MARVELL_ARMADA375)
|
||||
arch="armada375"
|
||||
;;
|
||||
EVANSPORT)
|
||||
arch="evansport"
|
||||
;;
|
||||
PPC_CATALINA)
|
||||
arch="catalina"
|
||||
;;
|
||||
MINDSPEED_COMCERTO2K)
|
||||
arch="comcerto2k"
|
||||
;;
|
||||
ALPINE)
|
||||
arch="alpine"
|
||||
;;
|
||||
BROADCOM_NORTHSTARPLUS)
|
||||
arch="northstarplus"
|
||||
;;
|
||||
STM_MONACO)
|
||||
arch="monaco"
|
||||
;;
|
||||
HISILICON_HI3535)
|
||||
arch="hi3535"
|
||||
;;
|
||||
MARVELL_ARMADA38X)
|
||||
arch="armada38x"
|
||||
;;
|
||||
*)
|
||||
arch=""
|
||||
;;
|
||||
esac;
|
||||
fi;
|
||||
echo "$arch"
|
||||
}
|
||||
pkg_get_spk_platform ()
|
||||
{
|
||||
local plat=$(pkg_get_platform "$1") || return 1;
|
||||
local spk_plat=;
|
||||
case "$plat" in
|
||||
88f6281)
|
||||
spk_plat="88f628x"
|
||||
;;
|
||||
*)
|
||||
spk_plat="$plat"
|
||||
;;
|
||||
esac;
|
||||
echo "$spk_plat"
|
||||
}
|
||||
pkg_make_package ()
|
||||
{
|
||||
local source_path=$1;
|
||||
local dest_path=$2;
|
||||
local package_name="package.tgz";
|
||||
local temp_extractsize="extractsize_tmp";
|
||||
local pkg_size=;
|
||||
local tar_option="$(pkg_get_tar_option)";
|
||||
if [ -z "$source_path" -o ! -d "$source_path" ]; then
|
||||
pkg_warn "pkg_make_package: bad parameters, please set source dir";
|
||||
return 1;
|
||||
fi;
|
||||
if [ -z "$dest_path" -o ! -d "$dest_path" ]; then
|
||||
pkg_warn "pkg_make_package: bad parameters, please set destination dir";
|
||||
return 1;
|
||||
fi;
|
||||
pkg_size=`du -sk "$source_path" | awk '{print $1}'`;
|
||||
echo "${pkg_size}" >> "$dest_path/$temp_extractsize";
|
||||
echo ls $source_path \| tar $tar_option "$dest_path/$package_name" -C "$source_path" -T /dev/stdin;
|
||||
ls $source_path | tar $tar_option "$dest_path/$package_name" -C "$source_path" -T /dev/stdin
|
||||
}
|
||||
pkg_get_spk_name ()
|
||||
{
|
||||
__get_spk_name pkg_get_spk_platform $@
|
||||
}
|
||||
pkg_make_spk ()
|
||||
{
|
||||
local pack="tar cf";
|
||||
local source_path=$1;
|
||||
local dest_path=$2;
|
||||
local info_path="$source_path/INFO";
|
||||
local spk_name=$3;
|
||||
local spk_arch=;
|
||||
local temp_extractsize="extractsize_tmp";
|
||||
if [ -z "$source_path" -o ! -d "$source_path" ]; then
|
||||
pkg_warn "pkg_make_spk: bad parameters, please set source dir";
|
||||
return 1;
|
||||
fi;
|
||||
if [ -z "$dest_path" -o ! -d "$dest_path" ]; then
|
||||
pkg_warn "pkg_make_spk: bad parameters, please set destination dir";
|
||||
return 1;
|
||||
fi;
|
||||
if [ ! -r "$info_path" ]; then
|
||||
pkg_warn "pkg_make_spk: INFO '$info_path' is not existed";
|
||||
return 1;
|
||||
fi;
|
||||
spk_name=${3:-`pkg_get_spk_name $info_path`};
|
||||
pkg_size=`cat $source_path/$temp_extractsize`;
|
||||
echo "extractsize=\"${pkg_size}\"" >> $info_path;
|
||||
rm "$source_path/$temp_extractsize";
|
||||
echo "toolkit_version=\"$DSM_BUILD_NUM\"" >> $info_path;
|
||||
echo "create_time=\"$(date +%Y%m%d-%T)\"" >> $info_path;
|
||||
pkg_log "creating package: $spk_name";
|
||||
pkg_log "source: $source_path";
|
||||
pkg_log "destination: $dest_path/$spk_name";
|
||||
$pack "$dest_path/$spk_name" -C "$source_path" $(ls $source_path)
|
||||
}
|
||||
pkg_get_unified_platform ()
|
||||
{
|
||||
local plat=$(pkg_get_platform "$1") || return 1;
|
||||
plat_to_unified_plat "$plat"
|
||||
}
|
||||
pkg_get_spk_unified_platform ()
|
||||
{
|
||||
local plat=$(pkg_get_platform "$1") || return 1;
|
||||
local spk_unified_platform=;
|
||||
case "$plat" in
|
||||
88f6281)
|
||||
spk_unified_platform="88f628x"
|
||||
;;
|
||||
x86 | bromolow | cedarview | avoton)
|
||||
spk_unified_platform="x64"
|
||||
;;
|
||||
alpine)
|
||||
spk_unified_platform="alpine"
|
||||
;;
|
||||
*)
|
||||
spk_unified_platform="$plat"
|
||||
;;
|
||||
esac;
|
||||
echo "$spk_unified_platform"
|
||||
}
|
||||
pkg_get_spk_unified_name ()
|
||||
{
|
||||
__get_spk_name pkg_get_spk_unified_platform $@
|
||||
}
|
||||
|
||||
__get_spk_name() { #<info path>
|
||||
local spk_name=
|
||||
local platform_func="$1"
|
||||
local info_path="${2:-$PKG_DIR/INFO}"
|
||||
local package_name="$3"
|
||||
|
||||
. $info_path
|
||||
|
||||
# construct package name
|
||||
if [ -z "$package" -o -z "$arch" -o -z "$version" ]; then
|
||||
pkg_warn "pkg_make_spk: package, arch, version can not be empty"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "x$arch" = "xnoarch" ]; then
|
||||
spk_arch="noarch"
|
||||
elif ! spk_arch=$($platform_func); then
|
||||
spk_arch="none"
|
||||
fi
|
||||
|
||||
if [ "x$arch" = "xnoarch" ]; then
|
||||
spk_arch=""
|
||||
else
|
||||
spk_arch="-"$spk_arch
|
||||
fi
|
||||
|
||||
if [ -z "$package_name" ]; then
|
||||
package_name="$package";
|
||||
fi
|
||||
|
||||
if [ "${NOSTRIP}" == NOSTRIP ]; then
|
||||
spk_name="$package_name$spk_arch-${version}_debug.spk"
|
||||
else
|
||||
spk_name="$package_name$spk_arch-$version.spk"
|
||||
fi
|
||||
echo $spk_name;
|
||||
}
|
||||
|
||||
|
||||
pkg_get_dsm_buildnum() { # [path of VERSION (default: )]
|
||||
local version_file=${1:-/source/lnxsdk/init/etc/VERSION}
|
||||
local dsm_build=
|
||||
|
||||
if [ ! -r "$version_file" ]; then
|
||||
pkg_warn "pkg_get_dsm_buildnum: can not find version file '$version_file'"
|
||||
pkg_warn "use default buildnum: 0"
|
||||
echo 0
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! dsm_build=$(grep -s ^buildnumber "$version_file" | awk -F \" '{print $2}'); then
|
||||
echo 0
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo $(($dsm_build))
|
||||
}
|
||||
|
||||
pkg_get_tar_option() {
|
||||
local version_file="/PkgVersion"
|
||||
|
||||
if [ -r $version_file ] && [ "$(pkg_get_dsm_buildnum $version_file)" -ge 5943 ]; then
|
||||
echo "cJf"
|
||||
else
|
||||
echo "czf"
|
||||
fi
|
||||
}
|
||||
|
||||
[ "$(caller)" != "0 NULL" ] && return 0
|
||||
Usage() {
|
||||
cat >&2 << EOF
|
||||
Usage
|
||||
$(basename $0) <action> [action options...]
|
||||
Action
|
||||
make_spk <source path> <dest path>
|
||||
make_package <source path> <dest path>
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
[ $# -eq 0 ] && Usage
|
||||
PkgBuildAction=$1 ; shift
|
||||
case "$PkgBuildAction" in
|
||||
make_spk) pkg_make_spk "$@" ;;
|
||||
make_package) pkg_make_package "$@" ;;
|
||||
*) Usage ;;
|
||||
esac
|
33
contrib/nas/tool/synology_version.sh
Normal file
33
contrib/nas/tool/synology_version.sh
Normal file
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Get the last tag
|
||||
TAG=$(git describe --abbrev=0 --tags --match="v[0-9]*\.[0-9]*\.[0-9]*" 2>/dev/null)
|
||||
|
||||
# Did getting the tag succeed?
|
||||
if [ $? != 0 ] || [ -z "$TAG" ]; then
|
||||
printf -- "unknown"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get the current branch
|
||||
BRANCH=$(git symbolic-ref -q HEAD --short 2>/dev/null)
|
||||
|
||||
# Did getting the branch succeed?
|
||||
if [ $? != 0 ] || [ -z "$BRANCH" ]; then
|
||||
BRANCH="master"
|
||||
fi
|
||||
|
||||
#replace last dot with -
|
||||
STAG=$(echo $TAG | sed 's/v//' | sed 's/[^0123456789.].//' | sed 's/\.\([^.]*\)$/-\1/')
|
||||
#get tail after - and do padding with 4 zeros
|
||||
TAG_TAIL=$(echo $STAG | sed -n -e 's/^.*-//p' | sed -e :a -e 's/^.\{1,3\}$/&0/;ta')
|
||||
#replace tail after -
|
||||
SYNO_VERSION=$(echo $STAG | sed "s/-.*/-$TAG_TAIL/")
|
||||
case "$*" in
|
||||
*--bare*)
|
||||
printf '%s\n' "$SYNO_VERSION"
|
||||
;;
|
||||
*)
|
||||
printf '%s' "$SYNO_VERSION"
|
||||
;;
|
||||
esac
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
description="An experiment in scalable routing as an encrypted IPv6 overlay network."
|
||||
|
||||
CONFFILE="/etc/yggdrasil.conf"
|
||||
CONFFILE="/etc/mesh.conf"
|
||||
pidfile="/run/${RC_SVCNAME}.pid"
|
||||
|
||||
command="/usr/bin/yggdrasil"
|
||||
command="/usr/bin/mesh"
|
||||
extra_started_commands="reload"
|
||||
|
||||
depend() {
|
||||
|
@ -36,8 +36,8 @@ start() {
|
|||
--pidfile "${pidfile}" \
|
||||
--make-pidfile \
|
||||
--background \
|
||||
--stdout /var/log/yggdrasil.stdout.log \
|
||||
--stderr /var/log/yggdrasil.stderr.log \
|
||||
--stdout /var/log/mesh.stdout.log \
|
||||
--stderr /var/log/mesh.stderr.log \
|
||||
--exec "${command}" -- -useconffile "${CONFFILE}"
|
||||
eend $?
|
||||
}
|
|
@ -6,8 +6,9 @@ if [ -z "$BRANCH" ]; then
|
|||
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
|
||||
fi
|
||||
|
||||
# Complain if the git history is not available
|
||||
if [ $? != 0 ] || [ -z "$BRANCH" ]; then
|
||||
printf "yggdrasil"
|
||||
printf "mesh"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
@ -16,9 +17,9 @@ BRANCH=$(echo $BRANCH | tr -d "/")
|
|||
|
||||
# Check if the branch name is not master
|
||||
if [ "$BRANCH" = "master" ]; then
|
||||
printf "yggdrasil"
|
||||
printf "mesh"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# If it is something other than master, append it
|
||||
printf "yggdrasil-%s" "$BRANCH"
|
||||
printf "mesh-%s" "$BRANCH"
|
||||
|
|
21
contrib/systemd/mesh-debug.service
Normal file
21
contrib/systemd/mesh-debug.service
Normal file
|
@ -0,0 +1,21 @@
|
|||
[Unit]
|
||||
Description=mesh
|
||||
Wants=network-online.target
|
||||
Wants=mesh-default-config.service
|
||||
After=network-online.target
|
||||
After=mesh-default-config.service
|
||||
|
||||
[Service]
|
||||
Group=mesh
|
||||
ProtectHome=true
|
||||
ProtectSystem=true
|
||||
SyslogIdentifier=mesh
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
|
||||
ExecStartPre=+-/sbin/modprobe tun
|
||||
ExecStart=/usr/bin/mesh -useconffile /etc/mesh.conf -loglevel debug -logto /var/log/mesh.log
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=always
|
||||
TimeoutStopSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
13
contrib/systemd/mesh-default-config.service
Normal file
13
contrib/systemd/mesh-default-config.service
Normal file
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=mesh default config generator
|
||||
ConditionPathExists=|!/etc/mesh.conf
|
||||
ConditionFileNotEmpty=|!/etc/mesh.conf
|
||||
Wants=local-fs.target
|
||||
After=local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Group=mesh
|
||||
StandardOutput=file:/etc/mesh.conf
|
||||
ExecStart=/usr/bin/mesh -genconf
|
||||
ExecStartPost=/usr/bin/chmod 0640 /etc/mesh.conf
|
21
contrib/systemd/mesh.service
Normal file
21
contrib/systemd/mesh.service
Normal file
|
@ -0,0 +1,21 @@
|
|||
[Unit]
|
||||
Description=mesh
|
||||
Wants=network-online.target
|
||||
Wants=mesh-default-config.service
|
||||
After=network-online.target
|
||||
After=mesh-default-config.service
|
||||
|
||||
[Service]
|
||||
Group=mesh
|
||||
ProtectHome=true
|
||||
ProtectSystem=true
|
||||
SyslogIdentifier=mesh
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
|
||||
ExecStartPre=+-/sbin/modprobe tun
|
||||
ExecStart=/usr/bin/mesh -useconffile /etc/mesh.conf
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=always
|
||||
TimeoutStopSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -1,13 +0,0 @@
|
|||
[Unit]
|
||||
Description=yggdrasil default config generator
|
||||
ConditionPathExists=|!/etc/yggdrasil.conf
|
||||
ConditionFileNotEmpty=|!/etc/yggdrasil.conf
|
||||
Wants=local-fs.target
|
||||
After=local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Group=yggdrasil
|
||||
StandardOutput=file:/etc/yggdrasil.conf
|
||||
ExecStart=/usr/bin/yggdrasil -genconf
|
||||
ExecStartPost=/usr/bin/chmod 0640 /etc/yggdrasil.conf
|
|
@ -1,21 +0,0 @@
|
|||
[Unit]
|
||||
Description=yggdrasil
|
||||
Wants=network-online.target
|
||||
Wants=yggdrasil-default-config.service
|
||||
After=network-online.target
|
||||
After=yggdrasil-default-config.service
|
||||
|
||||
[Service]
|
||||
Group=yggdrasil
|
||||
ProtectHome=true
|
||||
ProtectSystem=true
|
||||
SyslogIdentifier=yggdrasil
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
|
||||
ExecStartPre=+-/sbin/modprobe tun
|
||||
ExecStart=/usr/bin/yggdrasil -useconffile /etc/yggdrasil.conf
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=always
|
||||
TimeoutStopSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
BIN
contrib/ui/mesh-ui/dll/arm64/WebView2Loader.dll
Normal file
BIN
contrib/ui/mesh-ui/dll/arm64/WebView2Loader.dll
Normal file
Binary file not shown.
BIN
contrib/ui/mesh-ui/dll/x64/WebView2Loader.dll
Normal file
BIN
contrib/ui/mesh-ui/dll/x64/WebView2Loader.dll
Normal file
Binary file not shown.
BIN
contrib/ui/mesh-ui/dll/x64/webview.dll
Executable file
BIN
contrib/ui/mesh-ui/dll/x64/webview.dll
Executable file
Binary file not shown.
BIN
contrib/ui/mesh-ui/dll/x86/WebView2Loader.dll
Normal file
BIN
contrib/ui/mesh-ui/dll/x86/WebView2Loader.dll
Normal file
Binary file not shown.
BIN
contrib/ui/mesh-ui/dll/x86/webview.dll
Executable file
BIN
contrib/ui/mesh-ui/dll/x86/webview.dll
Executable file
Binary file not shown.
669
contrib/ui/mesh-ui/index.html
Executable file
669
contrib/ui/mesh-ui/index.html
Executable file
|
@ -0,0 +1,669 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="is-clipped">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>RiV-mesh</title>
|
||||
<link rel="stylesheet" href="https://maxst.icons8.com/vue-static/landings/line-awesome/font-awesome-line-awesome/css/all.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/slate/bulmaswatch.min.css" type="text/css">
|
||||
<script>
|
||||
|
||||
function setFieldValue(id, value){
|
||||
var field = document.getElementById(id);
|
||||
field.innerHTML = value;
|
||||
}
|
||||
|
||||
function setPingValue(peer, value){
|
||||
var cellText;
|
||||
var peerCell = document.getElementById(peer);
|
||||
var peerTable = document.getElementById("peer_list");
|
||||
if(value === "-1"){
|
||||
var peerAddress = document.getElementById("label_"+peer);
|
||||
peerAddress.style.color = "rgba(250,250,250,.5)";
|
||||
moveRowToEnd(peerTable, peerCell.parentNode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
cellText = document.createTextNode(value);
|
||||
peerCell.appendChild(cellText);
|
||||
|
||||
var peerCellTime = document.getElementById("time_"+peer);
|
||||
var cellTextTime = document.createTextNode("ms");
|
||||
peerCellTime.appendChild(cellTextTime);
|
||||
//sort table
|
||||
sortTable(peerTable, 2, false);
|
||||
}
|
||||
|
||||
function sortTable(table, col, reverse) {
|
||||
var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
|
||||
tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
|
||||
i;
|
||||
reverse = -((+reverse) || -1);
|
||||
tr = tr.sort(function (a, b) { // sort rows
|
||||
// `-1 *` if want opposite order
|
||||
return reverse * (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
|
||||
.localeCompare(b.cells[col].textContent.trim(), 'en', {numeric: true})
|
||||
);
|
||||
});
|
||||
for(i = 0; i < tr.length; ++i) tb.appendChild(tr[i]); // append each row in order
|
||||
}
|
||||
|
||||
function moveRowToEnd(table, row) {
|
||||
var tb = table.tBodies[0]; // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
|
||||
var rowIndex = row.rowIndex;
|
||||
table.deleteRow(rowIndex);
|
||||
tb.appendChild(row); // append each row in order
|
||||
}
|
||||
|
||||
function openTab(element, tabName) {
|
||||
// Declare all variables
|
||||
var i, tabContent, tabLinks;
|
||||
|
||||
// Get all elements with class="content" and hide them
|
||||
tabContent = document.getElementsByClassName("tab here");
|
||||
for (i = 0; i < tabContent.length; i++) {
|
||||
tabContent[i].className = "tab here is-hidden";
|
||||
}
|
||||
|
||||
// Get all elements with class="tab" and remove the class "is-active"
|
||||
tabLinks = document.getElementsByClassName("tab is-active");
|
||||
for (i = 0; i < tabLinks.length; i++) {
|
||||
tabLinks[i].className = "tab";
|
||||
}
|
||||
|
||||
// Show the current tab, and add an "is-active" class to the button that opened the tab
|
||||
document.getElementById(tabName).className = "tab here";
|
||||
element.parentElement.className = "tab is-active";
|
||||
refreshRecordsList();
|
||||
}
|
||||
|
||||
function copy2clipboard(text){
|
||||
var textArea = document.createElement("textarea");
|
||||
textArea.style.position = 'fixed';
|
||||
textArea.style.top = 0;
|
||||
textArea.style.left = 0;
|
||||
|
||||
// Ensure it has a small width and height. Setting to 1px / 1em
|
||||
// doesn't work as this gives a negative w/h on some browsers.
|
||||
textArea.style.width = '2em';
|
||||
textArea.style.height = '2em';
|
||||
|
||||
// We don't need padding, reducing the size if it does flash render.
|
||||
textArea.style.padding = 0;
|
||||
|
||||
// Clean up any borders.
|
||||
textArea.style.border = 'none';
|
||||
textArea.style.outline = 'none';
|
||||
textArea.style.boxShadow = 'none';
|
||||
|
||||
// Avoid flash of the white box if rendered for any reason.
|
||||
textArea.style.background = 'transparent';
|
||||
textArea.value = text;
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
try {
|
||||
var successful = document.execCommand('copy');
|
||||
var msg = successful ? 'successful' : 'unsuccessful';
|
||||
console.log('Copying text command was ' + msg);
|
||||
} catch (err) {
|
||||
console.log('Oops, unable to copy');
|
||||
}
|
||||
document.body.removeChild(textArea);
|
||||
showInfo('value copied successfully!');
|
||||
}
|
||||
|
||||
function showInfo(text) {
|
||||
var info = document.getElementById("notification_info");
|
||||
var message = document.getElementById("info_text");
|
||||
message.innerHTML = text;
|
||||
|
||||
info.className = "notification is-primary";
|
||||
var button = document.getElementById("info_close");
|
||||
button.onclick = function() {
|
||||
message.value = "";
|
||||
info.className = "notification is-primary is-hidden";
|
||||
};
|
||||
setTimeout(button.onclick, 2000);
|
||||
}
|
||||
|
||||
function showWindow(text) {
|
||||
var info = document.getElementById("notification_window");
|
||||
var message = document.getElementById("info_window");
|
||||
message.innerHTML = text;
|
||||
|
||||
info.className = "notification is-primary";
|
||||
var button_info_close = document.getElementById("info_close");
|
||||
button_info_close.onclick = function() {
|
||||
message.value = "";
|
||||
info.className = "notification is-primary is-hidden";
|
||||
};
|
||||
var button_window_close = document.getElementById("window_close");
|
||||
button_window_close.onclick = function() {
|
||||
message.value = "";
|
||||
info.className = "notification is-primary is-hidden";
|
||||
};
|
||||
var button_window_save = document.getElementById("window_save");
|
||||
button_window_save.onclick = function() {
|
||||
message.value = "";
|
||||
info.className = "notification is-primary is-hidden";
|
||||
//todo save peers
|
||||
var peers = document.querySelectorAll('*[id^="peer-"]');
|
||||
var peer_list = [];
|
||||
for (i = 0; i < peers.length; ++i) {
|
||||
var p = peers[i];
|
||||
if (p.checked) {
|
||||
var peerURL = p.parentElement.parentElement.children[1].innerText;
|
||||
peer_list.push(peerURL);
|
||||
}
|
||||
}
|
||||
savePeers(JSON.stringify(peer_list));
|
||||
};
|
||||
}
|
||||
|
||||
function getPeerList(){
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", 'https://map.rivchain.org/rest/peers.json', false);
|
||||
xhr.send(null);
|
||||
if (xhr.status === 200) {
|
||||
const peerList = JSON.parse(xhr.responseText);
|
||||
var peers = add_table(peerList);
|
||||
//start peers test
|
||||
ping(JSON.stringify(peers));
|
||||
}
|
||||
}
|
||||
|
||||
function add_table(peerList) {
|
||||
var peers = [];
|
||||
//const countries = Object.keys(peerList);
|
||||
// get the reference for the body
|
||||
var body = document.createElement("div");
|
||||
|
||||
// creates a <table> element and a <tbody> element
|
||||
var tbl = document.createElement("table");
|
||||
tbl.setAttribute('id', "peer_list");
|
||||
//tbl.setAttribute('cellpadding', '10');
|
||||
var tblBody = document.createElement("tbody");
|
||||
|
||||
// creating all cells
|
||||
for (var c in peerList) {
|
||||
let counter = 1;
|
||||
flag = document.getElementById("flag_"+c.slice(0, -3).replace(/ /g, "_"));
|
||||
for (peer in peerList[c]){
|
||||
peers.push(peer);
|
||||
// creates a table row
|
||||
var row = document.createElement("tr");
|
||||
var imgElement = document.createElement("td");
|
||||
clone = flag.cloneNode(false);
|
||||
imgElement.appendChild(clone);
|
||||
var peerAddress = document.createElement("td");
|
||||
var cellText = document.createTextNode(peer);
|
||||
peerAddress.appendChild(cellText);
|
||||
peerAddress.setAttribute('id', "label_"+peer);
|
||||
var peerPing = document.createElement("td");
|
||||
peerPing.setAttribute('id', peer);
|
||||
var peerPingTime = document.createElement("td");
|
||||
peerPingTime.setAttribute('id', "time_"+peer);
|
||||
var peerSelect = document.createElement("td");
|
||||
var chk = document.createElement('input');
|
||||
chk.setAttribute('type', 'checkbox');
|
||||
chk.setAttribute('id', "peer-"+counter);
|
||||
peerSelect.appendChild(chk);
|
||||
|
||||
row.appendChild(imgElement);
|
||||
row.appendChild(peerAddress);
|
||||
row.appendChild(peerPing);
|
||||
row.appendChild(peerPingTime);
|
||||
row.appendChild(peerSelect);
|
||||
tblBody.appendChild(row);
|
||||
}
|
||||
}
|
||||
// put the <tbody> in the <table>
|
||||
tbl.appendChild(tblBody);
|
||||
// appends <table> into <body>
|
||||
body.appendChild(tbl);
|
||||
// sets the border attribute of tbl to 2;
|
||||
//tbl.setAttribute("border", "0");
|
||||
showWindow(body.innerHTML);
|
||||
return peers;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style>
|
||||
|
||||
.container-ip {
|
||||
|
||||
display: flex;
|
||||
border: 1px solid #5d656d;
|
||||
border-radius: 4px;
|
||||
margin:10px;
|
||||
}
|
||||
|
||||
.push-right {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 10px;
|
||||
/*border: 1px solid #5d656d;*/
|
||||
|
||||
}
|
||||
|
||||
.column {
|
||||
max-height: 350px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.over {
|
||||
max-height: 150px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.container{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.box{
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, 0.0);
|
||||
}
|
||||
|
||||
.stack-top{
|
||||
z-index: 9;
|
||||
margin: 10px; /* for demo purpose */
|
||||
background: rgba(255, 0, 0, 1);
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
thead tr th:first-child,
|
||||
tbody tr td:first-child {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body onload="onLoad();">
|
||||
<div style="padding:3px; max-height: 250px;">
|
||||
<div class="box">
|
||||
<div style="z-index: 9;" class="box stack-top notification is-primary is-hidden" id="notification_window">
|
||||
<button class="delete" id="info_close"></button>
|
||||
<p style="padding:3px; max-height: 250px; overflow-y: auto;" id="info_window"></p>
|
||||
<div style="padding-left:100px; padding-top:15px;" class="field is-grouped" >
|
||||
<p class="control">
|
||||
<a id="window_save" class="button is-success">
|
||||
<span class="icon is-small">
|
||||
<i class="fa fa-check"> </i>
|
||||
</span>
|
||||
<span> Save </span>
|
||||
</a>
|
||||
</p>
|
||||
<p class="control">
|
||||
<a id="window_close" class="button is-danger is-outlined">
|
||||
<span> Cancel </span>
|
||||
<span class="icon is-small">
|
||||
<i class="fa fa-times"> </i>
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tabs -->
|
||||
<div class="tabs is-centered is-boxed">
|
||||
<ul>
|
||||
<li class="tab is-active">
|
||||
<a onclick="openTab(this, 'my_node');">
|
||||
<span class="icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 42 42"><path d="M18.5 35.5l-8 2c-.48.04-1 .52-1 1v1c0 .5.47 1 1 1h20c.43 0 1-.41 1-1v-1c-.02-.52-.55-.98-1-1l-8-2h-4zm19-1c2.59 0 3-.529 3-3v-26c0-2.391-.55-3-3-3h-34c-2.43 0-3 .54-3 3v26c0 2.51.529 3 3 3h34zm-2-27v22h-30v-22h30z" fill="white"/></svg>
|
||||
</span>
|
||||
<span>My Node</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="tab">
|
||||
<a onclick="openTab(this, 'keys');">
|
||||
<span class="icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M5 15v15h22V15zm4 0C9 9 9 5 16 5s7 4 7 10m-7 5v3"/><circle cx="16" cy="24" r="1"/></g></svg>
|
||||
</span>
|
||||
<span>Keys</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="tab">
|
||||
<a onclick="openTab(this, 'about');">
|
||||
<span class="icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 48 48"><path fill="#2196F3" d="M37 40H11l-6 6V12c0-3.3 2.7-6 6-6h26c3.3 0 6 2.7 6 6v22c0 3.3-2.7 6-6 6z"/><g fill="#fff"><path d="M22 20h4v11h-4z"/><circle cx="24" cy="15" r="2"/></g></svg>
|
||||
</span>
|
||||
<span>About</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab here " id="my_node">
|
||||
|
||||
<div class="column">
|
||||
<div class="container-ip">
|
||||
<div class="item">IPv6</div>
|
||||
<div id="ipv6" class="item push-right">N/A</div>
|
||||
<div class="item">
|
||||
<a class="fas fa-copy" onclick="copy2clipboard(document.getElementById('ipv6').innerHTML);"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-ip">
|
||||
<div class="item">Subnet</div>
|
||||
<div id="subnet" class="item push-right">N/A</div>
|
||||
<div class="item">
|
||||
<a class="fas fa-copy" onclick="copy2clipboard(document.getElementById('subnet').innerHTML);"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-ip">
|
||||
|
||||
<div class="item">Peers</div>
|
||||
<div id="peers" class="item over">
|
||||
|
||||
</div>
|
||||
<div class="item push-right">
|
||||
<a class="fas fa-edit" onclick="getPeerList();"></a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab here is-hidden" id="keys">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div style="margin-left: 100px; margin-right: 100px;">
|
||||
<div class="notification is-primary is-hidden" id="notification_info">
|
||||
<button class="delete" id="info_close"></button>
|
||||
<p id="info_text"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="is-hidden">
|
||||
|
||||
<img id="flag_colombia" src="data:image/webp;base64, UklGRpYAAABXRUJQVlA4IIoAAACwBgCdASpQADQAPtFSqE0oJCQiLNv6AQAaCWIAeIXYBLAMFA9f8BgrDzKuhE9x9GWK6QYvcXPYqTApg90hAAD+7+5j//yDDlmNa6/4GbPTedtphBBZRcDd4PnOa5vgRv/KS2OO3+UlsmZSrWYO0DYAxwSCrkPjdU0Dqj2F3sx1eV9fUs/xUAAAAAA=" />
|
||||
<img id="flag_taiwan" src="data:image/webp;base64, UklGRkYBAABXRUJQVlA4IDoBAAAwCACdASpQADUAPtFkq1CoJaOipnQJAQAaCUASoH8z0FckV4QB+lfv/i1tDlf4lqwtIAv32y/QR3NN1D8mTTeDQC9hBxIFWph04AD+ytpqrvawThdf+9LtBSjbGyfX7diHcyC1vS2QlD6nfx/X6ejp0Rwei3A4oK9C2nY4gm/vWUOXeBq5tAFNj3Xd6b047DG0zu54W5YXqKr7aY/tEZArTPVDQW5k2k/Twhjc/Sv8NilVYRXwSMJ6k16PvnIf6Kx/4YX+0hf/UhrCmd4v7CdYzV1qVlBsIehAOf1bg22cNCCe3fYuVnQYCGEf0eaIYd5ZMq8XVPTBeAJoOSSeLYTYHmYIyJ5yOgM2CIzkmM307kJC6wH1tIzFl228EXkjLmIXtqAzvuWBU4T9FAbfDopGo6Oj0A/EXyAAAA==" />
|
||||
<img id="flag_faroe_islands" src="data:image/webp;base64, UklGRlwBAABXRUJQVlA4IFABAAAQDACdASpQADkAPrlOn0unJKMhtmlY4BcJaACVA0Qlxbr3352hEkfVVig59XoAeYDzTf8B+2+s0+gB+u/VpBMtsx6TqUsDOTV0EYbsOYCjE/q3HxV+8tp7XFti7Rhl05mXMRm3ZovcPAAA/voEPr+kZUdWBpFVPYoAXint1DPXu0YxECTRRw+AnfoVakvhcXggdQjKwkzoegtL9cusBc5iPf/hmAtkFFoL6Njq3W776a+rcLVS5RgqDRGtzPlieLeOok8XLsrgz/Ga9fcCidK4/et/53MQIRGV39HXD7JgWNWvUz43OkAMsF8Yn2pZM7IgfD4X9MKXBhe0BAkl2Zj+fUF0UWv+tiKZoT4CwD8qWedMD+VvIiuIKD4DYz6mqAPr4ShiyVxT/rTtmKP/8jlkOV2NZEuMX5AuIOyCFuHOQuGtkBHABey1t8eOJEdUAAA=" />
|
||||
<img id="flag_niue" src="data:image/webp;base64, UklGRgwCAABXRUJQVlA4IAACAACQCwCdASpPACcAPtFeq08oJKQiKrZo0QAaCWoAeBFIB+Od5B5gOgB/o98A9ADy1PZHrmKrfbv7wZQPAC4AM+/z8DCVp2m9eNsxM5pHMbRxLzQzYzyICLyiZ39HEXZjy8fKasp2AAD8+xR5Y8uR2t3TLXmDekQwCkJcxmKYuiK+/fH9T4i3rK4A2X/JDGvV+JdeeWOkI26hRA179WrccJooURHZAmhuazthG0gY+H0K+Aeqg2YbWYLeJkEKud+ka5I/oDZ2lKMzFxYD4iUNgsvJhERQ+0P4rCGa/4mEHXUp4oiUC0M+cwby4fKm0R//47g45rws6mWKVMaOcnVTKVUpjVrvsbVwnwRkUx/uQ1dHIL7iRttF8T+3zD+hPl/NXKRQnDPhACuL1oaeYw7Y7AhAUCsyPFnh74354nLrbrqkFyZqQLET7eMASxLnZN+btaSiGEAbVWffbIzu2rHUqbSyH4mWMRghIB2+g+/OtuvkP6s/lLI6NN8q33+QPebFwz/LhXzyCm8yxhuK+QFIE/OWDm2esmyf8EatsBCdkqmU5aBxkzECa/Bb5GXBHjz/bUtM//zK/3xvFR0y7EKPNbwQyLxJMIupVR3/kZ5ToyTut4zARKM3/OpPLpWqvFpFN18VIc7TnY19UjMODyb+wVqZcPd7ZGGlcbhfW5wY1gAAAA==" />
|
||||
<img id="flag_egypt" src="data:image/webp;base64, UklGRswAAABXRUJQVlA4IMAAAADwBgCdASpQADUAPtFaqE+oJKOiKzJKcQAaCUASoCkwAHnX1Wq6JSJMj6mswUpLE6TrAWUnUlek023x/SxREJQAAP7i4L/3H9kfzlVb/9CT//gk//4JP3QgbhkyDy7bP621QJewSNOXJGYsHOj/4RQNI323/CKAF6Bhikl5DIzpxxGonjQilU/gN1SMT6JTH4c1E9Lm1J8MxFrMNxzWYufIIOQzrtjfW9+I+QYNO570zJPBIO4ov2L98tM1+fNrAAA=" />
|
||||
<img id="flag_saint_kitts_and_nevis" src="data:image/webp;base64, UklGRroDAABXRUJQVlA4IK4DAADwEgCdASpQADUAPtFUo0uoJKMhsBmaaQAaCWwAxRGTvD/xvFwbkRoEpk4DxAOmh5iPPJ8+j1AP+zklP6y+gBmj2mnM6YgVq7/E7wPAjSOsw/tH7A/6v9aP0T22D/zR3laplB/qGXM/+rLr5cSF5WR+x2wlLpdRMrXz5T8JLkEZ4O+C++gyZSCLzZeyoETJLtJ/slT6cUIAzuBln52/HOJAAP7ff+oJ0qW/6aR/jSP8aRQ/hdp4bUVXsZecf1ChjhIC/YojxrKF1Uwunm0CLYAN3P1slTxbhnJqNywAPh/+s34hGCahBiMTW4gzMADtvB3huNHVX0+5mb0HUdXqB+m7bLDcNmtjNlv9kCBoMVfbZr1Wp1zvDEXKq+cEJUSig3nVA9NQ03f5b3eJrayt00TB7M9bHbn6ixU1i0mCQDZWTvPxSmtPGxQu2zulsmWyvs8dEJTqafKlBizqZb+YLypDQCYaERdSiek9dkBSlE/FaUqb/x5OA2DddCvlkSynfD9mXN6BGdQcJalS6kOHeds0FBBYrMwkyNeeWlluxvpdzBVfrCkccXPpVLS0BqKYZmTTNv9I54XMWNGeY9KrEe10QEo6rX7sbyQ0t7d9P3p1lojprJKC2AJX9urOtZDfpwJN7SEHTz/n+4xo24Llb3C+6hhumo41R8STmZv+CgdmjWSc4nJ79LbRRSIc0Bb+fOy38xG3mI7go0YcDclip0op6L5o7ZImH5VGxnIuChbanPpmDVMK2Te/L01j8RdMVb1MxPWV3T4HV7SRP2LNbX3lQZbwU5myIYZ96K8BLdpNq5lYTlAD/lCMem0P2jbWUyO1rfP9L3Ga67/PD20lJXVTs1lMgAuiEUVVzpwO7BCKfQ34oAfwGHVPyOVrSjgpg3lI/xgpxM4zJ32h49UX638cWscDyaz1COM8Eo/NIeN1bo0/a15MKt70nGSXNpXFiXAsBtuuseHLjLWPfgb9nH3dbtg+nrmInyw6cR+i6Gd5vvdrLursqSNtolxrZwVIJfxTEhFimsRGxRMds6oiu+/JDhXAJlwpOckbbRxdJUm8A3urJoC8vFTRt+vesjh/u8M5Q4yBqUHWDfI66sTdj6imsfIQKGufc5Spqe6Xf0nqgpUJGfMr+BbYlBUMz1uNvU8rycJUkYAN9zOB1/OeyGg2O6GleY+wxa8NJ56+wPNWXFNorZuZE59HdydPC5gUgsKG/IoWFcdekISobRkYrrBuawj1MeaPtuAAAAAAAAA=" />
|
||||
<img id="flag_of_montenegro" src="data:image/webp;base64, UklGRrwBAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCB2AQAAMAsAnQEqUAAoAD7RaKtSKCWjoqIokQAaCWwAzQmHvV/wFzfcBjN7ZPcS70b6AHS6ZElcAaVhyWcmmVECvU/grG/96IaUiNE+EgHBrn4tmymgJR1gTBPNTgTx7jbzASp/yoAA/mg3U7iWdOsRv8MaNDZOdMywj7/5cW66hRa/hfW07WPyCWbt+HTGPYpMCAW0dhgx6z2PA/ok9DvY2T4sgTJEAv2RQQkSVCUG0M7Ehg6Ds9IG52VfmE7KvIapvdtkrmKTnPPC2L2rmiPu4lJLf2xAi+suzXL29sUrv+Hh9iyYbngEGZeNsVeADwPUEj6b5yeWY2oO953+FC73TiXKr2PH1ZwRUmTpd2HEg4eD4oUaghEYtVuSu/mXKXnFNWeIsBkB2G/0h/oZPJPnAPi7tmH89g6UQjRyj1FYhy7fHJSjg4E6n6t8hIZeQkx1umIZXw+R9g9ivLnH/sW6W5LNK/zdd5Bb6I2idJY8BoDeMCa7tciQAAA=" />
|
||||
<img id="flag_mexico" src="data:image/webp;base64, UklGRn4BAABXRUJQVlA4IHIBAADQCACdASpQACwAPtFeqE8oJKOiJFgM6QAaCWgA0p6qy1Hm4yRBCAawRXwo8mK1OTf7dx928jCLCndNrMGxCTDSTXjKU3bK5VdDHRAfqxQQAP2MYcGKC0A0LN//4tDzD9vOtjYh68KwIW34qZ/kwX0OB1Ddjt7x7uBsIQ8mvcCXXVAIk8yQDAlrBpsz0fdfY0lDPG/GNJNQiyalA1auDW9ubWvBuSs7IhsxSjVNC/s3x/of8TVv/MPj/Q9MlOSzIx0jmXNhHuH+2uEJ6gpqD1MerZByeZRa2MlX82wjOkiiFuUNUi3rqX4K5sMX6cdEyzFAzS+2SqdUsYtvVN8yN/jverhfD0WMhGJYfGl5a/AM5sNKZTNSpW/mHz4uRiVHxZIf8M23a3NBhPZge2H3cUjv/wAl96wUqWJuaMwQxTvwPey1EM99P8+r/V8oEJ2SQ0Z4bzxx3s/YiVjastlrEGQw4K4U7puctddG2ypUkEHBWAAA" />
|
||||
<img id="flag_christmas_island" src="data:image/webp;base64, UklGRlYCAABXRUJQVlA4IEoCAADQDgCdASpQACgAPtFWpEyoJKOiKrM/MQAaCWwAzfmB3L36emHK/WpeA8RP9FOsB5gP2Q6e700eog3jjyQIqDWnBgmfThw7ez9ok9plEbajp2CGmytK9qhENoDKFd5r5aZnXKUyaZGOFfs5ILE0pmSvJDlegoLBGJHYhBCv2x/gAP7s4F5i2elLAroUSJwzu/M+s0xz40jr/gzp4hig8sTxChM/LfNFkO+9wh7hsJ8fqJZIAt4d7q1Vc6ziGKTNqR/61JDES8sd5HtgPoHStHJp4WUSRJT0o26hQvvvcfBwblewWA7VOSaias/aZ0XahnzdsPZQ/TFZDsy74eO22IJXINXFk4cEsoslU3o/BF26bQ1G5+TZ+4gzSWTsAqR5uz+6cLja3afnxAY25HPpNVX3cHPrgvIMoIV6sfofz8QWp18iOnSbuc/1egs7zcxmY5bJ03//G7guekPeolL2Oe7yHvhR0qSNvQWe1dLgfG5+lceYwdWFqCyKygCWvsW2uOwN81pLAA5jJ8llpRyOKs/HDMU2X2uPQw4XHt747fOgOywWS78MOx4dXx6e61/4whFPjKT9cHrDn9t2c1hUZu3Z9KrvKHgmB0VmrwWQWiF55WU63/4DYcmKj8DuzalGRQpzmmtUQnFA1Eg3SbdSudMRsjtH+CgnqlvROppkmYcnAcC5hUlRzzzyQBA5X3saeUjBDBR5PMmMWq7rwS2N0iE4VG9GuK+FI1SkdUqIIEXyr7cAhmdEhfGEkWuQFYWdq8xvi93b0osxZwAA" />
|
||||
<img id="flag_eritrea" src="data:image/webp;base64, UklGRpACAABXRUJQVlA4IIQCAAAQEACdASpQADQAPtFaqU6oJKQiKBmaqQAaCWwAzyAv+ye5/yj9cPZtrH+M+7PK1Ld9QHiT/1rqAeYD+Mf1D9gPeX9C3/09QD/3dRnz6Pso+Yj/nmiCAAlaPdourcI+6tScA/AU9ZjTAU2l8u9hWLlunM6jqGSVDuG6H7JnxPX+g+6dhI0KZLk0AAD+cWXQFK9m3i+CnFFd8//dhUa9VH002QlP//nvL2ElbZpo96PwPDyC91pK0irSp2PpKrMbj+S9guAagvyrQ/BOmVaQqkC6hsXCqx1WWxvlod3kLnnP+EbQ3xONxmrrneu99X8g74KZ2vCal9PT9D2lwtwrzY4m+JYL2KWxXT/es/FGmOZEI3/joisobMzILj7EHJW0m1WYDZ2oxkEtq/RMVZgXvQPkgC5aezf0iLbXms+0LGZwuwfw5O5XcKS4r6MMjKhtfPzEn91/UNSucSbbFnIndEJ7qn9Hj/C6k1rPqtGAlSwqA0qdsJ0UIsBhy2FTKZRYDx+gBxMC+L83WB5WKQqneP50SJkOeReVO9/EDYL2yfmi38YMqXROtLG68Low1uE7vNZWa3fwcXA+/rlqukxAsIOk8UeDAF+7e/iqu0e+LNZ4PHCwKmI/gBKKvR8N3gHRcx01Qd0lCHtTMXl/1t7RthR3BICvbSA1RzgDnB2/KlZTNCrmZtNJQTp/6y4HZlsbCSg/RAxNjR4BxYd/sk/J4cdstUchi+qyUerINBTXp/pEtXtAMuzDUFUZ03/WZtOFpzzGgodadlQ/5YT5f35N+aYL7w/H4uWpqECI+C74FSNH7FwkrdsJV8Z//45dXr/iJm9iFZ1J2BoZHP+3OPAwbXAGzAAAAA==" />
|
||||
<img id="flag_georgia" src="data:image/webp;base64, UklGRuIDAABXRUJQVlA4INYDAADwFwCdASpQADsAPtFapU0oJSOiKzSc6QAaCWwAwzGu/mf4gdolc/wvm219+9fyX9I7xMaTrO5AO195gH+D8oz9ZvdP5gPNw/0PTgekB6t3ou+XF7M/+J/22CjaeL6CPv8M7JMcppid4tqQKghoHkQlOr2/tLSrF+f8e+EwBaaqRkwDbLonSAe7j+8w+GUgi8WcAP8Jl3K1lxBWYod2cCTMAvw3arYOrKVLvSRpo5ePfT62HXRmRAnxM8atzpEpZEZBRds5oQEoAAD+1ieL2S0PBTar1y95okff5VSOv1F/blO9KhrHizgZr5ffk1GOb1IPhmieipLJfFwaRc/8vrA/huiff3VJLWTe0BH507o97oOR5w9Bi7gsrxI+qFMxEatp8ImNybtmNgDsUeZVqALh/NXjTp/JvIQeb6a+Jnek32Ivb5XYMJ97fEkzOuOwjhXLiW/qM5AZXPSlxLFakBkNu7S4VDfqqNKTYOrpas8QzYQ4cwy6HXIFuW+8Ix5OWbefctHsa99GWNF35X3k6Tuzk+/fQ7NiW3mpQD8fMGMJH2YcT8rZYK8wBxYQCd4+WiDIZtJvMf2UD0HtzSWbSsRMpt6Lg+ruNAiqR7eL28OnkbD6uw1HMP5d97zFeGB1XDotJU2Ng3gCLuhgf7CSeBAW7eRAnmyyKZOAkr4BAZ6pmH41R4QBL+H16Fb0f2hSKyrFWNKs/lsVCUnZ3kL2Y8F7XvKOPJRS/UIPSEQPWk0PaSYg++ossNdCyRwT849bnEmrCV/w5AkrMxPMOyyQq4mOczkMqB/fKf8Si35nWT3ayU8gjCR14ETzn72XT+5FWYmJzARIWuIXduy6d8O/B1Jkvb34OmmDYy4Z3jxwBfdHYfAQtgsUf0VT0RXRG6bP34cm3Om5uBRIu942yVC+CZ33VNA+oWlXR+Vz5oRGJkfMNsRSRxDSIe2UlR7uVAApYWCYYEzvmWkP/V2P6VlCoUVQuoiYAObZkFMHhgHGXWAaAUqbMjn2q3kspVORzz0WQhqWb9VvkOIe0p1QHGlMyTzkoRRuon8sY51ZMiUitWI7/Nfhgtwk/lGQLFXN16g/vH/Sxhc00Jrb/s+P2TwJcxscNTv3h/OVzeJs0Mfci14/BvUouBXl+0NEGrAnl9nC2IcIDB6aDIZztMPNwJ/B7gbBkEzhufCrfjj9mLO1EdJnxkLa3D/ifLV5L5HdFpwRQrOr/oO6ffn9WlPiawN/QppO8jjbbO9itrsM8f8I159zVqS17NRbebTylJicqDq+izivp7uSfQ4yqZlhlEOCWLvieJgO4AAA" />
|
||||
<img id="flag_rwanda" src="data:image/webp;base64, UklGRhIBAABXRUJQVlA4IAYBAAAQCQCdASpQADMAPtFYo0yoJSMiszK5AQAaCWYAlc9Rk6B+IHMdwdtAGDAfsB72Ixcw6EuvH0AXGYI0oBoz8BHCPrL3OEyg4HUFASJPfXbMiAAA/qTX/8DpAQQ3/81/+XLv2qjBSoovrAhH2AhY2iTwesm55velo/4RzlwLYm+Hg9wTuyilJxCzP1RsPdoXZ57h5yDDwqx6UwiegTVG69KFn6PdWKKdnEw6mq7sYxexBhhDPuDYt2MxkGeyNiCQ5nnJWgFG7KIwx9yCJ3jKlrFWUYwHw3QrTWNsPHKmBGkSvDw/SVLUpY/RI58rH0NBn6D6VOYx/GQrcgKD/+f5rAx2IWiXQAAA" />
|
||||
<img id="flag_honduras" src="data:image/webp;base64, UklGRsAAAABXRUJQVlA4ILQAAACwBgCdASpQAC8APtFip0+oJaMiIi2xABoJQBqJuB/ANYq5n9gARX5lH5WhFN68JZTdZcbjzLmvMpb7FLLqAAD+7RJG0cDuyTGxeyQkjdZlfJK9v+m4HekUf+rPJnN9E77XF9FPQbxNblCreOkhOIjUXvwEZstGRQssFo5F0rHirzfAkPV+JquWk7yzZ05qbSF5p8sFtHW1/I1V4xbpeiL7kQXoZs/dBWIbnfRzuv449kMAAAA=" />
|
||||
<img id="flag_netherlands" src="data:image/webp;base64, UklGRowAAABXRUJQVlA4IIAAAADwBQCdASpPADMAPs1SoUunpKMhsYgA8BmJQBKgaljyABHxQ1VvMpkVHeDAMEYER0qtCPZsG0fYAAD+34A/NXzlS//M0eW/Lfs8mt8Lar1qLbrb77GhDa0q3DHwXBWIVLJ/v/jgLS4FJ90kACfPrvCuTYQvYbmnf+qFE0dycjAAAA==" />
|
||||
<img id="flag_sint_maarten" src="data:image/webp;base64, UklGRhgCAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCDSAQAAkAsAnQEqUAA1AD7RYqlPKCWjoigTOqkAGgloANSJwLwP8Rxt/HO4dtxPFy9Yrz/75QIkAO7J486TkBuZaYUFlUMNj1nZXZYGFKXq9ntScnsDe2B9OSKmqElNTGGhOq/L9y/kdIAA/thoHk2QAobZJ1FkVqHqTnELFHzlVA21NI0Kqezez02fgzAv6npOqa9xdFmwj+Iz1+wwZrAhI35pilDHN1jCyGtwytLI4ZgNyLyD1Z9FSq4oy4nFwxPvOvCGFrZhxr0AnzqVVcXsxrcxz8B2KcwzqFJqMfnpcNCaCUUWmAoY/wcJIiOxHs8wnnp9HrcJOSaCUs7VLUGIf4I2MOXoA2QCQtlTPWE5DiCM2KRDMdpinYH/NR/x/zBumFbrJxjOqrVtGp15htSrHrKupnsxaUXmglmDpF4e+aijrrh7T6VF38zvH5+VH8/SOj2eO5F50NnZybInvIDSG/OERohwIZvl1nnFveWw6fTvman36S/9HAGNGLHHi0NXTkgIoSeSLVloZiKg7SJF0+fGi9GQY6f/RLP0trBNIELIVx8Pn8SySNRHYr0hMC6h574CQuWVL8WJ/aDjR6rvVNrhQ46FsZTtJAH7FWlWZhT+TPKgAA==" />
|
||||
<img id="flag_zambia" src="data:image/webp;base64, UklGRjYBAABXRUJQVlA4ICoBAABQCQCdASpQADQAPtFgq1AoJSSipNVa0QAaCWQA1fGBvV3sKCe8BtgPFm6gHn/9UBvLS/AFLneP6PO6Y3KXVzSG0/rzuPLl9+5g+VP+dQC7m77NAAD+6GeOHw2VHb0ofMzbP/i0PrQ+s/2fYx/UPMO99nza6B1R/9uWrSyPqnqe2dYoea5ide0JQRk2UPLe/8LCUkcY96szdJqwviTCbkDHESLAoP++FzR6bitdBbUAcaincFTM7lrQ8K+HKMa+jTESLPAgalm8eDKudC+IpnkrAd4rXlt2UoHupquwZmXaNZ/a//Lj/7p/ukBLAI4VEdXv++18/dr/vFx/Y39E7kv5+LnNV3GeSnNIW3dMWJCRrfOB8xaQp2x7uo6GT1o6xUdRfUyAEFd2UAAA" />
|
||||
<img id="flag_cuba" src="data:image/webp;base64, UklGRrwBAABXRUJQVlA4ILABAACQCgCdASpQACcAPtFkrFEoJSQioipJABoJbAB4B/ZuPvuO8B4gG4A3P/qAN5G/ar0ALmbIgOVoYalg7CtxbrkvNb60p1U7//tJKQ7YH/0/FZWmAW1svfJC3FjrAsAA/tvXqERegdDuAD5uCOQQBGcXbXuVBBBGUpgLEf/PRIhouPeat5Tncc4MX//+TaRe07Sey3TGAW4Tq/yDPhZz79VFF1XPOhm6WD/IAUxgQkGxGeCq496KLoxiAQMre/S6Y1GxVKuMIf9/uIQgi8v7AZPHoPtfCVMSc4efyue2FDLyrM8hZJzhtUD4rg3dlhcizXWzr8j+1EGe3uswQFTDUFYdtcXysqJvF73hxHww5arc+2k1Q5yaSNlxySOF3RV00JpUuWsUy1bgjUvPmmNzB8hSXbmr+loUeN1WctjTyuLriEY0/1xUWD3mJUikPfyiH28+hUjWHHBg4Ai2Gbptzl3gmbYyvXKtWOnzAfC53Mmcggr+UvFh+qxFWbANKiGpToh1Y9Mhi8KoEIr9lbJlNluAl5bZ+zl6f54w7K9H3QIlCOPgy/Hx2xA3z2vnOaLAAAA=" />
|
||||
<img id="flag_cook_islands" src="data:image/webp;base64, UklGRmwDAABXRUJQVlA4IGADAADwEACdASpQACgAPs1UpUunpKOhrNgNUPAZiWwA0MBBzE7APUBts/MB50n9y1ADeRK6t+y9AF6dP8vzNdjnpOMDSg5hP9c9BL6G87/1B7BXSoC8UilGlMiml5tKIGEXfNR4xzh7k2f9J3NK0J/PVf4Lik4tGytgu8NGDv0u0VNNPU9uL9WiVfpbjA1ZVYJ6kAAA4n1+n9PwEXrA3xqn+GryqSWwQoRivf/RaihlgXAKmyGvmNFX7IkmfwH24ZH99xe4PioXI34teWO46/3u71ekhX6/uEksovk8/2MpWcUbfT6iljH6HzKyFk6HAUWncHKENM9BkgktQur+B6jW9tpcDdxsp3fRTBfOPzhlQC+0Y5DscfRBgZ6a1Ju1cRMx/GkKYAc7ErlDvZ/3zqVbikFb/cfIkwktISfHXj6asTX+1RLl0phJ9+xrO1N7/AFyViP8lOnZGpQc+/nJfyfSXJTGRsJD7ZVG7nxdTyDDQ+QTezInXX3h/HJ59dtYND3U2AIubJCbrQ87q+rtvPnbCGuDNMjZC5r/s6o6897yQH+sXKt2YtEPgYZEIHdf6Y7h2n0tFldZiobFPHmUAVGes3W5cHdn+cNI/FMiG5WYF97tu5i//82IsgFlgdccJ85paGimviVcClfMByDfWCjq+ra3+XcfHR6z88z5MpqnOa2NLXePfj7uumjey252bd8trZiKh5sCgYRxdJpWGJa1cbWHv0v5t8hndbL7/08Fi6mAdUYXNA8sMrDQajeIccSC5l+KEaneJ/kKxPt5mlPQve49z0NZPrwz26lVcFfd6J9VZt+gmt9saPMXW5hX0nEv7fO59//WAtdY6qxqJYNMyGkahCcI3n3jd61scN78EwrHW174maOasfcSBawULxgPsmYhgli5XMb79xy/oiUkW2xnCap7vXx7Wh1s1wja+Ijzwvjaa75fpowAYbVlfCcz0/BIMx8nKlLHEz+lZaSGnX3b04EDZ4DEbOGLMLcEHKCc+C3Nzpw2edhwydmRlejQiI/MfluKjFE2bHOIA7BCYCKfXXVc3a6tFrneGrzRQrxY6eh9Ys6258x20Cg2AB2v4ApRtjzNkf7ohXLCRXgYPmuPaCvctitAqwc4QKxN1WFKEtbHQQdP9jOFpvXjThy2AAA=" />
|
||||
<img id="flag_yemen" src="data:image/webp;base64, UklGRn4AAABXRUJQVlA4IHIAAABwBQCdASpQADQAPtFWpEyoJKOiMZi4AQAaCWMALv/AYKXaxaDfwtkVsd/SRHXtp/awM3IAAP7lCv/9avdf6tJp//84l/9Av/AXmCR9oH3ovvplpFCKnZ01fWPDsO6Hc8FOA3oCJTk9/zVpuYEV/riIAAA=" />
|
||||
<img id="flag_kyrgyzstan" src="data:image/webp;base64, UklGRo4BAABXRUJQVlA4IIIBAAAwCgCdASpQAC8APtFYp0+oJKMiKrM7MQAaCWYA0FHAu244NgDbc3YBvKuRewgygeBlT+/dDrbe6TVHR09+w6iQpHcGh+gO154jAKj1V61Tu+Cl8AeKGHItydAA/uLgvdHVrVlc/9QZ/+QZ/+QZ8iUmnvWwFkOPbmnUpNEmTfKTaoDMeC143QinusDYT4i9ihBXstXTISuPFs+tys4MZvH8eOhZTiVHj1rSis+/FOD6bg6bh4k5eekf8LsL7jysKchsbDGMeaBZROtCM/3XbuOMNNJkBQCnTL9PjzjZ9+xsmS678iXq4KUPMME8JjiVf5CdTHAGBJz3oPUbrata9yAdjkdIe0fa0knO3O9lnsTdzElCY8mo5AK4dpfwiPdDRdbjOG/utIciVxEuPw33QzSrlM28dfjriaqKtyiQImSbTshnpF8+jfSZD7KuPzhRsadfsWeRPXnV44ua9qyTW+RDqijW0c509L3Pf4FCUXWF4ayIjladfHh6bEoSLDudAAAAAA==" />
|
||||
<img id="flag_austria" src="data:image/webp;base64, UklGRpoAAABXRUJQVlA4II4AAACwBgCdASpQADQAPs1SokunpKMhsYgA8BmJYgCVA/gGqW8zkwFv/3cACNOMFXzKZHv3jY+EW812PA1iVSLgAAD+5Qry4jSZKv5xL4C8keti6Pb3XJ+b0XgPoyg/o0dTlH1/4Rb672/4RXjRV9gjSpsjqXZYPmkYI6He+O9hCdIz7CE6fAXn0j6YCZ5ZwsAA" />
|
||||
<img id="flag_palestine" src="data:image/webp;base64, UklGRhABAABXRUJQVlA4IAQBAADwBwCdASpQACgAPtFWpE0oJCOiLvScAQAaCWIA1ImBvJWcz1AG8Uftn6ABMsbuAGBvNPOc4nZmGRb1BO4xsk4Kw69nJNfwzfwA/uz3LxO1fhE/biZ0JTJ+TJm6KoBgZm/8ZLd0hd85AXU69/st0bCE3Kuxo5mvzIcrW2avYfuvimowaqvvhyJ8iJRNgFTRFX8KPmG5fMaCi9rxrmUxVM7t9pqLDxLkMOF+pzXKGSHtOpynDDG199z2M/Kk1DC0oR7SgoTUg23KX6yi3Zf46AXRfpYmz4pccOde0mJU2EgG4rvrRV3XWKr7/p3YSv3teuw/zaPVXLndv/fzYX1/+Df9swAAAA==" />
|
||||
<img id="flag_cocos" src="data:image/webp;base64, UklGRkICAABXRUJQVlA4IDYCAAAQDgCdASpQACgAPtFcpk0oJSOiKJgNEQAaCWwAzM1BPO/wGAGwg9QGcA83n/AepPz/+og9CXpTL9Am2qwFACGceLt8B5IAP0CZWBXqJVBNFdE3fyo+VXasgSlLCbQ6sIth7J0Sb2a6tYRkCueUStYV7DtlRHx/JCwAAP0mRUDXRQBQcFoH3dpLVg6/VlSFrh+BEjs1wpuVVLuh59uXzOcK5L2RmlU+CRn/396fTG/H/kBdz+tnm/ue/af26cbTTyg8zXN2MsHw97Z8R4Mwt0yABpeRWs9sjWgSPlaYRnz1xMS0Gw2XOQKJTNbcDU00ZZscr4U7+h6MHeTebwVP93lrkK3HW9zqJD1xRvC6t5ZYK1mNNitLXMTafsvf4tGbqWqXy4qjKnQb+kk0FWfs5ZPxs0Mz2MBnnmsuHgZzoYW/0K5H+b5aU4FAyAc8AQDFNIoSi4iQ8XwaV9YuGg7+KoNLOekO82M28jjIp/XtiWXXqxbzY3QjOdtPB5qM238rrq8C7EByh1z54roBvAdjZX4BzsZnmqMd+3tiIZv7K0DGS6eblSkdbhTgY9vNvwqMUb1wqNbJqQqHpQrUZ92cH5Sth1mAtW2WvFfL+U8JiwiXD3eDmzVKa24OJQREHkk6ceYOkhUfcPz1qdQqthAOZGGzfjIMOZRhRbyvfhB6hPaHVF6u3tidUku8nS7QZPMqwdpmCcu4g28nE4gCcZkpDZzRHmDC877gVdQiFlXbpwsR9OiFC0AAAA==" />
|
||||
<img id="flag_french_polynesia" src="data:image/webp;base64, UklGRt4BAABXRUJQVlA4INIBAADQCwCdASpQADQAPtFgqE8oJaOiJNVcsQAaCWoAeSH3b8ScBs4BtqOfY9AHngdSrvNaNBCAcptnm2trkWEGEPt5qxKLR6Hihzd8YxQ4P4vKICC8qnkKr+6VfrOFy/2BhmfLz4DIVcaIAP6cU99dj5NRgVf//wqV1W9jJH86H//56ZXTe8JheyDfOpOVH9or5G1TjG4Yg/MBfu/f5AQaAa0Kn5mkcsOYbwzDuGAFNlrMCwvbrhIfzuZu4kKFSXU0Jm6MqP75J4Fpnbpl6xqXdOwT/HJnkvB4ghrgiL+yKdGEMjora1fAI5lsyKRiWF7a40bf4wYU+QIEawFxzv1v4NSnAuHqxwZf3IHToK2nO45epR2J8LcAMWg0i2wfWr/GL/EWihgCtQRfkpwGlsKf9Jb0VNZW6uOXC8iMIwFH0ENYSILq29XHX7Z23wij2sHnrtyqXMI+evy5bWtX2HX7le52X6KRWYs9YcYaUCZxAlyB4uiixr+/pGi78nNfJhnygqJl9ddXIcd2sw7nyGrA+uW8qblk6bAZWKLSpdxXL6v3XxIAsbjcqEM5Ut5qTzuLDjuPbD4osQqKIDmRYf4Awgl35tMGWwoDCRr9yEHWSJOgwAAA" />
|
||||
<img id="flag_united_states_of_america" src="data:image/webp;base64, UklGRhwCAABXRUJQVlA4IBACAAAQDACdASpQACcAPtFirFCoJSQnJEk5ABoJaiyAFnVFWG4IKV9u4gPe8v/28tpu5kD9APf/u4f9QKdw+senq6BvgfSW7c/8byp/Puoqgs0UGLslPvMX41WkogrDyDt2mM1zld66CTvpngAA/uoyh5WV4EtMryD2QhC4sH9Lg4N0aIYL+8PxqGVPhNa/lhVVuqKdYzgIDqsH0+IdCLvcpUzGFB7oO3R0Ty1jyz8LauCseH4d9naX697ADCRCoHPHFtL25Qnz7bLJ76oloESlpcErS2+O+qkrq4fZO8oC/om5tuSHjt028G0xf5A1P81WnhMv+OjeefGzXrGOI518WIlX7rqUfe1HblV5LEaEt5DYCrTOgCiSB+/8uslQEl6L4sFGG7mtx7gGDoYph4z8JV4xGUKSYWajCraX8WqKnQO/KsLYx/5VhKZgK/7DHdobsD0GPjzPr032uret1Qw02Ph3BCtYW+3Kb6mz1z/r75YrpUY5FW3xFUG+rqqiB6e2YHbZ9FQLPEiw9nZYayXKFxS/7kdwLt/+yO4Wx/NuTs7eglQX9//yOOyu3ox8/qP2/mXpH5pa7cz76D9B/58VkZ/+/5O+/Hv2iSeRg+LKwgze6JDSK3yvr16DJ0kZq466m2ldD3gpAyU46kDYDU+87zDdHyvIXgcKnLUXgaXBxWvSlGyZ6qVLujoyt+STxIYAAAA=" />
|
||||
<img id="flag_germany" src="data:image/webp;base64, UklGRpIAAABXRUJQVlA4IIYAAACQBgCdASpQADUAPs1Oo0unpCMhsZ6IAPAZiUAPIH5BJgLf/BDMwMSMiw4+XaHXUu6c6ZrijVtO3peS9PiAAP73wxCf3GwkZap1RH/7sAp8a9LP7O9//+S3b/8pLZujx//qktm+SPTTxi7XDIQtW6aah5pPTYmMSZgErqEc5pAHQqeUyCgAAA==" />
|
||||
<img id="flag_armenia" src="data:image/webp;base64, UklGRpgAAABXRUJQVlA4IIwAAADQBgCdASpQACcAPslOoEunpCMhtVmYAPAZCWQAdkmTAf4DCQPX/AVx9+mdzs3MJcSzZHXc8GaOlu66XfTXdgAA/qiOQUYqh//U7RDTlG2x5aP//ziX9gYwnPNFELmV7BJoA7PX30gnlwWzeU/pJVRpo59JKqEwef209WcF5n6qInoyqZUg2/fUbarYAA==" />
|
||||
<img id="flag_switzerland" src="data:image/webp;base64, UklGRmQBAABXRUJQVlA4IFgBAABwCgCdASo9ADwAPrFGn0unJCMht+oA4BYJaAC/cUF+AflVrYXRvyg54DjTvvaAPU1nAP0lyWDntPaDCipvp9ktrWOM6CKdy47/32P4o+jEqe9w8Q0Uh1zuL4TqsAD+0Lu/tpwspLj0rHpWHfH1i/vHQVz3OJXE8T62IbpHO4K1hMAqmwV6xkOOymO8p6yaggeH5ct/3fBjEA0eBgYmfXDXd/+9k+CW9i624mIcH85lHVM/H/4BHD8OX+hZ7JKb5ZWwRcG+e6SX++fbTVCQ/oOXwq+Z7t+81i5zgROq4YYzmf//U5kNvtO9Bmjb1o8laBgGLfvkvwI5rba6REKYmyeTyY70/pcHoWDI8d+Wmnh9FNOQ7dupRyWc94ce6ey7NWxaLfodomOvY6z546guSH0wIXFoV+aQVuOdR8y+lFHz+TjaNXty4v3kvlHDdWv3MoYs11E8qHeAAA==" />
|
||||
<img id="flag_sudan" src="data:image/webp;base64, UklGRvgAAABXRUJQVlA4IOwAAACwBgCdASpQACcAPtFcpUuqpaOhrvScAVAaCWIAeKWMffrsRtYRvV7vv/CmhX6mXBLAvLvB5zSZCIiV1hqagAD+6hPR5hJ3/LAb6s4o9sqmN/v5P5lGI0IH/DVPGeUwXku+D5ftckdwpKHvn5HRONwT/MTrUEYRSLJ8pLyr5rfiDwW+z8i5WAHYsH30x5uQOElx+EseBHtOninlPA4IYGrwwPAOULd7atFCEFZgsxLp7WNtgJf23Qf9Gt24SBR2cGnox7XvIkJyF19iyE3dNXswrsKl/S2sfSL8F3MRI78ND/uQ3K3v5hTLYCAAAA==" />
|
||||
<img id="flag_seychelles" src="data:image/webp;base64, UklGRp4CAABXRUJQVlA4IJICAADwDwCdASpQACcAPs1QokunpKMhszOeqPAZiWwAv+lxft2mJeA80Wm/278G2kD1Afln/d+ox0gPMB55npE/42+X7y7+5lhWZ4O9H35Jtzhz0o6JbiHk7mlmhf8FGGxUWf8BTUUKfMi2jCvxXNfUaXgH0EO/fF5us9cuPuMd+5ifLOMZGuuB6lEgAP7wOEMEFEFDUhoHGYkr/AdoTxpKQjm7P+LY1uo1hcflJrs5mtmdYt9Xs7i+Ch64R48LEeg2ld8iM/4acUM2wI3cQ2uJJPBg4e2/ogGKRzGVeq+o7xb5YPkhVDFVb4WQvNEdQqmq67AySGn42oeyV2juZSybX5QAhHvhkV0pIC7Wd9PV3nO06EW/OuEY0cFDS2tN9tAugHQJyAyjmdk2VbvrMa2UnjUBzn6kugOZpuW+9BHu+trzDkps+f+fuxNJL08Yg60nXKkjbVcniERYtHe/VCrNTv2pHVPDzYCVbhCbTItJP5O9YHDjTaOKvg5vBeF+yRZbYcZOTxL0YgvBdE3y2ZIOIR/34xbLbfYlVq9pc619ONjFM9pO81QmC3mlm4U296DO65tBJSLzq1E+MfUSHjt4Y5y0xVTgej3oyRwZfiB6/uvAd1KRxRI7G52kMBpilB6R47/OuEbNKbSHbwXjtzhf2eyQfzp+jh0rifOLukumYnWZ5cACotaYNnGdJPST4DMqvCti3tC+2R7tF8xoRv8UXXO1OHS38pMlP55PxqerE+24LKFkBGyLg3vhCvm89WU37/qDIB8hD21Kzv+f+8odU/WARh+81/hJdSqF+CrNCBCosKuYGd9+Qb8VibjgmArE6OhsUYO/BJgFRUAl3M/CIYvSEhJ+C0h1NACiHN/NEm2B5gAA" />
|
||||
<img id="flag_tokelau" src="data:image/webp;base64, UklGRpQCAABXRUJQVlA4IIgCAACQDgCdASpQACgAPtFcpk6oJKMiJnVd+QAaCWwAuzmW/t2tMd43y6Lc8B4jHSA8wH7AetVpgG8kfuN6OSehQAhkXji1A+kt6Gf6gHfzcftQHXoFLB05gqGMKO2zSUuqTTGqRFUuJ6ZPiGWj9HCOwy2O3Vg059KiU3b1aUA62AD+93cNKJab7iMdtaTswLsaOxWOT/Qkf/fP6v6l1lFDhs4IJaqUJcvuqrWdZecyxiY2d48KnVu5GrkdD8zF180R1h95J4B/zSldmSDXHOAQOTFz0PCV01Njpgnnk5ryTYYK9ioUcfE4VaFZsGf0qpXqOVuBxTAIG1uxzbgPkaJYkd6YXoL1sLGg4imBAoA4eHs04l6qMh/fBr/8fgAgDN11Z6wyP0fl/49aOIlnSd9xcbXHxv1fMDGQlmg+kC7y6P1YisyDyfonSe36P9qHK0xt+JJ9BoBAjQ4wWF4UIy6IC+t7nKjGKWm2/LZgFKcuveU/kngkqW/Indfn1hyrfeOPFsourYJftnph9lSUnUlmk3gj5zKczmBTXBl2D5BfmkCdndEpGl4KbvXUUjnL3xyk3V26u3VYTOyFXOGp12JlXJAzuDSi/sknSZHwV/3uFSfjErHvdhF7fWr3Nj+eE0J59HSscAFhMQP6/5/5jmUfe1PH0YWCsJDdWTfqityxoemLOLdCM/faXgw4nC9yQb/SkJmDxRYkvhN+gaYvV9vbfRBOV/F9y0AE+v/ke0DwI6bb2MZv5fx7DAES9Bxl0/NCfAqd+bwAOHQUF5T7/Ytlrh6tERa0GXBsebDdm2CF9KWQe0Xt3tbjrjc+2IasFRhYSkwe2Vin/Tmyzn/L4+jUyr//LADONMJXgAA=" />
|
||||
<img id="flag_mauritius" src="data:image/webp;base64, UklGRrgAAABXRUJQVlA4IKwAAADQBwCdASpPADQAPr1MnkunJCKht/u4AOAXiWYAlQP4B+AGxY9Npf/bu/oFx/2P+AewMy9egFpKgnYV1J4q2GzTYLJ62PC3YADs8yw9WVSjmvXTEyImbdXRd7u6JuU9TA/bkbYAEZc0oRhhho/+c1LiFyKUdf4LN/Bv/zTW/+CzfwWBphJ0RZhedC1cDyWvxmyS38f03KJ3vZgsQd48G7dwuzF2GxJKLgbAAAAA" />
|
||||
<img id="flag_thailand" src="data:image/webp;base64, UklGRrIAAABXRUJQVlA4IKYAAADwBgCdASpQADUAPrVInEunJCKht+gA4BaJZgB45fdKX/2wLf/sf8EoiHkTkTuGY+/D65peIWOjtYO603t/iZ5gAP4Oat2uexZu4s3/+LOpMe/1uZ//6En/QednYlTUMnm2os/wNLoBrWa3O8I8VwrSCFt7xc5gH/Vr5F0CF9xFHvKXe5WUrNMCzQ7zyzZg3pDYgoVG3ouhMDlRohujyISXb3f8AAAA" />
|
||||
<img id="flag_denmark" src="data:image/webp;base64, UklGRi4BAABXRUJQVlA4ICIBAACwCgCdASpQADsAPrlMoUunJKOhtmlY4BcJZgDRuUF+AfkBrnfAPxg/gHQmaBdq7QB+oHuAzgH8A/gHq56bAD8k+kUlAWcK/OIKGaypi8I6Jlhun2oJe7DY1y46CUwAAP7Lrz+Hjk4CVzgPN/4+LdvRZfNWFcygH/BcT5GbsDHEbsDMlgVRiaAwEkmZF2dHoO8Rc4Dh9kZ2grni+jaxgfOPWUph8y5Xg9g1Kg8SjW0HV5t6oX/3uGb8F0IPbtM/N21fSPfq1VXB0sqEBvLYlwegDtRGPjSnYC5f4nwJxMHWK9TqvqV7J7EGS1U2FZNh6poqwXE7iL5U/galH5S70+3HQJ4c8nCnppe2nbrjMjuGdyw0g91ikCAZGB34/QZCAAAAAA==" />
|
||||
<img id="flag_botswana" src="data:image/webp;base64, UklGRpoAAABXRUJQVlA4II4AAACwBQCdASpQADUAPs1epEunpiOhsZooAPAZiWMAlQNXQBvw7zaF+lmYIII9K/KN7P03pc8TfEAA/uaRx5juqi3h8qDhKV+p6s+qZS9KROmJ10P3C0t3ghAAnvTAtOykC1XDCEIRD0q5Fv/kxcgs+laJ3yI60mbRVT2DrX0X8wMW2ZZIQVc7zWYisKTAAAAA" />
|
||||
<img id="flag_nepal" src="data:image/webp;base64, UklGRrgCAABXRUJQVlA4IKwCAACwDgCdASovADgAPs1SokunpKMhsrScyPAZiWwAxrAYRIj2OWHlTrMYDbReYD9Uf1r95XpAP206zj0GvLW9iz9t/Rp6gD//uJ7Fo/wBYU/VHUpTzrWhTYAF6F6b9CzjW/SFJbXvWuW3xktYS6nigpWvGRc7nfuuwjfBEeom4VgA/Dco4dQED35OzZ0aoaDmGx1ulN8yds3/G2zCy+uJdeXz7T9DKTUIYwoTS/NV7W/H4lcAau3FURIGu/V+ZFDC/MXpq/f/JuxVZLySOech0OnaNb/Fa61It3NsIfN3GRLNkua5loINoBtW6ZexGtQb08ucjnyHOaUVqCKoqDxmUgg6iQ067bIrJlhyYEqc6z9u5Ud+1gwiwbc/uUeJl4wPGTjuZ3i4fWnL4pFAk+FymX1JSlQB0GG+Aw+TgLFrkIoV2gF9Bwq5uBRHTX6M3APHtLFSD7PuUfKGTEZVntyjfMZPgkf6ilM0rMvS/V2Ybd60CmjemybjTT9HK83j7Gxd4FM3YSq5On27W1uGqaO186FZiNvAXmQN30KX8ZkDWXk84n98aKPISVS3BYDjrs9oREo5zYcgHFNSd1AA8D7hLYp0thyuVexX18dULEBD0JQsqcoSe+ZYMngITxl7ij1K2RowEwVALc5HLIkIMOnYmo2HbLOiXLUQfFOYP/DKc03t9MCyYz4zi8IzdQ4TSl6IqzoLggqwB2aOg3naXL1GvrAmB1UPtHDoFUEZISgInMak5mQwFCFr++bxTOTEFLjjSleJKjXw+J5SdvSbqOwkqAQQYvwZfDrSMGPjSwerc9r5yIC/hGpc8ZPzioBFL54vyZjF7bZSPsYZlhVkcCNC9JI/q6GvGSgBAQdau4zMuGf2/oOMIW9JsIFE00+Bp1HiZckM8T5Lm5DIXbGAAAA=" />
|
||||
<img id="flag_croatia" src="data:image/webp;base64, UklGRsIBAABXRUJQVlA4ILYBAABQCwCdASpQACcAPtFWp04oJCQiKJgMWQAaCWwA0BUANVv6rgNsQPUBtgPMB+yHrq6YBvK/+fR4IQDWRP3Su19XHp/xZbCcdKEigHB/thz/RqzDGHHIHFh2MtGr17ra5AhCG6AA/nCf9774fgv+GSn+FalVpAFBK2u//6tD/locG2YmDxqLMDJD5JNFFnUmLdWlgFDW7zh7/3B7o/QYiLSxRhjgiDDlAQsJgw8z3k71EAWRet3nTv0MwWoswJbL2IMfeuZ312/f8UgOM8gvsPc9InLCUEyjvMyrHrDrkOPE7KBaJ1GH92NoqCYurFdf9Lp5uxEhVtvdt6+M9IhqPk13SDHsV8Tp1PbV+zB1zhq4s/6RsfSpf9Mh/0GIhRCz3+weOaoPSD7YGEQZRcpxlqTywTXSo9fW53ie/K/buSPppTW3OC4jv5N7+k1XcqKvIyrfWzP/6iwUGxzprdAGLwJLWmz9vEVtZ9stFS3tQYMl6fL5lshe1NQg/fIguxTYrztQO6RfLYsUeswhQJdj+c66k8/3TjtHpbP2YQfbdAnB5j22naJx5O0C2JRLRW7imi6KI+gAAAA=" />
|
||||
<img id="flag_saint_lucia" src="data:image/webp;base64, UklGRnwBAABXRUJQVlA4IHABAACwCACdASpQACcAPtFiqk+oJaQiIiwBABoJZADS5Y273/AONndqu8q/tuTRjx0stSrfSIKp/qjOtJhybmUmOhL7vKuKEXVaydM1SE/TbxAA/u4KZ8N/ky1wdd9SgDupCdbhemNqPEEvI+Hhz98eAnJgr58O+Z5WSj2cVVO1qX1VKoNzV9AGhwFjKd14tyX6ss4UvggRQMl4k3+MIT+j+bsa07sgtXGeeYR8GXYRVJo/YTc6scGTqxgfi1DP2oEOf+fUxkZvKaPBDEBZxfi7dzKpiJhWlqtBBNo5+0+SXwCgq+r8C7SAvrQczM2ou9ySYTjx+HB0qn0B5VZl5FvN9ZNBIS89wC5MTqrv3DLqWoaUvdtPsb+KnNjGwy8L5GOpOLfPs9LMhz/Jcv6f8OP+fOIoGgMNawxKCwPOxiGaSwTX82uf77TQ/rMmXPfLmqenpgAyEALhJGSX6/RtK/gk/e1/+f+907bRmS92GB+2DbEAAA==" />
|
||||
<img id="flag_suriname" src="data:image/webp;base64, UklGRiwBAABXRUJQVlA4ICABAACwCACdASpQADUAPtFcqE2oJSQiI03BABoJaA27Q1TXqu94+Gf+A0QHPj6ZmrQANCw4AVGcqFftpndZV3iE5P3Uxw9R7uOsi6uSzuEtrcAA/pxzdxqQs8KRoN40gfvswoVsZRr//5BjQMo7cPEKwXB6N58Vzn4psUxTWIIg1jnk4bdeu80u08qZIz+AR3pWhBUqCowjh19hvAkZEkEhqeI5XyavsKSXvTSE66QBChzrM/qGZdo+BBzA/k6MMVKZpjT3htwWzEaXxjotGfBXekjrvUVkXFEqTrX5voCwZ8rkv5QcAK8/lBwQjCQKarTPBr9s1RZh9++fv4ebVMPjeNkwdv0ZFtxW9LsgwG0YKPlXtT9N5x0NNajVAZnNDCwgAAA=" />
|
||||
<img id="flag_democratic_republic_of_the_congo" src="data:image/webp;base64, UklGRjIFAABXRUJQVlA4ICYFAABwHACdASpkAEsAPs1apUunpaOhrrv6iPAZiWwAzJFBfxX5AdtZS3qH5R+zRWX6N95uYqQz6p/EvmnqAeYB+hX+C/nPWR/mv+y9Q/8p/1/7M+8V6Mv+R6gH+s6gv0APLk9iz9s/3Q9ln/zdnVwJlmTnnhkUQb+DfoxwOBM2R9/PsGx5Tu6fvRsr+A9xOkLzFT3x/mP9Cmf+mvk1r7WgkZnD2VDVajO/kWSmtdUVVhJ5+6DBlT/96QO89CD8VCllabeHVQS/QXV//2uX4jIhAwZf5hYRS+V1PnSrvCYQ+3pivkn/1A+e9fuAYv45AAD8gGzKrd4kSlDpVOHob5pLAEWlgG6qxad+08TjMwmWS2YBLk9C+EeCokMsfmuAQ0CFrBgqCX+RkH1xOiuqzYdAY4ijeP9Frn7Xh+NhTC2ssyxDNdCGdoANHC/icFJydG3b3dYDrGWXiZCp961/1nlN757+mEIwlVBgQ285Q/1bff0eXJ02dPnfSRdumKk2cNsKaXYdtMqhSrTE6QjeFp4A2i2Tadqq4wuarFV9d534TURFadh7yIilR6i5hq6dfS/lN0uthuZgUE+YYk1J+kRaFZxsEAPvuKS/3niQS5trS1QLtrO0ptHvAd+Pima8XzM1/DSpCaa/WwV+9tdHu+pKC2zZ5w4tZXQcP4SExenTb7kN5JK8OCq9DBfKV1Jj7cHNXAO9OJeLrfn7PNZg5OrUHYmWvuz3GruMdGOSn0+XV9XFn+/nS0mNKR1RyxUQynMKmFrfqj9hjClR6HBkYfTwcLuxtjaL42btxTWoVmvKHJ8YWCUPg7MH+vCSop3JWiqXA1vJ6VIVvHOShGUbOxQuC4eJlYSMSO5N8jUXMNoZiuKZ9QcyRnfkXJjqvyQhO7Hng8iGTl1fdXVhSYAMYRjcRoe7pHn7lxR8rOhkeHRi9H2L9fK9J8rLez1T/h6eYlIYSLLWvUb2YNJy6Q+B6zArtM4oDRpHXiNoGXilNDzypXSP/7G56bN3gEj5vXisTl5mUqeaYEEqDTgDu/wqF0J6Lv//i+n67cma5V9D+si0/2q/uBNBi2BZtsXArVdASnUpjcX28E6HVJykLdPAG/BODiTl0/IERUPx40ApXYDu6L5Ip3Grrhr+31bPpxt4u/fdjCBlFJhjdvySuJ6Vi3akBQktgV3S5nix239zusYw1mjLbZ46dIQn7Z6KW3AKtICXB4cxWTCcOmhSSFKaI+HKLv8GIhB8vd71M3r6F01j6WMIxuI0Pd0j0EqRd1DILNFGycjZsCkerQ2m0UcNQoA25NOprEHJM8iuVxD+L9nGz+5Ukwmb1BUAPgeswIhPqMDOhsI2dQTkFgY/S6qtqiU0ELjZ/5HaYf1h44gVoqP34Ir9jUSiBm3QfezEOBAUjcl3eH79xqUv7eyrhBTZDHeS1hHYdHoU1d+Ds9OKjoKWC+4y8GFwftnpIQ1n0eJu3zus0Vu6OE/TAYANdVunP/MPcngxU7MFbdGzOkNIV+eHVk/RhZr7OsiNoN/gZ4EKmXSHwcyo0B/72MeVunblOkdq3lCPUa2kzd2jdwJjn48ttkx4n/KW6GKba2S1uZzamgx6dZHAWgd26LlgSSSQJrvcm6T7CAAAAIQgesJWre2eMGqqhkFmijci4OknwV0+fAzae+RECVtyhrAQ5Om7eMtXCk2OwKtdvEq6HgOTLeW2yu0m/+WI+kQndq0sXVQmAEkLi2uJMDAs4a31r7i1eLpAHZ6hUAAAAAAA" />
|
||||
<img id="flag_lithuania" src="data:image/webp;base64, UklGRowAAABXRUJQVlA4IIAAAABwBQCdASpQACcAPsFOnkunpCKhtUgA8BgJZCzAAgCuTAW/+BQWIZgHJVRCSgbkonqvsP0AAP7uDvrv/mpcRVdRr//+YJ+/27LxJeGOdUy38EoKfM9Ghr0rlYuH+n3jH55+Seg7O1ydHuZljt3DZX+0ls233e/7SWfLzM4ERYAAAA==" />
|
||||
<img id="flag_serbia" src="data:image/webp;base64, UklGRqICAABXRUJQVlA4WAoAAAAQAAAAUAAANAAAQUxQSBQAAAABDzD/ERFCLJjkLz2Hroj+BwC9A1ZQOCBoAgAAcA4AnQEqUQA1AD7RXqdOqCUjIia2bKEAGgloANTFQTxeQKBAqB6lNst4un7Ae+B6FN5G3nJ9BmAdlaYEq0GdeMH6i3/H7HG966wrX0NgMNDQrXRUfLzGUuDT66v2AK7jDwSHU8vL1MWYpKmzG9eCmGwwaw62tH1a1rDOAAD+6WkVklC9H/ln/4u/stvSyNaRSDTyC6i6cNC2zDYmUAM8+P0/hf2G2LPpgeg+XEQcKSJnMQUisH6B9bTBw4nW4/FtDen3iB+HTi+BzFSvJ4j4BJBPWH99urKxwakgKBeixg7OSHaN3wI5k9Vom+JedqiWoYCV2aRL/AdNFhOHxVZJQvRydgh6KF61W9F1jENSHP23F1TwsMzENuIiqKihecQDSe8ayiZeUF/u+rgA0N+DG8GZ5Hcm8NaYZPVr65+gciogSVmk0/phKtlyvfIMVMfBWBRhsO/Caxy6KbyemjtAesgc4GvYMgWqw4scRk8bWSByszLDOEA3gkH7MELKPRCtLgibauUQ5ppP6klrr2IbHVBBvGzw/LP5js6Lx3GBbIf1VmkLR1IrJ8Kv4BL/S3xCFRiacd2bwcUFGvEattSeRbO/zKgeFKiGvZdWRkqMZ4QbCJB9b/096drqBGOtlhGgklSN3dDWRhtdT8kndAoGXGZL9qTwOR1wg61v5qFS+ytKUYIf4yVh9sh1IJ4ZV5vYg9hzrPT4lwII9b4vsD8Tnl6mRNuUVFrP7erMhiWjw42QwxvVtT5sWaAIUndH9cyM29p+hlcqOxBNgqjPGj1Kyirw5kktX9dGELr5AyJRB5FfIsxbBAAAAA==" />
|
||||
<img id="flag_ghana" src="data:image/webp;base64, UklGRh4BAABXRUJQVlA4IBIBAACwBwCdASpQADQAPtFiqlAoJaOioawxABoJZAB6I/KN7u8QMEA9dUWtpWgvAI5lLQQKUrzU3gYzQ/oSDzpaowT1BNuwe6QgAP7p7P//2Jhzgo///q0P+Wh/y0PT3sNW9HXpuZsom5HPUcwAN9p4ToizJpoMjPmeKfNay6RynnamcxPzfrVEhPEgn+HpqMX7QZiUDDQKjXJSIJnxuP4tLHJChBfkjOLqmYw3od3SxjwyNTyKd9K50cBWabxDTlyA5BLnW3HHl3HTBp9QTrFx7cUVmdvgJnAP+6PNHGuxa5weC3XNOuNWN3GLjqx3auuQmrqg40z9U6u28ze6gvrY0J/cQGTpUhnwEhekxlqQLHAAAAAA" />
|
||||
<img id="flag_monaco" src="data:image/webp;base64, UklGRnwAAABXRUJQVlA4IHAAAACwBQCdASpQADwAPtFepE6oJSMiKb1ZIQAaCWMAdIBLALf/AkKlmjXTnb9wpUGcor4aenIkfgAA/q4X//4VrEhiQrt//+Zo+k3sh5F9aMADr1PnNHAOWOpcpCd/4itcFCcBVgGcqR0jhOwlC2SAAAAA" />
|
||||
<img id="flag_swaziland" src="data:image/webp;base64, UklGRoACAABXRUJQVlA4IHQCAABwDgCdASpQADIAPtFUpk0oJCOiKbgNIQAaCWwNv2Ws3ggmlabWA9QG2A8xX7D/sB72emc7zy0AO8GU6DXzRPJQ2sHYg6wSIjPQsJhINW+GWA7YzcQv9r76/zDhxyECeH9LW0tQgtqHb2JqsyftVLc8uOuQIvNLn+w+51NAAPcEGsj3l+7LK9xmnP31K/punlG2ulPKNu4egv7L44Wbfjv0YReaHw7y4R/hbDGLBJ8/ONa/YRYJ2i3ZELM4Y+WCuehWcD+MboeSzkQ2iIAMe6P2DtVsuwYBsEj6V+uUtNTnlmrlzeaj6zWqYic6HJlKHwQJ7F/4kvflin0QKRDNz4yCEWBpBlD2USrT+E7ovWWspGOfp6m7suvUkCgvpTnmrQtRHSoCeGAgMmwckownd7y+0pMPR9v2CH2XcE3OYXdG2+/pGjPCsDKX5LoJOOnktX+F1eStVem/7rZU27pElEfiKRJS33n4XXTGl43odskqjqvzDkliXkqL8+r6KNO0aDPQPU5Z7f2lOeuHDYYcNjy2vyBQ28Ex7koi/wX7XMn9vG2Wcav8qfbnNi+z4LQi1XMVsVMe0Ot4WENWlZ+fGC1Ctu3FDly0S4PcTdl7q98qQ8+2Ex9+TC9UfZrrZh43R10wZLUlfADBkrPwd7TQTWmiK7dRcyyJNiNt+AXjKSpvs6rqqfJZh9tknT6yoEUTGAwTzKHEdmUOZGrPQJy/fXzeVjRj8RPsj9G8CziNSg+zfCM6D26Xp/fzmP1CoU7NPiapvBUhoNhd1gZ3QMl7KGB5sa5PNK603hcU+LZuGcnkEFHodOKXg/uU1PmswGA5GKIAAAAA" />
|
||||
<img id="flag_tajikistan" src="data:image/webp;base64, UklGRuAAAABXRUJQVlA4INQAAACQBwCdASpQACcAPtFWqU0oJKQiMRIKSQAaCWQA010AFLzWTQBuqIXfcL9uTGsP9Ar++oO50W361zyPe20dafciXhsG1wAA/hWU5v796O40es3c7XvaXz/0JP/+CT7k30hw0IfjagUOOAd07OE1t+12FcYnRBSmKVnI6uYvia5CJrlZ4tmWwtYy4e+Pc+M8Pd5x2LHJDgUOe7sOzdf6dI34sRTSKNMObsc9WEMoPmCpdrONJ+hX0vBsP9eh87+5RgJpdmxKKqUXvK5LbthPg3azfmwAAA==" />
|
||||
<img id="flag_gambia" src="data:image/webp;base64, UklGRo4AAABXRUJQVlA4IIIAAACwBQCdASpQADQAPs1SokunpKMhsYgA8BmJYgB34XIH9VAhWBkxLsGHaQ4Ud6LAZ3y4+08ulAAA/uUK//1qyZyZKb//5xL/YH+gXc99OeO7N/v+5yyeplc6ud3d33s1z+hxpWk/g43HsWKM3lUt/jmjsqw21D0KDdAaQfln6x3eAAAA" />
|
||||
<img id="flag_soviet_union" src="data:image/webp;base64, UklGRrgAAABXRUJQVlA4IKwAAACwBQCdASpPACcAPtFoq1AoJiOiqJQIAQAaCWMAd3nOAbxQRDIGWhcyJsqdVS+exC4r9XZueTAA/tjL1tnRfWERqZnX7BC9ydzfxrtN1it66vRq/0scxyWpCOvf/X07wE0urBGdiP//5xL++T+Aty5Ml3fOoYJl+HTgkfai3qGDo7tj91oIJ8G2rvWKGfKIFNf9LWjnoXuLp2Od/7Zd1aIPhYjZp6gR0qEcwAAA" />
|
||||
<img id="flag_burundi" src="data:image/webp;base64, UklGRnYDAABXRUJQVlA4IGoDAABwEwCdASpQADUAPs1So0unpKMhsBTeYPAZiWwAwcRHyA+2eapbP7l+D+SuPHCA8Q3pZ+YDzePR3/yPTV6kn0AOlT/dXCKX1dslzPv1diU2rPrSVbTfJfow/rwoKR9td1fZZKGCqD+HjvDlJ4dnPZ4es40LG0OYSy/tgO7LXuOYKbUe47anM6+lqqDJOC1KnN8edFWsrICaou70t98paXDuXonzAAD+4ds2nKD0OSv7bGmUnnnpW2FsAqu5678Hll7GkxdApW+KAzoSpfO9qZUKhWkWax+VSwPVTXn6qK4AW9p1eCwZ13JJ8XG9p0uPSwQlvcz/uppDBLuPDl4SZ8N6GcS4Qp2IpOEcfvi7uJvx+adAfQx0VvFUaSO4MgYcF7kLwEEGvZGpaASF3k0Xs6pckHnvSKTQRJrNCLGzmejeu7oZ2M1OyZRw9Y8fZLqZgs+oQGOxd7Mokazy7fy/fS1iiz+E4U4YFLlyypnGYbcQ9V4P3xpceLwN795LIuczpFBpHoJwbNQwsG6vJNwwiEWEm57A0ak1lfAphzTvZlp+jFzkipLpHbr2rrfRjBDIq+p5rBm3TPIUK9w27qZS6M1Q6gVhJKddOQ0ngKTU66GMtq9hiNCXXbP+/9wA9goC9pHTVPqZr9eqoex7YJ/r+OD2hvu/d0l2YbXJ91CMfLoRadR5oBcetDjsaRwayUO0g7v3kpWh3oOjn5iap5sbCwcr2xeL13NBmUqLPR8AAPGr7Rcrv/0BxCAx2xGMrF3u6PwbgMLVgdnsPi++sZPt6pQmT/OMoEk2ehciefgobZCxo1lo/oSTkqpTN1i43fD/bPH630MGNL2+iBIt5Du/3Ip2C+jRWYqMYPNkcWqnO1fRUQ04iaI9F/+RZKh69TC4N5gbkvB3Qx4wS4CcCCR6hOhcDiZ+a+ba+Jf3t24BcpZP2GOp1ArWtkkB5dRCrKm/ta/j+JFCg29TdR/rDS9QtZTNcAhR5yQN9z8bmLseqTl6G2fDZ8eKFlp2JfQisR32OfoGiZKJwciFWpXvvWaUntjKoBdU75DhpWJFry/V/mK2fFydJ4h3+LZL17frCvq3pCyFM/X/k37cFtBZJmMawQAAB4lPbWCg/wNd9B//OxTT0SvLO+AwLVwIifHj8Ue3yuPMysZl8/8GSYAA" />
|
||||
<img id="flag_aland" src="data:image/webp;base64, UklGRp4BAABXRUJQVlA4IJIBAAAQDACdASpQADQAPsVWoUunpSMht/M4APAYiWgAd9HxT8oP5nzfWqfhTDAsQH9kxBf8A/m3+U9nb/JfsBfMTFABAxdi3cFLBCQ0e6udb5/i97/ukxDB4JNkr9ApZ3MZAsWBEGRWxNEikAAA/u6mP//a3bE8P/8P3pnB7j0leb89Hkz5yBRVvJAH4LI3L/j+DGppoBg2RjS9/Iuvaw/J0UQbepB2dSdX9XyoC/OAkOiEc/LB124pBvGkA8+et6LNWY1h+scDOzHOGufCzBHbUTIhKVLPvgcsA3dqdFq965Xz7DjVqFRikxgbe279/20CtuQU6l5+H0onmUI41G1/8ETjP+mc8rkK3V3IPZnTJUbVg21CwaUmTYrj+k/GzDSHDQHv61OwK0wznHM0hVlyOSPjiUMf0sq9+FsrT9myMgP33uTI2CyR7EPeMs50PfZqA5Hr/kcyw1Ze+/wYNORftfm7Fu6P2IWlGnqc2Tp/xSaH55L7w9Swfw6XTB+bGRg7R0MN8HfbD3PBxjg8g6o1vEAAAAA=" />
|
||||
<img id="flag_saint_barthelemy" src="data:image/webp;base64, UklGRooDAABXRUJQVlA4IH4DAACQEQCdASpQADUAPtFSn0woJCKiLnxsWQAaCWwAlQJTqzv6FM4B5wHRVdQBvJ/+B/5/7AZmbt1tjnlBgdgQYFJv5AhpvjZ1Bejb6NP7MpvDzJ26LFayUj/KkuEE0TRXBtz91OVfPEA9V9XZElxX8iA7WjDjoeiqait1TJtwYuya9UCL2oYhZbdvMVChmTvFbLpyZRmCAAD++gT999gAQvCw0ag/rIKAcbaVPBCplgBCPg5X4Rhc+9KlNtk9K0Sxobw7cfX2W82uNj84Ji4lfb6SlmypgEQ09dJEDdxnSl1n8liGTgiKVL4FwdNp/2guXNnvBpMuvnVTxr4gBAnel1VpCare79xFkByxx4Fj+w8KqMmZdMv3F01tVRuP6twQqAE3A9Vw4LpGLQoMZ/ZP3zjh87GtuROw4AlJPI2YtCD5mhZqTBj7Qj9JTq3rru51ZDDIiTi2RF9pQA6nv/jfit3fhGEaV1TbCg8SiHf1TLdBbVRzqUGY68mN9cAI2WtHgMsMRJUpOzsepovJ9NPu2jHMl5rs1rF0hYxNnVr4WzAIKL6qeTdSHSMzJKnhPopafD3Z0HyWNJ6qqOYTo1RZnug2uRQqXGcjnynlaeJ9kn7HnNULidNn+g4d3nACBliJVRFQ4dVeoPRPnOKXmSOYCCxpeDp8bw/yOLL+9ynh+Jx8C9p/mOYoHqanlbeJylcOsW6U4AxZKpIBM3ca2Du52sPnj/pin5KE5Me5YuSbPP1kuWyoFWbWTvljrbhJfVHfa1IusqwhHiJbBvwhBMjHoVByoSuWPLqbuMn7rlQS/zZf3Qg5/6EYuYhg6Hk5Qt7shNVSXQy6gsG8rOUfoEeY6uXwwfiThz2UlZdVCvp2V18eSddESUPS9EZeE+BOD1QsdElknCO6qkCewrU5ezbjvPRDLw+fWKTtMsh7xz7GLCudHRgDuBPcAOExcXuyuSLhzRsR33RxPnRVKFz4cDfWx51tAqmXcDIFD0DfA3rJisFOMI17jykyAZh7+ELUBt1Vyb2xS6DaTgFcruYCraB+vyj8eyrrb9V/jSiDyUnEIaPU+rYdqR7Xfc3ThlLeTcVLgNSO10O0G0rM8B58ndsKDxVmBiBAmTPMqI9U19qxlkeZRrc8qn1o+mEDU90Ghb52UhyUc68O7JzgSdVlJATinIUwrG45ecOygZAr6pTyAAA=" />
|
||||
<img id="flag_moldova" src="data:image/webp;base64, UklGRkABAABXRUJQVlA4IDQBAAAwCACdASpQACcAPtFgqU+oJaOiIiyRABoJZACVA/gGuI9P4+EzFQ6Wa0RFxNdnnlX3x9z1JUmoL9HQ1hxglCb1N9ebZuyOx9mqAAD+795fhbjqt4GQ9+FL/Ei5xTNI1Gv/28yHdaUP/t5kN57vlrkMKdPlycSX8WgFm/nhErAjMsnuLDy6cGkfIDjxoZEjdkJ4fw3ENyzrNK7kd/Idjx3FJcT2wLfhu+oa/B3AyA0PC2Bd4712YvxjiUhWKS8bU6P56PqWbY6AebKuwdyACiQfX/zYQomZMW2Vvc5sFKwa+AZ5F69NHSq4uChN+d1NgaXDzuxryP2h5XN/ZZRDxn12B+dcxxs6jBlDYshao1guy7y2AqP5UpPFLwzlucJ88jyVj/6EV+ivAOxEuyqIBhhyTKoAAA==" />
|
||||
<img id="flag_malaysia" src="data:image/webp;base64, UklGRuQBAABXRUJQVlA4INgBAABQDACdASpQACcAPtFkqVEoJSOjpFgJ2QAaCWwAeDf1Xjo98nwrwNuTaK/0A6gH6d/sB7+N23fsh8Kvk5N8aWxi1VPqve8fqxaNcOs9lUkJ2iJ04o59l4Rfh8O9Hw8NzNouSEkMjTiKF8AsAAD++EvXizOCD4ks8vJsmlf6dlaQHFGNfn2/A8ud/9oMel6TWx8z11EbW02JU//e9CMTePv2x7Y/w6sR/0YFj+KdnH/4CacVfBAJ24xaEfMDRnXCQM2jGvFHKgZY31CBYHQuhkVAC/DDKg3r/wKDzBGQqJuGkrYW3YNEPMEFORvnULvEYg0+0Gvfk58KoRlrIoNwzpXpZ9Gd/PV1YzF9BAGE+LWk+LEw6aQ72MS7xf4NQGbqTfplPWdZZ8RLF3z4IhG9A/ldBb+A4zx11kFQJgtwLxWZJ1m/dKPLatTroovZ5l4G0xIZyfi6Zw6UxngzrEZVHnNepRwWmO07iBWgOTGhCpfC/o/IO+EZ9xcxIiG9/J2Q+Y1fPByAVxNjRxQrOSJT/Ym+paq631w5E2SJsdQKy0TQeMH/6fcZbbuTMbec+3XnKm4cEvU5V/iWd6B7DJnDDsmmstfW/ztVwz/6bbLs5oCjoI8caKcm6AAA" />
|
||||
<img id="flag_iceland" src="data:image/webp;base64, UklGRpABAABXRUJQVlA4IIQBAABQCwCdASpQADgAPsVUokunpSMht/M4APAYiWgAeWnznin9fY2r4BwD1AeXB0PP4B6APNV/G7LAPPSYhWIF1XDL4Vww7Ao4VXqUvA1yFn60Qme09W/d0ZUpB8LfGl8R9D8ZHIAA/u3O3/+jo9kXp//dzVIKvFPp+f9Ae/trXehLn/jBHmgul3Vu2T0SQwiD93+c6LvwnDr0Dk4PrPoveV38vVOKOI4NDB6R/LxInIfy3+ajX2a+iWYip4MCWL1iyQWI0Uh+jtZpBlLtkA/m79/KMdtFD+UV676TL+VafFj2yAov5o18jv08eczsv6lwEgfPXkolXCwTSRCPh/J81i+6e0u3cduqkHtK/wZeMNZ1QXTE9RsfTuPjUY7FEwOvAUH6l/yO976FaqocRf2RcCAKVd4L7XHIrOdpZNT0ejMcO9UZ5MjA2eTSmAx0FHEwnI5GtDuvkYwgY4Ft9+HRBueK7Ep+TV1a5dFLfbZW1hegAH9ren3T8goC5RD6tPex6a9jsAAA" />
|
||||
<img id="flag_martinique" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADQAPtFcpkwoJSOiLmgBABoJYwCVr08AILn0HYSB5tT7uF9cmn/IFgxNlHsAAP7u098j0x3Z98N5BquPQ9tsnWokne2arw05da3TXFi3Ts2ZjYzmdT/bHHA+P9D749jjgfH+hr+RddQAAAAAAA==" />
|
||||
<img id="flag_grenada" src="data:image/webp;base64, UklGRnICAABXRUJQVlA4IGYCAAAQDwCdASpQAC8APtFipk+oJaMiJEzpABoJbAC+fACLV5b+QHNxW/+b/OW8O8wHni+kT/r+n/1AG8sRv+yAigx+3csel71vHEm2EuzmEfTq69Xu6ik4uJfbCUbWEwQTf+UytLcQVKZynnESY2eCpOxk5raZWWi0mTcOXAF0cGLcaQAA/XwENAL6c5zwUWqI6a2CeH/+UpMsCKGlf/9CRijEKE4JDoDmCoCQHZ8JPxYHo/AdpwIid1glMzlOYNg3JoJlHse/Y6thg1IFQrj4XxLMcHheZvHnnbGxq+1tKo6lx7O0zX/cWgPaY0eG0sIt6ElKhCWj4gDFv1WHAIZHTCr/tYYLHumF6SkHQbdsJD7cdiO62yQCcDpMnP7d6ZTntKa9cRGzkC0MsIW3V5RdGDF3p6YW1zO6lTrUzyV1d6dZp4qCAcVSCypTi8a3kEGjRaJ2egHsjX3UenVqLPFr2firfEV6WmUgpDLnOcSfJNbUWt3H93QK+DffPM49d6GWRAUgyury5WsPO5vZJjWzCz/AEoB6vZF9TPCO6ffNOL2a527Ao+IDcv75Nj5tQ+Mmr5+E7hNnXsr9pB0NFEpT4cubJYxurs19sagrh7j4ja19wW5JyOiRMfFX8TP7046Zzy11DV59AMR8L6/8SFbqmOrallFiNdxAyOjd4KjeWT4AitLrTXbGCGJoW3Vw/UUzGZk9D53HLZFxqDqW07FEbgdcPbFFU3StgSlAtzdsBsUvMidPNjVa1TlJkLziyC+KZzddCb1Vf4FShbyyauR9guCSXhR6C4Ih5cHW5haNRepzSBP/hAgAAA==" />
|
||||
<img id="flag_fiji" src="data:image/webp;base64, UklGRu4CAABXRUJQVlA4IOICAAAwDwCdASpQACcAPtFWp0yoJKOiLNgLiQAaCWwA0blBPI4n222mfqA/LW8A/YD1AfsP6I36k+6LeAPQ58sn2QPLAueGM76YGvyytKtM78e+a8FP/RJLZk4qgRS6uA0Vef2OqVDH+Y/97O4C86RR/CizbrsGUAJtGgk4fqpN/5BHDBugAM49rLWriXfXpv6VuAYMm1Q4pb2TWntrd9IrievvY43u91ZW7aJA9laFod6p0qDre8kMh7TS4d+EL1ccQDwjFJQ+Mve00LLDTrc8mps4Hv1c2kHFkbePdh220+xU+xLrlPCMoLfVF+hHSPSVOUdnsg5f5kE5RjEVIX1T9amw4J3wz2NEV7ati4drLZncPl9vFzbBX7gsVhOSxpk3BovP7gxlTaevMIT4i6cg6f7ZWLAu8DzL+6wn9n7NYe/XOdwT2DwJK6Lh5N3EubiMsc4lNNSGzxKxcoqo75B210s3vp/9Ixs/OTt3z/lnOho3R++ts2hFyajoJbJRVtiLQq3+gb16KqBQ+fQKYoDZI4J0clkZw0ggrowLhHcacEQeOY6tC2lDTbvF61EhUlvZaC3xETBfH83hYvwvy+qqEZSEnPscjeyb6dWXjrhChgnzikTEhWBF8db0fvp3uhCtG9kuYyjf0eXh8uEmRtQHXwc5vy8/MKPkCzwj6FYS9MjmmZlSP6lpL/49dzJp0ohKC4juy5i8wjvhKjxm12vHWlBZjp49IZUXkVHecIKyVwFSCqmOgMea359eUwCHM16/qOzmEF3I4q6VLtqu6mwVIuy3SkZtQDT5fhl5u6yG9TIIZ/7WoLzeVYE6lHz0CeIdeMVKcVIWhTWFWeZey2ckH2Qh3eu/xYd7nDFXaAeVJpQlhsUiu5K/zdKwYmsN1As2U2ctzzS6dc5e7iflzVuKH9GZjVrFq4KuxDvCEtfIinzCzxQGBc7nqmEiC5OjSojdKX4n5pOrwk0E77wYWxivpkAAAAA=" />
|
||||
<img id="flag_british_virgin_islands" src="data:image/webp;base64, UklGRnoCAABXRUJQVlA4IG4CAACQDgCdASpQACcAPtFap0yoJSOiKrmcAQAaCWwA0ieJfEcPT0E2Fy79Rn453gHmA84X/AfrN7gP9hvinPmftv8G37i1zvGpNLLhPcaNUlgGzOwPq/550+2Vz7NbwC2nMS25FGImv+z2tCFdpz6sOsw+RJEg5oiPJWa5EdAgAAD8+d8k2GDFGf9nmoQrud5Ln6ZwqJ/Ar1dvvw2WSyCI9AsBSD5aZEOsjdC8jk3T7uPqTfWP83uIK/fZpyRLDRD4UsJtwWrruIji0VJu47ESEKOBXEcuJSazoNJV7Cev1yrL9Q6ykvR/ne76MG2/1hOCg1jlHIekhLcg+nlJohVbA1y7rUJbuGxPnegWvsS8yBf7jCwTxC2cJZ4vArv/Mqnjt8EFRIMhfMGXTkNeLHlaS4JSwHsdfW2+hzx03btGnrtzsdijMLzfFPXo6j0ABfJ27fbUcB3Q2UUyH96+XRDr69vIpYBKPNtVT/obC9sh0P+swtn4oP6UC2JrYiqV7EcMd0qyzBv6OdxT80aoI8SsOJhFJ111ZwZaDH6nBi3OjT2LqDKuHV2j5YPyntGkucXXJz99ds89Jrf/D3hpJZhAyNBXbnulAmXZE/GteC4QNrO8UGEnv7RyL/MPyaOGheP/TowRUmD3vGRbw8njx9fF14qzLaX+Of8iFilWbz3tzVCxEKPm/EqwtVq2lioA4xt7cOux+gqWDj88hygVbgycwcUaA5UUprTILQ35F3Z3aVnBW5I/BJEVCsdvkOyy5u4198oIaK30y8rStYoSlt/Y2un0aRdzLlFQUSWreSOz/x8qJP7YAK3A+qdejm+PAAAA" />
|
||||
<img id="flag_vanuatu" src="data:image/webp;base64, UklGRnYCAABXRUJQVlA4IGoCAACQDQCdASpQAC8APtFYpUyoJSOiLvkqAQAaCWwA0m0ANbw7Nxm6jvUBts/GK9f/z2PTA0sf9t/gi8pyJ405b7crjgBpPmWN5GH1Rwa2+xgnPAwBIFU3jk6mDp9htuTLPP2bOpHLjrBDjfhei6NI/RJNc1F3W8AA/unLRpwINDE7oBDylD+fB6n7xYB4c3fYgin/LWhs36FdjzNyZoItU6Dm/ryBWPqgQ9tJUFtE3609/53dKkmzGqAdO7A4HoR5AvRN7G1r6uFvnjrvFITn0ggdojMba2uGWv+M5ZADqKC9e1PTFttjBtAiuzcKKou5XdwkUarSOYnpfQ2+f31r45RxLFqcp1kKD0ZagFeJ2oeWvvGiKrgkV7aBaKtTXs63+VnFCOX5n5YBal/wrUc9eEwqiEcmB3/hJZsp2clA72V8uRAmvh9+4zyzVpbjw+1KOXe1l0d2pSTfFvqdW6o5NTLllhLvWFI1Qs7MPSWLM3q7hHeEGUBxTgs7iaPzYAwCcSwibL3fXO8JEhvBLswtg2rvzxOawt8J4imFHz0Y7R5tQWFaQ9rlj1O43aOK6WorKUTgyiF46zueHf7vfEcOgBkVRopiMV2ClXBBMvg2vpKvLTkDgzOkx9l+Oe9pHx5vcrWW7ORMGEzWvDbJa0c7sQ3bjH23gwBjzAhorjL77gL5su4gpuPdx571BoeKZfqKXXwd2AWyLccU0d+o9NW7sOoaJAuF5oQbeEAuQzs+QP2u+HrRanw/KilTyWtL/fNJxtgvLQxuPo/iN4spC8JaDg+Vx7V9bpJeI3n2wIbergA4Qo1TAKNCwlgAAAA=" />
|
||||
<img id="flag_pitcairn_islands" src="data:image/webp;base64, UklGRiQDAABXRUJQVlA4IBgDAAAwDwCdASpQACcAPtFSo0uoJKMhsRYMkQAaCWwA0XPgqX+vbpewD1H/jzeH+YDzc/6N6mv9VvkvoAeXD7I37l2EF4PxnVgQZAq2mgeOAZSUuVoIqskiP712GXGlnCEIBphY66WuAJgxcHnQRyJYVEOLJfL4ZezRgzxGJOzKcvVX9wUAAPa4T6tp46Ki4LvO8IuUJwYKspRRtV8M/mB74A6LljRMqDwNC0ET8cO7dSVoaA3EM8CsD/v3foHbzV6l8QoOreAq1WKNbWNJjGfGbIGp8aOm5F2is/tTmJTzsoxhs2X57jzbP/CMQTJd2ZFbx3P0XCu0RH753uykbd1+Gc88vQBVKcYKkUduresTIus1kVRxAgCs1xP3p3TZL+8t7Ewsv9lxBYGReT4v4uxPVg5e0bEssL/0jU86O7rrgJ08Gbw4SdT5/RdGPgSbYgzG5Nk4PhqTW2cvQhZ43NdL1loapadA4sGk6PJxeeH6Xn3QcSYxUrQNYD1d3s4d+7KoVp1ZD5nAutmc2TDtssW1Vor3/BXx/X8fXMNj11lYPZLwwB8gzZr9P+ZQrPOXI+/Wkd29RAB8DYdEGjj+XAHOImqmqgPRqtJspxUWdiyUUNO5/9zM8+iSUMJ9hjZSfROkK1v8hWrZyLqLII06jfjzSiC1VlZLhtAcEHIzl7dNyxN7KFMWWz1Bxue3WvzirYZwY+Vm3fUBZ/5W9ZJyqEmpLXJpHvbrT7aRrXIZLfFebo4aB4OSbngPHXnOX/AQeoSfBpUYhZ8422xfo6TJY1Wt4vQF+wT4Zy9Kta5Lh4rH7MB5c8PRUqYm4KmhI1ewb/hRUeTJlWYzbAupnOn/oEUPOPuZ7mMWoBP/tmAIx6cROGwwZzuARDwYB4bbSk1atdxmH/Rnov4K26HYgNOXZBEpcKYnjeKw+hCdyKrr6ckLHJ7n+WU0gwHp3MvS3sctVWcftczjuCLYm2x8LzsUIstaEn1Dh1ZXgqc2PL5f72SNIAWXgAPtK7JgdmGhUoO+PrMMASMMu8MEDTGSEU+Ly8VZZOuCCYancAAAAAA=" />
|
||||
<img id="flag_angola" src="data:image/webp;base64, UklGRqwBAABXRUJQVlA4IKABAAAwCwCdASpQADUAPtFeqU+oJKOiJngKgQAaCWIA012hfquqL9Pvw2HOgA8YDJL944IiDeIFTlXJcHoMetj7NJNOUSpmtYlrFdZFqHcwPRLqDPVNqE6RvD+kQ9lU3lzNvlQbGAD+6mmoxztdlOzGwV+rQ/1aH+rQ/cqqF0kNSgbG9n9GCxwnOfBQIp0+zT9sbuGF/MLV38G/TRpHA9vV6wpVprOZbWUw1iQ/mhhy/U+gqbigCgVHEJQMLsYq2JaW1MmVT86HcX8kF687MdM6H3QrahDkuWybWTu0rIuQEEAMOKttSxRj6u2bJmf1mPrXAYMSmK0YXcpVV9nE6f7b4eUvZM5HdKM+xkzB8n3ABBSJLXP9obPk12ZLiyyEdIV4f5PADzA31uEzz7e/51Q/koPFZRiH+yIpHx5nd13TXMBS7QyTCi20HtpLoTQey7vcPsX110FrwuYRx57wI3qx+BJ+b9l8bkcHbvTatRN8DOzyaCgYfvW5a/xjZcbm243u6PnmPOCuO6Z+B9rUNv9D8pcEIIzbbR2uNRiceiRAVNKwAA==" />
|
||||
<img id="flag_palau" src="data:image/webp;base64, UklGRg4BAABXRUJQVlA4IAIBAACQCACdASpQADEAPtFcpU0oJSOiKynZABoJYgDUxYG+/+xxIDbNbgC9YAUtlf/oeSgn5B81KX6Of8we+KGMQJRo/j4ugkh4LFQ1WQS1QADhLZlUnT21VOXofhbJPGXbFnJAiid9b4y/CfmocYW2IM75xmpjgc3E1bSusXcRb/jjz5yAoMEyVWL3bByQbehpi/Ij6KwJMwAQutUQ2opRtKUsEB9xoSprDgMbztbQqqOXlAzi6Gm+XbxAh9geOA9r/Nq3Xd992slVwXfnZmJvXwZjI2jdY3duO32coxo+z/PefLVL39vw6yxMuoISoKC75vP5XXWPODUyj6Uyam/8AAAAAAA=" />
|
||||
<img id="flag_netherlands_antilles" src="data:image/webp;base64, UklGRsABAABXRUJQVlA4ILQBAAAwDQCdASpQADUAPtFUpEwoJKOiMzQLAQAaCWgA0uWuuW/unE18x+QHqAzgHnX/wDJAPBAuStQAP5XPx6QB+syrmzWm7ECJMiVuj5eZqxAjBukwetVA64b0OHoRgz+P3DhgVoR27L/h9wiuZUnicl4JRgAA/vhNtc6xeecJCNdg+tIDUvDmepvYHwFEOB/hGwfvcgFtyoKIpKmGDnMy/m907XuAsf+Zymc12VJih8fwPunrIQZaxdPkh1snNjqji2giZkji/RwBRnCknNskuDN1FKLrmfVYxzOu2Sc7Y9R23aevc281cn8S14VN32/tsUfAXmMS83uHxLDs6xH7Ln+vr8qfYhAvV7yLYBQpX97cFDwp4hZvqijsXNKAK5Tca0sQ+yQUnxCvgiwad3ChX/iyIb2a8pSQBm7WRhfrNBtK99FcGjwcf6wLBBV/rnZPd2BfqfdgfS7v+ryX3f9XNUo+MwXOVrqBy5hB6T3eI/FIpVmhnTlqDU6uAdr8nDARyrx1HgkWPFM+ApyV2whsDV8pWJJLmCWQpmjmXy04V45NohHLcJu7OZznkAycGuu4KgmaAAAA" />
|
||||
<img id="flag_ethiopia" src="data:image/webp;base64, UklGRngBAABXRUJQVlA4IGwBAABwCgCdASpQACcAPtFgqU8oJaOiIi0hABoJbADRuY2/T+q8mDs2ZW1vf0rwyD9t/eq0wDeSGcAtMb6aUr9+6d3StYzlRRZl0tGivNg8RMlmoZjjaE4KxYchGpbYAAD+nFPeUdhqGuV+pV1oV7UXZ/8e34wLWfHPj0iQsV7+JHUmDn2QNUI2wlJEE42LjS75RfZwfwrYyAXrtBbfEsSq3ZGx6QfQLQI57sRGlBoulDxgBd4/nPMyWheD0G6vBY5xzw3Idwkykt5gS19VCp2y2v6CB5pdf1h6hMLforHgS9lSe0SfjP2s2zbBWF1l0aQmUzajgEFYSWBKav6YgyKTUbASCqL7J1dr6LpVX4YI/BMHdjQj6Ry04zkolMpkA3Sdpkev0ko8LoFr8kfahLOC1+iheJFyzaIrQ1DLX+bmt50q62/RdmNxjb+Blu8L4uoiUQMEcPvVQ5jQy62K07DbeF9PPDwHXPIGc1AAAAAA" />
|
||||
<img id="flag_burkina_faso" src="data:image/webp;base64, UklGRugAAABXRUJQVlA4INwAAABwBwCdASpQADUAPtFkrVCoJaSioaqJABoJQBq2sD/M9BL8gDP/7It/7YFKQCvNvv4QCrPFfzkMdd+X52cnWbc2GrXbAAD+v499uI7F3Oh79Js5O/J3+WO7sybwlpFTzPALGsGpKr6zb/w7/BZlR9BJ/a/+CzKeqiNUsYVYBOs7TDhB98Ky3dx5OMH0hNSNBtiBhqCOADC5GUc2IUPcjeOlvoKT+9Q7xMP2jE7OCVodyR7a/9xk28aaMz4P7mUfwei5b59dACTEbFjS9dNBJ/znNhQJt9OEEr70AAAA" />
|
||||
<img id="flag_maldives" src="data:image/webp;base64, UklGRg4BAABXRUJQVlA4IAIBAADwCACdASpQADUAPtFgqU2oJiyiJNqssZAaCWQA0MmqfsH4zacnA3bq54DngMgAAYYCdL7WbmUMYYESMvDaQ+CDqLfhCPxeQ2xLLRQF0aXMAAD+4cJKRnPZVPCZAV/uX+5d17OJz/v/TnoZHvj79+MAE7g2mNYvAmBemKQ5b4WQp9eBz/t/zAP0wpaOvZ7jMQTkS/hrv/pXZ27A0DEpuPlE3H3iRgbEyasgwOWWgjyPOesEZRc27QI4fnQlJ3txsaAk9nl8ZtywUU7j+zNh2YgPgUzGsem64eXyUE/+8mXxOuSExmY8KzOpWq7vyi1q+iHSRppFLgAqmP/t5l9QIAAAAAA=" />
|
||||
<img id="flag_new_zealand" src="data:image/webp;base64, UklGRrgCAABXRUJQVlA4IKwCAACwDACdASpQACgAPtFYpk6oJKMiKrZrMQAaCWwAzyVBPS4nyomtj6gPyBvAPMB5QHqi3gD0OfLJ9jqsyN0HgBcIucsPqX7dZXktlVw61+NJorE2dXiLneiuSVf2dLo5LIyvtHdcCLDiCzcobwmeAADOPWjPdibYrKqQbnnduy3Ok50gbwqqtoWS79ZD8U3fvsJOjorGRS44FpDKgNi3P0r+wJXGpy51TcyCIqVt4ti4PNePApAsUG97H9kQahf4GPcRmXKhZRKTsTUkP61uBxNOvRhFN9cRK83+YynbB9SeUf53uyFWT+3GUaxzVtI/f/kL6djdj9vy46PiRj6yDYgrWnyfFQSDT0OeTsyJIulHt4DmGddExUcv0UbwMTrfu8l4QxsFzGxEhR5boTYqSNYMHE+6OoL7Kspqb5mya3V864J5cZnOG8q5XgG2qMT8tqr0SVSGF+++IodYJTrUip0AkNj6GUk6aGH/r1efFswmVNCByHvlXWRVLHbXUmFnXCvpJsTFrvXR/1xNNwvecAOov6kEhsJzB+MR+d4wXTSfH/cPqSNFLBpEQLKsGl7WYReOxj3DLnUt+jYfJOV6yqgc2ES1Mvb/6lLZ7ocxBFBR7AX2xBLi/R+VLHysuw0+p/RXUaynypDhxV5GhSEZ4uW+3uLgpV4T+iU9wO5gs3qZ5eZFiKpbkhloDhYj7x1+is+FueA+o+MT0EighDnps59FPZyiLlx50iEnhFO9NWKM8znJzKAAwYw1j3aXVTBsSyJzXcQdmehxiScKD7PhMlxgM4XpYy/GRLR2UMlae5PA5wojxVkAgZgTCjvNmD39SZnfQAFY3JUEbzAbpQ5182VnhyAlP0+AW+qnlL+j8UEMUAD4ei9j6fwIvy1obqtvSnawGnidbUZM+fmAAAA=" />
|
||||
<img id="flag_tonga" src="data:image/webp;base64, UklGRhABAABXRUJQVlA4IAQBAABQBgCdASpQACcAPtFoqk+oJqOiKJgIAQAaCUAPEESA3gDecQDSw1pIRnaBrJP+O7wrR65qizUVXdXCAAD+9gdsHjKatnM6XCh0Y5rdIytWGXlv1jf4ks7POb/v/tiFwS5WHZf/JmOe1kskwSCfbe2kjGP+JR01VC6p/xuhucmVGpdVBfB+fdd0RLWmlUtptkERO5WfyVuw9ZecSz/OJDkUzpjGn4Q6nliyCVEwN7F8ftmXpZnXU3C8foMfH5ChF8FafH1iO33Ok5kwMCf1yZ53aHgeDJ6oTL91RbVEij+Q+zuH+S7K0dAjczWvF3hblH5BZA8ceT/xT7GcfvPIVd0RbAAAAA==" />
|
||||
<img id="flag_niger" src="data:image/webp;base64, UklGRv4AAABXRUJQVlA4IPIAAABwCACdASpQADsAPtFYp04oMqOiMZLoAlAaCWQA1Lwzegb2dCiUA58ADE3dus3H/Dm5y+Ihaq3JfJna3XBd2Ua//zg2qabKzqTImedgAP7qKv//mCfIPnzQb/9wLKcYbI61NW6LS8CBd+f1vsAsfW+o5Uh38XsSIbgUKxuvk4zPGKQJEc3qBhmrESn/2u1axgKLLlRDtxd14/DrEiDU8R7mEituNofsHZtevOqFaILntYq01OZx0Gz5wuuDX7DtaLGOtqUW2wWXmRdnQw6DBTzUkncfY/cMNLl0gkW1JwlY05U7NU8ddsfXLR0IYw3mlTAAAA==" />
|
||||
<img id="flag_cameroon" src="data:image/webp;base64, UklGRvIAAABXRUJQVlA4IOYAAACQBgCdASpQADMAPtFkqVCoJaOioawxABoJYgB5yfXGOAZYABS+VskdeY4h0Pf3DcMTAmNeOTQs8iz1srwAAP2McSM+P+aLVY//+LQzD2866usfYm8+n6H9mbDszOs6XixIofmGw//COlI766C/8I6S8axKZvW/Q4JiICwMUjeaJlHb7yR+5ZdS+kfrh5qyIWwuKvqACHe0wk+rC2cthVRTQ1F6T9z/RPdIDHOzLf9fs2hTXpM8Scupav+82VH2K7ddAIcR1gm3CyK3p+apdblT9Rrz6tLO7cDkoUoj0ABEmo+vXgAAAA==" />
|
||||
<img id="flag_norway" src="data:image/webp;base64, UklGRpoBAABXRUJQVlA4II4BAAAQDACdASpQADcAPsFUoUunpSMht/VYAPAYCWgAeAfwD8jfyO+UqoPw38W5SHyoY9P8BogP4B6APtm918lgAgHh7aV18KKZDwI07EsTZjADVYy0julRuJ1CRZunlXdCJpT4gNtjtpdc4AAA/uUK//+Kz2yOv//+kU/w3IIr8A7UwECz1xNq4n+eOnbZJSt/hFSYlMorL15LquXnBZdS5/nBgqZ42LkNr3xPM72Mx/yy+P0Avw0+G+M+ftA1AbnToVLGwrP+ngAP1+R6dY/k2S/GLoQ/t47ZPxHbGr1YEEaqhHbt2vkHyNf6jdzKejtxox6y/PRREyzsSWcWVKZSMD9x5nQw/Uu/ALd3r1iaTRRXKv+PElMtQ26BIeP7SAReX9gMnvgEtAETkGVD+2nh15MVop7F5l3DzQ6j19mzjLlCppfazMDo7hJjJ+qQtUvQStEk1ZOf6dSLFKmALILwF56EYqX6+/teKsgC19mxRy4vj+m1gJeZvVBj3zy0cKDjCf+igCxsYXPs3JmbKAAAAA==" />
|
||||
<img id="flag_saudi_arabia" src="data:image/webp;base64, UklGRhQCAABXRUJQVlA4IAgCAABQCwCdASpQADUAPtFgp08oJaMiJMw5ABoJYwAu/9S66gRwK4CVaOufO9592b56mJMPl56FERp4QT9i5RnQvPe/kF+rE8dGk+ckEctcw/eOansBYeltX4m+g/pxik4ZYxP/iAAA/uVJgU3//wrX9aH9GGX5MblywEKv8RX8WJ1r1tW0Qzk2QOEsZIdCl+0yqbBvGZU2gQFWi8kgBVWwpd7i0wHQ6xC/rjs99z8/bj0rCV1Y0Dc8FJmLAU5CitzRSKlcR+cc75lLF1NwAQXf+5tYGwB9CZBFKhUiGuHRZlGpxLxbnSteebVB+SM4dCqvfnJggTGwfCU0hRiPzjPbuY5ldAWczdYGkkvLn9/HoAfDs7DssysB3htJgirocqi/0CRFn29Ah2bvOFFwyIBJXIWuNAkJue7bREPGjcI29q1LvJcKdKdSpY046/cuCs0aaqlu8p6fUvPZZfxCq782vtXIsozz2rhpULBAmCwEcewgGgHgweJfSj0K/dqlT2L81DYjCvPD0kLOmos0fuxzQEAf01idj2s3WAnGP1S2PY/4h2+PR2irKoPhVoCRpfq6BXPVtBHSKcxxQZE/U/df1VI1FpCk93K45NAkQbPWQlJzuiCLU9o3ERjhkQ4OSccJb1rwUvWfv7Tv59gvHccp1V7zMyfdvozZ6L+hGvQDobpILBOPPU/8gAAA" />
|
||||
<img id="flag_finland" src="data:image/webp;base64, UklGRuQAAABXRUJQVlA4INgAAABQCACdASpQAC8APtFYpEuoJSOhszOZWQAaCWQAlQNUGezwB2ATP/0Of4ACY9PC+rr3tYkgYWDBqc0NbC5WWw70ji/5Jdnqdiy3RsAA/vhPJf+OfKDClM7UwTCZUkKTABsXKnHj4AOmF00UNVZ0vflCoo6/wNMqF/cOgV5ZC0V5ZGEwR8l54BkPsIE63i2I93d1cq3da3h+Lp+rzL5FNeVrwUlBXm0TvllYN9bSWVV0yISsthimWxowpnwWD0+RDmlDoq+S17RExDv3K91TCFtB01aisV4AAAA=" />
|
||||
<img id="flag_israel" src="data:image/webp;base64, UklGRrQBAABXRUJQVlA4IKgBAACwCgCdASpQADoAPtFWpUyoJKOiJngO+QAaCWQA07mJX6vcO9VeFgIAlYfpnzfMPOkBLY6P7dWTpUymU9vHitB/RtlBssCt5OGST7AVBPojVYfjrPwN2+O7PVUKeG/QAP77KuebF5NSTm7JnPK9KBq+x+/AX2J3kgwPYTod4hQmg7HKb5NcB4+fbnjZeCNWoEuShyRqXQmUKVF9AVyz8e2AXHQfs/b2pziDwtIIPyXnzMFYND1qWjkIf7EVmMc97piFO9KLMvkNyru+536/v9Nt8fAqPdGO5DQ8olrbCgNk1RlVr3cfdC/rR0klxI2e8rmicjZfg1olmCFQSGQALhyeV9ypJcapgbkThHWaQhVJ6gvfvMN+1s500vVWYuNeF/ft4ObtPwAcEgbtBscTWhLG9khRsgDZRLRFktGqA+1Y2nc06zqq1U7qKEXFjb9zrRm0mBm2NC7Hx51yz+XvCPhJcxMCW+X2kcXDgRfXC/losAo0wti2sPslmEjyameqNYtFiFLhZfjMzz5Q18aPPUpYLcC8ZH+XJv/kGB+T1+Omj4F1S5YAAAAA" />
|
||||
<img id="flag_afghanistan" src="data:image/webp;base64, UklGRrQBAABXRUJQVlA4IKgBAADQCgCdASpQACcAPtFeqU+oJKOiJnVbUQAaCWoXgAF9YjBCo5h9AG2A53rnQPVP9U3eaDaM0gTPKiTMXoPPqsjghfZ9uvYQnkHaLyahJ3Aj9LduWYNS3kI8ybAS2WYzgAD++l0BkjP+WgDD/xJRVIr0OAp7zDpTn1FOvT073/71hs5FkDT//47fHA6svQrrohxKsCjVSzxa/kd6tb75cfZKaBZrb1xfJiYxnKv8fN7068kFskKRt4NeaY60aElHiY2tBxpKlm0l2kZenCA//1oi+/zN/7dnL/nqbci3xc/7dL3gxY5VfZANTSCJjkYFzWW1UmesjQM2u5fMg1feiJ78jRziXt+ZuUE7Sk+tmgJ6vSp/GJ27o3HNV1X+QfSzJaYvYMmQBvA/918rCg6KR/wFJv8MsaX91wngynWMLOxorTwWIy61/Aah9K+C/17rYKHFzW3IVWB4hhMvmwpoWFxAWp/SCMbRxnFCffIMrsJQdr5Ci06sz0TnFVfEDPSSLXuV59EWtv4MFURufVbnDP08/ofYqhjK+MijQmYD65XS7Isk3kSwAAAA" />
|
||||
<img id="flag_myanmar" src="data:image/webp;base64, UklGRvgBAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCCyAQAAUAwAnQEqUAA1AD7RXqhNqCUkIim1W2kAGglmANFBwMAP7T+M35AdXrvv45eoDOAfrd6//RAaWh7Pq/AHcuTmEbeSlPeZPGKP9eHhbcBzqBOs9D4VqEeU9URt7DBoJSGAggaTCn+yscMwbQQA/u89b/1lY2rR6YftJ98AmPue9oOpuYCxtOfmBkV1ke84/4cLmVu7x9x8pYeOqwQaPWjvA0rx6GlkqWBn9EaU+fEckheEgW7x3hIGOKOnzeXaRHEARVFtg1ZfChfFfxDEu2SIacBe4Qs5l1/QfXC/w2Ja++D5fXVwAVLhQlU5+e0u3PbbB8oVbpNkEJkOPfwLrLRybn2N0PMhTf5RinnQz6rau76VQUV5hsfwfpK0wDl9zm3Nnl+krJNof/NoeC20Twbeu9Sp0cS/+yfv2Pf6wVmwD10l/Exsr3FROUkcZOuHNGqgZAGFMlv3N5UY7Eb1qpKzxUKY6ufUAKfz+nX6PldRn0nHe1ktxnudvcnu+VgE0v8qMlT9vNUrGbLxYBLumFzp2AF5ItL3te4/7ZArMfWNm1it4jLDIpmu51kipakw8qIAAAA=" />
|
||||
<img id="flag_spain" src="data:image/webp;base64, UklGRpAAAABXRUJQVlA4IIQAAAAQBgCdASpQADQAPtFWo0uoJKMhsAgBABoJQA7AH4qs3/AeSASMsCPK8sMrPph3yPaI/QUZSmC3igAA/gxLebKx5EP/8a3rT1s1Qe6rkWDX//zNF1OW9Cf/IF/PFE3WrV2r1UwFaFRnX7BGlS110zHSYTODBH3NP50JiyuHGtm8qWiAAAA=" />
|
||||
<img id="flag_san_marino" src="data:image/webp;base64, UklGRnIAAABXRUJQVlA4IGYAAAAwBQCdASpQADwAPtFipE6oJaMiKb1YkQAaCWcALv/AkJyckElZxRiiZ3ia3J6MUkj2oAD+84BXXmig36sAYhz3vCT3vIfrY/D4/Hlvy0sX+cB8ynmVJOhJmcoiqKdvPyw0SQAAAAA=" />
|
||||
<img id="flag_luxembourg" src="data:image/webp;base64, UklGRmwAAABXRUJQVlA4IGAAAADQBACdASpQAC8APrlMnUunJKKht2gA4BcJYgCVA/gGkFcAAYHkM8E2Olft1cRvRgD+34A5gfm1y/89M9beP/Ly1KVbXxM/494OMEKUNtV61FghTr5qmEzPr8U7YUAAAAA=" />
|
||||
<img id="flag_kiribati" src="data:image/webp;base64, UklGRuoDAABXRUJQVlA4IN4DAABQEgCdASpQAC4APr1QnEunJSKht3dMAOAXiWwArDPagC7Sfxm6zYreqBoh6mPyBvafMr59Hom/719Bz53mLDxJV8QO8HaN/vu9tce/pfEPpApovj+4jerZki0JfzWaPLK18UP/XGP6A0xMg/XE0S3sNtjEVJrSOfjGzsHt5SbK2C+YvyALcBd19XOqnNgMdG6eramAV4/XCVJugAD+7CZf/hWNhAGhn/+5wLv1Nv6naAI0sCsaRnG++turzbXblzfXOr743ghqKkIOY/YPoWc8OgfiyGd3nUc/nXGc7iNgbMszb84XJY3tdVC1hy8o2twe12kFnpSQuQR4EHL7dvqwd1rbqG/6qQuhRPi421/ULN8HFG7jWUi7LlUyq3iFM/q+y9QBGEya7J1J6P48/8TrQ9qdv1UGH7qah43Xgm0w94i7reHerHwZ5iV6uSGBZtpiL2V5tzN1KzqhVAIi8ivfGGmPJmVaBm+NxVyQf5t4fONUIrLUZ3Wvf7NI5fpN964dNgHYlSED/D2OrFeOkcpHv/0sjbgGoj3Uv/ovA5eNtPOmdkbqIjr6HJej1nBHy9rs/GhcsQSU4RuuwszBAcRHzLzoFrhEQM/o3YK6KG1vUFkMMTc1M7I9F8uQ6qno+EZ3IjvzFyaI3lujTqPYwI63dYd7dEGth5PdZC4nEyBcTJ5kKmk+CLa81esoAM44ZqhKIJuROOQa8Ax6jQEW2cSQZnJPyaLjdw/ImpJie1nb8eCE04M9XJ9hUGArmkW7sRdJVIb49yWpRLCPA7+AklHl5lYffEq0aadnvxQCcwGO5x2xL3ixDwccQeIGSoaas1XVLHFB1+YRPwz+ZyxdqpeadkiIhN9SBjxOzFMxRcqcf3VZasVj3rxQgQH1g4Bfmx1nV+1x8t6Oiii8Ia5wsASz7qrb/QjoM6k821bJd6c454F+8PJUjfQkhPDdPTj2WkA/Axk65FfFEK7TTsgZpTf/NVCDyy1knyLpxsPf1qXMv4w3P9UIHW/ZTnrEUmVfuMrIK2Y1nt/0geS0SA+87wYaFrznm37/k8uSh32CeGaF39TRnPrLTuC6d7pqoHUuWcoGFzAzn/J7jlifaKAabMejH0UNQ9cAyvhRwJEDuwcRLolPlP2P3aUZsa7QmoZQPweA2qLuXfOGd/TmTcftk8GxGuId2J0OHYq75KHPuC6mA/L1L8ov839FXmSVqpeR4UX5xal3887Imo45y/2p/ae5usMCpFnYN/IIQ+CXLXXMudUSVmjNkNAyvcFRWImgTW1qAQv2dNOpOiMZf/YHcZWhLT0pi/JvJrfnJAAAAAA=" />
|
||||
<img id="flag_turkmenistan" src="data:image/webp;base64, UklGRpABAABXRUJQVlA4IIQBAACQCACdASpQACcAPtFgqU+oJSOiKJgIuQAaCWQAPknLKu80I0EI7rJRJUR077UAJaAxWXZgxSbmaoB3kDsvR5BdJVrLvku8ruO0p1E3AAD+0Aje6+eNXJkLZi8Dds6TsmMIi6MZg+chV+/5/mW3q7T8lkupyrI9wh3GeuF1OyA92VjucXihGkir/368tdnc/KNVT5rNX2SjVyq98EWO3QqDgBE05lzysQ1NWIgcAyEbzW9YjAqkFEOfW+IukQnudkFVSR//CJeYyf/ZldJsFJ3tRa+L+FrdXg5gLt9ViVM/UyB+5WyBfHfcPzt8SohZ7aVLHzQrTYDofaDoyFBzo1WR12H3nsGs9H++qtD3pvGwHWIxanarATWP1+g4tlEOV1ISx/dPzZu5ByGdyWmtqdOlMttFiSVU0+S02TgHfmAVNW/nHbozsq8cPz9VsnSST9xhEe9eiBvIjuuj7fmws/p5Fcgi7cgT+GASqAd+TAugHBcToAs2A8ElerkhY4qwkOJIAAAA" />
|
||||
<img id="flag_costa_rica" src="data:image/webp;base64, UklGRogAAABXRUJQVlA4IHwAAADwBQCdASpQAC8APr1MoEunJKOht2gA4BeJaB9BUgDBZ4E+AatjwABhujn50X5+eH9j2LYzaQNwgAD+5LN//7tX40Id8Of/tAmmCCft36CBlsGRaNmWKf/FWBfxLzVz6PxwtLDziXsD7l97SYA9fitD/XcTGT+vf9QAAAAA" />
|
||||
<img id="flag_andorra" src="data:image/webp;base64, UklGRm4BAABXRUJQVlA4IGIBAACQCgCdASpQADUAPtFaq08oJKQiKBM7MQAaCUASueevvF5wJn/zpl91YoLLi0qVksfSbhDdI1kgOnRcB3MvJ5vnFbRx54u4BMdupQUO+EL9UeEUjqhVdQUtE/tOjYAA/vCFxNsQhUh/FuiWpn+HOyF3tJyLOx3VrZtwf+GZHX3v7+GZHWxV0E3PUPZUQpytsqf30+MRagnQJWdLl1937986+yMuanh7/FGX0rmOLtz+Geq27cCOpGL4/vPEBFQIjU0n/kxPA2Wx71NKPo6cKMhLCEFFPr4mTGxxJzQRGwUKKKXAZjRfl+H8ww4EfG6HCx81HqpTWj6G+cfl9ftVIgQjEAynjRhnEnf672ZMGzEQ00Zmvnth2Tv3CNR9jrVxefBWM23HZ9WPfmNFdDzavcSJWmRHlw6YmJkRyUL7J4i+PxQZ+I9SujEf3MfoJtD8H1xt+bWnB5Q3aO8Jt1qZEQAAAAA=" />
|
||||
<img id="flag_iran" src="data:image/webp;base64, UklGRpQBAABXRUJQVlA4IIgBAAAQCQCdASpQACwAPtFoqVIoJaOioiiRABoJaj734HVVkDwiy8A1BfuzjwG6DKBOhm5Yb/8iIzW87F2IRfxuKAzXZGiON0zUzZh48+bzbmASfxgA/rhrv6CBgImlmn/MwtaQaMgxJxbtjKUT/zBPkHIToEsh9fiYw3/kaesVvnPOWdKyZ1fvsd2+ay18Ye1ze/JV5KJHKR/rHUvXr1Lsq69+dPofArL8RIIvCjb61lkzidELniu3K1eXE/4Q1k9Xfug2CX4UXD8XoYDKjMOW/kUF6Y/KV8FYXR2lWGRKXSWn1mnCsyTLHLCBcOEGw0+RUrYzEnAqSBCyLPdnUnzKvBwG017McjjVKiIDeghtXwr8Z8mBBLm/00TTVtl0kXXclTXWx3cgs1knR2LiYzfc1ssQ7CtTcFT5rDQ11ro0iN36wqM3KtIjmi1mKOoxe77uBlRjLsi4sH4zZYoIBGwe9FtlU02ycX22onXc2OKwcTlI9Zdb+u7aQFDsliWAPF4F84BWCKbDuAAAAA==" />
|
||||
<img id="flag_jordan" src="data:image/webp;base64, UklGRmYBAABXRUJQVlA4IFoBAADwCQCdASpQACgAPtFWpUuoJKOhrvSc+QAaCWYAlQP4BpUnZIkB4gG4A/Xfe/8kz8h0mXh4HSG1J8uerItgImYdJD74BWCYJsiUVG+/jTsatCQt4JPJ7hgAAP7mT5Fis+qw2Pv1+Jl00MVGOXLaZP12mWeXfhTIf5y6bwUC5uN+6PY/+rQ/bvAVE9NCk9PBex+z1tMgZE6saZO+QEqwqTdSHJWuQzuqteDlRRBe5vUFbtkVgx7fUpNXag+KsvOL7bj//o/M8/qe3kG7oqP8Yyz3AajlFjgi7Bn7dw8E/L/yR+VvKz9KhKbUjv+l5AGJhimJlfmbc+LcV+4U1SAkINDPh7RBx8IMnEcGRu2qS4SUExhP/ucKibvJzE9kvoeN7vctHeKIV1n6te6H80XQaOzjmci4xgF/2Fix/rnZbGH/NEX18ZdSoLbyh/WixpdX6zP+uaY4tTptAAAA" />
|
||||
<img id="flag_anguilla" src="data:image/webp;base64, UklGRoYCAABXRUJQVlA4IHoCAAAwDQCdASpQACcAPtFaqE0oJSQiKrZsAQAaCWwAhMVaSwbZJob1AflXej+YDHOd5Vrss7EYe9AnO49Jgr1fo/qr4rvxtu3AcXtCzybZkpD0Q05fqxBD3heeEXTnhNMeHn9Brtm7k/3lURZat/Td3pznAAAA9q9ps51JjQ8ok3YjvS0CcEcBD9Aq4zIUKANEUfeP1Xg3rAKl/Xg55b11YvKOzQtfu24hmcPLXGQryl9WuiwWO+GmOaCb3WgCUDty0xGzuzGBK4ci9DrdxdPz8EJADCp/WbZMk+dln7kWyP44X4AEFgz3+B/W8pNXuvwz0aB2JxcUgPjofTa8VC7v7vXYi5imGJVoctRD1YNB1bRbf7o0wUq6Q8FAAdqV76rLmcjn6ahaaA8fe2UxyAsoCcEipSnooF6rPFSIpOtKxCpZ+DbPybBrjqErXdQX759/GOxuP/W/uNcG0/bVyd03Be6bVRqnrI2MFVFwZLL7OHed+yY0D1MSFcymM7iAdbvk51F1CL7DhPOhTwhCQFoKSsdWOUOGJx7MoWVgAXriooeaZfUPD8FVFZw3Xbbd9cYPIe7Bea2QCO9YQBjPMEjuR5DIVSCATtO2Lym3jfw89wWLi6xiH2LAY28rXYqyS47IF5B3tP3/i7606+nzz2UBW0x7UAvHls3tP35O/CLcYuX33BypPbBn9DRLZu5QDe4/ZLt9k3g8rmJyui+vv/6uozw7f5C9tVtVKQFxpnz7x5VlRhtUTJ3BHPZpctJWWeBfGeGzkEJ6pJiGO+3Bq9zNgrW8hfNbU64OpDmMXkUO/ItwFVjyx6n2yHjCaEGHQ5Hct+hjRK8TjAAAAAAA" />
|
||||
<img id="flag_czech_republic" src="data:image/webp;base64, UklGRjYBAABXRUJQVlA4ICoBAAAQCgCdASpQADQAPtFiqU4oKiQiKzSZ2UAaCWQA0X2W/t2t9JJ+2dUA8QDpAeYDn//Sq6gDeKPKAJmsEn+YbF1iWqR2MyBPH+45Z7tWlkd9pIhnRgzIhAgAAAD5cNhzuNOSOCEB6QSnxMaL9w4S0sWZ+/SdfdeCPQrq9kPrKzwMNM9noksGuVLg3bzwJVABt9E0OJpbiOTiOpO05ZOd5I++46AjnpUTdAoAsdiYojaUyNIIHOvNxdxmbUnDQCwvi26cqv89e65uOL/q59dQkiFSvUd42E2O5mX+mRyR31FZnmtTO8Wn5zReqkqD2HmJZD9IPPfAY/zFv7It3gzrOKj1PlCZd1jGklyG0WeUTqf/YUUN0sCdRbj6p/7Q6zWF9781n/2MWBQAAAAA" />
|
||||
<img id="flag_isleof_man" src="data:image/webp;base64, UklGRmIBAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCAcAQAAEAgAnQEqUAAoAD7RXKlQKCSjoqRYC7EAGgliANLljQQBdgG8iFeB73nOQLwazg3Vv4QEYR0R1Y5gYL/RfDvsPdDo9HAHMPtXIAD+7kMb9vzNl3/z0z/7l/+tvUbmDN7ewmQEcnByAj85BjBjBzhmyfmY+mHpD/e8diBY6o7y0h59K2g5+A4y9feZeGSKl1GLFEsLLtT4VvddiF9QWEJsV21olYepyTDN+CDbGz85PbdtW2fOZXUteX3hsi20GgCCQFnQgWW9KL76NjP9nsp/hErfGui090s68AJb0uR2axkCkbXozkFwiYs996Es5Hxzv/xdU4hUXP4co65ZMjRFbSkIjmC42bIKxLjsVIq3hK/LlkWEmGZNxUAAAAA=" />
|
||||
<img id="flag_bangladesh" src="data:image/webp;base64, UklGRvIAAABXRUJQVlA4IOYAAACQCQCdASpQAC8APsVSoUunpKMhsygA8BiJZgDRBQA1qPpOB1SY0Kr+AcAB5WvsgfYB7AGrglY6m+mafP9CbhrVViXYBXEVPsfaDhR/ZjZP3VNVOykAAP7uP+8VMF1Jy+J0un+Fu/fBuS9julN1hfDNSvc8B8OuJL8D6v57ObQGlTx4LQO9Vm2C5K0iZ6mix8NlR29J76Lb0/QgmVXiwxYRz6kfoypNv8Ld4BS5us2pwfW1Za79W1+XmYn/PY6/Eau9SCEWHsp32fd/zGPzhoqdD/M4DsJtTGDOXrB9F5IxBZE7WWQAAA==" />
|
||||
<img id="flag_curacao" src="data:image/webp;base64, UklGRhABAABXRUJQVlA4IAQBAABwBwCdASpQADUAPtFeqk+oJKQiKzJJOQAaCUAPEAZQSFe58TOZDggtETR2PUMQm9fLqbuDpjxLm0uD2gCI+ap+CjiYgAD+7pT9htkpBRP/xa7Y8MM/JXdMwbFCQ6COPwHB05LA8bAPQ8YJvHUPCoDfjcc065uQHFTnD/7U5KwGZ7djrbjTv7zf6dr2O76+523X9WdpaPZonQGs9U+nkbqKpWN2oUYHbRosC6z0CvwhuGB+NhRDOPJbpEcErGTaJ6zeLbp56OnqJ6h8jz/7RBXNB0JFRJNTWsLuwGCfux5yHmAzvwertft//9jfYz+xxuv/o32M/scXtZEn8wQom5QKCAAAAA==" />
|
||||
<img id="flag_south_sudan" src="data:image/webp;base64, UklGRmQBAABXRUJQVlA4IFgBAAAwCQCdASpQADQAPtFaqU+oJKOiJnQMAQAaCWgAeY0jnglmAeYDzqvQBvAG8sAv5HwlvzIRLPM5CixN9u0V/cAzJPo3kJZctYWthgT+M6AEs/mgAP72y0LPrfR6/9qg6N/EFNH+57V3VHkj3yrly6D8iRUrS7yqasWkI1VH+yfq9gR2rQB3u8cRGCmMlDl4r1NWPMGzCtApS+QMOwDbHONPcZj+KkKmKB7OvxQccEE5fncQVmNHww1zVevQ6g9rvs8mdoxWpBOdris5OCj4oOXM3Gh/OpPNk09SP7b+RJ2s6b5VZf5sFy0/fYS7uIeFXJwtYiFtJT578MtNey4kCYl+bYFiKs+ER7Eeq7brMjrheO1nSgOfm8PU20PP/Fc99PscmK3xY4TxCSlMkoj+GCu6GDtF1EBFk6Vr56O3vwfe3GPVHA3PSb/a1H2R4YqMZNes5TxxmAAAAA==" />
|
||||
<img id="flag_malta" src="data:image/webp;base64, UklGRr4AAABXRUJQVlA4ILIAAACwBgCdASpQADUAPtFgq1AoJSOjKBM5EQAaCWUAA+Q4NcBD3yLcAPr0LbfGffUfftAoo4NEqE0mtZjhBJjc0AD+9gmy1QkvP3p2nS+87YvwWU4k11j82K/bZZV2ST7/Cfxet0ilXRg0uHXFcm+J2pK+cfU75rZYMGq3daOe2lFfXX1mlGGEHCpGKn/+tXxzAHp//iZea+2U5KEzjfgnM9Pjr5R0AaZd630KQ9cq7U9RdgAA" />
|
||||
<img id="flag_bahrain" src="data:image/webp;base64, UklGRgwBAABXRUJQVlA4IAABAADQBgCdASpQAC0APtFkq1AoJaQipmipABoJYwB4T/dJb/tAPwAsgDeSQMhTZCtnHlluGjNs4lcLw/yajvaKRgAA/vXO13rU5NhkHKb+I5pwNhQPiWViT3bsIYLZ+hu8MWM8iKBmAFKf/cp0sw9k3CVqKTm//+DXbYFj/i1D/oEX26TsP3H9h9DWj+sYGrTs7OxeNZRkSFGj77VwD/N9NvrSOzBCR9uxlC4ueMNg9489lgrRqm9gIAlaC0/dLzGvs9EatkJILe5TPtz1o9ihQ/cj7ym9yVBYX2BRyJMKrI4GlGVXtATb85NTwgKcKOS+U3sZ70D+vnSqjjD1KZzagAAA" />
|
||||
<img id="flag_tibet" src="data:image/webp;base64, UklGRm4EAABXRUJQVlA4IGIEAACQGACdASpPADQAPtFYoUuoJSMhsZdKqQAaCWwAxy1BWf33fQvyG9kqw/1/8ScfgWLtA/eeb3+4ewj8a/5z3AP0e/zP8r6yP7AeoD9cv+Z/mffS9I3/V9QD/Hf8D0OfYN9ADyuP3M+Dj9vv3F9pdomzvUAHubfUFtgRcIROAY0hknVfHw5U8/y/q8MX5eZwzH76TqrUjJepouHJjd0ETIB0ETp7LPotfT/A65a0qR3+bDu3FS9MybmpGuG8J3X4Ro8k6qU7Omi/YDpUbn4AAP7zfnZJ+bMXEEs/wc6zj/m24HN6TPXpRydQu/wc1nYuSVwC4Y6/CdBI+OA0flOF0C+Fh3HeZPMHitrlML+8Xdhr5jTL9ZzJv8uk8HNlVwqQT9mY6DJSYrxXQvIQSEz27wP1H8PhFAuZWXCkvJxv4IXwNdfHi1olV7SgN/r/gcdQnX/FTBb2I6XiPfxkH/P/qEFLsj+APPA+b2/2SRRvIhlqJwvPyk5VPjKJmbiS/GrKcrmVg/yLHLtHFimuMiSfbCPKZBGnZvk438D1/NWv3y57bvCd3m1y0doIUGTDh01DzwI4m8G80qsgcuOJs0A6JkJR3iy4VzTlfwOessFSAfFrCrIRteWQPm2ctmei4IkhEmZV1SQXk2hmxDbIvckXqdHDN/Oru4va7/5StSONMZsZRBJ83tSU5+ylH4gEvY692Nm2EyUMW4M6/U0IA0L7hmURm7uWHx+KTjc7lvpJlhZqxb8GLJdHHkzoGHzxMyPzPlGC43/0RINyiLo8ijRkjVpQNpQ1vyzhQ4ei7xTzGxaVg9TcnjOgP0iotB/XraeWYlBhkLi3+7q1uIHrJume7JZMh4SThPBBFgX6MrFjJn807I8dzrBRYl65zFrdUKKS2VvsShw+Q/v/xnr28VqkMhnbTNB6Hcoi6GitzFmAdfSO8jiyxDRsvIKYvj6Jb6u+InFYKith/NjO4/0gTzXoNhWIu78EFNn/3F98F+PL+49V2n/LOfy3Oc83O9lpyFW9Ho/EBPiSiDRkf8Ssjfsiiw9NQrRCAmP1XSsu/3VLXUovnT6xvc9j41DjWpoZA9PIFqvj5XM4mRXPlsnOs+HQu6DWQgB2w/20A4/wcQ/t2lDTENaH1oN/BRI7Fe2w3RK5ut7MCYyW0VYA15+DJsUCdjGuAiThUp0uqWj+Tl1AfJiCkpYH5x6xqUdXmvEqnXhInDB1D1+PbPHnGpjjqjRMNwXyhBzJF1HbPelSCf0p3WsK/g6pfrpyxjqRxlQCs+M4jNbexCBKh4GvN7fMEmFabxiEezZaubffnnj2+klYb02fZHyJfFEO19pp4vg+y/wsyA78wXP94WBre9Z1S1ZfRsIrWh2Voo96/sWgxJ9u4WZXBaWi5t+ezFYasMrLuUXnEK0jWbuiINnaM7qYicgRBdHrjN3MXxNBTe53bBLieluHULzj9k2wSsB9YBtig5CwfsUHQm9ULhPT4AA3IBzcA/wAAAA=" />
|
||||
<img id="flag_serbia_and_montenegro" src="data:image/webp;base64, UklGRoQAAABXRUJQVlA4IHgAAAAQBgCdASpQACcAPr1On0unJKKhtUgA4BeJQBK5/wDVrRALf/AoLDgAh2YXCrth1iIqQm2mpyhV8QAA/gxLe9n8lDqJPj/lYGGMpnUbTtc9mFLzlr0TlZ9VJO8NXYl6t/BN//9UifxN//9UfjckA9/WL2usUprCwAA=" />
|
||||
<img id="flag_guatemala" src="data:image/webp;base64, UklGRlQBAABXRUJQVlA4IEgBAABwCACdASpQADEAPtFeqlAoJKQio1gLiQAaCWIA05lBft2uDdVogAcKXqywdxzPCkdQD5ye+8r6trwqgIwqPhpnH9MR08/ROgr5oRhAAP6uFwtzFlkt87B+PfejxH6sOTbAPQw1uWC3wLBd8CuILvhoKSN0zfDKOY9Wl3tevD1Yn9gb4euJRFRklUtuVbu7l7eqaT2JPTlccVXyWSJvXbYidv5GE+A4eI1YRJnguYjS3l7WXt1gxgVfQbK8yCXHCQK7Ff3z5saEGIEx8xm9nT7iBFdy+AYgSyZ4t5Z9C5e34pBEdrsntKvig3+3pjLHaf35KtZOvY68441wcb3me6OEzH1oV5ZhC7znRFSdNjWat7mxTXr2G3TqiAjipCOGJXS00U8qg60QzlOyssAGiTreT8bUjkuAC5ZVc39pnJXo/gufP+iBAAAA" />
|
||||
<img id="flag_north_korea" src="data:image/webp;base64, UklGRoQBAABXRUJQVlA4IHgBAABwCgCdASpQACcAPtForVIoJaQjoiiRABoJbACUANKk7lw1G7rYZ5r9x3HcFA/QD3xbJuRoBYrVurNAe+cPBaL48xvR3NWjxLIvMr50secGejqHWW+s5KWXyN1vMAD+69g8v3/vDBG1qG/jVxMV/yf9l61iUIDz9iViee/xSfkxJnrjawQoWV4bELBCsz7cArcr9xJI3XJeljmuFSXobI7EDe+kNVt0HPzBnnnPfhm119zHfIbEcONHo49OvaTBo/2tC+fqMoVo0BN79LThNQWb1yt24U/68P907rZWbdRxeBiMjfemGPNRxMY5oUuFm+nq7UHzl9dfEUJ4WMt9N90Sw+4+45EWDGChYZXzNpgtuUIWNQuy2HPMrWDmVJq+/Ya3xfbm1/H0rVx5OL5BK3vrImB8/EDwN/mXLBmXXdLVRYpfByuNnJsEO9zGRzOBMHj8+e63oz7iXktY7j2rIEono73gONf2ZBoVGz41r55ABLOJAB7haWAA" />
|
||||
<img id="flag_saint_martin" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADUAPtFYpUwoJSOiLmgBABoJQBq+MDe4AbAdKqlNAmgSOnGTFnYkYtvO2JEAAP7wG9/q7wo3slfv2/vnSv8Hv17zbJ/qV2ep3Zk+k4daqgOdHBZnLlmOd3s/Zf32WwTjIWr013Cz8AAAAAAAAA==" />
|
||||
<img id="flag_sri_lanka" src="data:image/webp;base64, UklGRjgDAABXRUJQVlA4ICwDAADwEQCdASpQACYAPtFcoE0oJSKiLNgMcQAaCWwAwQ+J72dd/Y75O2z5E/13nV/Sv3GbafzAfpx6vX+S9QG8FehF+xnlAfDF/h/OkzQB9A7M4xpVi3YzWmpd+BN5EY4WgrDYySRHmRDQ0K95Pj+JchFyW/t4a3qqaxv3a8v5ndgvgWXVeZkpJqXwcI0ZTaw166doAYHvt1a6oAD+yKRDxtRhbCyStjrB0PSUB4//P+NDiSS/e00XnRrKx2z49MWm9+8zk6RMc00fUEOE9Nk6pHTMFrrXj1vEGlx9vIT2PvsO6BvJWxOuhzVJ1xX+i6fjn+DFw+ycTvdEy+6uPu6FRFWFf+J1DLaXvjoOqoEURej3JOIQs/6+Oy4Uwz64KxrMloQCkVQLxE6QSIG98/nRNXeJubm5/R/XWbBG0ng4h+659w8Ky9R+N7hR+afaECVpj6W2xK1bbBxf5PNmAGBeoh/xotXOMYk95t5gkNJKBSeILtKAYD8ROIG+FtlBxsQMcq2OM6jYcvOoazohgOUkeOGpuWBTL3PE6ePg5RYHvq3VUEWqeVqbvjT73sFei3K1nnwZ5I/bKvOq59J6TFaM0ey22YXiWSHriHrQCZlZ10DiY4NC++SrSulO8priALYwX4/x/E5d8IXiiuFNb6qJS6aj25MemxYpGRfFhH4Xm7sjvAYrYdmA46JyXzP2YWxKaydWMCslQ3o763DhS2ZcSbjS6da9XIt5Bmz48AhzCC4whFIiHEj1kejVc5AGfAHPVKvlw2wcnXj97Os7SVatqAr/B7eXUqzM++FWnenmHaLpV2SeBjE+jv9gDFJD2CNGmPHlUrQ+WMGqEtDj1UdQdXU9LdPeOsrC9djXuR3RGM4FoqKxdTC0MkqoL2mPZR38+TyXXj6b+MlTBay3pRU/3LX/0hD9vKWwfmTsRhz3Gamoy5vqF7XJvnHhdwB6S/i74pZR416oHDWnzYqDe2xXj1u1YjJPwOx6ATI/4IPlI4PSiJIPOkiELKkzgQQLM7hsBqgdBBlYVF3WZDJ3MjO6dyuuPp4g9ja7PnfxCppGYH4q2bFc1aQLjMBfiLwAAA==" />
|
||||
<img id="flag_new_caledonia" src="data:image/webp;base64, UklGRoQAAABXRUJQVlA4IHgAAACwBQCdASpQADUAPtFYpUyoJSOiLmgBABoJQBq+MDe4AbAdKEW1Q97vjwo+coVXYk0J90+NjwAA/vAb3+rvCjeyV+/b++fyJ3drbJ196wj6815/+Gflj43TDxOhuzHxwYkV51lesfvNIr+QfmFNJhZvCWoKCwAAAAA=" />
|
||||
<img id="flag_south_georgia" src="data:image/webp;base64, UklGRqACAABXRUJQVlA4IJQCAADwDQCdASpQACcAPtFap0woJSOiKrmcAQAaCWwA0m1BOt/vPEO8INhcx/UBtk/MB5Lv7Ae5r/Ob416AHlueyA+XDGyxz4i6E5MNVcmvvNEPVEhSwe19AXiLzjZScxl0MafGaXmgytczVSYgRct5rBcKNMm/UxCD+AAA4mx494r88v8pD3Zq5eGIcOBY+/EdhzUP7+odGWRSRTWDLLQpxpPqAAtQq9PnYyt32nPE0Ar140APN3iz/3p5JCSduv0OjkMJLm0LJXs0BUJ+FvfODNpQQlzXLRZkzCaRt+edO8REFhSzY+2ge+d7tXN2+i/KMjWGT4P6lM1XCXdPFw71NQnaWSHYHaf3vOpn9HBce4GnZtOCHPxsnEAV6/hLzrSS3y7Xzb1w1lrchDi2J6AKDfytOSQTHeRP3yH0+UUltxuDMKhpED5ItHhxD9MaZS1pEItOc7x0Yh8250exN+2l4TGka2aaoLfAoIJWwhe6ZC7lRRAr+D8R9LosjppUkGJqEizo6FDkDHXeShvt+821MEP/f4o8lnUVr8AuzKMU/nLQLP/i3owBJYJNf2/CwsTrSFrGkE4fHPPHiE+0ePa35/63/VyL/jY2/32v5lXMjoGDQGXgawVdeOZL4XW/4hyr1Oagf2/6qsVRkSbsCgHJn/FbyBOlJB9sjI0eOlZiCdrhrV/r/rD8+1C2YBHYFS0oApxr7XJ3ENAT2CTrNGqzGiBkb6wigI98qOnyiz1rtWct9Ox8v4cwS7ZXI/c8I0Qsh10k8TutJQoMjYY2VE+ouLCue8Ssw9fTzSc/4SKTW8UO22aKiatwOYNGdk85nW9FIC3NJzaEbFmfSWuCq3gf1nAPARtHE27S4Avlno/FBDFAZUAAAAA=" />
|
||||
<img id="flag_guinea_bissau" src="data:image/webp;base64, UklGRvoAAABXRUJQVlA4IO4AAADQBgCdASpQACcAPtFaqE4oJKQiLvSZAQAaCWQAdjlPQG8tAeb+AxnpXCEU8kAY/Q/hS88UVoXNxH5GgplkoiAA/r+PgXKCcECj2v/9bZr0jdlAIZ///SbP/E2f+Js+F4reeuF+R1r2vac/5u45bvzSLfzMskzqGvpPP9Kh2hv/Oiom9SbO6wArh3am9BDwQf/QMttg/667XyY35abWTp/mj3RelJnoR/Q3rsFR1SdBi7HscuAUOZoipYYLDyfXiwRolWbfFeKFV/R6P4etUwanFwPc5xQsOmMhGfPhhBVzvNZmVTwIvixFvSiFAAAA" />
|
||||
<img id="flag_peru" src="data:image/webp;base64, UklGRqQAAABXRUJQVlA4IJgAAABQBwCdASpPADQAPtFgpEyoJiOiLn44AQAaCUAatqgvyvWKuNUQDZ/2VnmjOyZGhhbKH3yaxyEXXUtjamniuZFPzrggAP7fgAnnsmSr5xL5I9Au6z9vq395jLyvtcz6v4atg9P/wTDQIL4//BtrN18B5SeLTjgFRGbTtEvAf8G/fAw2t/g39hnSUay559M+ulmaCQADHEuAAA==" />
|
||||
<img id="flag_liechtenstein" src="data:image/webp;base64, UklGRgwBAABXRUJQVlA4IAABAACwBwCdASpQAC8APtFeqE4oJSQiLvSYAQAaCWIAlQNNn7ofi+jQQimsrUIfONL2r6HlyupXcRYIHYnqj8qCTSnkI9mZVYgAAP7ucjKb5/k2Qtbugvs5IOZJ/9qPW9DH/DmELCLZ9zreN+C2+LaqyD+ROl6wKlbUraYApj4ckQTsHp7Xtu6QpUV72e8n5sbSdOH1e7NwmtDH4/OK+8S8Srsceonvvf2CnNaPMZA+Oip8vVAF1jx/uko+Au/r+eYInrIZ91PLP4/8gHytba5BG+JqH1H4w3tE79T2jJhuEvS3JRVOGNX5lHTDShij+d6aADkYASEyB2N7sBmQzTr4sPAA" />
|
||||
<img id="flag_british_indian_ocean_territory" src="data:image/webp;base64, UklGRjgGAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCDyBQAA0BoAnQEqUAAoAD7FRJ1Lp6MiobVeaADwGIlsAJ0yqq+vKQhTpEnn5JIl/5hhm/0nqX/IHQ6eo/9mfUB50foe/7uogeXD7NP+A9My6ZftHgn4VvYMjW4f6t4oH8t4P+4/QR/jv+X/LDzudgVkX9s9AL2z+s8QulN/7PGA9VHPlqIfrwOi+3gwjga4Mi5YZhdIiTykiPjZh4C5IACN4S1w3tkO/Su66Um7606oaddRmyqiXp2oJ9+oO0DawhtSn20+Y5f6eDJyalg10QoIT1l8EgKK3hA8NPIN7ibjukjFAAD5OlsNtLGpQ9O93BeJYf3e+hFKPJ4Jl65CWyqvUPRXsa8i0H87uhzg7o0d1B1LQb5r7raWAZ7avI7oFpBW/d38wlAv5O5Fc79/iS1Yj3+zNmuXq3+rBKPr87+MPSxf97+AvsaUmPxDxTUYPeH6Tf2OPNtAER3B1okGaF5jKYqCfiKC0K3R2zC0S/DLxJo28WFrbDbiLvohY0gfFmr+NLXFOqxvXYuvzRUmzkKdPb9W7ZpwlfCYf9OYWDKSYFZG/Z/uf8XZZYjhJzG7r7yRGTrY85Q8dcXqunykeYe8Nq6+GlVxd8ks7HLGdBrc/1TvmVnPa5pCgJ9gu8wPEC7xO7Sz9FkFZ3GQP5gEEfQBs9zIXJxxJCTW6SB5hBUyRC+OhP4RCu4mX85ENBFNvU+jvN3qOS4vRbCUu0kBd0LfnhimJDJhASqWv/jy+8baR8rZP+lNM9Tl49w9EFKxCCqMFsp2PDoGClEcwg11IXyhgJ+pPzbWGDBxibC8KSYOO52SgX4n41XlTxwkm3h+ElKA0k/tqhdGoxLGQhhQX2qHpELKhJxPf6U9Ga1o5JTP4frhjFTN4YKrGdsrW/dHsaYzQINpnspcH5rwDQtcHmRCL1tT0sS+a/rqW3LkObIipVqDD7jruE8GBblKNIlwzfM+YHpSCy5OQSDgI6QWKDXePPlN5zrMPLlIXta0vA1e782dSb30iAsRi5LvNElm0H+HpJ8FNud/Azy3oBwa9qp9VGbZo3Htgyd6lYDM7dFLUIWm4LZHsCp8eqTLbI5SDhcisv/0jNKUWPUt4InJKForoEj4kX3Az6oQYWUmtkkns81hUjXGpkiNn7gBGN2rIFI8UT+Dtuo86blRuW6bd3PMdSp5TuBf8IA7WZnVpJushyrW/NdnVmgqh8XJ8mXh3b4RogRZ2ltm8v3LGj5nU2fO/s6hbFUzkFsrWp9XTs9dLfZDhbJ7sy4EIE2O2EKNzy4cyxqcTHGDrgPLLakkeXk599mbCyfaPCofYKLw04n25utQ0gpbPnYv275iRHbWClIP0kdwaQ7vAicUx7zV3HlhyzqJPFQlwNjvUkJU06m/g7lcsUkWCwiA0QH5l675Y0iJPy+YZ6I8tX4V5FycUhpz3xsQwKHzspNd630NL2vkbGCEQfQtvqgSkZ1BEV9Wne0BgYwsDxFJlQqordUU+rFSCN1ecsEzLvdrWiT1blPmL8f4vg0kzmgwmUtoINgbkPIdFKcAsiR/z3xpmAQ+n9Au8iBTJ2bK0b07VyzUxchashngYxGY/f/Wl5pcmeFcHEK0W5aKUW1LFYt4myd1Gvbp5a828LtZkyGOgJUIrzFMciXUqFt+Y4DRhcAggrychDpn9XGuQe3tFHU4bzt+wSGlGfsSkf5IjujLKK84ghqLJJ4Kgt1ESf22mu9Gffu2iW+X+3R4YmJaV4DTUB4Sdni+8u8O0jpL4yQkCOxo4Y5d+QQQ1RFkcGGn2laRbHMWvymiKW2SSJ/nQ3AC4IK3rJJZ8YYuZUMWfusdsp6O9BFdQDv8hTZRL05PLEQpePJl+h0FCayid5yVhJuj7h3PD1FMtp66+8kWiP/e419lRMUEET+XxkGAKjSlzcFTuBAdZkVG/JvXTe94He8LS8GrpG8WMZ2yDCarFiTSmjKfj4+7j4aDltua2GASyh+sMIXiVFBvcQhFLQ5KNmVdjrBaKyL5ICtz75jkDzJZOBS90zinCviUovAAAA==" />
|
||||
<img id="flag_bahamas" src="data:image/webp;base64, UklGRigBAABXRUJQVlA4IBwBAAAQCACdASpQACgAPslWo0unpKMht3LoAPAZCWgA0xeXyx1lNtfNOREXg2s7QVt8OCzxsDc9DLhz15v2yuR+r9ek3n+xLX5h3UMAAP7xqD8d86hsmxLdLCgrak3MdsFb5XLJwnNFcX0ZuPgKezMzoej70Mc2RZI8CEWwsiLFeZ3+ffPE9w6KJaK5ghLfKm5NJIiqRMFYsKPbvVCJE6KuhkbNBu8mixUXq2vQYyceEIS3A6t1LoXh5iXniRgeRakG7BJ+ucVnd5ZM/e/0tlFs3mQWc2mj52qtPYyx6T5uhrwPmEl2/hdPdXxzWKd/gNDf7M/Rpo/pkI88UzVG/WLCx0+rjkw7lEEWIMvN6pFtGe7frW2A8Y5KOljiJOAAAA==" />
|
||||
<img id="flag_ecuador" src="data:image/webp;base64, UklGRloBAABXRUJQVlA4IE4BAADwCQCdASpQACgAPtFiq1AoJaOioitpABoJagDTXUE7b+q24bDP8AMYB+yX6Ae/DpgHPUeyZ+0SRA2g61CW5Grl47VFKwAt0o3e/OIMEcXS9c+ASiE0JDVgAP7weQ/+sr/1lf+sr/fI1c9DQaaUgdHnmh8YSTRRpjCEtgLGY0VCYg0P+Y8f57YP2cSy9VoQN7+EFUhGF127/zpu0oRlZIKcS+mGe5fU+upNT/66Vf7rb0bvJ/tIzRhapUwWb3Rl1EnGS3WU1ClW8BnEFqE9WRuM7hTf9AgijVsNIp0uu7t51JA0wGmgX5aKraaJ4+Phl4jr3L3h+krzp7EJsrybI2cMkGsmSGrxxB4yojtsvuVhsQnqctHM0ge8ytlwplIScJulqkfW9JZuD08vSZ8iwoKZ8WAWzwwdzRIrzQrjXcT4wib/zuS6Cubq1kmUMAAA" />
|
||||
<img id="flag_azerbaijan" src="data:image/webp;base64, UklGRiABAABXRUJQVlA4IBQBAAAQCACdASpQACcAPtFUpU8oJCOiLvJLAQAaCWYA1BGNvVvW11XCYAGLOscQoS5ENFXuJKAC0m6Tmb3X5y75XgiEBDsz2sbKarvAAP2McZ702tqC4OLom35654Fe/+LQ+q8lwvBxaDff4ONvfiGStRxZL6700pCLTpzymhlc62J6lkETo6oW4+oF+1z68ima+HwhAv7r6IKBa8RB/+Un+4Irao//jY2IeCK2lQwIr39XxHHrwTxc3zO7CJAOMO9ntWBYdjmlkHocaXX+kqAOQ5zP1uevamntfMuKI41lYp0PwNXQ1+vWotfS1/fgO7SqCSlpOALlrZSwzeIGnpiyCGCgw/RTSX8GmYsMa0o4YpqoROAAAAA=" />
|
||||
<img id="flag_montserrat" src="data:image/webp;base64, UklGRjoCAABXRUJQVlA4IC4CAABQDQCdASpQACgAPtFeqk4oJSQiKJgK6QAaCWwAec88X0DhpTW1pfUB+Vd4B5gPJ0/Wb3N7xRz7Psd1kluhGHrYqz+DCUvru0JQ/50bHMQWQmIv5lv0GMvCVoi+MSrRapOXkQIkURxImJQ+U3syxWfuki8gAPz/bePjivd3LNHTPDJIlHTrFTeObA6b4lpl7lXGi0wAyxPKVV6bpe+2L7xOAwlaJSXruA8U3Wt/4x+5CJHX7Lj5adp3ZghGZ8IAOUIqgflibTk2vNgliyH1au9yCWgEJpaWPzKrILcN9YPo+8x4g4yiPirc4El7qJYq/lPsdnNZ1Px7Ws7wLsUQeE59ZdXus73bACaCukVejtBB+OmcsgO03Hu6niOugKT35635po7z7IyY80aeelwxIWxQhkpz9TfijkcfL+HB/SS/IrVHMezuRNxMaHqFvcIbHRs5jsDleR8hR/pSmk8E8ux8S5mjANQppMsAaxblnvXWeF+14b6Lm8RthgQ+/64zmmYPyPvzlEOIsA+1IrLYIyWqoyKzwoYmSV6dAC37BFN2CtX6o8kN657X9gWkKTCdajxWNGhBK4KHkNsIN9fJuxf29zv9jAQGq5ZYDmcMgRF4Ky8txJcKbBzu4nnyFR5TF/L9wEjWaTv2ig+t1RG0CNQpmyTk436IBDbJHkT78NqoiIHtgdA1263S4nrrnTyPqJVCx6PPEoTBfYHSNJHi/501JUKJ1aGEIBBiobIAAAA=" />
|
||||
<img id="flag_nauru" src="data:image/webp;base64, UklGRuAAAABXRUJQVlA4INQAAACQBQCdASpQACcAPtFcp04oJSOiLvJJAQAaCUAAfDNZB+jyUN4G4/mk6MVVFPUQXxlbQhFSgAD+8JtD/+HP1d+ds8vuT9EeJr+zUceh1GfTcXU1BE+07EHm0YE7n4uh1xN/ZBc/3cdtUeso//u47aalXPr7N9ja3bH4MBIfSpFsmQvhnittyUZy/u6tkE93czSNG6U+oZpDoiT6AUeB0/IFZAz1eo0Y787xAubgU6yfLGY2N+COPDp0Xuwib8+AI7rMYbKt03qW5KwmSdNFIzyzl4uAAA==" />
|
||||
<img id="flag_malawi" src="data:image/webp;base64, UklGRiIBAABXRUJQVlA4IBYBAADwCACdASpQADUAPtFcqU8oJKOjKBmaIQAaCWgA1PfH+q8IU4ZNXQNc//6GN4ABAA6pLaTMZpQlc/pAo7lNp8rEx4AWSOuvB7Zwc9Wm7qRrgAD+93p+OOSu6FmcfypJ+7ibp2oqCJcvRbP5zC3DNa7ox+wFnZCFopf8rj7MHlTP16FuxSojn+FoVPvuXFqPZW2Cpwu8eATxMaE63uHS1L/jhOP2rVUtj46iCZj351T/9W5w5D0sHypOXtcdxFmF3oJ8s9NBf+QmpaBUQi3Wq3//PXE//lJbN++H//VJbN/y0PmNI3iIZNlOwr88w7WIFtxXbDNbdBkcG19jRPSSf8m2SD+yn9/k2yQf2b/8MP0Hmw9YAAAAAA==" />
|
||||
<img id="flag_chad" src="data:image/webp;base64, UklGRpgAAABXRUJQVlA4IIwAAAAQBgCdASpQADUAPtFWpEwoJKOiLmgBABoJQA83dYEz/5yABEC+g7nen3xnXqPaj+mo5H9OECqN+8AA/u2QP/8ktSeLIy/3o0BXV9b3HW+wSzz/OFjuIRN/nCx08fNpqZS0F1b+G3zqJBSvBfq/pablK8dpG/l8cTS990mRaDucOeOcY4ZfUBE9wAAAAA==" />
|
||||
<img id="flag_tanzania" src="data:image/webp;base64, UklGRkwDAABXRUJQVlA4IEADAAAQEgCdASpQADUAPtFcpEuoJaOhrncboQAaCWwAyNGhO6/tPHlcjRBXkfEA6QHmA6BX+49QD/gdQjz7PsUftL+4XsZ///OTetP+n9EP6OPeogVo3/Fb1MMFND8V+oN+on+5/lvaIR697kR89TPf0sEici7q/hHE66r3Qym6r7+4Iom1r+/TNrMr8GS7PyZgqV/L2HvE4N+fSAAA/unrtxil/mCe/3f58BCVkMl1sUW6sx0RqSx54jTI3BRjV+Tuwp/zwh3ANYegBQz7WqRsRpGGFEuvRMVUy5qdHMFWTfOr/sCJ1yDssfx+2gcjiZkrugHQgTcxo4xwI8Y74YXWC/Hob9HJTisEq0rsaKsETyjAZVHJjmqteergU8olOcqwaMLx03K+4cuYBrdrFbuQOgOKN4lnzzq4Ed4BxvhDXzeYioIhpKaLMxb3tdz53ktArYq7+G82oskzpMkDbycEGKjtaomzFgp/X2i9wQC0d9wxpJvSF2bOfRHOebtnt64q9rByAJcZQEPJHs07M+qC94QSrlkqAe4u/NeyrrwlHFz5/u31m5Wj++528jLADwB4OshiL3ONHTtl8wPdnRcKD/sc8HKRsNWDgn5CVm5ayq4IxzpN8z1aPzr9g7JLNzryLpwdgCNwFvBK7tYCB7cVZZ3jJOro5arYzMWEESfbvNe5SipzRBs59wduIgrJHxL70UudvFsVCpFMpnl/96sZAEkJzotiaOcywS5ak0tHGKQJlWPxRxTQvvwWSgp61uQU1I0zhDLV123XybOu6Oe0rfmMwjhDF0lndujhWN/20nlgENI/+BeQcFkcDX8xGWLgbd07lwe1gCpVGUvUsMp8617JRl4hCYt9gu79vZCYGiUTKh1tby0jb04YwqX9yAiUZ2zdd1Vst6Zt0672fwdg35WVLX33eveEdPtj5X0ON+RyPTbeHlqpi+9LGc0Et7vpssyDFhp1agi/z8PRG2of8erRUNikBXQKD6XjoHArjkF4fizH9kGqqpkJZg6N15/ZC/g4rxNFInTE//NEXjF5S+RJXqGAWw7GvHguK9K/wY4D+DhjM8qxxUJsVW2u9Y4reXfa4x7UPjo6q1pEcAAAAAAA" />
|
||||
<img id="flag_guyana" src="data:image/webp;base64, UklGRugCAABXRUJQVlA4INwCAAAQEQCdASpQAC8APsVYo0unpaMhsRYMkPAYiWwAxRF4/lfVAWQ8ByTXJ/xDhdTzQgPyL/x/UA6QHmA/Z/9gPfb9H3/09QD/q9QBvGn7h+lo0QVyPrWno9KWOZ6KfpslD8E38a11QMEwufU1t8mt+eBjgnnZdyDPYmMSLuldu3yl/FDnqd5Uz94B/iC6MU3bFvYAAP7eA0vUva8S8u5C2dAEj1U21fI4MR+f6EPcgxf5MYFtopfHTVaXE76ZUJmMKCAgtV04GMXhYhlZ9Fp/hee/WL/j278PQ9QybAbWuwFUv8Ib79jOm6/WRVM5Rjz3Wi4T9HgX68Ni2QvpEvLK1Zd9qzliYx4sOG/HHKMPCXVmCWj3ymXAXmADEf+hDAXXhTAoq5lUVTtbRiCtj/Oo5uAbS0fySvbVIP5rYWTSEm/IegNM9NCO+F9RZWi7v7MKnZqL+4WoCyLKYCAnQQOAoI/cW/9aVS4DfPR2YbslP9JwXio7ph6S9tjQ6+Qz9k4rr4m2RwPohr+vnWbnCFqseXsBw770GKPwav9BUJJz3W1sf+v/jR5zwtoYTl7p033Esc9IY039cw5j6IYpnkwabCkGEVa++GE+zsCdkb07dUXG7Fk5Z73b11ZnWt+ZDxcLPjsnsfBOVDcgSTV78+lswBu62uSlc9EVkjqQhEtCkKx3XTR5p3pimeFlxgoE3AxCr0gPFx3CUn0l4BIpKetwQa69dW3N0UdqeK5P/t25/ZxGCmK90DOcLrTljZubkPtrIe1ks7U/wU9Gfrnog8dBo2AZ3tCrsClwj2Om4h+RsfT6U0fBlJHE/mMZJ6zMj8laCRI5jWfqR0zeiW0s0h/E7nZ5pH3W7zko61YIGln+29RhbTDzhfTv+QbRd49Bk5LmnmurxuFLhwGIrEZrJnYyTVLrEQwa779AvhLWwa68m9DbklIMo+e/kJJmLqTCX3wRw4zkwE+UvLrxMCoAAAA=" />
|
||||
<img id="flag_aruba" src="data:image/webp;base64, UklGRgoBAABXRUJQVlA4IP4AAACQBwCdASpQADQAPtFmqE2oJqQiLNv4AQAaCUAPFNaA/QDppdMA56D2UwFXtu0QTQH71sJwnqanIFhM9gRz+llEKA6ZSTAAzVXQRenxaCCuGBm72F++iyIaKmebYz2r+9LluYG/pwSIyLau7ak/8i/xTWoxE/4fjER7t9/67T2F/n1ahQnc3bgph/vAf340De2rDKi2hRJhPZpvuR/YLvCjp6AgOFG16aD8N/yaAzSKFVHuQsLcLu2zwpfndrjALvWEyJHTX2dUznz1mM1fp1mM3LT8q6P0bZ3+VdH6MtT/yfNhz/yfOQkxIJDX5h5AVZnIlInG3I7c/y1474AAAA==" />
|
||||
<img id="flag_somalia" src="data:image/webp;base64, UklGRsIAAABXRUJQVlA4ILYAAABQBgCdASpQADQAPtFirE+oJaQiKBZpEQAaCWcAAEyOBbR1GvnTG7slXTO7QKLJF/+i7F1T8JmPM7JsAAD+5cbafps1ZL9meymh52PcH/8GyRTXZH8vtTEkndxSP1hoOB0bqH2kUJ3BmjrQDqkHIlIoHMe3KgZJ3mOscbeABy55SZJp9AKmPb/3vOaaqDYevT992oGSqkUQePx80aJTfr7KjUBuvmUFXPjHDgw3x+vBzcNR+TAAAA==" />
|
||||
<img id="flag_libya" src="data:image/webp;base64, UklGRgQBAABXRUJQVlA4IPgAAACwBwCdASpQADQAPtFcqE0oJSQiMZF44QAaCUAat44BGDPIsnn8B8fVvaFZppmVnXoMulK1TYJH6U4n7EMMPcuSD1IVNIrgAP7ipPcAgURff6+8oWnaq3DL//pNn/9Js/oyfSMBXl8f8bs+JGW0IitDI/Ytv/RhRxdjxlVbQ4zVinvafOCA+v37zPwvVq5CtDMWKMyr0tZ/nNMt+9fb8dO/v2XtCs9ZFxfrHDBe9BJs98/gzdWpqPWs85zSRwpNZw18emYoH7UOb+LnzHqiWghrbKRbRFxdYLVgWaoDJMmoxO5v/u/CHvB78FORMExxSqyXEWcywQAAAA==" />
|
||||
<img id="flag_slovakia" src="data:image/webp;base64, UklGRhgCAABXRUJQVlA4IAwCAAAQDgCdASpQADIAPtFgqU+oJSOiI0wBABoJbACVA1LHjXmT01+u4v3VA9QG2A8wH6wfsz70noR3lD0APK39movEnxMsLn0klKDkejd04IoTalFYVzbBdYfG1n0aznr6G5gnGUbx29StxrRnxF/19VoBE4aNleg8Zno4AP76EF4fjmLcYNM1UVsLZ5Ph/AZ4r/xKOl1BuAu4/gzseo8ccnP4wo9sgww9a3zqClsfRC7m/3SFMO7QziV0MYh7urvFFSqz8/5hrNoQrb+KtNCsZ5BKlkjXU5UEfvqPV06HyHYGOQJ+oi7j/8VOy/5N2GgXiEWP53nG6DJ72vO3P6d+oU21E0HMWc2xssCVLV7ZsefgSuvpbVFakkxQXcSArwzox1qj06QGtHi1vP7+/ABL5XZ6NozOvAiwnWT4Wix4+ICrnljlbWIA4Pzjk4GmxQme2GRth80sRika3s8Qa9vUvoTvsm1jRAOUoP+tJkUj5869aURubNdQL+gdPyiB677fS/+bnzf6lgYcw1EW+fajqOJ/eRsHvZHBlAo7/lX+M8ZBQO6kMwEwBtkm5s9e4D+os5rea53MJyytVR+5ic3lvvobvV+72BvRNZ3UhO6ucqJ9wyR+Tl3ncnFNtxuFE1SXK1i51xKRu+XwMEA2Bf46X8p3Be3t1naY9mDqJN7B/LlBbrf37jK4Yl0BNsAAAA==" />
|
||||
<img id="flag_american_samoa" src="data:image/webp;base64, UklGRswCAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCCGAgAAkBAAnQEqUAAoAD7JVKNLp6SjIbMznVDwGQlqAMxVgdy+KNDWoX6X+oHub5XL9Zvcx5gP2H9fH0J///Hv/Zsrr/8T0JyUN9XaY72f6AZq1NKVA99WmR9vySoe5j4C7AjRBMF6k/t80yOi5T+30kLl44IJkw71PPOyMxvr62D636ghXlUbQZ7rL8/nORGAAP74I2/4hzxT9ylVGHuqW0Ip/kacnXdS+tt2U7s7MSrZzZiBV+OeOJ3XOfWYmDTU4AGbIcB9ap1IpJ5X5K2TWIDbMKLfwihZagXn/gaRNlu8jQc3lvQoan/NTWFtLB02SPA1EuF4MRoS8In7Naz3M2GwwvxKgLq1f0T2DLLS6fILInybchstinPJRFRnNNeNq+h6f6ykCoEPUwT/uNwr/UAAQ4fu+7s3s+ViOwo6B9jtfEBz0Q1EM0ygOejK+Vv4PaYIQ3wlwmtVkn/fT9diVMSKUoTCzYpIEdLA/Vpx8eW1/swUBwaS9RbcAkBLpIjEk0pOeXYQzv4g8DUS4Jk55w1sUXUV8SPNB1I6FrPzAOc4RNc8LOesrbNt16zbohNM3eggF+Kgi6HS/H5zp8/iX+4xYozbHu8GQPUoLSx/R8Zv2zr3Ebkwnl7wJbvoBsajCkfkX3cApYs2r5gkpUdxggIV1PsfWMc7g1Mri7TE5Zv0njww8GCuB6qB8Jx4eVQv2cQ5pVoD7ZM0/gMGt06mNwbr/eKIBrvPS11lAgwHrOtFEiqsEjYOZBnquQY3S63kvviggKgUoWZdx2aRwPlzaWx1zXPRiMIs0aCShqwiQxvg4+97KhmooviR5oATTX1M35chh4kqeBw8zYQfZ7ifoOHd2ALb5UAAAA==" />
|
||||
<img id="flag_hungary" src="data:image/webp;base64, UklGRowAAABXRUJQVlA4IIAAAAAQBgCdASpQADQAPs1Uo0unpKMhsYgA8BmJQBKgahb2aTAW/+BY0hKNHy9C48B6EvLHzJSHKD82g8AA/uUK/7oJf2d7/+cS+gXgL0B5dQ/55fxsFECVS1jsGBFs/H/wkqnLh3/RJUc29ubNjR00eeBROEoqXAom/hNo77jQsAAAAA==" />
|
||||
<img id="flag_guyane" src="data:image/webp;base64, UklGRqgBAABXRUJQVlA4IJwBAAAQCwCdASpQADUAPtFgq0+oJSOiJnQKgQAaCWYAlQNTd61+RkYA8QDpAeYDoH/9D0gOoA3jvI3qjtlgMXPs2mpWibBhPCLlBcFAZdZuih6OEITi/Nt9/AZAxM9b1L0lC3UAAP78Ls8SPCqHAC4TcA5IjKNQUTJvxgLGlX//P9zcmM0tWB/Jx/TZAzyMda1vq2ufLkmst49it/LaVK5JjzZKrkg9o/nKh3i77lWxi5qaVFEOjhKuh0sAFMwJCJMoCysG21wAi9141Hjklu1q8gVBsIIPGqS5c8HxlIDKVCTprWvq2BlT3Dx/YJdHaQWxoL6xD1+n3c/Z+pGl/ni+6vz6PxxHl/vN0lXBhjwBu7d7WraP0Lr7x9+b7R8HmiS71J+b3/OY/SA9RP6rvZrR9DitOoA8oE3i7vhsRpZ9f97xDEaM8DprJOrTsNB2qnfeVPLLTJiXMf0DcbyYVy1ERb5e7BBNpvPGlRvHWXPT0sJ/KRvbBvJ1xDKvdqoUDvReKAU7SPVZj9Hbud78QzLMAM8RP3sR5dPVeukCAAAA" />
|
||||
<img id="flag_sierra_leone" src="data:image/webp;base64, UklGRnYAAABXRUJQVlA4IGoAAADwBQCdASpQADQAPs1Qo0unpKMhsZ6IAPAZiUASoGkhzAAfmYGI52xv7XMJSucwCdJCStpUpSq/gAD+tlf/yDH2NfQ1olbpbfCIHM/SRxsHKrM8b1MjLOdW5N9jHTIijADX4UoHZH2AAAAA" />
|
||||
<img id="flag_togo" src="data:image/webp;base64, UklGRnYBAABXRUJQVlA4IGoBAADwCACdASpQADAAPtFgqlEoJSOipFgJOQAaCWwAeIX2a3DYteoDbKc+9pgG85kqP8j5vebd42aB18Yrsw5vkH35xCRhV/WG0GoA9cgPjcIqyAD+uH9Hrj3BySpDw4Sa58atXUUk+F9w3Kf2xJGieAAsv/+LMVvgYZX//+rQ/5ByL/yGVhvtJxoXxBS7nssZY76Wm75LsVD+hV4QAuXHfaLSwByHOWWPTDxTT4TKif/6sWnqbSFW04lE+2XYfbFT5ZCPDNv5NMHzQgKSGfFu9sxVrXC3gETDaN0eJ4UO8mBI0tAPvmAfOZnu/Vx6JFADjJwgpy6AV5DCHYPnf5Wv7OsgrCcXzBGuP1OEmIHBdE1gQOF8gpNXfECDaD3TGp5FEDQU7Uzhaj3qpfABP8ShmtCCZgnrUXVYFW4mgQM1BFYEYouM4+qmOHpIlw6C+ZwGj+B2kPz5gKyHcyzBy/VAlov5QYeQfUSSAAAAAA==" />
|
||||
<img id="flag_uganda" src="data:image/webp;base64, UklGRo4BAABXRUJQVlA4IIIBAADwCgCdASpQADUAPtFYqE6oJKQiI1gNwQAaCWgAlADU9uJ70eY4/4FxTDJ/tH65OmAbvi0IFqCX/L+aoZXxH8t94OwDwOJUtN6cocAoHH/7GBxLeBdm1f8mgol1DIXZx8AA/vrmu/xgcZirMP/rC6v5hc3hGq4rYIqOi+nPQudpOBYq1R/f+KsSxtsCMobD2Q2Ijp3wgADF4P1ulS1ux9qFJgzdtOBe/5S6Mlbjwc4KxFsMDV2w8wwnjuUC4c1MjXJhVfg9koabNTqqM9Hg2b2Cu6124B2HEsohFoa+/HB0ZwAsP5hgdRNdELOuC8TGsrxwDvm1fuDfwR9qZAECKccbr1PPrM0H1iUR1MPzvU3NjFi2jjQmrM/zGCiLidlxgMzU+kJGUNh7RMKd8RN6GPRBwLMxVJpuek0YWeFhJYPrFMrsTsdd2J2/VEc2GOYcxEdFjyhf4/C8fnvioNeQUdVWjZ8IW2fNACdwlMkb7vP7f6Twmkk8TdIRZKrsXB9Ek2iAAA==" />
|
||||
<img id="flag_tunisia" src="data:image/webp;base64, UklGRsoBAABXRUJQVlA4IL4BAACwCgCdASpQADUAPtFirFAoJSQipNVaWQAaCWYA05l4/qupldmk1egA8wGONbybMPOkDSds8j3K63yxjtNZbf/BvjoON0H5BXN2NZb1kxgVUnihD55qpKHjXrVTN8kAAP7paRMPC6cPfqDP9QZ/qDP1Dn6MJ4A7fQfE8Pu2vrz8s67xab1565VOQ/PklA/E78+IRVd/id+bHJOzIUHoAIGrivVaN03Mzmy4yPyI1rD30Sd8cHXGKijMZQmsF+haduUNsV8PxXlv24V3O9he+96oDNUAx+zYy+F2KlBIoezn+3lzspqE6Xi/czu5kS2syZY0UNUlSproYN5hOFfJ1goI62XKtDeoCremIf/dV/dYrgASyW0KNAtdcZz1uIPq9yXS1zQAC7pH7r1Vy3S1ghQUZNRk5nhuKqzRnjkEiEfgofBfexFsHLCb6NaDE1UJMRtZwxok3rfnYT/2T+WQgagyaG2Bb2aHzCuAiYbZGfpovqeddGx5C/O9oJ5BP76hZEME+ak+e3pPJoy+A8CmvY67fX1E7J1Lbx7b7jrqd+j3Vj+51c7jC1q0g3g2OMv9xJPywR/Oilx3qSfg80AAAA==" />
|
||||
<img id="flag_jamaica" src="data:image/webp;base64, UklGRgwDAABXRUJQVlA4IAADAAAwEgCdASpQACYAPsVSoUunpSMhszOeqPAYiWwAv3GB2d4bfb+NV22MvO1icB+afQA/x/8T673mA/jf9i/ZL3sfQB/0fUA/+fUk7xl+3fonf//s/4Iu3bRTORf/SsAe35jntByuHqvZnbqABf7fXpaj3qof7TNt9Z2MtPK4WG77DMwsF52vrFc8Ei5ZzTeMKZA0POKTamRTYXGwAP7yXVt5yxuxAVd3xlqsFfzDqppOeECG6ZHkeyuEgyf57fvf5h9z4bj58dUQL2Ez3cYCiN1QTuQrenyKDNC7jNRw7xY17oH3xD/Bk98kiqzJpf1m9YCaj6AdtQZy6nwbNExvzSm7xUjhIgza82qcqW0AwJ9tITOmMcxaEX6YuXrnGZazSd/WTSVoam2FU1zmI/rZZNVEtcYA/vXsWxFnzlAAneaYnH3IafDQTDGhpxgufFjIy1mM4BeHTSDLdJZDdm11a6n/5UjDmPqkllxleGrRc/aUuMK5GK7thMCcBTYKwXqsUar9/vLruINuuAGsJhZhyFs0tLam2BfQuEYw0rLSJo6hEs+/Cf4t3fa/xJCbnynsYrfg7P1bT9jY3GDhfLtYXE7gb2MGa+BkpyMtqouYwZyGo44AOuLw9U6wmG04HpKlazKO1a5ToNwANRwsxP5fdv7jTzAmF9bOWJDXiPwx+MjOweTas6y9U6q1ai21XHb17xrx/HwzZdIsS/Ds7YvO42QzTWlkatTxXFJbm+zI9vR/PqHJGjyZuPEPhqOp+ysSdIbsBoewHCM66WHoBNrRLBuwDWt2zFYO35P57Zmr9vWgQYg9+iyY8Nis8zqueTXOwoDUVc8CCLW0a4NGrktVKit9Y85Zb/epBZaDLMwFzyqFe1sKWIWxNR6D8BfQtp38pLUaGVuJubKoWTOD/nUpQzuVaWYDWtPJhqZOWJSf2JR4d8HNA21lNGCgNmqx/wkDlmbjyTOSzXkVeUjz0TMZ8zdizOtjUIp2rEEmQcXuNtM4+nl9384h+jLqHZoqMdigAAA=" />
|
||||
<img id="flag_kosovo" src="data:image/webp;base64, UklGRkQCAABXRUJQVlA4IDgCAADwCwCdASpQADkAPtFeqU8oJSOiKBM7MQAaCWYAaR3zPGsUi8wGOM7yp/r3EAcAYw3nIeivYA3Ss1Ire7LcEz6SPkVdQTxl3EOq04Qcjo4B6zMJjEoMJDayRmUS12SjOt1RsBQPAeZwAAD+7qY//9wfqD+HiD/160ty6Lb5AkaBSLMbppYWCMgvlOp2G+j+jAWgbviloiGMyPgknfVlAem07FQFn/nA+GEkq+yFkKo2N+Y7oWTC3hqMk0os/v8jIBhtsg133+ri8deoYuUUm95AnhKOfsSE8zx2FsderZxirPCUc/YJb6349PPtSPAV+xsBSiAh5hGwiZKm7B4ytiWr12+EAO/0GxguVM3DcV0pf7mwgPWNS89nyFmhjyOqWwikzWHkEjTiDSb4HkM4zs6X0JZMF11N2f9Sx0w9oYU6NXz7i4ndXbYoM8Kx0/mReEJRcTUspg+nl0x9OD9n5cmZtv0dhGLW317aKcItl0KQEhADranmwMqJpZkE5pRqESuWEGUlNQBAe8dAZBuvZD7DWsx9GUJibAg96OCqN7WvfbRbvosBhS6G/DnOA8wDrOn3PY0ClCSETwBjRobHmcvwCKzAcPaMYKWSQ+D8f0S5QaE0yBaKulSTwAVSZrQqay8lq7R9ptX1a+dSTwmLfvG5ewAVazXFH5StDIZ957DzOMHJ3fNW4bniw1gUp/JQN7r9qzXDE1+w1WWRpTzgpgebGttdk6dLqMjbZqmuDnhdpNBdygLo8AAA" />
|
||||
<img id="flag_uruguay" src="data:image/webp;base64, UklGRsABAABXRUJQVlA4ILQBAACwCgCdASpQADUAPtFoq1CoJiOjpngIAQAaCWwA1Pded/9uz0M4JoGuf2Uw3wDi5cT4s2yJxpK9LsdHXRevV5rAJKii8OzeNFq/VJYiYfTPAbB5fa9qMgIUPVN4SabUAP72CQQ5PL7BEr+GjanA1CPd+xo9U30YjvzhkA9fmSwFLN/HMqSyIYGvwre68jUzPD/i+Zz6ZsealsaaaGdGOiTfIJxdRV4FqOFBkxJi+JT4RFDKc3yva07ZcGk+39poxWivEv0ntz2wVTGPSyyI729SovvDlkrrMLHBlnmBZociwrgCsGT+qsvsUOAERAinru88vttU47UkEDT9sjcJcIVJ3eB3WRUEsBN5JBVMruHrx7TM8pT53x8ZCwjJkNtOQGkdjRRFNqTW+r/OUYnkC43xygsqVUVBSZNLSNS2FDK8e69tZyYNcV50QgudxhwX/NPnx5gDsCa7xa5FwPHAL+6bU+WIgBO1GU3nr4r5AlJgSnUZxT2YwTj4daOSCP2+8QvJ/UiQcVUFz20br4okNDF8w3PbS/pa4r9UQ2xX6fpf8Ib+/+EPFzCQFIBOnfbFAOTiAAAA" />
|
||||
<img id="flag_indonesia" src="data:image/webp;base64, UklGRm4AAABXRUJQVlA4IGIAAACQBQCdASpQADUAPtFkqU8oJiOiKb1YAQAaCWMAlQNEK5XJgAGrgkyaGuW53iar9r0iE5yD8AD+2ib+aIlxX/8zR2G3ydDiBuXqFzQfssXr6KIf72Q5wtFPowaSOe5aQAAAAA==" />
|
||||
<img id="flag_poland" src="data:image/webp;base64, UklGRm4AAABXRUJQVlA4IGIAAABQBQCdASpQADQAPtFcqk8oJKQiKb1YAQAaCWUAQgC3/wJCRzOq6BIai6N6xyZScUaK2wAA/vSgvBBZRdgnvkDlnvN/+xktV8aIAv//8cXP/5SWzf9Nv//lJaoE6OxXehgAAA==" />
|
||||
<img id="flag_gabon" src="data:image/webp;base64, UklGRpAAAABXRUJQVlA4IIQAAABwBgCdASpQADgAPs1Mo0uno6MhsZ6IAPAZiWIAebHxreYfAD9AAMjvxO86zcTEcbTcXqVEq42eA8JVB4AA/ru3/+Nm5lLX/6D64boyNWnGU6ytDLsRmHjXemMWF+BaSteZk8YBG0shp9H5I+bf6OSP8Gqf6OSL0atH9aA13yWhV5WAAAA=" />
|
||||
<img id="flag_mauritania" src="data:image/webp;base64, UklGRnoBAABXRUJQVlA4IG4BAAAQCQCdASpQADUAPtFkqU+oJaOiKbK5IQAaCWQA09V4u9okGEA3AH+q33LeN0aCEAGqIzEyqGXwp/Cu2RypB41kyS6Qo30PvFq6vWQ44sV8gAAA/YxoRnZ8jxf/i0PmH+DW5pGpj4V5fRFX43idXo6xyAkKGSQabDViws7qLYZmSTY4xGh2xFtbbuH4ASg3uN9gzETegFlnjLHos3X8BDLySlCXMO8Pa2iMIofk/UxNEnoUXQrCBwWXCNBPjdk29ByqcvqyCZHM8wTnrvKsAjHuLmX2pmdDa0va+6m5/e1UL87do6zeKS4ETigE0OnCQ8fIhlTM2LRNDLctMLRtletpLm7XeowFYJkyIpbhylrpv8wbej/aBN9OcFCE3OQ1uU6sDJbZEtqAbgyL8SbD6oanVtHuIP6Gs1GAwlqL6840tGsC7JTYoO1EtYFim2aeqiaNwvCBwE9NIEcYPt8o0uQDsMFzwg5ND1SnZGyoAAA=" />
|
||||
<img id="flag_puerto_rico" src="data:image/webp;base64, UklGRtYBAABXRUJQVlA4IMoBAADQCwCdASpQADUAPtFapk0oJSQiKBM92QAaCWwAePFEh2/decGNwBuYHUAbyr+0RG47twQHXmWY0+SGQzW0AcDtWYPiKDQPDJvFUlDrCsQsaT5rFyLjb//JdQep6nvZVu6XNWBeSqNAAP7miQJAJ7wW4BrrDsjIx/rXJwgEvsPxYFd5r+p6y81ZGgbC/+db4ITTbh//WpeZ38dnWkFwABzTOaNZgleWB82M980QB2U27UTEpP0eqZzLyHCtTf1DTHubQf+X8Jdd0yOqne7/7CEAuWmjXnYE2zzSwP3YiIB+zxefmqgK8Gq8rLBfgGkR9c9p1xE7kEm8lO0xpZtjwC3eCPQ/j1PDZlFJBchyLlwBR+d8+zWHZdHrY6nMhZbVR5ugGfm8ye0/YDKBCrqbirYQIPyv4OPsY+x/Q5AVIQsO667AZwhWTowagwYEe5jCJmt1xRrqRSC50vHDwtC72rexDfDOE0xHk/v+ea84Qm+s6OfH8pKHLkVUMUPpm/ko3speTYvT6Z+9H5RthnEJ7xsX/DXbwsjxlVA0GQGCryUvhklCrOJRb7WwhxWi50akgSRDayFcexjXwB4u2v0HtzpoIz1/UcoUcAAAAA==" />
|
||||
<img id="flag_cayman_islands" src="data:image/webp;base64, UklGRu4CAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCCoAgAAMA4AnQEqUAAoAD7NVKVLp6SjoazYDVDwGYlsAMyHvar/wmMb1gPUftjfMB0IP9vvgG8sV1h9Lxq2jNnxWM5t35KBwC9sqH26MnnuEdiD3p5VSyo4C0xkyO/PSX9Ju+r/b4SeGH7O5u5jkSz60CbfNzFpdLYo2AYAQtoA+WIRwOKE5AXHdmdWopeNQsHzfjPXVAbEHQfbFqsoR+HS5ovPIeOcks3pnfh85yO+63z6ASkw6pkplxSvV6NmteMI6rnh3a6jUOOeoj7NPSI+1OIA+5jMIXjzL4svmP1jfzAd1+GXdouFt6CCNirx5pDTPxafxDdECeuvPRB6xeQRdfRo8GdwtXisMwuC/6Pn/h0kccaxWv2qKP96qm3c2O/Z6MgSFoGK/JPPKiFrJ63TznJvOrrZINIjWNfMxlnIJPQMk6b5R+G5KszP6Vb3+2/s+dwzLZAKIr3aOPTmGS2k73VK++/n8JfvKtpTMy+xNya3lnJ3bnPJwHHQ3DMgKiwUu0XgOUyMew9+6EBXdpvTfrSO5agd47hx0Rj0LgFCB3W26YGm8xciAg1yl1C8F7/XHG2X/fdlmdkuV5mV/2/9vKVdnQMKVPx1yRN+7KamwBD2W/fBru+Zh37eo55r0UeVo3BOYPssFF16+//rAWt/nQRGP4pElP4ZKbERLwSgNqpLoGF+SHyiihpP7+iX+mBNvGKR/aJHdbOzhcMdAYVFgVLVyphV5RohtDIUswv1fht09ILB+6eRnfE6TtxVOmiHU7qhsFlPuahXzXJM1MDMbK0G6En5QFhRCL5elzHdcX3+Rv4SLgR+0CTssW9XRmugbdWeBlXmCvssDSdTiAwUhjH6osIMzcYij2PpYBqkxHdlQKQM54Uqgd4RVyE9vgWh/1xLPe8lkAHwAAA=" />
|
||||
<img id="flag_laos" src="data:image/webp;base64, UklGRiQBAABXRUJQVlA4IBgBAADQCQCdASpQADUAPtFUpEuoJKOhtNToAQAaCWQA0fXvfqv4gbCzZn+IEuq+wAQQe6AMKg3LLbRyjz9Lc+Zr/vPKyRaTn+F/1LhObejpBSqaS206SRlELTAA/rhrvY01DbT/f/Srif7VzVM0KPr2Dz2Sad2Eg3PVOvCwARkSXdDrO1hxPbZOjikmd5dwVbN7KNHvMhOoSm8usd1GZNAz5J5M3UWOmmR4guy21UB08UCmpmZunsz00PryawOoyT9IVF6Miny5SVXDR0Af28p1MGPXEGNnzWCdJ2ehlKH/hdiRmOqc/ARXOmqTDj7r6k/k6DqUoEeRGzgEh6y2SYEzTOLSdJlilt429QLSBGYFfv2vhMmFmWAAAAAA" />
|
||||
<img id="flag_bermuda" src="data:image/webp;base64, UklGRsoCAABXRUJQVlA4IL4CAACQDgCdASpQACcAPtFUp0yoJCOiLvbbAQAaCWwA0QVBOA/rPGq78OssqPUZ+G94B5gPJj/W73T7xn6HPlu+x1+5lhs10toMsDSuM2ftOFG2+KIMgBKCnSN5xSEXFg1bszWaZom9jKBuX7PNmr1vFzoQ9sGd7RV3hsGbVjk4AAD8/27g/F6dIrODBoejgVLC3SV+otV4IXyUw8nXnxOvKX2ukBZT8lc/rqZph+QukI7mexEBvvtdNT1fabjiQdV4GBmQ6qn2oVRGjUhioUp0iVxlsWTaXOv6ES3y9xlwSTcnnCyLvr8ihnbz/1rPt/f/DOtTcWnmMprRUzrGmlxwz2GSUJ9I1dYnBaXGcmBZNxw5c4lV/0i+63GXAAKo9IuroT+42ysiX7v0ZUL2hPbQ6YJNl2+mSBcN4gr7IuZamrZrxF9DCG4U+n54cMKE9a76vZVGRj4PDb2dP1HgAgwHyMTBgaHJWPieInb02QcdN+8obnzfOe34nAaFztsKkOk2g1O1UaYJ3wtlnbmXjCe12zM6OzdZ85zMQaSa12alaFBOBhKpPRuuAVKY9IcOUh08lLR2F7Pylj49FhJEeQUx0B6dLIcsrovP8TLW62K9voyNQ6FBJ9bxCLmc+QcAn+uEtUR8fstrjuHEzX/GDJhdlNlc40mu8KhQ9KpPy4sz+OiMRnBCkrj6Fldq++clvB3Vrbd/XYfVS0DK+Zp3Fvwb/ctGRCjE2ESz7yGN54flXw6/0GLoDSFgpQP8dDs8v4dcFmkVf9gwwCYIR4g3F+Iu1dtmZioOTQAvEUVJCkdJ6sICiAJVeuqHxfpEPJtuf1IPEQawzjP0xvMeIhPJuHccDW6bE6ZzRb92GNqQehgmYc6px4/gblYsi+2xOaE5xCeLJxlBqXgNcE+1bjMa/FrS+gjzKP/nrHm6AU5+gAAAAAA=" />
|
||||
<img id="flag_dominica" src="data:image/webp;base64, UklGRhACAABXRUJQVlA4IAQCAACwDQCdASpQACcAPtFap02oJKQiKJQNEQAaCWwAyXtt/M8ctvxC/y8/xXsA2wHmA/gH9J/Wb3lf7N6gN4A9EDpb/3Erqps6ocQDBXyNWPiK5yPcGWfZ3mqrSH0c5USfuGJHoRX7s4/lKm9Lx+9ENWxj7hKofmA0AP6EZr2ePCr4oBF5jKpHt9t9y+4f/5SvpIKcJvuL9qSgrCSpXDlsIBV/m9WHDbLzp+Mpzz1xvv6H/C9y4TX5uRPW5zgDWReBJ8upd3Z7NM4n5gI6Zv97WcWhjnv+/0f/wrfzlL3lHANQOgjNw5fw4s8Rzmqalrn/f/ON4l2h/jfl8fxfoWzlo0+TUYPsR9yt1S8KxSSQAKRvZyV47zvnTNdwjh8zDs2oQda8+Zf7YNpQRl/k+HtouvaQ1888Zrotq5oky9X9R0Um4Je/zIFh5g37bR5rKAmH2xzRu8nDyojr5HvGORV8DLtgeFvMAIYH1AMFCUkWbrxO+Pfy6xbKEgQQcZWR87fqPhzjJgPLHn0p2rxCsPjoJ0AFhq7Rf8L28vNkx6Yj/cqYLMf5Qe51EXkmJebBPAgfqzVDiYmVqRQQQ3ruutdYcJhDmrGKKp/K5b7cYEu+E/3VQ3HskPW4yNgAaOaSZMZjbpX/4BDEA3wBXoLRDrdAokML31rtPlxnZoYhhZMtn574NSlmAAA=" />
|
||||
<img id="flag_south_africa" src="data:image/webp;base64, UklGRogCAABXRUJQVlA4IHwCAABwDgCdASpQADUAPs1WpUunpKOhrnccWPAZiWwA013Au2/r3DhdBPFHgPEA6TfmA8+P0l/9L04+oz3jlfrAAJVT2iPmyU9EUpk+WhsZ8DTRomQOGURhOPC/nIQ9cTal0/axBGi350rEfQYN1iXatB0EJ4zsSvbW6hneTRYAAP6dUeAl1RFdpz51a4akzh8ffCkbs8AgcKwrutSpxw5A+biIGn8XPfmuucwPTh/8WhMsIEOVoGuMdiV50O78uxqyidVSf+Oy8SSwfqhKUOmitduTRHMBSyLPSOBhfbl8Eu3dPjrAVvQV2SwfHHPUwWW0Ak2WpqQFiDkM8q2oicQ5ZoadE6wKbF/NJe8XMtZMFb2xguGGIrgjHFRYB1GUcRCPv6KLVJXPE08zCppwh6Oj0Dgtb7wYimSmVaamAd94I8eJplTTPuUnRL6fuim6YY2UA7kb2Chk2srF3bNY02zo9blT3SCv8Z37WGQ9JbnpLSPTx7YE0yLLsO5dYruWsvwIo/UHCz18ypnIRGF4axO82ZijbV2VXKPxmwuWE0t9qwFt3Q9a9UwDAY2l0lYZQWM41F39dDsYztwCpkyhZTF93Mypz2eAduq9g+qOM+Nw6suXGFzupDgq2L27afzzF8/oZBhBydWr/mk7Mt/rnUo5SwAuT8nxCGNHGHbZL8KEQ6cDbVzOihNZe7jrPMMs11PU9Zax8pewIz6D9+KWgNpYo4KcL3qDQUQE23HgPT7qdUqP4mCx7K/pRJZFINqz32xQJ7jg0Iet4A31Eh13PXOZ6aXS007oj9FZad6kt2RPxhodOrbLfEZztKAt2BSj1cUwuaJxB9aIoZF6qKM7gAA=" />
|
||||
<img id="flag_albania" src="data:image/webp;base64, UklGRg4CAABXRUJQVlA4IAICAADwCwCdASpQADcAPtFeqk8oJKQiJngLAQAaCWYA09WBvA/uXH2ZAbZHcYbxFvGX+PYIK1WWZpKWbiYCkDpvw+2mHyAOe9jYHN6RV5sTBr5ob4JYFT2q6LNX8WMuxw83zzxOKQQsWcgxgAD+6ez/7Ew5xOr/1aH/LQ/5aH1muZnXqsubkhQzEDwShL37QRwNyvuT4WzHXNmxfHXNzbsbNpAq+hXYCAkUb6nrLD7Z6S9sQSUzX1FxCavfvT/f8t2eyDuS7hWVjnWhQRqDnb92GKl813VWu17J8fUBWusgTgnfrIycex5kiPwJ1rtBAeZF/EmfBZQKjv0q/ia658bLEFSmit2ixMLtHInKIYgGp4u7Ox+NA9l5omr6qpVv5n8+QESGSO/+WBzWpHdviY4RJLSB277EC9JoiftfcwyfObvoaB2SRhjTz7TBPJdi+WOqb+5QxyiC/ZucUqlJS05k8tF3KZWS1eN8AeHP3sJplNxAzq4oimuZw7XOVsOL0qaS1WqTK/5dmkz3/OT4/t9ZvyqH2/i4h7yFPgTyaLpFvt13xJyX1deutu3VVKrKlfggmIgFT6oxSOGgaT2AoKg1EMlSjhVXsxlb9b135BOgqQF4ml/0cxKfnFRGjw6vPDPgPLhJ+bFEC0ITzPVxIOQ7whMP4Tjev0/4//LeaiHvdzBYoAAA" />
|
||||
<img id="flag_chile" src="data:image/webp;base64, UklGRvYAAABXRUJQVlA4IOoAAAAwCACdASpQADUAPtFkqU6oJiQiKzkoAQAaCUAPI+4A/gGEAfoAK99LFrp9PP0nIre+0mzfr5BT52wMWTfysKbZVbKffGjj3IoMAAD+3HrI7Ff9fZD66Unzr4LpYcGBDZKPSZy4bnR//qJmtmmz88AP9/4dSz4N79JkL/y44p/eykqWp+zIGbYsCj72zVNnX0LdIK/STAThGbKSMDkdssjR3SmUrRUiXTrp44PWYAb0J+mn6s1y/nFlfoqBxkwiRfjMv6iambjxxRmngJOXTMKXzISMKXa8PWeDqo8ZFERnFwwukZq7cDYgAAA=" />
|
||||
<img id="flag_central_african_republic" src="data:image/webp;base64, UklGRp4BAABXRUJQVlA4IJIBAACwCwCdASpQADUAPsVWp0unpSQhsBTcyPAYiWYA05lBfmeuDd4wF5wL6r6B+fVz2T+b/q7lgH7KgGz/c8LkeTqZoZNl9mgGg5XvFf9R2uEjUwd54ena8Jd75bBmhFM4UuXfNezYRAAA/uvgY5bjmsqiP1vk2Xh9p1Embi/yCqVDmTZK5838bhuXoXPwaPu4PTs3OaInzamNP+Bj9b5aCxjCA3R2gF7FuLxCaiz6Dv5WVO3OMuGwFne/lOkUPSW8hLgndtHiXURfpHCVO5sMLowNGRC8Ssx0GiCn4BfRXYAAZ/b5nWfo74zINX/D+VellivPs0bw+nj1m7zFD+526+eQLVT+O4sod7xluHH4uzq61jpb/vJ/ulddDgENie0xDIFpeqZiHFcJA389pjt0U1tqbW3PJwaIAgvq66tWwnzfSafJBCalUFH68PuS26vDwdR4+nZw3dvn36yv/mOQfXdteucVUjD/TIffs3G/3c34IbIKmm7LmwUGRm4qQW9wEUyu0lkpTUzRwiqomY4KF6A0AAA=" />
|
||||
<img id="flag_gibraltar" src="data:image/webp;base64, UklGRiQBAABXRUJQVlA4IBgBAADQBwCdASpQACcAPtFeqk+oJKOiJnVaqQAaCUAamLGpAHVr0EHeAFmCyAKZxk+eWp7pKhBiohq3uO5/lXDjGGG1gLSYBbO88AD+9lCyK19KIFLlEBkz4hhM5FRCGEtu8AmJ7R7ieCDv3j/gfYxNkTPvUG7rY4vFCIfz2tZz0afpMLtFZAbt0JWuKjf24CPPnGSXXnz/40i+06Cf98N9pzwu76A48LDUKwtBP2TbsrCOozWii3T0xEXigzIsqdJz3HXuaJwnnYXU/hPt9kkeuV0N+L9BK78+cuyyId3v9IaIAWqJ3wxsGbhzGAaA8v1ejvse9yZv5sTR68drR68lgNKepI10LvBmCMxNSisDds9yxjj9aUuceAAA" />
|
||||
<img id="flag_cyprus" src="data:image/webp;base64, UklGRiIBAABXRUJQVlA4IBYBAABQCACdASpQADAAPtFeqE8oJSOiKJQK6QAaCUAPGkZlABtoND/yUlfgVN9moyprwY9UcasZDFDQ4Gh/AH9do4okSl1f5UOwtRAnqAAA/vant+8ZPjZ5HU+7fDXLPBr/cmTn/K81wrrX5+JPl+DJAKTq5PzDUMBxnHG0nv1i7ykT/5hsvboK/8vySO7L62WbcOhFttFclY91jCGLVEwiv6duKKEwYh3zVXDt65FbMgMNvJ95UlTFJ+HXp4ac9plrT6YGTbia8/Avczv5qnEid8acJfuckSPNrUIedcGrnFqeANd1GS5zxTyU91y7dmiTbasm/DElG9cKzZC6OA8leHTP7b4KHADyRrmcJqIfrOLzFXhSegAAAA==" />
|
||||
<img id="flag_panama" src="data:image/webp;base64, UklGRrYBAABXRUJQVlA4IKoBAAAwDACdASpQADUAPtFcqE2oJSQiJnQM+QAaCWQA0UITfmbtn6ADnkNMA3n3/yo8EI9rSXm9rQILQY33yJbjW3EpT44F9n4Zm18nduqU1Tw+7qgg9e2iwLfC3w1XTa5qQHc6HmnEIAfZgcMAAP74/MsGZ3ksIypzxBZnhSzo1/CpcXkm+d0V7l1O1vVRh1oZVaAIM1f5Vidhq4mIcwYe4Ir8DXQVNEoANXJvmjI+Cj/aQESfUmbA1oFjjfWZi9kdp/3r/SQv/8RD1v2FDujt2yRvjt5OKUVTr9wkI1UZU7sT5HaLWV/46tCYyd6sSXgNhcPiyQE3tYN7Tmt/j3zE4hCuOxfF10u3jphAIa+qqsbWSosql0Svq141qJqtiXqO/SwJtrUsDiyDcgoigLWKXvSkddGNhTv/A6DgfusqE8z6E9VOLGgyUQsUcXhM7LrapeTphUuQ+aLo7Xl1u/J5x5irFKZuu+TKqVQcxxwzb6xPe359zWNZGefp7iB5Wcipr8GOjDbdSJbHT1WIaHbEu0jwZZK7B9/rSLPAYgKAoC1IweFAXp3WEAAAAAA=" />
|
||||
<img id="flag_falkland_islands" src="data:image/webp;base64, UklGRtICAABXRUJQVlA4IMYCAAAwDgCdASpQACcAPtFWpUyoJKOiLvbbAQAaCWwAzmhCKvs+WWvUvtovMB5M36ze73/gb4BvH9ZAxsnb/DCDBIASqKaT5BvqMKMaGqEWamP8smLQknwQiBj+mQVBIpLtu1OAm3tvTFQ7I7TQ5Z+zTBqLIVMTug1md5vrYADieMrnqgZQvf6sWaSWGvGNUxwCUfJqL3yx7kszgP5sxCOjUp7irk647vkYFgNdv37uR6hlSp0Vp9PdLaFaOolTnrmSBpwi01ZEGuzPenR/7GdQ8KzF0kt8qJ0v5ij8maWiQ7V9ya8PFs2QVl46yrsfvfMqSLKPhnOJy39PX7bd8MMF2OubSt71x4AWr8BV7hnt74ZjmYSdPzpgoIFw5UtYmcgt9f32EyPrcG/eDxk47lbPrbxS3b/+Z8N0pq8LFkNUQg2hgX6GfU6nnaic2d7df/0c+Oy7wXno+Nqtr8cLGyM0R+PdkQGTlGVqqmT7ZmA9wRYv3MPaBtc00NMwZFvfAABDI73bcYeBukfIV/I4j3I4dKoeqBoRDapSJHQ2GafsyjQf1zn9w3H/2O3Tyb5VNpefxekEjc/cJw8+1d2X96apcJnQwp8asfKT51Pba4KdNXlKWezd35JkOSDvmzzwnbhznSJnbbDglQmpwlJbRmqoQSkf/WcXCWg8HtaVk1UdwJn1OvuFFFvgUcUuGo9DaLuUqsRvEJOeeyCRg0ZwbpQ9HmEc/LYrWG+3/y54Epb+StvY7pLaXySXxYvzjOzJobwSN2sb8g5aoOVkOB9BeLeml5x5jq9KHKQ7IR5aO0aAw9a+kp8d1mjBy9Evx59Yq5zkN/2Uqu5u52xM48pg1XmfN5Q/22lxLjEER7CHIIg5bkVMVIKuqkaPJf1PfoCFXsawVaXyjK+ahgfx/hFGHN2cHsIUkiacIph4X2NMTl/srAMLY5YAAAAAAA==" />
|
||||
<img id="flag_guernsey" src="data:image/webp;base64, UklGRt4BAABXRUJQVlA4INIBAACwDACdASpQADUAPtFeqE4oJSQiKBZruQAaCWoA1E1BXX4N/TdP/v1/RG6dBh5j/OV/mfql8//qK/Qz8ID4hyI7Vdohb1xvjKuLYr99KVgr1ulmOkTvth7vncGXKLLe9Lc02zYbXSo96wa1lTJeEAD++yHBeT3gHs6qgaazbzNyzHjNaaFWO4mt5zkr38NSAqGjtmmSaaT2Bwtz262cTK8rmPMLOHOA90F30RD//LdG7yzcMtb5C2Z9gDLZnuAB+/CO04ZZaoiR3/6S6o7ShM+VZ0o/x6X7RK5B/FCQiyZHg1ccvJrOhlIwHhm4A61aFv24LLGFnhYL6X9nFgD4flCGbRysq28qCz5vzpSqMW0UIZ3NNfUuVV2cNcG9PsA4VjbUNoQ1cf4v0mBcuommQ8BYb4h/1ps8bZOtG0lqSsCJ35w+eIWkTCRyRQEQQUz1ZDX9Xb95dfh9IFQAWs9boQirPgeQWUj6bEhbzv1+NZihdCD7NLQrecRC+3s5TjOcN5puCjOP3KJvwxByIzw08ggjbC1SbwC3mNG4qt2TwT2CqLg+79PByzrVP250PMPudDzD8tHJ0Ab12NVnEnNDh7URnRJ/c9Dxb6k+mbCsSEae+AAA" />
|
||||
<img id="flag_morocco" src="data:image/webp;base64, UklGRpYAAABXRUJQVlA4IIoAAAAQBQCdASpQADUAPtForVEoJiQipNqoeQAaCWMAVgBQA3hQAz+EFY1AT495j53cezyAAP7kTUyeGyo7elJ/6qp6/G7//5mj/0m/7DeGokEbdI2EwvHfRbktIQwFCLXWShT71uzR//Kx79x6wsaibxI0ex5MHP16cSOS4MhnRkLl04ESADWz1YAAAAA=" />
|
||||
<img id="flag_kazakhstan" src="data:image/webp;base64, UklGRlIBAABXRUJQVlA4IEYBAAAQCQCdASpQACcAPtFmqU+oJiOiJFgLsQAaCWoA0euJfEcTS4X5TbIaH/1DH6zcByjWlZ+8v1+1OXydY5EulQ7c5dDVcK86Fr9/sNPQQVSeyAAAzjRgZrA/doy8ThF8sdjwzWTA6ZFG/HXuWhRlDu/ugUvxwTQwedqJOW/mcmJl4YHnEeZurSuqewfcKTVuBclTHCLUZVslf1DXtAzdecItZ2e6hWRSKALdcLu93bzxE8+amFYJtB9Crffh+sxAkTb6UJZEH9yxTy+JMMyFxCyu21z0LucFt9am9dlvUj4dLPWFpDvdyZwFlXiYCN8YbykQSkotG8g2LfgTagdXXtP03G0WLmVWBN88InW4rbVsf1UGYm4WLeWRj75TLQnuvNjytjgIKV5GbTsB5QSg112+1t5dzc5MTvAc2YdfrAJwwdaAAAAAAA==" />
|
||||
<img id="flag_uae" src="data:image/webp;base64, UklGRpQAAABXRUJQVlA4IIgAAAAwBgCdASpQACcAPslQo0unpKMhtVmYAPAZCUAPC35L+KrN/90ABd73sbAb8ie2Nh7c+k41sguk8zKAAP7E7///KUE4Lt9//+emNpQevQCxQcbfVVyRWpuWdCmCXlj+/7WLFMGWLP+Jp8uptne3zViS9iiAIkYRf+VHc9Rwf3BI2FV6nlymAAAA" />
|
||||
<img id="flag_belarus" src="data:image/webp;base64, UklGRloBAABXRUJQVlA4IE4BAABwCACdASpQACcAPtFiqk8oJaQiJnqqqQAaCWIAeR9+ZbOe4V9YB0u6NBIwf7N4SRfHO5GOyVsdcF/1IN0IFdv+EsKiPaSpJU6P43YAAP7rhgZ/AAea9bWN99MY0ak76vrCXoAdZTcgbdXyII76ENkyu4kw2ko5dAk8U0/7z2rdCFdTcCq2+jmSDD/adOzmREQU0PEKK+65yX/5jNYWx/VGlX+d20u19Z4Kjk4iyvvr/ybqwsoEq+sgGTQSqRhntSOG+y7azJATrb/y9MJpmlNMCyV05X2D+y6ldFPSiNUfCTZ0O9+rOkbhCzoLNdvRAtLGR17/g0Deo7JvARXY416a+pNAPfimn4D+P+f+n/H/PDx//qbpG+BEkFafxzhW3k3W7T+kJUrX1aKfa0BaZZUvohfgG/iSBmjU9H3bC5NiQ/c/7w9zf6G/5EQbeYAA" />
|
||||
<img id="flag_ireland" src="data:image/webp;base64, UklGRnQAAABXRUJQVlA4IGgAAADwBACdASpQACcAPtFYpEwoJSOiLugBABoJQBK56b70kA3qRZd9VGuk+MyEYoiX4+AA/uLev+LHecz7wubTrbufs7UcZDIxflVXiDb3jhmjy/vD2+hPYgitd0jJYHnp8yJtN0feMoAAAA==" />
|
||||
<img id="flag_northern_mariana_islands" src="data:image/webp;base64, UklGRqACAABXRUJQVlA4WAoAAAAQAAAATwAAJwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzru9Ivo/AQ04C7wf14ADAFZQOCBaAgAAsA0AnQEqUAAoAD7RXKVMKCWjoizYC4kAGglsAM0JQT+/tV9jasNzoO16BfIE6nbAbkv0AP7N1PW83ftAwwVqctjSBM9m+CV49s5syH1UBXyFnC43F4oAFKRD8j2nprNhTNzfGmAZWopLDBzQUrI+llFLvSEwAAD+7CZf8PFjdvxSqf+UA689+mkkD9gRByQbb0IojIMxtyuSZH2JQhT729cTblUi5h2MLgIQgOGmAGkzvwlD+h74TxsmMwWgb1nT9v/q3c4TmTxOefu8ODpeYinIyUe3QIaMw9kAI9Vn5F8lYSnCcbqXGYFna0lxJ9O+POOVIMLZ2qFFOd4SaOehjSaNe99dAj1mH6xO47r3GxoJAZdOVpcMLZ6AGyVlSA9lSItYki6HLRkb7gkIMRt6u/A2hGG23+FzcYEWmr3hm05KejPIVzQCcvvVFh+m3JK4YG34UfdguY5j3k2hZ2fdGCVf+V1PS3J920lbzWj+ftLPCVU5p7UL4NBLYQq5zj8mbI8aUsH7cpabyNv7cFK4xJz27IP9kSnMYIxQogG4+ahIiKELzMz67wXntpZ4pzPDglKK9wzlNQXAxWFz+NMPpdqNIc/b4zsZps8/9Q6QLw9bN3h5jyM3j1JGeHgu6Ol9Jpt7o9Vh9ZQ82soUSDcPZ6jz5YKmewkFjd9e7EZeg4teWrjfp0KeZ5zeReFfIvhp2iyUqYLBjAFOzHL6vLYtUfxw/nSV0b6T5FoLFqW0G2WxOw4ZuL0HZtjR4L302Q0XPugQREuilao8feQRAdVDM9Ldqyr8WhYAAAA=" />
|
||||
<img id="flag_bulgaria" src="data:image/webp;base64, UklGRnoAAABXRUJQVlA4IG4AAABQBQCdASpQADQAPtFapUyoJSOiMZdIAQAaCUAO4L5WAtIgY8I5lkqmaBkOg5WPyFYeXSgA/vULaD3wF/s3Jp//RYdiLZyhzzPUpPcunZghSa/4vHVVAbq1QHf+L/2ckkVn9d/2cknkj00N4AAAAA==" />
|
||||
<img id="flag_guadeloupe" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADUAPtFYpUwoJSOiLmgBABoJQBq+MDe4AbAdKqlNAmgSOnGTFnYkYtvO2JEAAP7wG9/q7wo3slfv2/vnSv8Hv17zbJ/qV2ep3Zk+k4daqgOdHBZnLlmOd3s/Zf32WwTjIWr013Cz8AAAAAAAAA==" />
|
||||
<img id="flag_namibia" src="data:image/webp;base64, UklGRrQDAABXRUJQVlA4IKgDAAAQFACdASpQADgAPslSokunpKMhsZi8cPAZCWwAy9f29leueazW37B+IOZ1tjnIeIB+o3Xk8xHngefb6bGSPfsxhHX9L7QP7JXYfkzyA7wdqD+3bwPAnSasrftF7AH6jdYxONll2xbtE/KCkXAaCQelDb5iS7y9sxhM39KJtnBLyDCoijQZvC9h4ZYMUPV/LPT9Mji2zVNNsX8yHIrC0ncKYW7I7tuE3qYAAPugc7e74/hfM8MBIx89jAwtHLTnZSyrp7/+IcFNqv/Hs9xS9Kuf+tH2HoewwtmuZvnZF4GxGTCvV30U99q6CgtxXxV83MG5gPmk8JBy816evuxBOy5NPvmXRRCKkOQkFBkJsLDGZrBiJI99iru8pf6SreGBD6NxI4oHaLzJKB2gV996Y5MujuDKACpeWfb6XgSlokuZzyZ0mqDQuUjwMUvmvaW4I0T8eYvngEUfhu0Aei7PZqenlq06HhNjIFrbsGhUr3FuDO6P4/jQ7lVns21O+W0ohr/o1jTSCMkd3giWJPrLkxRk9FmZY7ukjWF4bsxF/TKu9xLgwnMuc5nsub9EzG9k+WOqnH95R9cR96wCI85EMRjXwhhPSzg5a9TD/i3435kIjm607UEovk7S7594zwmQF4QtvtNISDr3ePiMsTF2YB4Giaq1Yd6yN+MRXE3EVcQluM7gQH1sZFEwgI1Jj+TfLEXeuFDz6xwpznA17WQmZRSAczL93GBTREEyN1z3r8IdTd3xkLP37NzK8VdAbMJFF0B6KwzeZ6L3fugiui/5F8B+wH0CLD64frYNzl3hBtuZta0n3ah26OHDbtoTCUbNT7f2e2LK3XZQd2Skew0pF2P3W0RcjYuAtmGaiR+Wf1UeUaROhm2Ppm7cNxb9tkHj/Va1PVbqaMd0eyqcg5Y1N7kYjmE3bQ6b9vyx0YIum7qhPDNdZ0C7BL26DvYZax/xswgSEGuKkoUJcQHADiok4tliRYBJOhbxHOEnijlXxY34U8M74HDI6H14dnRH6DP4Yt6uWILHTN5PE4i0O5RX6MY/UdcshU7zHYwc+0IlFMD0O8ThX//rT9vGEJCSOt5a9qtn5HykrwjLKd8pjNPQ7C7BDmebeI9y3df3gtTO/ULgTaDtSi4ABJVs51wQOXY4d9R46z5h0xQnH4DYc3kan8acJULN1u37v4/KA1C0fNhOemYu2aWNTETxfV5114XkMY2pMfxaiGqhUzKQrkYjXfScASFPAAAAAAA=" />
|
||||
<img id="flag_hong_kong" src="data:image/webp;base64, UklGRvYBAABXRUJQVlA4IOoBAADwCwCdASpQADUAPtFiq1AoJaOipNqqWQAaCWgA1MV4/qupIQU0AbYDzAdCXzgOo33j9fgrQUAHuZVdowIwTnVZj/l3/DhDtkfxaQjF3+0mbF1n2PPdMC2A3EtXqYpAunK0oyIRhR6WAAD+5VE3ro/FBDFVfUeyPZGLf0mz/4mz/4mz5FTjNsn7uXtwTRNpUNtwvOFVHeiW1fQBz+ar0uM+q/z+55eP0+LzAb5DdGYZkBivI57c+91GGr3Xz0rEe/zn4GkUGnz4Qp/rbHeDRctxRMleF3OGzZ4lXToU46euGT2ZIoq8XtFyeadZDdzNMJMz4nvYgJQlfR3FzFkOPxYKX3JH7uNO3a76vcc9OXfp4eog8UBobmPJHw+mRjpMzQjTo+jEitaJS2HEDGvt/bC/+wYMRwHT3iAqq9lzl/+cYp7TQbB+XdgkI0+ob+GpURbFOTasrgKuu0eZ7w2kAiPvEASeBpF2vx5GqLHA4s9b04ZyouF6nOy8P0AfUEazNRD2UZ81w3zq2ri992CxpR5RtuSfG7lBYMWhX1RiSGRo5v7o9wQ1JUvC0YfWB/c1SOoPQy1e/IMmc2WN8k/n2JTD9fOmH1YXdwcFXXsyuJ3hv98dZOYy65TrO/saOr5xe7OnQ5q6BwngAAAA" />
|
||||
<img id="flag_belgium" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADwAPtFWpEyoJKOiLn44AQAaCUAPA0D7l5fUv4xdk2dRbVW9t5KKD/dHxIgAAP72neeq0Jt3Knos/+NHapT0//N5qoueLw/CD8nvBAUWNw44ZaCyMYVX936h2l1SBeuzvkmTZq10f3NE3uOYAA==" />
|
||||
<img id="flag_qatar" src="data:image/webp;base64, UklGRtIAAABXRUJQVlA4IMYAAACQBQCdASpQACcAPtFkrFAoJaSipmipABoJZQAL4A/2jASS+UHI347PGN+ePbla1PGhy7yIAAD+9W5l+WL7J0BdT9Oc/V+ecarWq2uI7zfxRnbZsv/YzHTn2fS8vMKnXyyrj/AKuy5eEDTTaghRYjDyaw61T4dTYTnTa6KTnRpyBw7gkaewJqyXIFtMs2b7O3BGp8JpW3InljOTj3s3GA7qOn5tqFx3RxZZ1dsgeCOxbth7UaIOsu87V9ZenuNmXREBnyAAAAA=" />
|
||||
<img id="flag_sweden" src="data:image/webp;base64, UklGRigBAABXRUJQVlA4IBwBAAAwCACdASpQADAAPsVaoUunpiMhtVgIAPAYiWYAhQY7vr32MS6X/AfwD3AZwD9dgQeZcSVuaG4xQxYgOjom/G2lRiGWNYXJvPagIAD+694v/yAaYSH/57ewen6HqDMcab3/Ds12h9z84BfFZXtue9cqX5wLSboz/9GBfOdCf9GBfPcJynQzn6LSUZM5zwButiO+/tcjt9p5v3M6eWjPczSRvBvsct6EAA8w3B5eChJC4qWcyUR3OPKUKWXrC6fvfAGpPh2aGCn4X80NRTEue4ycVXqcNtpn9uFD1Zvv9f78oLVLOZZjahghp/UFAX+C5H7qDtFX5XbqzWBAfhW9Ca8J9Y4/e8k3HYkikZBt7ksKpGRFRlduMVyj0gAAAA==" />
|
||||
<img id="flag_soloman_islands" src="data:image/webp;base64, UklGRrwCAABXRUJQVlA4ILACAADQDgCdASpQACcAPs1YpUunpaOhrvbcAPAZiWwAxvF42/3lfgOPI318B9C3AA8wH6ueuj5//pwZKl+0/7Ve0zdrNICpBHArgJWA2xitVk32tR/NR76f2CJeKn7/bfeJFcpUZAsozvn/8QIRvz/hJAv+06oKLzt9C7QVLyP+fwSAAP6nCJwkWzLOiBR7QcLFzoo+aLoRCiWpp/g6vlUdA0xcrwNk4sf1toQeIHRBfohM+fJfEu1TMRW7rOni16Zj7XU74jAztWDp3Nl/o/TuhiAf1OTD4YU5KkvK/c7vkiC9/RHqo53ftEBp7alaPnwy6eo/dxOXycGnM5eRnD/ZJiFnxZJ181ZMAozxqBG5bP3LbuO9pZ9sIxvjMaFfLbZ2DN5ealoY/ZVx0veLX5JYpB+bdRoAl5ftw2Ph6cvHvG1d5oyUIqRDFdGzHirn/aVimaY0UeMx4en1zwBTN0t8cXkgKJ4MXyU9W3DUfoA9HxxD1RVTXUFq5M2rF2JWh02RYY33hjAzF+8izEEzujdD8lHogw7yW+Oo1XvLqwdLzMx7p9/wuNlYdDyld/4vaiCyi1AIvOzElMgT6BhUoJkfWDBfvnu9QqPVzT7T004nC6PoMniRZYLbuOlsGAPSVNFJl8yLHFkQDEQYjcnoUVQkqBwuo7EAL+9VgdGfw/mWlN0RRLHE70Mfs4EiwfA8TiGlctoCBqIYUGexCaPL3XF8V++dpyM76TYvTBGZRX6cBfj+H8y0pn6Y3RcQT6P3amTxQPbvEx9t4MjimF9Ak8/sayf24cck/w52J4LfgjOuIDsruW3cZ+HfkY0D6VPlDuwhfxiaDO2eRdrj/H9PlpaP7wlb4Uceb31kd5eVRWrdtDrGO7IS2lUQDhsBifRsBz+njZFbdWNhZb1VsJoAAAAAAAAA" />
|
||||
<img id="flag_iraq" src="data:image/webp;base64, UklGRnoBAABXRUJQVlA4IG4BAACwCQCdASpQADUAPtFgqU6oJaQiJMvBABoJQBKgfwDT3SAHrZ6YBu9CPBCO6u9xHF95tj3zKYutKKtcKveMD3QTNRnj0/v9qXXVTO63dzsvLcn8zYecwAD+6mX/ZeyPYF4/6tD/8tD/8tD9yrBVJkB8Bv9eC9I4JG632lS+kcVlL6fPukQqcufDtIhQ4eoJb504nH4uMtFl9pWWpplN78vL/EPeZntPpqbftwdzMguVD6pgSgiFpJgMcF1WbA8SbRH0cdrCgWE0aUE5zHu3Oq1RvgaK40tTxzgK0pS3XUuYx2zmPhYYKiEuFyHiXbGzeSQieLc5B85O1JSFoBdj02AVdBt/o81Fxytf9vhi1VQjDLB8nGNYc1P6KD9Ilj0i5VQQ6onjIJaL+fMqMyybvUke/z6dmtnILDwor0Ivpoi6KFByMjLGzIo97DMnkPsTPG8KSPYSi1dihQX0y5wt0D/f1p9F7JS57AIr6TedAAA=" />
|
||||
<img id="flag_micronesia" src="data:image/webp;base64, UklGRiYBAABXRUJQVlA4IBoBAABwBwCdASpQACkAPtFerU+oJKSiKrM40QAaCWMA04FvCKbYAU7YnFWI+TH+maREBOGU2+RRi093L5Q7uM5iGxNh6GtMgAD+0EgKj/w59sfvZK//X3lDsSiTmlNou23OehsqHlGH5xOwVPVZgzCuhNTrGruH+jGALNWz3C9XtlvepFlG9JuOXlPvhLrA1nzjEsGtqqBFpd1SWtG5WeAZ6OgcljlAlfsN7T6PbQRn2Uhg2s2VDJmBjvG2db/kLsQ1oJLFigG44cHF+RlcTFt0psdYatRnsNzSJ/OX5qSH8G0bxgkoM7847LDOvR6wHlX9Z7aj9ydVlun/Md33lxo7WO0n47VDPIL0bj4mZMyc3aLYh9LvwzM6ZOJoAAA=" />
|
||||
<img id="flag_samoa" src="data:image/webp;base64, UklGRvYAAABXRUJQVlA4IOoAAADQBwCdASpQACcAPtFkqE6oP6OiLNK4A/AaCUASoGpY9Ak6v8AuMC7QCCmFo/e6Pl5Ok4qhZypRaknpwT0r8thxaQI4/d1IYAD+680lp/pgtSlTvPrBc3XSLVef2nDyxb25XkZOOGYJDauZppX5NhP5Qe2ilh/qXr6hHM2nFSa9jeCrSueue/j1vRZV3hgQZeXNX/tE0tSyhDAdZhtBe//PtH7L/+cSOSEcGqAOgFq8hKAqr7Ujl2p+Vq8IZlecKVbpcou1wUuk/t/Qjde4j6AoWNxz1FKxSduIPFObWyckfs3RsIhHQYYIAAA=" />
|
||||
<img id="flag_nicaragua" src="data:image/webp;base64, UklGRtgAAABXRUJQVlA4IMwAAABwBgCdASpQAC8APtForlIoJaQjoigBABoJQBpMeslgC0RJRgcotUAShn7ueAHEQ+7favOwIQHqY9GJM7AA/vdxfM/6H3hg4jn/q7vZweTXl+t5WTIuvWFo5yePqAWMRfprPtBnk3ajDtJ86QqjllL/gd2ePh6JHBUCc1/ibSUpp1qK4YYgPCgb7ygWv7IkQIBZNVev8nSRvZGgTJ7gwI0Pr4uV5WBICYGJAXYUJyaWEaaOUIY2Nsoe2vKT9z+UQZbDJ4Rk7f3ZG/gAAAA=" />
|
||||
<img id="flag_norfolk_island" src="data:image/webp;base64, UklGRp4BAABXRUJQVlA4IJIBAAAwCQCdASpQACgAPtFgqU8oJaOiIi0hABoJZADQja4o/kEg3tPfNZmPoT2Bf1S3YA6UGMNuzjw64W950KONLCzynJjsv1mu3IJPkKRWuiACBqeAAP7tzs6h6NNf7j+yP5ypZ/hgQ44xfq5SPopG5vkbmmb02fuRpXF1loYzqu/3MzNw62F/7BdPNZzq0j/J9STBEr58o5QWz6m27PJsyL5Py2wzv7hZh30DVL5sXnUQzTSvH6sxqkoB9quVKnpSt/Zh//ia36zT/2H+bJ2AWlVmX4x8tk/pCFjQcj2oHZ8sIGCb4xk0nb/d3+aDZjcrXZYibvhvlOrwcIhej9ZPdMf5vGP7Pp3jwIrn7N5qhn7fE0FpXi7exgDoIe4Pk8+OMV4PUJ1M20A2NNuX++z+F4nFCgolipeDmuiku7RPA2RwlgRiwmEZjmkAfr5iISk9upXJRfbtmWOsyjqKru0RDre+rJTxRSpTpVluWmtYAW0l1gEn3Ox6pxJ/0eYQ3A+TP6BC7n8MzTciLXoAabfE4vQAAAA=" />
|
||||
<img id="flag_slovenia" src="data:image/webp;base64, UklGRkYBAABXRUJQVlA4IDoBAADQCACdASpQACcAPtFcqE2oJSQiKJQMWQAaCWYA08vWSx6xv0Aw2D9M/fusmMiOhAkVEU9IQlY9jXgp/0/1T/6Pplgp5kbUp3htGhbKGkeYAP736YGvrUlbOlCf6P2I/8gu55El6w8gX1nSIbG/fdfblzVl2+4/Bq09oWZhXMtGpbL5IUtxg/hbuVZ9rNawma2KBQS/hiSpUb2oJWEXySzU8QWBsa0o3VNWZlvtMiqvpRBq8weg3VPYbfabb9Df3kwpi3bTBJldedTd54oLw+gf9ooCV4C5bl2zH4VltzjZP1mQWWhbEhAT7cGGf3EamRCI2K6rdFj7yKS7MYDY05AE/Tcq+Zs3hKzaE2XoMQUdeH3FBccS6xgC9b03f/7eKGgT54fdlK008U4aF8AfwBpDXB3El+9iUAAAAA==" />
|
||||
<img id="flag_turks_and_caicos_islands" src="data:image/webp;base64, UklGRqACAABXRUJQVlA4IJQCAACQDgCdASpQACcAPtFYp00oJSOiLNVbiQAaCWwA0QVBXH4efeeMh3yfsZZ+oD8q7xTzFeUB6mN4i9DPyxvY1rlCrgICMOrAgwH0Z5/Q8Z+nSWoyxcvED1ojKJg2Ld75K+dvVwiCyoDVCnCKAvCV8PAB6GnchuxTs93p2tM0AAD+CN4TltGBXP23cnKkZeyu24ip8CLUajvaLJ6RO1dm4l+4VYDrmdI2bZVy9XIwVecPp/O8PYEN+GEkfXHUqVWtvdqGdzr6FlCCujlEBClHRWcF+0cw0DohwEgvNJG2K+gHbC/LvldtNCpHj72/DfgeoBQgWoLZ73eXlb2auoOOr43IV5mEpP5OThKraog2CBc8ouxvNCFXQdc0Ij4fq1ydFGr1LSQcXV2FRwP53z5nuBhrNNA4wcrRpYmEYr+T1EAt6M2yZFYZeeQSrcnFkuZLYl/317m4uqHAWCm+p/MH2h9BH+9OnfHNQ0cOHMt8YWTsblMIvVoeGxMCEPGdHDUWrg4H3HeU6mzLb3S835yvjfnx2ADvBxBJ4mu+WWVDfzYs9mnbd95aDS4dYrPyF92ml9g4DUIP11+4oP3HyhNUX072/zZH9PdviVlLSZFwKkHDungCwngk2LnXlduABEabVCbhkMCu8O+PokpM9SRkpJptb0z/o7Rtk+UhtrSbVgK0quVUPKo81+AkuKAu2Aux8t0Q0PgLyew6wKFxM05wpC3S/wmMGFsmfL4c/LjTpSAWuBbqHbQYJ5JCBimgdBoqo9VusrSSJ7XWyjUV6kZtNl6Md/xKRd+sJGtZ8wX3gTZRoZWE7m2Wq/705hk7Lb4ff2l8iTrj9ePvjPYgOnj+s+f42/BKMhLTPf7/J3x+QKHHRLCeAAA=" />
|
||||
<img id="flag_antarctica" src="data:image/webp;base64, UklGRu4DAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCCoAwAAUBEAnQEqUAA1AD7RWKRNqCSjIizZ+VkAGglAGWQCmhWFDaJiyHRvYzKYYCaR2av5Lntw6Ha9F9bCN8jdqwSVAB+rwCF50aUbYCtkpPIK1+NIhpXnJZmCK4oXz6Ih8MpUyzxePoj5UIzJN/bVU2XoQRDQ5F/CORnq0sfJx3P2vRf5Sts/Cefo8zeDk7t0NZkVR7AAAP73r2x/D7eoOVVQQmWhvSr3vTfUO/wAsqm/V8/4obH8q80/Nr7JUiuzphVL8kduHo1Ef1IckAm9iC7FtzK28Bp+xsiD4KZ2sNzBM3I9epS9s8ae1wjlNWT+nR0y01l1V1szceAF0xUoMEScDMlH/bLDc44R5gNL2TTk9FYerSMCBZ695dtbtm9X1Q/k8Q/KZmZmRQ1twZ1YMV91viIk8kMn8uAcqmWeR0nLIaFGfSY7d0aMbx/pBnv/2Ckhg6ow6NCG6ITdFZU/WouGBNTowmIYTE/EyNMMCtopnVx+FCuOputbEppWgtHsntBuXDI2DZNRx2jDIHb5Gm2NzUAFt/HCb1T174n89EHIxf+c7Yg1VfdycQVVuAZ3aw33K9Rt0kyuMJ063s74Z2NyJQfW2MT/FO4uvQRBR83hZH4CLMIEYYq4JGHUISqw1vZ0WxOcri/W8i6+WkHdxdWBLO61aGQCEefPb5KEnm3Un/ToKzpTvjG3Bfp7K5t/FDhoI7KdQDYhkc6LnJmvgu+uyStH8K4obeWUORU0fYyLMWMws8Wlx9ocW0whzAUQ1w71zxIIcQWk5QuhXvLUIU4SZvBQs4NL6+/KPBE8pc5xRvuZijgTXJtxy3qJsQg/iMx6vROSmF+p54BY8Ik9Jne6OQkv4Jq2I2eWOXtgffxyxJF5DuMl2WSmccnf4rpZG5nJqg+OvcdCJzK8h9QxB0p9kaa0oE3R7xVqoGfK+HUUFa88CacG77Tb/l/Xfgy2U3ZIWuQQ+UwnQmcUTWtHmINfsfYOlTTFw9Khp4aszKRlRIOqCTKvhkikaPXlknYpElOdgskCtpBk3xeA4GA04wz6Htzk5sub6Ov+mLwHBWzkroLDRN8QpYhNjHzmu9erVvZPcTXN+Cp3NIDLtNrEUhuGFbBzKaaykb8VxhvkPdJMHi4BLKbkGhokkw9ADVCm1y6qE57gmbQ6oWEt2dt8UtYJhALuWXuuQ5KC8Us4stroehi5QSt599UzSzszPUf8oundOaIGx3WnrBRP40fEVdFIimlvH5gAAAAA" />
|
||||
<img id="flag_algeria" src="data:image/webp;base64, UklGRnoBAABXRUJQVlA4IG4BAAAwCgCdASpQADUAPtFiqk+oJaOiJNVbSQAaCWIA1IAeygYkvPhexfkVqw7lFhyZoWDug595fsL9dZqlTZ6aunPr8s+fbnoz8fAlO76by7zzWP9Q/aKAOUTyeAAA/n9SqXL85/W+F9nq2sknf2lJuPuClAVYOlDCX+sg3bP81YuirmO8q1J+yY7/n/gVzkNS75SXTWCe4jUGAgCkIWszhiLU0tXNkzv/8Gv/VwC/cRzsD9ufkVfP5ffUMe+fTcqi+99jmImE6LH3wZH/jaEG9i0VZIMvO2nhFZgp/omeYx1T0dZ9WX+HwqVx+y5m3jVdHN5ReLfxW7v257xSl0MWR36IqfkLjdsBE0b/dLJklHQpFmR8NEMbe1FwuO/4qGhLVQ3Ymz+i+4hFrbtzPJLlKBoBLG8ZU50ApqjzQ7qHXAc9vGdGLN+PAfUOi/dpRqTMnna46sdXpXFqzppR9cQ2lOcl8/QWaUgP24ErHQgAAAA=" />
|
||||
<img id="flag_russian_federation" src="data:image/webp;base64, UklGRoYAAABXRUJQVlA4IHoAAACwBgCdASpQADQAPtFapEuoJaOhsZi4AQAaCUAO4G2AYQB+gHv/gc/zyTdn/SAVwoxWx2UtOwaBMjxA6tsFwAD+9Qtm0Ian5gfRCryMFJ/9VHajoac9UH/0WwgSsQPHqXLs8CMOBq0mnp1O/2qa0ZOD+AvQCqA4AAAAAA==" />
|
||||
<img id="flag_portugal" src="data:image/webp;base64, UklGRqwBAABXRUJQVlA4IKABAACQCgCdASpQADUAPtFiqVCoJSOipngJAQAaCWgA1QGBvH4sfgDcW2yF2NegB0qExOtArgJWj3J6hk00G7Wa+LbwOEvQNkvc9HM7N1P20Vx78Rj3LvkqArdX9J+LEAAA41aj4qv2Z7KZtWJ/4D2B69peHTeqkDav1qLz5SBZLqqKGpVFFYoKgx8Zt+oWt6Ud5uk2EpgJJ/r9DnxPtIW3EcXMKM9xHhV/5Qq2TLWOF8G4uCsFXQ62wpVdGT01sxfas2fOprEYL3o7925xV4flP4x0zVx8aBrXm7WKyIf9xhmyNedc2xpFvrYC62pSUvTDZJ72ZQqw/wRIYhsf3azvAZZ7aEJE6XWm+DI9cKm0oSqRp330ixAefFwrZGJh1cMJUb00BaLqHtie2so7YAdh86V0KehXrD8Lps86rlALkoojApo4vGsh7N9hfesxVbzYEHAxhQffT5f2sOtTIZUlXM+1MIdWISFyHHrW2tK3Du+6UpfW8ffWRPPMnnkwxVMg795CJJS7GCsHB9coU5uURGXXSm2a5B80cyBUcg7joAAAAA==" />
|
||||
<img id="flag_wallis_and_futuna" src="data:image/webp;base64, UklGRlwCAABXRUJQVlA4IFACAAAQDgCdASpQADwAPtFYqUyoJSQiqBzMQQAaCWwA0I2Nvj/vPmqW5+02ED1G/aBvgPGZ6oHkV8An+1XWtL8EAA67x7WAI/0GXUA4CBm6kY1/BTtD1XC9KlMei0Tx07s7KiNin+JaM+856mhhsyD8BVOMhm6ujYDAJg4AAP7ZV9TmO1ZKd13nY5AlY+R8sqUXHGWI47926H/xi5sj4hqst1/aaer/pq+BIOqv5yFOhMunNaCOwuAQKkLoP0GyJxOABKamTlW4Y+Hqe89FxbV5PxYDA9+BxSWROF+RTQUXQ72cmIF2SQumI0OIkLLv4mp8JTcSh10b27atWiRj/nD3I0p67YoFf8EnRl/wSdAOXtY1eNx/2BV+S3de17Bd7BZHeRFPEtzWzmhp6ws+BEAnzYJ2Z0YbJzkcJZJ96g8U20fYTEVFKDnC5p4FfemtyMy9SCfC7/tYXMlR4e+Ag6IuLGy8LXGA4XmnuDye0dtiVomS8EklPXTT8vPuhBgcLwNJDEa4kN6yTSA65i/1gtawzq7DqciKQDxsWKbS28gle3nFTWd+qc9bBUj0LGuPqsklT7aL9/LA8pHdELJRVHohBotzFgRG1gdHk2fVlxLWnRRKSMVmSvRTBsaDRJYhLAzRwGpVRtC4wx48KFl54d2KNqwstip4cDYN8edcm+q7rglBepzQTF01dexDXKTZVrEV+lq0Xf4swhG6gCsrOVy3PqVO8pK5qy+MtyBifl82S/Os7Hi5K1TckKlW0tmbqBIIGEEI5Q/ED38yjpUm0PbmAAAA" />
|
||||
<img id="flag_saint_vicent_and_the_grenadines" src="data:image/webp;base64, UklGRmABAABXRUJQVlA4IFQBAAAQCwCdASpQADQAPtFcqU+oJKOiJnQLgQAaCWoA0uVBfgGru9V3gIhh/isQBuAN489ADyyvZSX4K0Ajj+AyVI9FfOpfn3t8YfDJC2oWy3LDFfFEhWfz0e6dG7/lSWT59N8gAP7ptmxccbAxb2HUjV/A/aTBf264/ub/8ycft1x/c38JB/kEC0J/IIE0d5Ty881mi3/GjWW/40Y+GqmZrJz39ra8EjrHo8ZbZ77A2bOIG7XlH9j7cJy0mu0CBbt/bHBTMhvk8dXtb6IRyLZDA/QDpMjvE8I9aR4KLrcCM0XqG3sdktJ1cx/BthP+qyFkgVDq4vBTnvsJFg9zcoH4U16RsFkDSmqLqbzTuT+fV9V+gU+LQp+sneCARiU1A4wWv3i0Dm4n1vvZvlqkz7ntkYkfueAd33IW0IXd8QsKYPpDuNDCtrojTJYkP2gk700gEN/eAAAA" />
|
||||
<img id="flag_lebanon" src="data:image/webp;base64, UklGRoYBAABXRUJQVlA4IHoBAADwCgCdASpQADQAPtFaqE8oJKOiJNVcsQAaCWQA013sfmf4AadX8K+FhkgPEA9f8bwLeWZYyLXjTY0RhMqkFKKSF6b/7GR7Q2yEiD637vkBhPl0139V5jflM+XpHo4umAAA+daF7VvOh+mqYxv7BPc+50tvytLY/ZeKPPuUR/p/h2UEihWV3gLu0ofzC8bw8wpddT0X7YWpny9CIKa2Sq9+BKCe3yOkxxRjd3e2IIy5R4IH1B2+K4+1VCH8G+b5o0EFbqv9pN8m6M4Rb2rFLRpMdkEUrd87C1336yKza609u9DL9WHvqkxxh3QBehyDWGQJndiLvpICUxnYdEIP51OTYxDUEWKnIGjYErB0izLTdbxXWiYGXyxMJ2xLSrymyrcuMl9rNQdVZ6WF9awUD7csCo/jwe33njrESl3+Tj0N7Roj9jOyvqS5+9sKPCuBTqhXAcEZhrv9QQEK1uHSKFRLp70HoFUGLcozp6Wp4X72RamQhgD9A64AAAA=" />
|
||||
<img id="flag_cambodia" src="data:image/webp;base64, UklGRr4BAABXRUJQVlA4ILIBAABQCwCdASpQADQAPtFcqE6oJT+iKBM8Q/AaCWgA0UHaflehGu92QH+A9gG2A8UD9gMtr9ABWAjgQgGt8kB6Tx3PxX83UiyRcgxQP3lEz8v5TzVpeZcJXQqfTBxq20gzJlkXdvAA/u1ZPn0jX5csZemd+LK51LXmlWL3t2CO1ctKW/M2t4lZmkOVh9dfqnvGcJlh93dBIo0awQWFSfsA8gtF5FoI7SUFqftJjpV3Jxa5AaN+Cl2de115sbx2EmtpnOcJnUTt1upJv8+hVMJBPi7t4Qn3/CHaKOZsLlQVt7OJFUjX1jHko9CWMR+n6xMEak010DWomdO6xdViVVTUnn5ZtMJMzfMvILxNcNwbmfsGt3HTQv7BM9z0gpSo2iwTCX1KAS5xu2AdsyUIQ/c0jDZU9+mA0av77oVLHMvkA/whZG4Qf+QZ+qTJeFz/sgH8GSMm3kWX9jE3idLqeLWDqsCRAp048n81dZNWlwYnK3Q3hnnee4zbYY6dgn89oyXiPVwjDaLBQZX+hOtFtlENSSy/57i/RH9qfhjd0fh2Np8ZnU/g7WnAt76M07/FszugAAAAAA==" />
|
||||
<img id="flag_dominican_republic" src="data:image/webp;base64, UklGRvwAAABXRUJQVlA4IPAAAACwBwCdASpQADQAPslco0unpaMhtNToAPAZCWQfQAmn3BPpOqReGogHiA59cDSHicpd3xWKx8xMcxzQWIgSZDEMJmE+DaNgAP7svX7/sQ1qRTSdjkL51lryXSso/oaK+HXda+M7Bz0mP8f2h7C8x/j/K9RbJ4x34mmLRs9/n+vkimyk8p2we/hv3/4rLF8n6rbJNwJcgiTOdozUTP55dnfMTnH9x66hrc+PuxCiJHQy5gCPwBJ4/7P3WMtsSzq89M/RP0T5hQx+F/c3+NeJadoDWM1eYehBLpvGMZDy8Y6v7hogLSNsaCQK6j8i3GQAAAA=" />
|
||||
<img id="flag_japan" src="data:image/webp;base64, UklGRk4BAABXRUJQVlA4IEIBAAAwCQCdASpQADcAPtFip04oJiOiLNYIqQAaCWIAeXslXdLrAbZ7nx9Mz3lUFk21NWsH3vTlGpFH6yOANLpGny9BxEDP5hwJsIGwaDSE37wCMx3gAP73HCTWiMD6akq7xoiv9k//zK0J/SUMlG+b1Zw43ye0Ak487FOw0utYrpSbc2mmDwT/cqtqfESCNWSsqfb4ppLW809JhYrRh2hOrUvDHOhG49eFy+omg9EB4+cRCzyfMk249NF/j/8m+BAxe+dDfs48fjfSkL8UzVL+sDc1SRk5VdPZ8HFz8S56WBLd08k7XAqFvsHTTuonlto8zSRY7FGzFXy0OXbHp47otGboslbIGSHlm4+dziMEe0i4o4bxAN2bK0/lLp6UcTQSPylZjrfAS8bDV/Fq5OJ3kHgVeSfFBYkHqIYzsO9bdygfwAAA" />
|
||||
<img id="flag_djibouti" src="data:image/webp;base64, UklGRgYBAABXRUJQVlA4IPoAAADwBwCdASpQAC8APtFaqE2oJSQiLvJKAQAaCWQA1Af7VgHoco0ARzVSGU3Oe0sgeb6Lse9vxJfN6B3lYWuDOorkjA7qzbyowvAA/vP8DzgahePUhl7gD+JzXGuz6LhNH5fgvkMcg5BJE+SBK5SbPJrOPlO8/HFrUv3eIlKnwpA3rNpHFCRJTePfUQaMMbsZyU9rSHf2V7XrXDySTH/aW6XD89j+amfq+Cxq+oyO7MEdvQhvybmlsOditRCyEFPKhb/kSuUKw30+wFDlsAi3kQwpfQiV75Ljq4rui60oqTD4NTZeLRP7f7/bdIt7BohoDKItqISNc8YAAAAA" />
|
||||
<img id="flag_belize" src="data:image/webp;base64, UklGRioCAABXRUJQVlA4IB4CAABwDgCdASpQADAAPtFYpU0oJSOiKrM+YQAaCWwA0fWB+AGud9gtw7alub+gey3bT/QB8AP0Y/YD3/+8A4wD0AOl2X4K0GWBpAmZDroN+08OGz5n+PWvmD79EzIuIlOzf/1daYvjoAGFzFDG0yvHcxuyT04riRlECtraD84AAP6+vC/6xHEx/GKKJ4G+454jTf3zPpv72bb5qjwIeiQ/YBIi+fMrv2tQRuMD0YSuuaEwhVMUgHkVSfwBsjWCWLwcRaEs3a4FjaJRfOiPrWoTnFVj1ApXPa8beEzxgaJ4NzLpIDriyE1FQdTGqHHRBwvRZsLJRbH+GQbQA/vOrNIM/cLN4L15fuogV5Yqntf1tL1X4mK0Hxodic/dTtrKH6unUHpP3mp6UbXa8opubxCTeP9WBvgXfn/FVX0nGk0PIJX13RFNJ0OJln5m0i1W8yHZkiXVuHggZGL1Afh62xD7PPHSCt4VwVRvg950IrsPED671D8/Sc9dfP/f0Vn7HiBnUWdA+xS36tX10NHdGAPncGs2Xm1DkeEiXHYCABrQLEKQha4i2Lhxm8780ibWjU7nLKhlb0DKFu98Xf/iPRNTui2g6AOwe7+FMq9Euxys3vtr+kWd0UCT8tHGmS1o+DWYWijU03YxYiusPJ4gKTWNxrkH5pBjUryvOyNjil67XV5+dpRHDgulFjYklMeDU0/0MjdvYC/2PL6f0+6OqxYAAA==" />
|
||||
<img id="flag_el_salvador" src="data:image/webp;base64, UklGRtwAAABXRUJQVlA4INAAAABwBwCdASpQAC8APtFgp0+oJaMiIi2xABoJYgDUEY3+AacB2P7ALsHGADlFRSTnlTzKZOUQ/L67EpyZokWfuZxgkFmFAAD+6Diz+FQSe6Y2fyFCHw4h/2voLNMGjEDw72Pv4CpQJDNmgocDwUmimlYbCYgiQZtmSkeXoy0AsftHUPN5eaRxzHw9a+YnlJNusepq7Oyde/hJ8vMI1K3lwRqMDq2ZCoQoJoMAoCAIIMFLo2GDIfZGf1/teZCjN9mH0u/0BEZAeYYJbr9F3QYAAAAA" />
|
||||
<img id="flag_iraq_new" src="data:image/webp;base64, UklGRkABAABXRUJQVlA4WAoAAAAQAAAATwAANQAAQUxQSCcAAAABHyAQSFRHz2SNiIgJZgImwWaWgGbk9d3vE9H/CYjBjsD9czHYQwEAVlA4IPIAAADwBgCdASpQADYAPtFgqU+oJaOiJNVbwQAaCUAF3qi15r21mbUfLzQ4mEgajMv3AWZ4tyJwlK83TYuhxlS7JGsAAP7upj/6qp6/G7//6En//BJ//wSfuAkfaB/szNWTdvJsH25U1xP+EZjSN9t/wjMBG6UKSpowKmL6BreIjZAUMQ9rwaTaiV/qbw6RG3BSAwawdDc/PIi6Cg6B5F//EOOwnL48/a6MrAo0UrVCVQtJ06BVwmX1tjRy+QDM9Es6jWd+jpuYAD6Gl5qfPjOvIb8FnpHaqVcvEjfWdrwgFFMask88OyV7J06ssP7Wz6AdgAAAAA==" />
|
||||
<img id="flag_mozambique" src="data:image/webp;base64, UklGRuoBAABXRUJQVlA4IN4BAADwCwCdASpQADUAPtFcp06oJSQiJnv8AQAaCWwAhQY1fs35K8pVuzuAeIt0mPMB5xXRJdQxvIf7b+hW0QVuXuTg+pAYV4CW05wkE+f7z+DnGW4/J57BUOidlzzrMZeZL/WLc+C3E7CkgAD+57Vs/+/otl3hWNOi3/+vff8DRaCXrPkXAcs+jb1dHVzWtoJ2+xcCVpAc1NNXoChI4ZA5P3P4ehyX4lk7FuWyu5CF72XkHwr5wuezct9Rf9O5OiI0nne2YL61eED74KG1OIpswcHwd6/P/NJbuWnwdS8eY/EA61xE00XlYrHQ4kL+AXS7urIIhahyxQPqetUilSwV1yOCDhSaxnVrMTey3P86J5dOUAlZV0isF8hKt1pBGdnLbwNC70SFejD3rCF9ezFClYQPfaUdRO72tA0K3XA3fHkzj+iGbqrF8UoMJLPN8wN3fEBrGYrp5E/8q3yw1bs7MwylK5vanajqGDd7wbsG9co+bqpHkZlVN0hvoDGMrXQCTCezQedendQHD/qd2he7+xMuuLoBRHlb1Pmue2YVhanYJtb0NYow+cf4An+dDuvKnars0M69fzZ8MKXAvFAV+DrbKVg4HmjzUDBgyPZTWX0weqyZ7ligCLZkw8WWAAAA" />
|
||||
<img id="flag_greece" src="data:image/webp;base64, UklGRnoBAABXRUJQVlA4IG4BAABQCwCdASpQADUAPtFirFIoJSQjo1gIcQAaCWoAd7n3rjOXDfIW7PUBtgPMB56NjnVrmaAGMuRnFeD5otfH/2ayfzl19mdqUi/9F7V2F5pASlP2X7Ce9CbHXmZ1CUH9NakpNMgA/uvgQlRe+lGrKssAvdHfqSh//+Aq24Fy7l4iVne/mnlH/9/Y2GYefXvxP+hi+3VFm5ezGqrkgVuLGgw39K6+jBpWXabamnGvkL80o2q8Sma2XbZJ1MqtKwwDTQkLgk9Y2IFEDLlC8KlFXV650eQg+0KZ4d9cmdr0tB9LAEDhVokql23hBNXMqadxaUdcb95tL9xeQnMWX4QM5j+puscHKZ2upwi9MpYGk/+Wf3J4lnOIvARXIW6lF6SRMS638WtnwWePf1DLIToInAmZZ4jrYLeBU0YCumnGDwYGhZ730z+Ampr3fU7fhY7vbr0DDS2hxyJ/dziICkuHx5mghiqI2co5R5urJQoAAAA=" />
|
||||
<img id="flag_united_kingdom" src="data:image/webp;base64, UklGRvoDAABXRUJQVlA4IO4DAAAQFACdASpQACgAPtFYoUyoJSMiLNgNUQAaCWwAsR7COS/Afkh7LNYftW9Dmz7DeVXtO/kfyGutt+tfqZ/Y/9o/Zs9MX1AP/lvsfS0+SB//7rvXbZU/e5CLfFX8QPcD/a1vszryDjDnKLTvPjeRj078ynhDVxGo6/6Wu7C1PYW2cH14LBik8YcukbxPELa2ny7iigC6CRt69LgftSDqlqEZSohvDIi3Aw5gAOJgeTNHiG3BbK3ylhp68l9r4uO6lq55aSJ3PMoGclPy1OByUtBGIUzjU5FDNxJZwYW8Z+C6g/+Thh9Y8HPdHue2FmpL1OFLoX+x9gpIXHvwTd2PXKl49NzwxYHSqOuO5kzePj2Ob4DhD+3nRG8s7rk6Jk2k7L/HV+Fl6IKrEcYc6fX6/0I8ah2KafJ9zfe6pzl+JuT+Cj6PhgSqruvvY7Jm0AYxI6vKIOUH8Fj5hR74PWz0AqHQmsOMj0SKGzdLMVsQlAoufi7kYetxINUVHSxGUOjQgDb8NGlT8VR2YDcwhN3mqvhsnEfO9oBzHJ7mM3V8y7iaIMB687wNUFMdGwu1P9b4xCE4UHQVnTnf0TCZ1Qd9YzdKN1hkL4IVbFCVgAkx90evkMguS77JNXnECH8CqlcCITrIxDgIQcHGkC1iOlYXt4YNFbZ8DwjqSJWL8pfCRgmGf4OsKF2AIhLsoooYWiv/8Hn5Yj2TXL5wBn2g7AB3oeJ2cufeAMKJmuXp8vkxEbhqDJhJ7afJeBM8Oy9e3fr3x108EndnoCWBc41y+9PgdEWW8KjRGYCA4f+WBI45I0hy1UUJ5rQyV0Nr+87goC1isy4SP/i8lLuMwVhP9/+eu+6CPjUDP/gV+/SWnn29HDu6BP+v72/jYnDfdme/st/pX/w1+rUCEKK87JY5hD2GtxGCnH0fhG439EfzsO8bIEo7OPxFOwWjj6hrzBIlkuDOKN/6CG+j8opDJCfJkXk7QoCtXutXH2vPWiOvcXbsbJDjF6wsAghaFqOrG4QF98v4njrQm0nxPCdevFFc1+nol90pftTWPjgYETv3SqjrtDV1vFS6A2qXQQdwoWxB5Ne3cfLeN2mUZ57XxOsQBw9CrpPf5dkURxf8yX5gsHxeSEtRkoRY4D1g04qPJV5X1MhBXlKaZVv30z0omr9N59ggjBaXbbMSX3c/VQd7+0whwuU9OxzzpZAEGASGyGJC8nH/vOCR/7zSq4VaWSkM1Hmxh8Gv0dPn/hdvtRiYwCgZ7OHuvmmnPElJaihc4lRC9kv09ZPoiNFCuI9gNKzE2AODw1D+mHnrloOH6eezbKbqig+XPLiF1gy9+mXWyf9cAAAA" />
|
||||
<img id="flag_senegal" src="data:image/webp;base64, UklGRu4AAABXRUJQVlA4IOIAAACwBgCdASpQAC8APtFgq0+oJaQiIiwBABoJZAB5jdldKAqED9AMsAAq8s/ty3eY9KYPoiQyixik9bHSwhrYAAD9jDFZM32zyp///CtKWUBomQS7PXrAJJKk5JTt1Fv2O8/kuMpC/yXGM6bcTNfYbiHy5NtRt8PVAu6vnTM1gu5N/MCiClk3+MBXCgnClPNN+Lqwn83qPINYDj3R5g+lrBmJedl4q0U9FYv0UVTSdk4wcBdKkQ6P6BKsvATOVJfyVPtYl7NgcVJBf6Jv0B91hPe15GGA+Mi7oYakQWC6ka17AAAA" />
|
||||
<img id="flag_antigua_and_barbuda" src="data:image/webp;base64, UklGRp4CAABXRUJQVlA4IJICAABwDwCdASpQADQAPtFYp0woJSOiLNYMAQAaCWwAyjmBuz/xfKochwj0bs4DxQOlf5gPOv0zb0APLZ9k/9zHIKVgzRUfXr/5Ug/qXFs/B+MT8pUAVV4MtHvHBBQGAeO7L2nXj1t/p2tnzDEevA9V5s58hLXGOPPg0v4Xhk47w8guSmoh/AAA/vGuZL4i+/Z3iKMj9+10vR7hR9zSwI6zal0wnvMtpod4DWkjZxLT4uzKIRxyX9Jssme8Ck9/FlheLnya7naeiPvyCfop2o+v8+vbdSLkl47PTEBB0m+BlPz6ED9XLwwyqXO+9DJ5/FA47WyyhjOpyjF3egOzRX2xPDH48WitOOM70vkF+kwY3gYZgLGBz1L4mh6iS3sjy6YPmIJawigyi0hbTn/bu/OMaG+lqI8RxVKRFb/pi/+m4+KpRTn8T49m/VrjkEbsohhyB0oKDNzvsLMzacImgnsjJTijVQST6xm5IcoXeEQ0n3VMiO6k6D52N24KWFsAiTHLt2YsiUp1qaZ7N24S7pvv3DAGLfTwrghINOq/sWzBJCSePgUEdo+J+vVMcUZzfhBMJPx+O2PzFBz727mGgBiaOze3a0kq+85H2FVxuXSHts2tJYZVyc5NWrmje0hL/pnyzs4/VoxUD2Cn6ba7039MaWitW+Kakz68GIDokbm89ntNdJotiCaZiGH3sSz4lfi7pWhwReUVJvmGVTVN8AnCtDSOn5ST1kQV4Vc6mHBGBxVkecwMRlL159g8Vq08cxnFF53yR1cvLmnpHP7U4gqB5iqc6lkDQtUIhsyfBCNH3Lqt8FpcnVEk/umzk7IHRtR71/c77SSMFRIGRDJ+U+1PFvfqproUzLrAGfTYZrjjEN0wAAAA" />
|
||||
<img id="flag_marshall_islands" src="data:image/webp;base64, UklGRvICAABXRUJQVlA4IOYCAABwEACdASpQACkAPs1SpUunpKOhsRYMkPAZiWwAyNGW294BzvPgN4CNbYP9Sv5O0RH7Y+v/6Of//6beSoeTdd9NHSpBWit3a4xwteGHhBjMef1TkUDyzymWziE4eedTMp2u1MLsnjneEe35KWqQbeE7d0v/BZ//pvugeHv30/0Ic/gKn/2sSupFyxBDgAD+9W0otX7baavwubXemDiZbfS5fI92TYXoMZWaKV+et+iBdQlON6AFGZAoSv92jW8g/V/Nu7fgry9kQcZxKMg1jrzrAfRm/EB4kpXJmZAtTEa5sLe0rZ/4pMaevZG9Ux240s/zLHbpsriVgw65VTaEFzZWMibtIQA+Rz3VaNHYsmiNkD+qlvBIzXOMamD/8cbMBxemfBulSum37dU29iPEzgrsEgrDHFhPEo8broyTmUy2VH4BYl/PBdQk9x8RmvX6RjE9FRR4A+hoy5n84efrsyUHCp/XZGZ7vbaCjOJg9kdZ/yYvynZn+u0F/H+w/WdleMbUoTgLC8t66DUhzIR8W+h/Vji7zzd3RArJX9u6naywwU5jR93enulXpIohR/Kp/ZuEYfgIHAfrTyduccGuRjA1jyonOb+pxKbFKxu8qZZ9sIDsMSWf6BELYmAJdJpLpee33mnsZjEPIgfqt7HXkEAMMh8P8+XXFk3yWRErPLEYS13CpBY++bSPCvxJ5zTde9Ef3ZLop97WkfkBGBZb+51IH6Y+4a8xAY0kyF7wa4miO/459EWs3G4mGhK1hnwLB12zhHMuK6fjV5jk0MBmTKvZtiXOJ5CMUuPdGTLQENlXusWq67e9cZCPHewossKVqIwgpJFpkpA5dXY9knt+lvNIPR4oFVWLkkVd3xXCi6+D64tu8moY2mscP3mmTMpGE+3kWoK7l6vku/JQhciebMgSolMv67KpoJRVxj3crAJuyz0yJonNLVjGK8FoxDIpzi3ADNcnAqtFbhKjcenuveUzoAAAAAAA" />
|
||||
<img id="flag_guam" src="data:image/webp;base64, UklGRoIBAABXRUJQVlA4WAoAAAAQAAAATwAAKgAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7z/0IADAFZQOCA8AQAA8AkAnQEqUAArAD7RWqdQKCQjIqRYDEkAGglsANAVbL86Zb5iQgHiS+jpkgHSqAk+i3rSwrtLaEDltuDc4hx3BirLHTJJuYIqDCHOxC3VwX31nf81zXz6gAD+7PLtBGW22B0XrDsvk4dbsIC6dP1MP+nnd/H+1kT6g3b2DkxOV/jMh/wbTInwYn63xzbg2triQekJPsbjQYiXt5R8cb4JS8jeiQAvW7aALV8AM35KzRrYx68KegZv7JKJFyvv6ApBiP+S2pAt8Blww1mVm2iUGXsAL9zSzO2BvxzmOYdrK80iYWwllSmE/TcsOMY1lYwYplxtvYNjuAQexrLY/NhcEyDrTCmHzD7knmOX4FSqnm8weO1Ox94fhQ9ylflPdTpv/8uQWiv2zWl//iN9JVgySMAACTz75LWyqkkAAA==" />
|
||||
<img id="flag_vatican_city" src="data:image/webp;base64, UklGRnwBAABXRUJQVlA4IHABAABwCACdASo+ADwAPtFipk6oJaMiKBv7UQAaCWYA0ewv1mpZg3i9GurgJXa34PKDo/W+ssM5MWpU1bZd9AyQmFbBfRwMChxXw+uCd7FwAP7wpdf/7Gb/+jN//Rm/sAf28my4AB3kkoIj/Jnw0+3/5Ji8vw0+3/5JhbnEvj526K9oqBKWP6yrJhAGeyNjJQWHkfnjsEGBaRJJDgFYchYreqT/Jz88ubNg9KoLgMdFs5F2ZZn05RS6QOab3fsoIH8vFsaEZ+GwdNi97HRm86gZ7ZFcDjbsX5f7aCHhliWkcydbRxqKdub2LUhdFOWRanXL5kf5mTIb1uvnhcpR+1fdRvRc7Gcgb4hSKgw4uynFORMPAQt1SubSu9vZh1khX537CLz5CxJGzgyFXQRpqHX2RotG8ksPP3o9QVjeSCwLJlaKrWiz5kP17pwWZEhm3ck043lruu9bImBQPlswObj8upjA9ykmAW+lngdRk09CxbAAAA==" />
|
||||
<img id="flag_venezuela" src="data:image/webp;base64, UklGRvwAAABXRUJQVlA4IPAAAAAwCACdASpQADUAPtFepUwoJaOiMZRoAQAaCWIAdjn5QJiB/ALj/AzbuVh9ZuF3QHdF7L8XCwCDYMlhy+i2OD4RSwdn/dHIc1LtMAD+8JCj//6yv6j3mo/TD/gl6lmNMsXVffYt/aTurvnaf/4yt/Js9T/4yt/Jv1BfSWPTqFyY9rn/sEWgivhm6JyDq85Ftths4LrCeDNdK0pqZXa5nCYQOnu3MpDIcu3d+G70yRbdi4vZx07PcRE3DvBy1qNBgNL81xiFrjKsQSw//+CaN+BOCaN+BOjb8zHTlGTGvP7SMAa83e5eUh7P0oHdfsAAAAA=" />
|
||||
<img id="flag_macao" src="data:image/webp;base64, UklGRoACAABXRUJQVlA4IHQCAACQDQCdASpQADQAPtFapU0oJSOiLNv6AQAaCWQA0xhOUHVj9tNzznow3hDeSl+bNXQMW858gaS/Iq4oo+G6RS3P/kw86TqME8RAuPUffGHeqU/5z8frg9ZhesO2NU66aqPBgaOoo/5feLdQEIkv5/M+zN6PFKAA/X0QLAYlBhTBr//kGP0NfgrvxwiHa1BfQ2H9dy+rnF3CjjxhANTWJ6cnx45RbflkGluZLtx/lf0B0yaQE5YKhutNDKb4QQ0YkOvq4vAI/Bbnc6uQoNxWjRlS0v2mM8m4NEa7IqnYOb0qXuJgD9lt3LTxaHsKRogwqqbKIXw6iqAW/6YMG2s0OJuo1kUFNbLjxNuH7p5Q1/eQ+YVPa5xNEjCEKy1TK6LaaIr6ak87elgpXSbKKDJjCstkNxqNDDOtVaWmO/795q9rFbaNOUFpEVCbY7ytukD6d0oGQSCjBaiGqIFTix+/l0irn147VZL9Ogj+Q0+5yASkWIMIdXB8EfzMWKb6EKEPHSXamopYaiB9XAztu2iWWyEwAXR12m4vhWtBtgfvudhdV5ow7fFzTA+pMZ8nSI2kyzrHZh282VS0/OkIvFolfp7wpwkVjgDOcezp2fhfXMn8qdTr+XWD4dnybL38uwf7vKfKkm614WhKXSq7z7Lk6SylNfpj7cZlr9HsB7K/zRjgQNZl2+YjnqG2s5bmMe9Y9rybP5pXRajHmdR9ujdwl0QuEd8pyQFwgEscBkPEd7XOgUitsLcg9fhYTSgjeX7gP7+swV+UUe4Ft9romT+Dh5wtoK/YjOmRh7bsq5AqaYp63qQG2gAtOwYVD7k6wHvwmJX4AAAA" />
|
||||
<img id="flag_papua_new_guinea" src="data:image/webp;base64, UklGRooCAABXRUJQVlA4IH4CAADQDgCdASpPADoAPs1Yo0unpaMhrNgN+PAZiWgA05l4up/qtxWcp8QDpc7jj/4+mBkr2AZvqnZatzPT3sBj9h3/O+aQBhXQhaG7M0dxogTzpfpK0sWOe6NxZKnxVdRArKuYNdSw93NXmKqggxXEETV/Aq+FtYFJIEpx5t1umwqAAP7D2sYmthmkeviCOqZ1VkXcG7mrAYqt835Y73adImUrytr91GzNb7ceo8kvWMXsEsUuiVrVnJSLS6ztflWOvrcNMFpLpTiH5TPJVWaNEAptjVScb/xbNxVkXBw9iIF3zq0QLJdloVyPojx2OrwbDOcFgsajVQuOQf93PULfNWL5BbGzI9U+hJZWrN3y56aVZ7Nb0fpDhhILdtBTdr3f+AzGT1p6iax+c8hQFlIbvn7iG25pZy/jVu8ttHWPK+46mWWci0y59+E+92QX4LM0XjSG99iyYRsfCaOoGMEx6f50FVK5zQAhmUUN9lqBIGW+NX9uSfWVSGEQX3AuKCPBxJsf7Rv6HiN9RqzGUxmPlMm/nxFOMCR4Sl67rNiHptF3R+3BQDHQERcLxfXIu76evP/egZc/7KGWxUsJp9Ov9/zQZLzNb0ha/tnUYw+ldHVeIu+nu8B5wdU+wV5dCT6dP9LwxDgcM9++4oyWE9SPNan57QfGqj+sK81azE4g5zhjh4hVflItw/L3yx46UAS8w6qfDoJNsYVQ5Y0a4M7SHCdjhw92xQGiDQ565ScK6/TDMkOeYjoUZXyoFASqAcCOYxjmXaYuyet0M1SnfPfgAnFw8lvnbAvALA+xj5It7SHSWoM4lOsGWtlvxo+7DSxSjV6Tz6XDZgK0oYOlPH3AAA==" />
|
||||
<img id="flag_us_virgin_islands" src="data:image/webp;base64, UklGRkwDAABXRUJQVlA4IEADAACQEgCdASpQADQAPslOn0unpCKhsZuccPAZCWwA0l/E8BjoKJE5KgH/qvqZ2znmA/XDqgegB/gOpT3kf/B/870dGkOuBQfu8OAFklsZFWXzjUMUJRw4EpJnY919JMtkzxJT65Yxc8aQAKOZk5kcHcurTyArnQBwVx9njBSG3WvhoFanNTCrWr5kKRqc0OwLIHiQ11zXNY8KlJ1y6dYAAP75nbWUFmpI6NFG+89UHGQ9h5nJwtfG0GXhXp9aN3HBHpH2y05zW8q0Jt8s5Om5zxA8JDE4+Sdy93eWYBWMgYt9CT3ib6+ZjmGsu8Qe3185PiBtAORZN/5Ggu47YW3fo4Z+if9lyM1L3E2R4XKL5ta7hpbqlvS5qJmMntfB5ecQFejyly5nE2S57/H53urSIf/+TxZRZq/vstjo1+A7tgIkj/0/kMC/XAbFoH4D/aTwnQc5HYMr6q4xnCpPgZOc58728fpkdl5M7I+pDFVcbu/ktFowO9T8vf9Psj42AdP1bmHxaQ11+1Nd0WoozkmHdH7F3u9krbtG74F0N+sFnvwPGqJZ5A3o79Y8K1vcvx+RtffLKy8ZNzRH4x3aXoq8qfqClBDEr6O2j2dWy6qemiZu1wGN0HKy9WPudnet3vlrWLG2q3YlMRttGxDLpsq4GBYqY61AS72xJj+5ZKfpXcOtpkDd1E4fETVeSPU7guzRnIG+rGeIdLrAWEPmRDHkjV2DClvGqfhPfIQ2hfteIoGMHuHUmfalGSOfZrs6ibZRr67tO/FZfogca3M+u/IxZbX/8ITYY/mO2RTq0T69LSi9CZjVZcNpmrxNoSmW/20OIRvdkjVEda67tUOnU7TYISjbSN4NZJwUIUO1dCVTqOrhJkCJeXivLerpjgrVv4dNbOLJVYluMjP/4IWfZxUhum9WqmviMiOLPhVXeNg8s9IMfqMIuQ4+rEOKXuaoxyioQlLtzN58Z78tk0tgft6HLsgDcWcN673+8232yIcp4UJ3bGzKT8B8Ps1XR3CCpfaQsJ/PkidHWmxYUYvTibvHRtsIMavwoja02CK7IMDrQ0IibkEA1kMXC4jg6YF5kQEL+5MblkDogKihxrZOu8VaAAAA" />
|
||||
<img id="flag_latvia" src="data:image/webp;base64, UklGRnoAAABXRUJQVlA4IG4AAADwBACdASpQACcAPs1UpUunpKOhrMuI8BmJQA7AABNIko7c5MS2WXesVXuEfk7XkwQA/m1ZySo1LXv/xvN5vW2b///maP0m97Kn6/jdtnWlwnok/1G3Ab5wKRTFRCo1E9X5b9oRK6G0GlAXJSAAAA==" />
|
||||
<img id="flag_south_korea" src="data:image/webp;base64, UklGRhoDAABXRUJQVlA4IA4DAABwEACdASpQADQAPtFaqk+oJKOiKBZqIQAaCWIBBgEmBpX7GtAG2A8wHnZ2SX+0thuV4NoMsDSBTBPGb9M+wF+rv/G9Zn1nfsgqJAN+ylpvkrvaS23woXK4YjA03lly2hzi+3dvdVLh06j1a5RWkSBXYgRoch7kkE64GWWES409g2c23kLjtjZpSSPMwAD+/SosVPDM+40ktYHCrV1QH5+I8NV+A/xAEYP32Nx7SJXPUfjLP7jJZrw7AbojSq5DSoYbi5iJJ6u+ELl5Rs/t5MfF7/FW56kHpPLb0u/DNrplq+OhbLMvjQld1lpXbO6uDgDd/tvAuMtSDHQxJBu/uxfP9sag3Wnef8QCGg+Mc1o6M9KqKoozhb/v6GkgtYJ/1b+w2e+ADwRQuSaF0sxb173xovXiD+4JADYg7o1ju5T4nseuA0s+Z/dwisGU80WSMU6yyEOEtrn+A1lbx/jZPOUb0t0bHZi1903+h/Fq+Jz49N0H6HegGMHog7uLiOmnOp8ly5Md8WABa5EFKF+zf6H7/BzMh1/JzffjgLs7C9S+Qf8f/WI7fc+Nf761L0BBws9aLUZ+HH43DbOltmEcwh9x3+yX/zny1UrghOjfP/P0a7+uqmPZA+yB2PAs8fDimqe3FsDNGPnqCD45M36Y+oPGIDUGgrxdeOmBMeBm6OhBRviUcD1SczsE3ZUZ37no8ELUE4ejvRdR+bOJLfS/r/ngynxi8wiXKdf9J3nCeHgyXST/04PeitsCXek2zVaI1AE/MnioXoh3OdccJPQNjgpStNBGeBlV0FlGf+5bqUMex4niNuh94WFHsHflN04AOw7CW6oc01zzby0APS1IYLBcfM585Or5Bz6Xoc/Ff09k2GU3s/Prrw/Yf8OZFAizsI0cf0gOpUc/Waz8y73tLbAUZ752D07wiHDiL6gg63tnxMzXOIwZKfCDlm+z3P0s7oAO2eNTO4EVfe/jXodZ75hQNj/EfLz0v7L2z9B3mxqe6e/kDRdFwC3Ig+J9XT4mOUVQWcipTK3I3J4FNAAAAA==" />
|
||||
<img id="flag_haiti" src="data:image/webp;base64, UklGRn4AAABXRUJQVlA4IHIAAABQBQCdASpQADUAPtFgqU6oJaOiKagBABoJYwBCAP4BhAAC6kfbMH9H7+AtXVNeaj1GOAAA/vBsr//V352/U91n1evFz212Pi5ifChA6XVBQD//4JB7/4l4V2iYsZNyS9POl6SMaRbi7pkyqBl8pp4AAAA=" />
|
||||
<img id="flag_zimbabwe" src="data:image/webp;base64, UklGRgwCAABXRUJQVlA4IAACAADwDACdASpQACcAPtFmplAoJaMjJnqpWQAaCWwAeS0zp27dMS8+wH8R9AH6wet30SXUwb0EvwVsaDRM58fX03qEoQDgUygkWdU+wp6ymSwZFn6EJQj/uGt87Li0sKvFgqGR9tkJtlUfjdsgHi4nFd9UAP64RhKsT9vlQyy8Wj7cf7K/YWmQhU1OC1PeUSt819bexNr7t8+8Z8yCWbDWI3/0N2Zi96x+foffuhZ/3BSPih/gFb7PsI9O+7xbHzYMPTD98aefZcPUstei/2LXpsCwV10e7ywS8EyeqRAZMYB7l6DqPVx1N2pc/8ZNPNAKVf7iB4RxgNmSnZweYSTaC3sRlkMh90aQvhay4mANMnc7EMwdzIbBBr2O1KXCwu67ojL6TocVjIG83lGZYnlnTJpKBrWuJrP0eiD/UEUqkJk2StT6GgBtdfX9/ubVYtELmgq3zJNocNXZqxJTxj2cfOs37wKSTwa/heFdyH58+Ez6OcEBWpwsLAi91/iAl9V7AejG+Tf+4xun3SPvzFIZx9czoYQkPaDhBNYu6T4KvS5dH4UvdTvM95F/ynSvcM9H7kn5/zvJroChb+23wxNt9TF4klUaElFrlEXuKm+mzjP5vgmIQ9Eig9NxUREKkrERp/VzQ4E+GLMgW7ypRCTTpL7eBclHaahOW7KkYRBfEAAAAA==" />
|
||||
<img id="flag_cote_divoire" src="data:image/webp;base64, UklGRn4AAABXRUJQVlA4IHIAAADQBQCdASpQADUAPtFYpEwoJSOiLmgBABoJQBK1/zPVDOQAGwKwaFguUPvk4PxsoVXYk0/5AqAAAP7n5L/FoTDwa3NdC9AZRMQ4fqHVarp2wEd6+eTrQknGoWag7hcaGcqA+F3oQPrclO+wYm4IxfwAAAA=" />
|
||||
<img id="flag_brazil" src="data:image/webp;base64, UklGRmwCAABXRUJQVlA4IGACAABwEACdASpQADcAPtFapEyoJSOiLnVboQAaCWwAzQlBPg+1X2QKm0w4gG2j8wH2Ae+B/APT/9QD/VdQB6AHSueRm0QVtN3nmrf6P88k8viceeyEvGeWU9rRkN1uh6I4aoMkgOXRHDTN0ybuMXAtyYu821zI5c6vqRz9F9fhWrgos5rGHeAn8AvBgRCYQADOFqpSFWz/CtNFcs+v/kGKxZdT7nSgXS9Q4xrcJQP52srLDWsYgjtjXGQRq0YzMlatKwUpKI8nLvtpQsYEkE92kKgk5oPg/z/Q2Gud8/0YfgRM/Wz0hGcxEekIUHUDUIYPTn14SlL8O64AfMj4WeyvmRw1dIibJvbY4R1FigXvpMb2PXkss40NxBB4HQnmwq+gLIjDtjas/Y1rX49K+R+oq8iy+TDvUkH8FkqnyTXxej0eeP+XN70GM6NCRvqT8SLN5jK6obmgLet2yaOwa5AITyU88lQp5AMhz9MSqL1fHQbgeM5fyFFw991gcRwpuW/Jlc0elp01I5fw17jbJ+ox+3YAgyD4PFcF9I7m5waNNve+m1PcmfsnWqZtj7AOsrLDgCcJzLY/Rg9T6zpwMs+bI++T/6iilXKjuY2sOlSRjG4XnTURY7KE/txK+0dC/OMP/zn28O5WadAtGzUj0DdSvJV8lv6jIOraBKrOjYirN0/hpdv3yJt0uuKApqR99XHfxKvLfIJzuuf2pJPGUzeZ/ekvG5hk409OXkuCwxAvs9/RfmHRC12Z+K8GiyuzHrPEoEzUXXT1HwfPJu2x/tdKr61ivcxFAivQgfCsAOUgD8AAAA==" />
|
||||
<img id="flag_mali" src="data:image/webp;base64, UklGRpYAAABXRUJQVlA4IIoAAABwBgCdASpQADQAPtFapEyoJSOiLn44AQAaCUASoGnjRAmf/OQANYjx/BPOA3T8VBVRHxJx9bMpe7iojOAA/YxxIz49BOQ//cfOXnKoIJ49oAbv6jqSnGo/rHCuwBoNNN2sltAQokFJjH8DKRx3iUC3fbsSsnFnNMJBAsQTIizDKkhGjiN3mYAAAAA=" />
|
||||
<img id="flag_mongolia" src="data:image/webp;base64, UklGRggBAABXRUJQVlA4IPwAAAAwCACdASpQACcAPslco0unpiMhszjoAPAZCWIA010ANaY8PRGPTRzf+cvZKr59ABCjymmJ8l2y6ML7KKXNFzCOuSKTbSwExLkggAD3BBrxdk4vcUZ4BpYccRHIq59R/cZ6sPNV/xDmJsEwCxTpHk6Fj1hVGg4x6wUCocCBjGVejeqwVi3/sfJXo99kzZ3RKfodBO2IrtwnVK4uEdVGwF/+5XTHsgPIas4AkYsk0qLfpfijtnVAc3dxzppedUO5PkhkVkUiRzQ/mHkXyOg+/ogoka8y6kroRd8yAilZIGF+TKKHGr/FVPI7t4CQJaX9YDM1Zcz2N6LH4YxAAAA=" />
|
||||
<img id="flag_sao_tome_and_principe" src="data:image/webp;base64, UklGRvYBAABXRUJQVlA4IOoBAABQDACdASpQACcAPtFap0woJSOiKrZsyQAaCWwAzyWu/merY+A4l7gHurwezAMMB57HoA3gDeWivA92hs8bvLb+KyQiAeWC7ZwxETvkT2R7fAjPH95RY23EdyEODF0dAczhED+5XQBEpRbcAAD+PWc7ae31l2dyoBRv0K1qkPdBJXjUCuTatzGd63wlHB+1XbRJ97P+g7tsSf3Eoj93YBIbchBYs4TzBzGQne4iNgKq2RAvJgLkSnZv9/6w9vmcuy+8bdn+y2/kCT+Try5y7T+QWkmV+4M4E0qiAiYH75gFs76yir/uZWk09Ug1sMfpV5f8ium+U8N34EaClGdDWq1vmshg1MWdFHOTd98oq0Iv3Ghw2KSqbYJwdmrWvUz2lmBZ45zV1zcnC9yvZlwj7uyI9CICcPO9YuSowbWMvl5TRa0uWFDk9USm8pXxDRbvtktU1WbOjiNYSTsC7/MIPFrnhK5i7/Jeu1ob2UT7vKaBcZsDg2RvnTzlHPuv5O68+bCDdhv1qesJkfuo2ndJFWTas1JqFBawY5yK7c+6geBZv7yKjuegwufgOgB4miMucEtAOyn6Iu7rmkaKcedNZajd+H5TxM8lBxxB05McnJtmK9n1hYv8/9VjiX0WdPK9y0yqxCd+1gxaYAAA" />
|
||||
<img id="flag_saint_pierre" src="data:image/webp;base64, UklGRvQEAABXRUJQVlA4IOgEAADQFgCdASpQADAAPtFMoUuoI6Mhrvts+QAaCWwAwrlBflfQMRw6Hxy3AL2LdXzWOV+cB5gHOJ8wHgze4v0AP7v/YOsW9AD9kvTA9j3+6/6T9svZ7/+1a15o/U0lilPfP99iYMmNxIaSCap5APrb2DBHl8xY4hW/u/956j2q1M4NT7YmHEk3Y2gqPSPNALbiFW7oOEGQaj1agF++az1sjowvuWUBuGeGfU7RQZlZ4wziRS3mSpNYhgaJ6PtKfvVHAAD0RKDjS+B4Dq3Xmf+S0+JPj1AxPGxRFX/IxGSbCtYlLfDI1Ij7jMmaLBHTODFWZPdDPYPs159ziuw32dOFRYhI+q9ZSbNfJylOAbJIHQr4mip2UYh56R3ZI3eT/Fwa1y/wLFW2aNGWDyzzGI/UHSM3MNEkaW6mCOqcBOzaFS/sIHzKxrIGe+0FrulBC0ptd0I39U2vFXEIWnfwTk3b3v56fO9tF1fhC0MN3vHk+JKj8DkYj+9xhqMFumz8y9WMH8uGxf/oPZqk3C+va10jjevj+rrply4+BKrF/pZY+6eYDU5uYXgP2KPMZcBxmajjMDRen2uFFiaxpbGapLDotyDlVZDG1Z5wPs7uumVIIThXtRDb+Q1gO6YGDHJHiVIpCEJ0S7DiCqgVyZpImT6/jpAqPfE9FxoJhiCwxfLfDl/bdLB9W+dfjt8SsDPX5J/vkPdSCiEYqtHb3WnOLXi7YTBdX0QuY9jqdER8ORQiTTrnFZ9nGBKfes81TZAqyOTzb9zT51z7tiJ+ytoUKof+jSXzgpXxk3yCjhaEQworIfLLH/LGF7u30Dhp9X3ugDxKF8Gk7baljLttOBGR/4vI58ts7vnlqs59OeFmXew6egwucpZtMKhtiM0gHthw1/a5ao4X9E99C74i2fxyW8mkabAc1JFMXeGEX7lD1v08soJzpIjm6NOqZu4Vjykdqbopw+M0MtoTZPRPFj1LpcNocjp4+ikkL1hjHVvz5/ZJRflYeqgQw9HkAQqIAlCwjSFmODMzQr1RGlCS7McPrdBXXzrdQrc6/bv5E8PVGH2NroPZZYaXF75PVwelYC1x8vX7u2g5JPBnL/kEoiCGazfCY3gq36Oj36Zp5plufIWenB0RH3b753gU4PYn0p2+M8vRYY5wtlKp6KxvkBt3sdXg4/9xdzH1D4EibmQBSmr+yjUcushHmteYAsB5tt3m+lh1B7PUp/bmKxToAuRZU6tPGJ0oNyom9CocMQUS06s6xPLnakFE8zn3/XMflnTaRNOYHoxNF+p+w0uybQ1wZ62u354gR6w04isVWZWKnwnGI759JI7ObHES4mmX9gb0T26/8j7x6ly/5hy/hKzecOOITDXGJWLNIe3EX1KSst7yAP5jD4J9A3Wnt/nxFa3NQjjL4fHe2W+whzUWcaotFQiIIFHcoRSR6uzNcQR+lxby6FN4ObKKz6c18sGv3qoHBdioZc4wVL80+PypKTEKvOvkqKE7tQUSpkWXpx21wBvPDDKGsZUa67rPP8pISN/3heCiFdbWx/fjAeD++DL10qEZdNbZFsgFGWJmejbmK9USzeVF5fdrjLsaaPKCamsUR2ZR0Prj1sKT/hczz3EI/xP2GNuhZLM37/dZFuew0qf1iR6mDxJsMF76YmRbzSntqODU/Hjx9lswfm3AAA==" />
|
||||
<img id="flag_philippines" src="data:image/webp;base64, UklGRmoBAABXRUJQVlA4IF4BAAAQCQCdASpQACgAPtFeqU8oJSOiKJQK6QAaCWgAeVxC6CvCuuj/6gDeQ1+CtA9vZb3G1bdMO9+aekuJBIzVvqhZG5tTb1QbuJe/4PtXhYis3yAA/sqemnNXW921n5ms5KyO4cE3gjcl6P+hPXqbrnc+t+KKvxXoqbutGsqHEP3f5+zbwC7Zh6hHp6TRiqy76vmAqpFnPJSBxcZCKc5i0O3gzGmAJEvoBPPIWKYW6EvKBg4FCoQ+X+efZlbud1B+Vhr4HIkczEyVW57hbsFfrDvNCK7FIFMP5hwR6wwp2mnEVtmt4zlYxYyWoODNgY6RXWeN9apK5VIps4DEXthNnwdd5pd5xnJ5bMBB/uZ2ZAiubwfizSf7Zs+0nyqGl87/gQ+80elQwi+SGQ86o5RJokMBD3MZq5Au0F7U6KkQcbqWQUYP5tbBIsLn/xHc+UFETkBNjSl+NWsvfrhTTcAAAA==" />
|
||||
<img id="flag_macedonia" src="data:image/webp;base64, UklGRvYDAABXRUJQVlA4IOoDAADQFACdASpQACcAPtFapU6oJKMiLNK7iQAaCWwAnTLLsfe0fkp7ItK/x+2+GYr9eoD8TehB5gHqA8wH8L/xf7b+8t/h/UB/p/UA/6PUQehF+0fpx+y1/dv9/6Nl4Yn0TAOxAJayF1T/efJjpSq1KLRtOLuvgGuGGtrwWWOtfoX/c7zk+3MG7MoCSY//dbhcfgMSOw9RDcAXpheh47/NIwf2mnI3WbS8f2mkQXo3PvkQAP6sLbfca7cRd0y2f+mwtfSOe/gxP9764FSxHs+VDH/8a/aXK1/+QW9ccMfHP7uJLbo9f/q7FxvT1mY7BZjm2lFbszfRxs8KgkglEEJVwKnhMUg6ak+utg2t6mNzB7KdivahE6v9z/NqZmXfa9eGlVUchX6sq0X3UgxxSAD1DXHSv1xC6wnZpC1hSHw++MHRm2PsEoiZ3KFi2QQSHdc2nw/DWUmcrN+HcJUwOyrU6kuzibDWPrtGYcZyBUX9beOg0eLO18vwZzhnpr9X2ALDVLkv6kq8QEIRfGR+36rd9TFRnuZeJ24pHKXVewrbf+vSlCkfMmfd4jk7lbLXVYeI7up5U/y+jT41lvwSejiIDCvMfV2Qx+SdGSedOUXD4bPSOU1QjC/KYV7zLR5DnzxIi3FEMRftNwV1E/Bjtd+3JMfHODIUUY/riYOJbTmAGhOaYXA+kPJW12hoTi8Zlgau3pvx70+8b1zdXgkO8Jm2Iw5ZPQ6RPCcC6DNFk39x657c4J5Xj3vxUbJH6iu/0hQC9qbabts5ENVmH/nEmnCXkje1E1yOT1QularTzzNrweREUhKWwOsmiaKJF6rX6aRXkzkVTBgQiZKbExJpUeVdI8G100AK0Gg5oGrcZxq/N9YUZsnaqdUy0OdhO1XoRqYRDzoBSe169B5IWU9zxbVgKmh7RwTYN/i7r1g/2aGAHy67y4D6qHcMWDnNkAnBDIcHpZYxt1kflToU0dVLsOtYcWK94/J4xdznoNeAm/4ShjPj9g82hasJrMVIaA5uc8PiXjiBeRHDyZgHNIaTF8h6Um/MR/Q3GJo7pfPsIkdDRa4mOqj3uu5wstvY5Uj4L/TPyWlfqbdGL1uD62TAhng8SSj6PmqYPD2X22vBvH7t4kDkzMYLFHKCHue/eSJgY8pf79BYAD+9cXiuMzmpMWyDNdEX3YhhhAPZgnBs+VMqB/IqSY0YREvWbNWxuoU0yUEsTtpUGvFMD+YWOmRUHPnCc5c9BdYB4kXglMpzA55Aq2j1hwJdwZaEeSs1Lyw9wsGkXrbP7Ynwf3dLCw9hffuA7/dKzCs/qrR+NrCDJTSiN9dFXwQdybr7sh0AAAA=" />
|
||||
<img id="flag_kenya" src="data:image/webp;base64, UklGRlQCAABXRUJQVlA4IEgCAAAwDgCdASpQADUAPtFWp08oJCMiKbVcAQAaCWoA012uvL46vgFsM8DbS/1XsY21HmA/ZD1qtOA9ACyui8Ckn0BPeou1KWYc9xUEIcG8vatY480S1wuu4wO+eBlHML84GHkHJLYIDnrI3qEjhV126NBDtrZS9UM4DjJLMAD+98rb1xxkYnKG/2sGG3jd/imFuDQN3aptfArC9M26gxj+t/MzASB6MVMjW8bd5AY7kgCWULwg/2JvC+8tt//LvVi1/3lO7ZkHxFp+LkVIS+8bZIj8Ww2sXoIHjWuOOH2mI2KdlmbszFlpmGgrQ44ofz6OW8gpolbV3yRq7m1N0h/P/wLKm/SHZX/drNODpukjO2ktjlihBIP1LHXoYSRSp2bfvDNJ4D11a2ZS6YIoi9MEeOmnB1hTwlC/M/Y15bSg1T+XMd2FzAYhdMnf+iu3tS2M1/yP8xiO5a46N0zZNNwQMMlurq0cCMCAbH2yHqHdmyuT/CY7m2UPz+d4ts2jq+KHrvfATvEqz9cr+y21JHPRX+6J59xy9d0G/3fZKID4jw+10h937/ZUF+pWyIeXonVIQWCUYmWqz70Gro4ZzOIA9hsUAtfZT/WLn/Gcm2lL/Mye1+/SZjmkzWqH8Tn73UEUeZtafMOY2vkivmjQY6ACkV1BNKp3DzQ0EGXoV4DTr4HI8OQTt3bZdoOoqHaFJfKIW2MYKgvzN4+/InLChMhGkNZ06rKXbTnyywQatffapvhBJ/0gC21o+yeMuiBGhqJFKVbXy5+KAAAAAA==" />
|
||||
<img id="flag_canada" src="data:image/webp;base64, UklGRqQBAABXRUJQVlA4IJgBAABwCgCdASpQACcAPtFYpkyoJSOiLNgLiQAaCWgA0I2BvE/t29ZvrMLndVf8z7MG8wERWc3fMel9QBNoFeoKeSlqM6gq3KzInI5PpNmHGo5GKUtikejX0LJHLOUcmAD+6Di4VVIl/64D/nAf84D2h35Jd+S0jpgeHe/MTkF5ywOgHGtXTX/g3beY/8G7fj84X4waxmZAez5DdA174BqQyUq3HRJFbet+jp84fh5yha+/WBNGpRicKS5I2/Zg7DlKkdLdjrbBp2rnSyVy0+mOVDjDSmNGmFt65Dui1h0LimZf3TzfiL1TXrRDmEdf0eNS4zcHMjXvku1hq2C1bdLemHu6lZ/aFxo2PsIUhaPqmb46wQIf30t+fbeH8T/Alr6W6FO62Nb8VtIdIO3FQA9MHfXPpLyF24BzLznOQuSrmTHwp4/u8BkiAEMlxnA9ovGcDh7LS7zHobVRhoDWSyf+gXS8okLzSUeev6/Kv39U+/z5jdHvNFB4FAxOVsi4DbQVdBX7QJQQ4gXRQrdaFi1AbKBQEl5axgAAAAA=" />
|
||||
<img id="flag_bolivia" src="data:image/webp;base64, UklGRlYBAABXRUJQVlA4IEoBAAAQCgCdASpQADQAPtFeqk+oJKOiI1gMAQAaCWQAlQNTd55+RXCBd7uULXBgoHrQaZXu8YIW1l30au52X7T16cYYUlTw6txOMt6OP6WrN38zP7TqS4dZmOcJgAD+qIaXf6A0p3ZX/6EnwSfBJI5WjJ7sneUs2YRn0l6PEk0XERHn0zb4BzDqRlwqWgcHoxEduiQW6uIw81FrKFok0zakgY0RgQVIW7ydnaKXuIqR2Khj/zvCTuMUkTk/S4p5bHhmxi839bzwVI/3W6IHLqGgAKt6xpFf7mpl69Ctf9wZwa/JgndAHz4VmybYkmoisP45svRr5ByjQ49YkHY4xdO/tf1PdomgA+RpXyHTjF3Wb6XgmM+oyx+gOkBz+58GKRjelrIMj8wdlXkXXAVv1Sfkh6x+lAp740Smzy3XEYmaSGEQxWa1wyIe+JAU6AA=" />
|
||||
<img id="flag_estonia" src="data:image/webp;base64, UklGRnYAAABXRUJQVlA4IGoAAAAQBgCdASpQADUAPtFYpUwoJSOiMZi4AQAaCWUAdgC3CQ/wGCl2UrcMPACzhFbHdNWd29KgLM+pdpgA/txR//UREFJLD/8Qu9jCgw+7T2jxvYLuITWYhSI8linZVLqwT2ez15iHskAnrAAA" />
|
||||
<img id="flag_brunei" src="data:image/webp;base64, UklGRrgCAABXRUJQVlA4IKwCAADQDwCdASpQACcAPtFapk0oJSOiKJQNyQAaCWwAxBeV/AcdD7766MZ+PP8Vv0vE7/YD3o/QB/oN8z3mCsvV02YpyCb5/xAXCRo2+TbLJU1ciqtMNwjRj0bMSj2vo75bp6iiczg4ZVfXlJ0C3kM8GEzk6geghmsUhsxKzc/VIGJN/pAbQeU3TaAA/vczONm+k92YX7FdxN7IcOiSj3r+szxlFpj7ELGWeuLb/228qcTwHQ/fI/kvQgaWI8BkojvLwn5418+E9tyr1QJnqOKgunL9ptc7vWIWAG2m9uuPkb3efHO4gSa83ciFzMPCHx9n5UPeylHhtSiR9kf1T1GExOLXMYQUQ6NyXYQHo+pBqaLh+qT2BP2xIOVag6NJ+3aFnKPoyZrjIOnAkUHtrSZS636OHp2pX8I6eL/TQUEiHQwfP+xfr/R/5nU+EnpWzYs5HAufTvsEqOD9dk6E+Sp+a/DQvN94n4OLlbSjJd/8r2SKz2Q7v01S7J4gpyPn8c7EHHoJp31JmO+jlJo9EYKDZhhUtfpqC8Z4H4/XuI732hu5KH1FAm8Bj497g6ungnHFBDjiLUMjraJJDN2s/p66lwCFj3/3ACFDIwcU+Nx1ZzzAya20pcPkwMQy4fL6NRcc7Lmm5XMdXbY9RRP8lHa2QGPbjP4maTYRmxeQ8x9/TDbD8bOTBH24er/kOinKiYFHswb5UuHoBYiMcn9q1l/GG5B1Kq1HDsljjkhSMi4Cx41I7rKEMRZq7siRDvPeWEfOEnusGcDpd37sJwvXhuaI4p1Vd1zgGII1UXzF+5sJQ7B2raqcGxnza45/VcCy/O5U/yCn+NhMAdL8SgEeQqjFzclgEwuXlBarQ5aWI2PsI1/lWa+j96weQneu4+ZhdvdYmlHdwQM56/vHxbl6AAA=" />
|
||||
<img id="flag_italy" src="data:image/webp;base64, UklGRoIAAABXRUJQVlA4IHYAAAAQBgCdASpQADMAPtFcpkwoJSOiLmgBABoJYwCVA0uPptEA2f8BwN0qqPE22lM22RBFTx4i3nT0/AAA/tom/MgEaP61n+FMdPg/A25U1P+MqaoEhbtx2hpQzTd5jNP7x+AxX8f6G/lqwfH+hyFGa6Q4hBgAAAAA" />
|
||||
<img id="flag_tuvalu" src="data:image/webp;base64, UklGRvQCAABXRUJQVlA4IOgCAADwDgCdASpQACgAPslSokunpKMhszVdUPAZCWwAyNGN2n4SflPNKqHcxED1pfUB+FN4B5gP2W9FH9lfcV/j/TA6gD0HvLO9iqu66561VBl73hwGmX1NKVEfEkz/6Ck4ZvogVF4MQ4LV1tt1N3tE7Wc32kwO+5+Bkutf0q7xPC1JAAD8+v6e8jU5X/j+IKY6s/UraPrzE9nuJ79Iw3QsvjyqZWbUBKuEEHiGcgH6vEnhgSUO6tW4CcqNNh2dI9VRPdxpDC+nOgZgWmEYWtTxpNgGkip6BWLtD9yUMckf+5TfnIA92IMnEkHlitKT9bcWG97+GbHTMvLtUaGz9cmMynbtCia42PEjk/MasTw4XApAUHSfK31h1REUnFeLkJU/R+/5XWAmMDsio5ZKG5fzlJVlKoN2/4QAEsJoOGvMC6+KOdUxTqT78d14ZNcv0Ojv3R+gAED49jVNvkrF8WnIGaVarFElB08T96HneQvqoNJPSwUuF/z13N0t24GZz6WMyG7OdmtQoMRonKVL7xEzfhgVOoO/q/nQfKbtfFB6zP/DQYjq+9/vk5V1OyzDAeWowH6VqiuuRe0bzyfRe7KEnnZeDWhzjkGZQ3pMURosufmS9TJlRLvhFwAqDHm/2cHKQ/4nhhlBcEp8jBrsImvcI/1inCzkQDVv6MIyrp/ZbY4Q7e53EnSs0t9kXUjiq87KXmwDw7YVAiCecjciXIyORiVWx5y/JerOF9+dMbleuPT0mu4HzpEbI9bZbto4aPbJBREDnUums6dW4JI4goBz2oUOC6TydsJSV2m23dnFfdr7e6+RU09j9yGOIfIytzuK4jMPVmOKqZwmAAwRW3l2cYnpM4zJXJKTQXym1Gqos04/x7PF0IxcZxQNmgBOTyuICOigke9cX5APBp7Jn+EUBSp/QKno/yIVlv+rarxNZ15EUwfUeYKokjR6GLtDh81mbi4uf+OHu3fnPVtaTfnbK6NU1EgVCE/AAAA=" />
|
||||
<img id="flag_syria" src="data:image/webp;base64, UklGRi4BAABXRUJQVlA4ICIBAAAwCACdASpQADUAPtFcp04oJSOiLNQKAQAaCUAasb6qx/8AAMCviM2taMvCv4DymR/fk74FPMaEQM1M3VMK5qw8xnr372RAYsfWAAD+5AF/6Fesvvpsf//OJf/QL/wF5/WQZLcy4yXl/1tIWTCswtWQRw3uP+EAm/xP+D7vJxZY2mG10lBmGKPYjq0Gqvm9qsFJKLs7lQOXGlORSdp6V6KR/DRumD0NrPJYltjMFnv4hVfoibu247PL39I03B4TuzQOFBwxakY124JZSyfLFi4OtI7uZyO2eIhMy1jryv8wTlCCMeLmNluEIaKnIAe0PwgGnu08GXwAtIElLSZIvj7LQP0HvxoOJxAWnnFrHTp1l2A75S5vylBOgFInLZl6tUEAAA==" />
|
||||
<img id="flag_transparent" src="data:image/webp;base64, UklGRmAAAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSAkAAAABBxAREYiI/gcAVlA4IDAAAADQAwCdASpQADUAPtFosFKoJiSioagBABoJaQAADHThw4cOHDhwrAAA/vOdgAAAAAA=" />
|
||||
<img id="flag_uzbekistan" src="data:image/webp;base64, UklGRgwBAABXRUJQVlA4IAABAAAwBgCdASpQACcAPtFcqU0oJSQiJEzpABoJZACVAqP7zwBbBInCh3MsxJsw2z7Vg5Tmg7nO4pNLlWMAAPnN5mu3WOZLy3YSy6hTiE8O5IX8Rdjl9dkEKQYS4WtDwKEXyEyfga6E4ghzsPXJeUTBurDxPEBpfs3/xEWDfvPOkh7c9sMeu6T/BjWZCQr/QsY7erhJma6qaUbCvcifnVMP4AIdj8zWrLNuTZ2D07OlTbK3c2ONBlydyY/ulDDCL0P2d+cYwbc7dDxGy1jlvsUYEFT4Es7HzQqmiBhhYacKFpiNOd/0Y6JFXZ3X9BN12hvYjiB317aQMhiA7pZAwLoiAAAA" />
|
||||
<img id="flag_argentina" src="data:image/webp;base64, UklGRqYAAABXRUJQVlA4IJoAAAAwBwCdASpQACcAPtFcp06oJSOiKJQMWQAaCWcA1ImNvGubALkALb88YQ8v7P7DAF/mDQpUMrtYwerXlBb8kWNUPeAA/vBnwQgSi6RQ6wAb7RUjL0zvtWROxmlq5tdK9iz3TX6P5/82E/+iWCag7CvT1rL8maE2XQ3joGJW67B81fdllBVqssF4xKBTmGeC4sbZEUjwh+MAAAAA" />
|
||||
<img id="flag_paraguay" src="data:image/webp;base64, UklGRkABAABXRUJQVlA4IDQBAAAQCQCdASpQADQAPtFcqlAoJKOio1gMAQAaCWYA1T1BOA/wDjm8//kAHSk/7MirieF8CPbOX10zh4wXJx/Y+jSV77yTrMI3YiXvbqfUPQWPzeAA/uUK/9iOzIwV/6TZ/E2fxNnxzFd5av71nwLNhRR9aXRr3Evz3c/8JKpy54z/CSoI3gJf+hBpGIKFm7ziklyATy+CK+a4AbrYpvifD/j/IaMX5VeLOAJ0C9ji+2hAHADL23KiUqnwCAfHLDbgYOIIVszasjgsAZvKZ8iwh33tCdBNrnhElVuKLOQMGWXoRWDOu6dckhCSmotC+fAPx3qtzxKZOLFivk+nN+j5IutC0b4GhOsjV7MMsLfTyaSs0cL8S8i3EWxES5kX1tjQKBwQytTaIPC2xxG2JybBWbckwAAAAA==" />
|
||||
<img id="flag_equatorial_guinea" src="data:image/webp;base64, UklGRnYBAABXRUJQVlA4IGoBAAAwCgCdASpQADUAPtFcpE0oJSOiMBTY0QAaCWYA1EQXrB+l2CvmANwB51Wmq7zeBuFzURcoD0mtH7LzN1BrglNhhy3srwpvSj6DhPsRWTkreCAGvLSA8HubhgAA/j1nPqowu5BnUnrPY0D//yv/ez0Qf11KqoJJWuT3O+nTtfDZo9xgAsPKLV6ycdpaytwCvM/JpVZY3FEuTS7fI9//njKPyGbbxPfnfSwfcwRclM08bQSu33lQlVIQqbx28tn33t9y4smcGeYt0T8h+PeDv/5etnJpbTGmZ0NO1icKFlvYdQxJWqsxsO65ZI5x14gcbw9u45A6G6O8G3lkBgkpkV9hBeuwztNj+vb+7vIMpkpYOVPBoHIN0u4ynJ1oQTTiV1DGdLTIqjGVw62Jyosh+yh7/ClAEnZp7NTlz7X18cAeLxWeY3Ureb/MGfj/8GxYz/1E//c/8//fwqZ73gP7z+mr9//k3YBBygAAAA==" />
|
||||
<img id="flag_guinea" src="data:image/webp;base64, UklGRpYAAABXRUJQVlA4IIoAAAAwBgCdASpQADQAPtFWpEwoJKOiLmgBABoJQBKgajfzl9f+cgARAvoOvrUXmSlssfWRgT2VfowmaxiAAP7mOdp+j8UEMVV/xsl2xNP/zNHwF0m88VykqdP/ujcFLN1/4yiPmURP3zXL1Hth2sA05Z0YWdwMq/P1BVWM/DAMOgj04nJwnnNZiaMAAAA=" />
|
||||
<img id="flag_china" src="data:image/webp;base64, UklGRjQBAABXRUJQVlA4ICgBAADwBwCdASpQADUAPtFirVAoJaSipnv5AQAaCUAPC38A4wG4Y3gDeTyJABxtc/Mbpt1Ew25lOFPrz2Q8MCnaO2S27ejEhylkg5gA/qiHSTqccvTPAwmVK2gbQ0qYChelUCvY4erQ6bL/+NshfjoNGjrf//ziX2EYdnT4IkxLJPR/uU12B4U682MiLO4XQOdltEgCo/2UDihrzpr/m7jxFS+nympKqWqTB52qlOrhLS3UjkdJKI9GidToDW3NVrSAQA/VAbWzuSuK3csAWc9lGMdEXDV71IobFxazuySCF0lDGu4/g+07bsrbTAx/zTmxsUwuu7Qe1t1TKs7wUo35JuvAWmSShzrHDPDT1r4VG2Tof9xhBgusDPkr7izlpIxkh4aV1pHBMAAAAA==" />
|
||||
<img id="flag_vietnam" src="data:image/webp;base64, UklGRigBAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCDiAAAAMAcAnQEqUAA1AD7RZKxRqCUkIqNYCVkAGglADxp+k24ZwDbAXYBvLAFRMOSnYYYkoZZGeaIGuFC5TesOFgLKLYawAP7q1H/+g+uJin//84l8kegXaA2nDnGLuxSMAkK5CeoOwyUx7E3yms5EomQVq+lzxMmWlpG+8MEMFFP3ipVshWFTGxaK8BChQ1PJbSYx1OgI2iK6gMuLXL4zsG0nBmf6mOrbuZwzTkKDQqiNY4CclglHJzNX35xBn0ZaVFckW3YqKY7lJGLEEWa6jdkkOtho+Qdoi69eky7eNjsqOhTgAA==" />
|
||||
<img id="flag_cape_verde" src="data:image/webp;base64, UklGRjoCAABXRUJQVlA4IC4CAAAQDQCdASpQADAAPtFepEyoJaOiKJQOiQAaCWwA0I2N3F5yfN/yM6CnkZ+G8Bt7/MB5134AawB6AHle+yyjW0nGs0sAvc+DtY240DulG95CdVF2K8NcgHX3lVpslXAVLTfcvxdCOPweBDHeM7a+TCxiYAD+8IuvBdH4oIYqr/4HVVK4fmCBp6Cx/niOqdNVr9RSWy4ekB/+LdosCMxuH0QtmAwBU2tHT8eQXAv/64rBKtfnjZn5fdysrcR9kMkUh6KddvOaYGbfQgiN1Q38Bxdcb8fA73vD5t330AZVJwukGsoPerJA96mLOWuJJK0kq0jKzDX8r78gJUXrHKCX3VYzh07HZEd3bFFj+SfKSocdNEVRWCi33tcwVqsNVieWkJHNxSGxxF791Ay099sqk95X92PiqrhXZKEyD57LdrjGc/xUWI8h+7Gr7ep/xcXzgPysSIDaP2ZDl0ugHD9/ofD32j7m+lzTuJ/M78I9giS+fju4j9kpYxP4fJxi4SYCm/P1lLjP+V4xScRFIadB4yaAmkLM1AGn6tuK3A7Jip/jdEdWG9Yy6xb8pwvzT40SHMQJxi4Hbkh9NRPBP8V+nbOT/4ivopfrs0d/2tv6Ltu8DWPg6Ph1n/aAak56KrWsDKWHNa+rySB4TcoP20LMD/OO5cCt0zkdm5M7LrTz/Bdd2ZcGCtn3531j4VxnQDCeexf7/6Y+j5SZ8PB0oFFN1aoPmhByvINfzaud+EAAAAA=" />
|
||||
<img id="flag_comoros" src="data:image/webp;base64, UklGRtwBAABXRUJQVlA4INABAADQCwCdASpPAC8APtFmpk8oJiMjKJgKMQAaCWwAeGH2njfOZHZ71gbPbZ+YDz4/Oq9P/qAN5V8kAwATO+8AB9UcANfI+da7U+FDXrfU16Exb8YXbWA4ZxT7CyN4uCTNpriiYh0snK6AAPv81TuLDEixNQJNg9itmBzW/7r9BDBcenceH/+3z/QMT//+56B2GDkhot4vXf/eUX9/4wBZEBoSqbbmIqO0yC9JRJNW61MYZ8rdTZ/QUYH/tVh1vcnUAqPMVC3QfqFTjY7Vh5OMnZMLXj69MjVUg29MBkV9ss1GDcg721DCtYC2zw5gnJZijO0rrq/CbQTtMIFidLpf13srpV0r3WKyo5EGf4s72U4Jd85Iq+u0LjZUE9Bk8h8Oh88uFmMwYZUBiHflUzSexD5uIwhxsw48W5EqW+37nGZ+ZaMO23qjOK16UZ7Bw9ElZO9CKtkmTFovPwuQPX1ppVXWWXu72seIMn8OiPp342DRa9/AK3Cr7hktar2v6KV/Y7xVAOIsJP3hr9YZztx0b2Q1YWkKSWVgpiJPNDdVBoshy54U/mvTf77/yh6eoQ7mGKTicNGaKof6Y9RWP+qW3m3K/QbOtrXg0L8l2O9xlQAAAA==" />
|
||||
<img id="flag_lesotho" src="data:image/webp;base64, UklGRqIBAABXRUJQVlA4WAoAAAAQAAAAYwAAQgAAQUxQSCkAAAABH3DV/4iIg9JGUqA7KqM0OsddzvKIiP4TTNJU2zF4PlJDRYZ9NUHaFwBWUDggUgEAADAKAJ0BKmQAQwA+0WCpTqglpCItszgBABoJQA8cSn+gY/9ytQEaq8ZCn/yC/M4WuaAo3QbCnoEKQ0i4Dr9eSTdlw+fvmdMYv1PXVeeOwEcIHpemPP/rnTm0QAD+8LA3//4hz4p/cpsU/8FxL6USO/agilnb8ZmYrORIxUBjau+VJXsc/yZFh73X8k9/v/2aAn5vwzu5z7234hKbP/OXj42Ue7XaD5NdS4jgfAMX4eQUtrvz91PrY1atmjPQ0VAtrsD1j49zxU2DzmOkUjbGPrY/D0mhz1pxjcDh1ZW68zoC9EQhhzNc4Cfd+xRQdZcA93/TvCwyvdOJYF0GrgECSi+B908418viuRHEC2rEXSKYV+DdiLChPo5euPBB0OwAuqm0eoNGGadflq9M1kjXuf0gZ+wp0v3O08SQ/6cQPm9Gg1nGezcJuWHHKIx9alhJAAAA" />
|
||||
<img id="flag_timor_leste" src="data:image/webp;base64, UklGRtQBAABXRUJQVlA4IMgBAABQCgCdASpQACgAPtFeqk8oJSQiKrM5mQAaCWgA0yGNvw/qsSAzgHnK9Ez1AG8Yt9IdAlQPaU+nF6mV6WSGXUJ9I2WQvCgniy5Q7lQ5QOpSmv5RzjjuXb8GbMnAAP7xo+bTk9ZZCQDLp7JpdW21tiAeRkYBpB/V5fa/S11gSKwAx8jmQfxSsHLSNCi+9aDs1sFGtX677MOhSZza5ztmiZb9NZNIBuaNTTEdC/sxcEWokYZrrCwCJXzLDV5nBg/Xa8WYpVDlqSkyfxB7QilDuS3yjx8Dcz/nz3iHPSPdm1JKbCmMM/3AHypp3NNHQYiuxOHqtjP+znKuUhavQ+T+Yw5uaVaS1pgg0i+Y2zjDJJUN2WfkEH2WsVLq/L0F8H1PgpWB2KX0r3moJb/hBgEFi2Kl/xd3Nge1Yh5ETb1VA8bKa19CD4hoiM4/CFbwzKUvhGjJQ2I7cvGq4K7MCnFjexvQ6TdCBFSyBXKKYHNJONAhHJ0iXlxkGhPCYzOruEDWLFfNMfbSY8cjg94yTNdY7EW0ElrThLMW3UO9Ylp1O6YE8twdadRf8vvQ9MDpMUsh1WSD1RrQNu6XbX6g53RLv5e3Ozk6JoBgAAA=" />
|
||||
<img id="flag_liberia" src="data:image/webp;base64, UklGRoABAABXRUJQVlA4IHQBAACQCQCdASpQACgAPtFgqVGoJSOrJFgJOWAaCWwAd3c8RyrhgP0o/VX36bu0Y2f9AnLJ0YDNyAlqkuQa6aDoZjpGofshB2VySrQLo7TI8etWqqE6c4WAAP7yo9H5rc5eoTiFBhOPtXiSPr0RysPE+6BhTnMnCo4G1pnhmjLdlIuyTS+mLZn6gCdfT+sBF3KZDStklN2FJHcXBAFBW9/zpXKZ0rf+fAtioLv+LJ27V2KCqRed/h9gYFJ8//B9y8WH0fQLOfAIF6jweWd1rCN1jbV5wMfGclxMS6Z/i65PC6VcO4MBmWMgNkVR63DKjtFHB/K86A3oBoqfGlL9RwNLfsHJrGyY0APa8EvuYrvcqud804k0UyzCSlrrsF2TozYl6ppsS9r7o04KHhn9wUHo3JuXj7I58SEPKIQEGdnb7n+yHM35jD/XBns0A2S4xYYDL4FbPITjsZ1kWZUBOqMPfMLRtBN8pTi7MG+j0lw/BgFppuAAAAA=" />
|
||||
<img id="flag_france" src="data:image/webp;base64, UklGRoAAAABXRUJQVlA4IHQAAABwBQCdASpQADQAPtFcpkwoJSOiLmgBABoJYwCVr08AILn0HYSB5tT7uF9cmn/IFgxNlHsAAP7u098j0x3Z98N5BquPQ9tsnWokne2arw05da3TXFi3Ts2ZjYzmdT/bHHA+P9D749jjgfH+hr+RddQAAAAAAA==" />
|
||||
<img id="flag_australia" src="data:image/webp;base64, UklGRt4CAABXRUJQVlA4INICAAAQDwCdASpQACcAPtFao0yoJSMiKrmdmQAaCWoAaS7+xYD1AfkveUeYDzefPR3wDeQq68/AV5O+zLDOHcIGmJmheM3NjCsCvO7ScnBJTnz76SK80NdKxFO9aZOQsuQE+wUdS5w8nLjq35qPhf9CkJ6ucJ0a3qWCGqyqGhx1YqXc6AAAzj2sT7WyuL6hDYcReAcVWacrDMJtPsCkHzPnFJKdyhXbKiaaVPO1djhJB4GR5GaVNXjCQ/jeSWwzzCSxqnIrrCVzAdMEZ0igQlye4aFCfUAMDHTKns0dZf65fXJvRYq9fz4uvmma+8k3vt4ve+XNdKx/hnBcH1SWFX96XyJY80c7bQUfxQXieO5r3ewv2woIWYXF3nfCoH3aXE+1RqrOVHgNauwHf7LEp9EROYBpmD/qsn7VqD9L8TRfCPsPYRGtvz8lcv2HwZeQd7Pr7+cj9tq7udC9cm2fLE+G+8XZY0drHOG80fb+FWnu0znnexShs+rsHlLwdfhsAaWm1Kq5YJNV2rsYNcvV7+YXeIieOOdqkuAC1xaxOPZlGhcjKgouEi4b1DSOD6fEej+FeXDtPzt/w01w73RJPzg+Q3tjWIk5IegyFNHdZ/TCBWEyCT//1WNyXHn0yPKsa9naKqXXI2kH9oawqMNhVrzD1UGPxHK0As1SbkTqt7Zd6a1GYst99xwbW+fg2dZFC3HuYptXE1NDX78YRXqz0lavrXPfB8vT2nWCefJfjkTE7TVL/NbIiJfJbrkdWldeAFXkLi4rE6icrTt42g9vyaqLIdkbVAIjl4bmLuqOCAHPfTHuMlvNNS0dmGFzBFeRc8PvRVRhifR1gdYf1xDkNn9j819qh/XlwkG/yKkiw3wzWvzrkrG9F7gp/6nGo+WryHPxOxkAKjmbDd6hpX6tOGb8sTKi27gpSKmvX4yYSacuxgH7WLYZpawPIjNAleop8pMY6JAAAA==" />
|
||||
<img id="flag_romania" src="data:image/webp;base64, UklGRooAAABXRUJQVlA4IH4AAADwBACdASpQAC8APtFWpEwoJKOiLugBABoJQBKgAFh0HcccH8GDTLqzpc+XIKKqMygA/uuOXpytj7Pv5w7s87NReIFZ/Y/+/qXvH7/t90n5meBc2ONjZyuPDS/+k/Ps1odKbP+GYEyinazWGFr5jdr23fI2rXo6FXVgAWEAAAA=" />
|
||||
<img id="flag_india" src="data:image/webp;base64, UklGRiYBAABXRUJQVlA4IBoBAADwCACdASpQADUAPtFiqlAoJaOioawxABoJYgDVAYG6f7Vaj/1gGGAeuKLZArQXgEcSwURBH1lU7ybDNYuld08apvxfiORuiu3/MAnnLEbGIAD+5mnf8wTtDqd37f+IcQ4hzLFk95R3hMqHsbvs+UTC+v5Qz37PWmyvtKAlwafnl5WmZYR3cswJtnqPeUloNTXbOce2V+PGAdbFugTC7uj9MkhT8yJP2v0V7ICTw1S/rDNPB7XuBA15DfZrvMivdoF2hYmPxlv3xtlgdDtC+9YflbGc1DtCNDp4NjVZTyPgOCwWSZJzbEnR1KLva/U8aRdKJ7mGnH1nmbzghpqvu+jCPA5qHl5/XICxAlPE3eAqazLSKGaQvqAAAAA=" />
|
||||
<img id="flag_bosnia" src="data:image/webp;base64, UklGRh4CAABXRUJQVlA4IBICAADQDACdASpQACcAPtFip06oJaOiJnqsAQAaCWwA0uVBfgGqW9Nv452jSjygGazayNz5nsm/uNXRsWTLuTPfHj9NlA0JzSywf+KBYV4Cg8/EAcxzf8+j8ihxW4enWq2pYsPqnG97PyHKAMQ13XASa2AA/umIYedoWHb/H1PD2wXqZiVhakI76/5VxNyiOjvZ952ANnGohmmD5dVKH/hZw8R4dvFJg66bkf+iFel9FQgsJqdqre4XKXMyJXi3+SXPqhoP3QQSOZNkYsCpTR3rjuv1X/egCettKV0dnpW0GOBh8jfQMtoGKKX26H8kJvHAyM9rc+eQVO8473bT2ic7SZ4ShqoE6cRWYaF2M3g1/2MtDwM3v7GWh39omdGETPDSTgYKtxQaLDTHiB6MQHlMTKS5dm1Al49z/75mCtsd+1DAoS4+udEIriMg8DEBo6Hs9/CZ6cKIaLHSr4QArFAz2DoO2fnfzKNCbm446HkABsPN6tM9OzgiWoJhdVQvEZpPvEJQ/NtPaIhZawT9DmLZ9BTccN5ra6mAwccCzaKhaESZ4eyxe5Ux1H3bT2hbDFGAS7amRNjjkQ4teRj9uNMaEmoVLeEYjO6DCD0QYkN6lqbBpNG+rXdrVOlkr22Z/ScbvcBLOhNlD6/zG0INHXMauOJunjgd9j5/8TiZx4wIh0yjT9ycP3Hhb9WKoYHaz5cFnQAAAA==" />
|
||||
<img id="flag_trinidad_and_tobago" src="data:image/webp;base64, UklGRkICAABXRUJQVlA4IDYCAAAwDgCdASpQADAAPtFapEuoJSOhszVYAQAaCWwA0X1BO1/vX5K8vxoL4DxAOkB5gN0A/oHUAbx9+yr+YMA7GAxf+BYWNk2mh05fQgMWMhVzmmwL41fWNf7mziMt1uj9IWCQwlrWOMx6iMy/shV7vsdKun4KPy01Tk00SAD+bQm2Ul0AHINTBFDonJj/1SCxhdNnIhJBfAQjX7/zIiZUXqnVPZk4gVPVCFAgfajI3ltBsX8vf/8TGe2QjEZI8TSnslSnXAo56j0d7yPwd+wHi3PxacGSDyH8Sl939jNiygKUxPOfd9vmAThP5mtIbJPLRbYSXKN/EMqksobN8pDB1HX+HHz4Iu7m3U3zDIkcY7VyU2f0qiiHkBAU55O1m9hmomZaNrjDF7oIBAsM96CEooeEjQnjAsDQpW1jFLR0k7t2IIcWdpAZKq7cYuDT4ZpBaNANGGGaJpkJvWjAwWumTiJ0zq/82ePKL29NZua18DkqRoChUvwE5+rm9Aa2zi4vGRh5BAJ1turG7gmGlQKsfWbvT88eNCwrNuDTxpyYETlhJTsHlcFsJD5tzkBB5HaZpLLbqaM/F7c2YqNSIY9Fw7NUNBZaH8yhb8nCyTw4Pz45TzaOvjGzrN2f46UtkIez6WknZIyh4izeA3c6XM9zd2HbnYpv0FXaulFzmj1K/PiGufmpFmfCsiNZtNKyugvovWJxwj3BzU1BuHmvanW4zuftfql6mFBgjCq4yHAJeL4gzT/nXHaAAA==" />
|
||||
<img id="flag_nigeria" src="data:image/webp;base64, UklGRnwAAABXRUJQVlA4IHAAAAAQBQCdASpQACcAPtFcpUwoJaOiLugBABoJYwDUTb+BBi+g7Coa2XiUv0Nk/suGX2PYAP7a0848NlR29KT6+8odiY8W1IChrLGaBcMMECciishdr/T4d7l1TjnnTuwKDRDF83jYOBrhqBBaMoSAdgAA" />
|
||||
<img id="flag_bhutan" src="data:image/webp;base64, UklGRooCAABXRUJQVlA4IH4CAACQDQCdASpQADUAPtFWpU0oJKOiKzksSQAaCWwAyymT/umkFd04+KoDwG2z8wHnM+iveKd5Z/yz8zMA7Lg0pVi3ezys8sh24rIn+wAqp/Cz72cOsGclsBSNRlBilSUU9fy9Yqoxw1zOtgF+u+L83TC/WeTTegAA/vDNo9nd/07v+nd+2/S45zoG4iOiv17cbGRgWCrNqZ+p4ZcK8NervJt8ElPBk6xcfoSmfZQOCZDmQT/IZaPTsrG5CLgLjJBWrELMakSjKOFbx7t3Zb0/etiI7YfxMw0xcP5fpdUX96iw4DPKNFXUtf4K2w6jmTWt3yTgL0WIApbUY8Cy/e4kRcLn5oO3Fr/kjXtcDRE6pT4nG5G/j6twf+tKwEhgkw6X6HT0AAnWQCCY5UYA+hmi8leIplEHbBP7TRZwBWejcbnpy/8gGSI0fWejAV5f4P1DLgUo+PmpQumXJ7TMITYrHiZQoZfIJe+xuB6Z6QDRzjC5datXuC+BN3KtsaCIifYiarw9Y4bcVqUAxiRIz1xQgsFJVPNcfJOX12SCYOcw8+EsV/Vbyyb+p87SKnx9rzf6QHKfIrqY8vBOdu6SynjUwrC/xbNigSey0AaCpzBNAFOyNJhBzLciSqkhZZQ2PvdcOtgWanU3GtYLXVk5iBQtWBLBkMyUPoy9OJ3AJZM02GFObLJVs4p1ju0yHNjjzTr1PPnCWHdOTkjiCjjvlr2Dxm3B/ZL3EiG0YRe7h8U/0R+mO+wF2WG4k8GMNvIrNf9I12Y/Yp8BtTq8CwcCNEBGZTnOQrMTHKHnHhVQepWs6Xw//KHGPTvmJLgPHacUiFKwyS7lHjOlzkpJk8uAFVAAAA==" />
|
||||
<img id="flag_benin" src="data:image/webp;base64, UklGRqQAAABXRUJQVlA4IJgAAADQBQCdASpQADUAPtFgp04qpaOiLNn4AVAaCUASuYBtLm+Prjv1H0VuElkSQMitwuYNLDmrc3oAAP7NW8F0fighiqslosi/+xfsD+JZw578HSZoDb9vtSIp9dIP1pP6bjR2H+m4L9TtvHojpjqhymZkFjdVWPT/sObyBP2emp/cf05lDW2n9evFO+gDVfOQBmgIGj4OfjoAAA==" />
|
||||
<img id="flag_kuwait" src="data:image/webp;base64, UklGRvIAAABXRUJQVlA4IOYAAABQBwCdASpQACcAPtFYp0uoJSOhrvScAQAaCWQA1InAuAlo/oAEDqCNdGdWoq5QutPMdkPHpP2FQoHR5odS7FSiA9gAAP7qTmXL8oqODPJkfkDo5BnJoCqSFzUOEPEfDmYntLrGImpYZ9nZ8z50iKiip/WR/GdnBL19wNXmC3dW3xFd9RgFlYq8N9wqe4woJglVe82TWQ+UMxsCJ0N6YMt34idsuXp27nA5a/7fZ9wY6Y/xgP8NBU3R2EKO2FWtCsVuSX5OTd4fRCcMMXqIcPLysD7vU4lBdXJW+bY+00EZ5QkkAAAAAA==" />
|
||||
<img id="flag_ukraine" src="data:image/webp;base64, UklGRnYAAABXRUJQVlA4IGoAAAAwBQCdASpQADUAPtFmqU8oJiOiKb1YAQAaCWMAdgCTAANXBJk0NczGFEBkrqmvM3OPwAD+3FH/9REQUksP/xC72NYeRVYanqHgqRSM7F3YX9HJio6l3YX9HJiohQDcoDeoIHumLI6lEAAA" />
|
||||
<img id="flag_singapore" src="data:image/webp;base64, UklGRkoBAABXRUJQVlA4ID4BAABQCACdASpQADUAPtForVAoJqSipnQJgQAaCUAKtMoO7zgjQNoURACcNZPQ6rMOM/Gbqw4luh1mtr73GDOsNw3DWnGbNDYHjaIsVwAA/g+hk5NM4a4f7Sjs2QM90D96IWGn6D6NZNJEqN5TsDJceE6P/r7MGfJ8lC2M1P//5mj/MSp5M+53M1/vsQrjZ0FnB82Gb+BrmOQpCqqgYV9wh7WQsofdkJvj3JuquR2hKOtcbh4YHAdqAStiEXxX+ZQI88Af8Gj+Hi6KCDnDVdxSRtFZZhlKAUaLU6c4L6grCAAlfW24veV90pNPjnLXMAlaMSCmUIVkO3GSJP5/49gWN5HrJ0f/Bxgio8Z/g4wNa5RaxsAZQubjZ8+GbnJgorQCoqa4Al/qBQWNvKWTkvK3sUUQLJfgAbhAIyCPyAAAAAA=" />
|
||||
<img id="flag_greenland" src="data:image/webp;base64, UklGRqwBAABXRUJQVlA4IKABAAAwCwCdASpQADYAPslYoUunpaMhtNTqSPAZCWgAz2HaQA/unI4/yeA26XPzdH/1Ge8ukSajZHAm/7LOlKQe84JAN3PEcq1m2YcLTg5NLDRM9argiHlW4GFblLod1NLnSi6zAAD++VhhiqUaqg4TbCMsbR775L9wkATjJCcHhUMDTvIg7uR6Sn9CN528xU6a69RhbIuibaY3KfKQoIlQLMndpfbQP+TvwE3Pp75OP1lMAra2XlDQ79+omVEu3k8/IK18lS4Oqwtu7DNvtSOldaiDsMzKcaEik6WHv/ef3kkkVkb/PkJBxeUjuCZVQ73AWcF5ec5YWrlydirq5U3udD+yI4K5hRbmE5sRhPqqaWISP3gKpcmBWq54lzNnPOnp2Ywf7P9eTLfbq3zax46XcvpLuAZPwZZ1wn4YVRXvsuhS8QbOJY8a+1r3oFNbbexBcTt7FyvSnvlaAwFTxArbcGfa67E0o/G16tveoGy77UAFq6Zf4beZu18Dxz/WAqIn6N7cqk7sUoQylN4Krys/ZLplXSgLLFA9e7eVXMgAAAAAAA==" />
|
||||
<img id="flag_madagascar" src="data:image/webp;base64, UklGRoIAAABXRUJQVlA4IHYAAACQBQCdASpQADUAPtFgqE4oJaQiLNgIAQAaCWMAlQHf/AdLsAw2k4t2QW1q5RK+f/d/3T2oAAD+8/iN/XVokn/uURq5xGv/iY8cDZ/H/Z/28yCjIEyftL4tX/xi960eO1/49+nitwgfJu4NUqOYnleP2XyQAAAA" />
|
||||
<img id="flag_jersey" src="data:image/webp;base64, UklGRlYDAABXRUJQVlA4WAoAAAAQAAAATwAALwAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7wf1IADAFZQOCAQAwAA8BIAnQEqUAAwAD7FUJ1Lp6SiobmUCqjwGIlsAL81wNseas+V4rb2zE9Kc4DxGP0A/gHtAfoB1APPt8//1AP+P1AG8a/tL6AHX/5mfO0rHXi/7XvZ8D/9euRd1NQpPRtqQ5N4IOQgls4OpOshP5n3Co3zuWpEPwA1jWrEztiX/zn5xsx0VEwILQ6oK2vnILZ1mHs+Pn8POlQ+/gaFx9FwyAD+z2X/Xi+9XjxDIYszq4j2O+z8Qtt/sa5Xp71DrLhvU9h923jY1UAkSodb+TBKtX9y2KkatM66jGyxu+6XpboLGP3LZ1IV8euUwHPf+W24I4/J2dkY20/BTQI6lbOcHCbKzL17l+aYfbJxxaPhmRTiNGuBEfLPV5xovsDNF7e/mpjfvC39csxHphaQDmNMrbED3MJbbwgxfhpY8IJVBz+daBpJNlguizB1Zw1W5YG5YR4GzpJYHQNB7i1Kpb2JJHrQHmqjPDWNM+Rd/JaSa/hZU6jhftp/zl/3A/e8E9LMnWrr8Bq26u7z997jZfD2At+Vm3veZewksON6IW2nFm9y60SKbPi5ko9tarcm5eAozcVvSeRImTn6uZnHdTdLhW6xkf21adh+9Qho1uyHpSxSFQZQjwJFMtViw2+M2sMVs5B/kYY460Mgea59XbPx/ttXLWZMuoi9yjljgTE6FxKaut+VTprq7zQf/BPEGqEaRBZflqsbrZkLdRm22GV5ZOiSt/cR7RpdDRnLflSULp7vq86/nYurnj/wSUOXtf2D+ag7K1C/mE3eazAWbcsDZZzv4VVuoLFONDNrdYyP7atOw/e36EPMCuSVX0VPzAg+ILkrEQBpL7ITaEJeU5Bwn8mONmaLo/hnXve4ybassizdVxpl34B57powDD1NFSBEeMVqyI06ZQJKtSjJMve2Uw6wQ3XgQ2HVSe/0BKkmFT97loOoVKJ0XT8Er6VC/Q43sdIMaebxxLCUB1/tgctX+tbDY8R8A8RwdzUmIBGqoRf7Gxwf/GAUvSaE0hGeyd1tmp/emEdzQ389084cixAAAA==" />
|
||||
<img id="flag_barbados" src="data:image/webp;base64, UklGRqwBAABXRUJQVlA4IKABAACQCgCdASpQADQAPtFiqU+oJaQiI1gMcQAaCWYAhTpS3nnI34AfX/PAcw7qIG80+QA757UALWs88rDWUB6qCJA0DpGNpGGZ+qvf/51u8cta7sNIfPZv/rz1oRMbjqgA/u/eX//nUfp3g/+DBo2v/EinrOhch/mEV8zvDn/rC18rPK7LSqjZ+8afgt5v3tQF/mDKe0GBsMiepKVWanFvzZhoJ+9j+36xOQRBJ/jAonIKwqjJmq3dMtAxf/f6p+b6Gx+Yt4bU8e1FQt665Vk5emhRgAuUEkqvUYyAywOmVES/b5ofLr9NymVJv2Teo9DH44f+TNzfZqyFiDDW/l3VY8J9a9pjGrwP9TsZe2dWil/dqZGzFBtVk+BMf4oK9ZcNKzucmvu3uINIA1pdp7iCPlA1/rCqmlh3SFdrYZso8p5Ts1c1xP4MLZ7sxayyrrFLSwnD1qmyZCXsF2FBW7JQFDixFtxODM/bj5KgG5F0FWXtNd6MoA/3WttQUuQ1WOF5NY7H0gYESmcY0hP1zj8p6F7/iVywmqs5MxVBnCALbAAAAA==" />
|
||||
<img id="flag_oman" src="data:image/webp;base64, UklGRhYBAABXRUJQVlA4IAoBAAAQBwCdASpQACcAPtFcqk+oJKOiJnqqAQAaCWoAegRCdGA02DeeACcjIP0eDryw1mP5oz9rNpfCSYCu8AVG1QGioAD+FSHGZzCyz6oJqF+6Kg3xt0Bxapx76HZgH6+OMZK8AnfPEpZaDxlu//G+ZmNTm40YH//8zR+6RD5XVyf9GUEbKYrAlGIVaneicgUoSk14T2L5mowNJQPmLZjk5zXCoRKz2oW8q42FuatN5dLtqvx8xt47lbwCj9j6utlS3G8wkEmrGaVlOoMLrG0ju4dpSjunwYs/LO13snuV+QnX8f8/9P/x/vuP24JhbZZRy80wYRkmKIG10zmEAX5mws3Jq4zx5LVZfAAAAA==" />
|
||||
<img id="flag_saint_helena" src="data:image/webp;base64, UklGRvwCAABXRUJQVlA4IPACAAAwEQCdASpQACgAPtFSpEwoJCOiMRYLaQAaCWwAz8/PfD+Z3af7lwOa5PUBtm/Mb5w3op/2G+S8/B7JvlM3f39DnyLIEcCuApHP+A8FrxDoDM1T0n7BX6qdVX0UP2jDLKSRPmcP6RW/+m4xy943Kph06cMSS6vj6z1AbuTWHln9eLBhHK3509srzbMK6RnOTPKoAADifcv0LnfEWG4fVe/6MJxXT97m+c1cbCBnfmQt6k4l+6S1G4a+ty1MpXBTIl4L03OkY+Qn/Rw1R/Zg8Pb4Aj6nOYK4CavWT9BmmZ3M6tQX2lIU0FPDVeAp9vmn40J3iPRBaYyxSEnhFr/pWdMF3zsFBfMf/oB6sFvI5MPNnEXo7mmsjXYuByouHWM+xAX9tDUEdBkreBI8Uma8VJDv9y+Lb0vWENI44kFzjonzoe8hJjTeomLb1GR0SN0nl0vaJ/I+gzmvw/Jb8+8+bZpRIoQGMAJUHXDmnXe6v9o4mYUCL07Tjyzh6UGvnYIi2wMzBLkOKlpfzevy3zBeO/yumpvrbDYWQqDRW9Zle/y0yO/VhB+ITXYr2N3Pwfm18gIClD9ObowNstg8U+eIsrxS9yfP7vvPlz8F9855ep1whwqfx7kf3rH60XMBpLRmpuALtzbDv532H3HQiAv/9XLqf/ST0w/+H3Pgh7+/lNy7OTdXSECqjiXwwVmkfW+aRC9f4VOt+/41mjme/kq8KGoQVOsT4EZ84sOYLuSRjz814q2S5UrXzlQr7NZ1vRKNZoSX19/8v6AhYLdxpAmcX5+S87U16I8HIZt2MHqnf6C2xQZRswxlVmNXIxirO1BIQKmzBz80XdHPuPSL+VVltnBoW05uJG0ApRSkaWJkldGUEd0NP0agXVm9q9geJR6VBvnoObvEZIUqA48/am7OB5sCZj5VSLiN7fE8RTJ7JE0OriuqPrxOJnRQcJvc7dygMTI9ZQhjHAqb8TxCrzzAxNS55fkg5hf6PxRlJpF5KgAAAA==" />
|
||||
<img id="flag_turkey" src="data:image/webp;base64, UklGRrABAABXRUJQVlA4WAoAAAAQAAAATwAANAAAQUxQSB8AAAABF3Dw/4iIwEzAJNDMEtCMzvt9Ivo/AQ04C7w/14ADAFZQOCBqAQAAcAgAnQEqUAA1AD7RYKpOqCWkIis22TkAGgliANEF2jVU/EYiSSjs4CUZW3N+RxeuWUQ9lXes3IA5zpAKBiAcCI8dM3YgboDsOE9KwAD+7kMfEP209H/6gz/5Bn/yDP09G8A9arAYObf57Rpg4qxCZkPvjlx+TXn39TiiyHdwsV/rFgL21kcNNoj0HH1psDQjIHgiJ1h5p0bt+c/Ow9vrBXFAtR9yiukgFhCns60Ar1hoGYkaJgGT6Fbjf/UZHSEqVlf6/48AiQS1XkTBtvjfsiM93eeXMwPplSw04+AEP+ENJxo3GovRWV0ymM31c3t6V7Ik8imvykhRz45QqdN6ryA6TEAnLoKOHn/IdWOOXpu9oqKO5P1Apqud6Ecar9WjnfxGcSICPgY6VWQzWDlrvd0H4PILgoLRQVjh+qEM0Llrl+eyepWjx1onIq8Mu30ZcmEKl1eMPMk6ESnpm0vq1HOktASwzo9QAAA=" />
|
||||
<img id="flag_republic_of_the_congo" src="data:image/webp;base64, UklGRuIBAABXRUJQVlA4INYBAAAwDQCdASpQADUAPtFUokuoJKMhtnN5WQAaCWwIcAF0fT75nkTOLigH5h6f/QB4hnSA8wHnodFV1AHPs+zBgvcd/maS8NyWK7iiJTP96h5OXcopZacJ1EF70OvGhALBZq8plrx7zXtlX26QJ+p1RHdSIuAA/OZoM8VX7M9lM2rE8JkDTf/zBPkHz5OrckgmQSKQm0Abl1QvxEFE7oKqZk04aC0r7Xt4V0dMY/GRkpefk/DsaeoETf1r89z5dqLU2zpceJmW41hmBqQuTotDSH5fBRqInCx2BNG6R48FXLZFaJUhhX/jUdX0jOKiNJ6jIaoF9J26bO/hSKLfAAsjxBtjXA1bk0cYvSQEV1f0f2OeryXUjYxdgkKPkVBRMzlic9G8z9Umo/f4dWZ+qp2OETsx9QH7nLpDkbCs2zxno399wl83+Gm83UPq/OFl+ujnWFrDq3frseIdwwAJvFdTgGxyyZo8BWHKPCvYu52uiqDcCJveO9a1pb34xT7NX+VmXRL+g1GUUCVhEBSDTLRPaGu0OeT3/O8BzeSw0OItZ3l3iekwqPz/MBftxWc6hFobpcw70fnobsgmSIy17u3ijIa+dgr5Uh3y0aGkgw/BqJcE6Af4AAAAAA==" />
|
||||
<img id="flag_pakistan" src="data:image/webp;base64, UklGRioBAABXRUJQVlA4IB4BAACQCACdASpQADUAPtFap0woJSOiLnVa6QAaCUADtWUaAXGjd0+2Q214vysc/OZiUDwki/dcEV9kHEe28IYcDgWXPwy75opq3l5T08iUkAD+9x6iqcdWIUX/4Fmu5B+eGiu6z+TmiHgpHVS8JhbjP8cxUkAZGXA+KDA9EcL0E0ws0tzJmG2a3TNpTO3R8I8NyoAHRQAdnPm8RFffgzMHju6wDf3PTJBNgDydMFTxM8o3KWvXqw+YbvS9hCLPHdt9CyiA6a8gJ23CtZcup2lsnmgYFBh86j64MbGhiORR/lqt+mE9Ok4D5sbVegzcUYAqySdjJDIeV8BbPex+rUHC0F5yz+UjnjeciyhsFVWc8SjMeph6CVw5EICIWbYQg4AA" />
|
||||
|
||||
</div>
|
||||
|
||||
</html>
|
266
contrib/ui/mesh-ui/webview.go
Executable file
266
contrib/ui/mesh-ui/webview.go
Executable file
|
@ -0,0 +1,266 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/webview/webview"
|
||||
"github.com/hjson/hjson-go"
|
||||
"encoding/json"
|
||||
"path/filepath"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
"strconv"
|
||||
"time"
|
||||
"net"
|
||||
"log"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/RiV-chain/RiV-mesh/src/admin"
|
||||
)
|
||||
|
||||
var riv_ctrl_path string
|
||||
|
||||
func main() {
|
||||
debug := true
|
||||
w := webview.New(debug)
|
||||
defer w.Destroy()
|
||||
w.SetTitle("RiV-mesh")
|
||||
w.SetSize(690, 920, webview.HintFixed)
|
||||
/*1. Create ~/.riv-mesh folder if not existing
|
||||
*2. Create ~/.riv-mesh/mesh.conf if not existing
|
||||
*3. If the file exists read Peers.
|
||||
*3.1 Invoke add peers for each record
|
||||
*/
|
||||
mesh_folder := ".riv-mesh"
|
||||
mesh_conf := "mesh.conf"
|
||||
user_home := get_user_home_path()
|
||||
mesh_settings_folder := filepath.Join(user_home, mesh_folder)
|
||||
err := os.MkdirAll(mesh_settings_folder, os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to create folder: %v", err)
|
||||
}
|
||||
mesh_settings_path := filepath.Join(user_home, mesh_folder, mesh_conf)
|
||||
riv_ctrl_path = get_ctl_path()
|
||||
if _, err := os.Stat(mesh_settings_path); os.IsNotExist(err) {
|
||||
err := ioutil.WriteFile(mesh_settings_path, []byte(""), 0750)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to write file: %v", err)
|
||||
}
|
||||
} else {
|
||||
//read peers from mesh.conf
|
||||
conf, _ := ioutil.ReadFile(mesh_settings_path)
|
||||
var dat map[string]interface {}
|
||||
if err := hjson.Unmarshal(conf, &dat); err != nil {
|
||||
fmt.Printf("Unable to parse mesh.conf file: %v", err)
|
||||
} else {
|
||||
if dat["Peers"]!=nil {
|
||||
peers := dat["Peers"].([]interface{})
|
||||
remove_peers()
|
||||
for _, u := range peers {
|
||||
log.Printf("Unmarshaled: %v", u.(string))
|
||||
add_peers(u.(string))
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Warning: Peers array not loaded from mesh.conf file")
|
||||
}
|
||||
}
|
||||
}
|
||||
var path string
|
||||
|
||||
if len(os.Args)>1 {
|
||||
path, err = filepath.Abs(filepath.Dir(os.Args[1]))
|
||||
} else {
|
||||
path, err = filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println(path)
|
||||
w.Bind("onLoad", func() {
|
||||
log.Println("page loaded")
|
||||
go run(w)
|
||||
})
|
||||
w.Bind("savePeers", func(peer_list string) {
|
||||
//log.Println("peers saved ", peer_list)
|
||||
var peers []string
|
||||
_ = json.Unmarshal([]byte(peer_list), &peers)
|
||||
log.Printf("Unmarshaled: %v", peers)
|
||||
remove_peers()
|
||||
for _, u := range peers {
|
||||
log.Printf("Unmarshaled: %v", u)
|
||||
add_peers(u)
|
||||
}
|
||||
//add peers to ~/mesh.conf
|
||||
dat := make(map[string]interface{})
|
||||
dat["Peers"] = peers
|
||||
bs, _ := hjson.Marshal(dat)
|
||||
e := ioutil.WriteFile(mesh_settings_path, bs, 0750)
|
||||
if e != nil {
|
||||
fmt.Printf("Unable to write file: %v", e)
|
||||
}
|
||||
})
|
||||
w.Bind("ping", func(peer_list string) {
|
||||
go ping(w, peer_list)
|
||||
})
|
||||
dat, err := ioutil.ReadFile(path+"/index.html")
|
||||
w.Navigate("data:text/html,"+url.QueryEscape(string(dat)))
|
||||
//w.Navigate("data:text/html,"+"<html>"+path+"</html>")
|
||||
w.Run()
|
||||
}
|
||||
|
||||
func ping(w webview.WebView, peer_list string){
|
||||
var peers []string
|
||||
_ = json.Unmarshal([]byte(peer_list), &peers)
|
||||
log.Printf("Unmarshaled: %v", peers)
|
||||
for _, u := range peers {
|
||||
log.Printf("Unmarshaled: %v", u)
|
||||
ping_time := check(u);
|
||||
log.Printf("ping: %d", ping_time)
|
||||
setPingValue(w, u, strconv.FormatInt(ping_time, 10));
|
||||
}
|
||||
}
|
||||
|
||||
func check(peer string) int64 {
|
||||
u, e := url.Parse(peer)
|
||||
if e!=nil {
|
||||
return -1
|
||||
}
|
||||
t := time.Now()
|
||||
_, err := net.DialTimeout("tcp", u.Host, 5*time.Second)
|
||||
if err!=nil {
|
||||
return -1
|
||||
}
|
||||
d := time.Since(t)
|
||||
return d.Milliseconds()
|
||||
}
|
||||
|
||||
func get_user_home_path() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
path, exists := os.LookupEnv("USERPROFILE")
|
||||
if exists {
|
||||
return path
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
} else {
|
||||
path, exists := os.LookupEnv("HOME")
|
||||
if exists {
|
||||
return path
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func get_ctl_path() string{
|
||||
if runtime.GOOS == "windows" {
|
||||
program_path := "programfiles"
|
||||
path, exists := os.LookupEnv(program_path)
|
||||
if exists {
|
||||
fmt.Println("Program path: %s", path)
|
||||
ctl_path := fmt.Sprintf("%s\\RiV-mesh\\meshctl.exe", path)
|
||||
return ctl_path
|
||||
} else {
|
||||
fmt.Println("could not find Program Files path")
|
||||
return ""
|
||||
}
|
||||
} else {
|
||||
ctl_path := fmt.Sprintf("/usr/local/bin/meshctl")
|
||||
return ctl_path
|
||||
}
|
||||
}
|
||||
|
||||
func run(w webview.WebView){
|
||||
if len(riv_ctrl_path) > 0 {
|
||||
get_self(w)
|
||||
get_peers(w)
|
||||
}
|
||||
_ = time.AfterFunc(10*time.Second, func() {
|
||||
run(w)
|
||||
})
|
||||
}
|
||||
|
||||
func run_command(command string) []byte{
|
||||
args := []string{"-json", command}
|
||||
cmd := exec.Command(riv_ctrl_path, args...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
//log.Fatalf("cmd.Run() failed with %s\n", err)
|
||||
return []byte(err.Error())
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func run_command_with_arg(command string, arg string) []byte{
|
||||
args := []string{"-json", command, arg}
|
||||
cmd := exec.Command(riv_ctrl_path, args...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
//log.Fatalf("command failed: %s\n", riv_ctrl_path+" "+strings.Join(args, " "))
|
||||
return []byte(err.Error())
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func add_peers(uri string){
|
||||
run_command_with_arg("addpeers", "uri="+uri)
|
||||
}
|
||||
|
||||
func remove_peers(){
|
||||
run_command("removepeers")
|
||||
}
|
||||
|
||||
func get_self(w webview.WebView){
|
||||
|
||||
res := &admin.GetSelfResponse{}
|
||||
out := run_command("getSelf")
|
||||
if err := json.Unmarshal(out, &res); err != nil {
|
||||
go setFieldValue(w, "ipv6", err.Error())
|
||||
return
|
||||
}
|
||||
//found ipv6
|
||||
fmt.Printf("IPv6: %s\n", res.IPAddress)
|
||||
go setFieldValue(w, "ipv6", res.IPAddress)
|
||||
//found subnet
|
||||
fmt.Printf("Subnet: %s\n", res.Subnet)
|
||||
go setFieldValue(w, "subnet", res.Subnet)
|
||||
out = run_command("getPeers")
|
||||
//go setFieldValue(w, "peers", string(out))
|
||||
}
|
||||
|
||||
func get_peers(w webview.WebView){
|
||||
|
||||
res := &admin.GetPeersResponse{}
|
||||
out := run_command("getPeers")
|
||||
if err := json.Unmarshal(out, &res); err != nil {
|
||||
go setFieldValue(w, "peers", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var m []string
|
||||
for _, s := range res.Peers {
|
||||
m=append(m, s.Remote)
|
||||
}
|
||||
for k := range m {
|
||||
// Loop
|
||||
fmt.Println(k)
|
||||
}
|
||||
inner_html := strings.Join(m[:], "<br>")
|
||||
strings.Join(m[:], "<br>")
|
||||
go setFieldValue(w, "peers", inner_html)
|
||||
}
|
||||
|
||||
func setFieldValue(p webview.WebView, id string, value string) {
|
||||
p.Dispatch(func() {
|
||||
p.Eval("setFieldValue('"+id+"','"+value+"');")
|
||||
})
|
||||
}
|
||||
|
||||
func setPingValue(p webview.WebView, peer string, value string) {
|
||||
p.Dispatch(func() {
|
||||
p.Eval("setPingValue('"+peer+"','"+value+"');")
|
||||
})
|
||||
}
|
4
contrib/ui/nas-asustor/CONTROL/description.txt
Normal file
4
contrib/ui/nas-asustor/CONTROL/description.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network.
|
||||
It is lightweight, self-arranging, supported on multiple platforms and
|
||||
allows pretty much any IPv6-capable application to communicate securely with
|
||||
other RiV-mesh nodes.
|
87
contrib/ui/nas-asustor/CONTROL/start-stop.sh
Normal file
87
contrib/ui/nas-asustor/CONTROL/start-stop.sh
Normal file
|
@ -0,0 +1,87 @@
|
|||
#!/bin/sh
|
||||
|
||||
BASE="/usr/local/AppCentral/mesh-nas-asustor"
|
||||
CONFIG_DIR="/usr/local/etc"
|
||||
|
||||
MESH_PACKAGE_LOG=/tmp/mesh.log
|
||||
echo "start-stop called" >> "$MESH_PACKAGE_LOG"
|
||||
|
||||
exec 2>>$MESH_PACKAGE_LOG
|
||||
set -x
|
||||
|
||||
whoami
|
||||
|
||||
init ()
|
||||
{
|
||||
config_file=${CONFIG_DIR}/mesh.conf
|
||||
if [ ! -f "$CONFIG_DIR" ]; then
|
||||
mkdir -p ${CONFIG_DIR}
|
||||
fi
|
||||
|
||||
if [ -f $config_file ]; then
|
||||
mkdir -p /var/backups
|
||||
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
|
||||
cp $config_file /var/backups/mesh.conf.`date +%Y%m%d`
|
||||
echo "Normalising and updating /etc/mesh.conf"
|
||||
${BASE}/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > $config_file
|
||||
else
|
||||
echo "Generating initial configuration file $config_file"
|
||||
echo "Please familiarise yourself with this file before starting RiV-mesh"
|
||||
sh -c "umask 0027 && ${BASE}/bin/mesh -genconf > '$config_file'"
|
||||
fi
|
||||
|
||||
#chown -R admin:administrators $config_file
|
||||
#chmod -R 664 $config_file
|
||||
#sudo insmod /lib/modules/5.4.x/tun.ko
|
||||
# Create the necessary file structure for /dev/net/tun
|
||||
if ( [ ! -c /dev/net/tun ] ); then
|
||||
if ( [ ! -d /dev/net ] ); then
|
||||
mkdir -m 755 /dev/net
|
||||
fi
|
||||
mknod /dev/net/tun c 10 200
|
||||
chmod 0755 /dev/net/tun
|
||||
fi
|
||||
|
||||
# Load the tun module if not already loaded
|
||||
if ( !(lsmod | grep -q "^tun\s") ); then
|
||||
insmod /lib/modules/5.4.x/tun.ko
|
||||
fi
|
||||
}
|
||||
|
||||
start_service ()
|
||||
{
|
||||
init
|
||||
|
||||
# Launch the mesh in the background.
|
||||
${BASE}/bin/mesh -useconffile "$config_file" \
|
||||
-httpaddress "http://0.0.0.0:19019" \
|
||||
-wwwroot "$BASE/www" \
|
||||
-logto "$BASE/var/log/mesh.log" &
|
||||
return $?
|
||||
}
|
||||
|
||||
stop_service ()
|
||||
{
|
||||
pid=`pidof -s mesh`
|
||||
if [ -z "$pid" ]; then
|
||||
echo "mesh was not running"
|
||||
exit 0
|
||||
fi
|
||||
kill "$pid"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
start_service
|
||||
echo "Running RiV Mesh"
|
||||
exit 0
|
||||
;;
|
||||
stop)
|
||||
stop_service
|
||||
echo "Stopped RiV Mesh"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
6
contrib/ui/nas-asustor/var/lib/mesh/deviceinfo
Normal file
6
contrib/ui/nas-asustor/var/lib/mesh/deviceinfo
Normal file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
echo vendor=Asustor
|
||||
echo vendorOperatingSystemName=ADM
|
||||
eval $(cat /etc/default/nas.conf | grep '\<Model\>\|\<Version\>' | sed 's/ //g')
|
||||
echo firmwareVersion="$Version"
|
||||
echo model=$Model
|
76
contrib/ui/nas-asustor/var/lib/mesh/webauth
Normal file
76
contrib/ui/nas-asustor/var/lib/mesh/webauth
Normal file
|
@ -0,0 +1,76 @@
|
|||
#!/bin/sh
|
||||
#exit with zero status on auth success and 1 on error
|
||||
#
|
||||
#You can use our cgi to restrict access to RiV Mesh configuration page only for authenticated NAS OS users.
|
||||
#==========================
|
||||
#1. use login to verify authenticated NAS OS user
|
||||
#
|
||||
#for example:
|
||||
#
|
||||
#root@AS6208T-RD:/ # REMOTE_ADDR="127.0.0.1" QUERY_STRING="act=login&apptag=mesh&account=admin&password=admin888" /usr/webman/portal/apis/appCentral/applogin.cgi
|
||||
#Content-type: text/plain; charset=utf-8
|
||||
#
|
||||
#result:
|
||||
#{ "success": true, "account": "admin", "sid": "yPgoWu95eXxCxZJr", "isAdminGroup": 1, "model": "AS6208T", "hostid": "20-16-01-21-14-01" }
|
||||
#
|
||||
#explanation:
|
||||
#apptag: application name
|
||||
#account&password: which you want to verify
|
||||
#
|
||||
#2. When you finish verifying authenticated NAS OS user, you must logout from NAS.
|
||||
#
|
||||
#for example:
|
||||
#
|
||||
#root@AS6208T-RD:/ # QUERY_STRING="act=logout&sid=yPgoWu95eXxCxZJr" /usr/webman/portal/apis/login.cgi
|
||||
#Content-type: text/plain; charset=utf-8
|
||||
#
|
||||
#result
|
||||
#{ "success": true }
|
||||
#
|
||||
#explanation:
|
||||
#sid: same as above (login result)
|
||||
|
||||
|
||||
|
||||
CACHE="/usr/local/AppCentral/mesh/var/lib/mesh/access_key"
|
||||
if [ -f $CACHE ] && [ "$(expr $(date +%s) - $(date -r $CACHE +%s))" -lt 3600 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#we want read e.g.:
|
||||
#HTTP_COOKIE='access_key=sdu45KJFDHksadulf='
|
||||
IFS=';'
|
||||
for x in $HTTP_COOKIE
|
||||
do
|
||||
eval $x
|
||||
done
|
||||
#we want get e.g.:
|
||||
#access_key='user=admin;pwd=L4edNyoCC15.kDBLIN05480'
|
||||
access_key=$(echo $access_key | base64 -d)
|
||||
|
||||
CACHE="/usr/local/AppCentral/mesh/var/lib/mesh/$access_key"
|
||||
if [ -f $CACHE ] && [ "$(expr $(date +%s) - $(date -r $CACHE +%s))" -lt 3600 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
IFS=';'
|
||||
for x in $access_key
|
||||
do
|
||||
eval $x
|
||||
done
|
||||
|
||||
if [ -z "${user}" ] || [ -z "${pwd}" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export REMOTE_ADDR="127.0.0.1"
|
||||
export QUERY_STRING="act=login&apptag=mesh&account=${user}&password=${pwd}"
|
||||
S=$(/usr/webman/portal/apis/appCentral/applogin.cgi | sed '/"sid"/!d; s/\s\+//g; s/.*"sid":"\([^"]*\)".*/\1/')
|
||||
if [ -z $S ]; then
|
||||
exit 1
|
||||
else
|
||||
export QUERY_STRING="act=logout&sid=$S"
|
||||
/usr/webman/portal/apis/login.cgi >/dev/null
|
||||
touch $CACHE
|
||||
exit 0
|
||||
fi
|
BIN
contrib/ui/nas-asustor/www/assets/partner-logo.png
Normal file
BIN
contrib/ui/nas-asustor/www/assets/partner-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
35
contrib/ui/nas-asustor/www/assets/properties.js
Normal file
35
contrib/ui/nas-asustor/www/assets/properties.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
var ed = {
|
||||
partnerId: 1422,
|
||||
applicationName: 'RiV Mesh Asustor ADM App',
|
||||
nasOSName: 'Asustor ADM',
|
||||
useAuthNASRichScreen: true,
|
||||
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh",
|
||||
getNasAuthUrl: function () {
|
||||
return "/";
|
||||
},
|
||||
nasLoginCall: function (nasLoginSuccess, nasLoginFailure) {
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (10 * 60 * 1000));
|
||||
document.cookie = "access_key=" + btoa( "user=" + encodeURIComponent($('#nasInputUser').val()) + ";pwd=" + encodeURIComponent($('#nasInputPassword').val()))+ "; expires=" + d.toUTCString() + "; path=/";
|
||||
$.ajax({url: "api/getself"}).done(function () {
|
||||
window.location.reload();
|
||||
}).fail(function () {
|
||||
ed.nasLogoutCall();
|
||||
nasLoginFailure();
|
||||
});
|
||||
},
|
||||
nasLogoutCall: function () {
|
||||
document.cookie = "access_key=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
|
||||
},
|
||||
getNasUser: function() {
|
||||
function getCookie(name) {
|
||||
var matches = document.cookie.match(new RegExp(
|
||||
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
|
||||
));
|
||||
return matches ? decodeURIComponent(matches[1]) : undefined;
|
||||
}
|
||||
return decodeURIComponent(atob(getCookie('access_key')).split(';')[0].split('=')[1]);
|
||||
}
|
||||
};
|
4
contrib/ui/nas-drobo/Content/install.sh
Normal file
4
contrib/ui/nas-drobo/Content/install.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
. $(dirname $0)/scripts.sh
|
||||
_install
|
20
contrib/ui/nas-drobo/Content/mesh.conf
Normal file
20
contrib/ui/nas-drobo/Content/mesh.conf
Normal file
|
@ -0,0 +1,20 @@
|
|||
RedirectMatch 301 ^/mesh$ /mesh/
|
||||
LoadModule proxy_http_module modules/mod_proxy_http.so
|
||||
|
||||
<Location /mesh/>
|
||||
|
||||
AuthType Form
|
||||
AuthName "DroboApps"
|
||||
AuthUserFile /tmp/DroboApps/apache/htpasswd
|
||||
AuthFormProvider file
|
||||
ErrorDocument 401 /login/index.html
|
||||
Session On
|
||||
SessionCookieName session path=/
|
||||
SessionCryptoPassphrase "exec:/mnt/DroboFS/Shares/DroboApps/apache/libexec/cookie.sh"
|
||||
Require valid-user
|
||||
|
||||
ProxyPreserveHost On
|
||||
|
||||
ProxyPass "http://127.0.0.1:19019/"
|
||||
ProxyPassReverse "http://127.0.0.1:19019/"
|
||||
</Location>
|
40
contrib/ui/nas-drobo/Content/scripts.sh
Normal file
40
contrib/ui/nas-drobo/Content/scripts.sh
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
tmpdir="/tmp/DroboApps/mesh"
|
||||
errorfile="${tmpdir}/error.txt"
|
||||
base_dir="/mnt/DroboFS/Shares/DroboApps/mesh"
|
||||
config_dir="$base_dir/config"
|
||||
config_file="$config_dir/mesh.conf"
|
||||
prog_dir="$(dirname "$(realpath "${0}")")"
|
||||
|
||||
|
||||
_install() {
|
||||
if [ ! -f "${errorfile}" ]
|
||||
then
|
||||
mkdir -p "${tmpdir}"
|
||||
if [ ! -f "$config_file" ]; then
|
||||
echo 3 > "${errorfile}"
|
||||
fi
|
||||
fi
|
||||
ln -s $base_dir/var/log/mesh.log $base_dir/www/log
|
||||
# install apache 2.x
|
||||
/usr/bin/DroboApps.sh install_version apache 2
|
||||
}
|
||||
|
||||
_uninstall() {
|
||||
pid=`pidof -s mesh`
|
||||
if [ -z "$pid" ]; then
|
||||
echo "mesh was not running"
|
||||
else
|
||||
kill "$pid"
|
||||
fi
|
||||
}
|
||||
|
||||
_update() {
|
||||
/bin/sh "${prog_dir}/service.sh" stop
|
||||
|
||||
cd "$base_dir"
|
||||
rm -rf $(ls | grep -v 'host_uid.txt\|var\|config')
|
||||
|
||||
echo 'update successful' > "${prog_dir}/update.log"
|
||||
}
|
121
contrib/ui/nas-drobo/Content/service.sh
Normal file
121
contrib/ui/nas-drobo/Content/service.sh
Normal file
|
@ -0,0 +1,121 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
|
||||
##!!
|
||||
. /etc/service.subr
|
||||
|
||||
prog_dir=`dirname \`realpath $0\``
|
||||
base_dir=/mnt/DroboFS/Shares/DroboApps/mesh
|
||||
config_dir="$base_dir/config"
|
||||
config_file="$config_dir/mesh.conf"
|
||||
|
||||
name="mesh"
|
||||
framework_version="2.1"
|
||||
description="RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network"
|
||||
depends=""
|
||||
webui="WebUI"
|
||||
|
||||
errorfile=/tmp/DroboApps/mesh/error.txt
|
||||
pidfile=/tmp/DroboApps/mesh/pid.txt
|
||||
statusfile=/tmp/DroboApps/mesh/status.txt
|
||||
edstatusfile=$base_dir/var/lib/mesh/status
|
||||
|
||||
start()
|
||||
{
|
||||
mkdir -p /tmp/DroboApps/mesh
|
||||
# delete edstatufile before starting daemon to delete previous status
|
||||
rm -f $edstatusfile
|
||||
rm -f $errorfile
|
||||
|
||||
if [ -f $config_file ]; then
|
||||
mkdir -p /var/backups
|
||||
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
|
||||
cp $config_file /var/backups/mesh.conf.`date +%Y%m%d`
|
||||
echo "Normalising and updating /etc/mesh.conf"
|
||||
$base_dir/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > $config_file
|
||||
else
|
||||
mkdir -p $config_dir
|
||||
echo "Generating initial configuration file $config_file"
|
||||
echo "Please familiarise yourself with this file before starting RiV-mesh"
|
||||
sh -c "umask 0027 && $base_dir/bin/mesh -genconf > '$config_file'"
|
||||
fi
|
||||
|
||||
# Create the necessary file structure for /dev/net/tun
|
||||
if ( [ ! -c /dev/net/tun ] ); then
|
||||
if ( [ ! -d /dev/net ] ); then
|
||||
mkdir -m 755 /dev/net
|
||||
fi
|
||||
mknod /dev/net/tun c 10 200
|
||||
chmod 0755 /dev/net/tun
|
||||
fi
|
||||
|
||||
# Load the tun module if not already loaded
|
||||
if ( !(lsmod | grep -q "^tun\s") ); then
|
||||
KERNEL_VERSION=$(/bin/uname -r)
|
||||
insmod $base_dir/lib/modules/$KERNEL_VERSION/tun.ko
|
||||
fi
|
||||
|
||||
# Launch the mesh in the background.
|
||||
${base_dir}/bin/mesh -useconffile "$config_file" \
|
||||
-httpaddress "http://localhost:19019" \
|
||||
-wwwroot "$base_dir/www" \
|
||||
-logto "$base_dir/var/log/mesh.log" &
|
||||
|
||||
sleep 1
|
||||
update_status
|
||||
}
|
||||
|
||||
update_status()
|
||||
{
|
||||
|
||||
# wait until file appears
|
||||
i=30
|
||||
|
||||
while [ -z $(pidof -s mesh) ]
|
||||
do
|
||||
sleep 1
|
||||
i=$((i-1))
|
||||
|
||||
if [ $i -eq 0 ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# if we don't have file here. throw error into status and return
|
||||
if [ -z $(pidof -s mesh) ]
|
||||
then
|
||||
echo "" > "$pidfile"
|
||||
echo 1 > "${errorfile}"
|
||||
echo "Configuration required" > $statusfile
|
||||
else
|
||||
echo $(pidof -s mesh) > "$pidfile"
|
||||
echo 0 > "${errorfile}"
|
||||
echo "Application is running" > $statusfile
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
pid=`pidof -s mesh`
|
||||
if [ -z "$pid" ]; then
|
||||
echo 1 > "${errorfile}"
|
||||
echo "mesh was not running" > $statusfile
|
||||
else
|
||||
kill "$pid"
|
||||
echo 0 > "${errorfile}"
|
||||
echo "Application is stopped" > $statusfile
|
||||
fi
|
||||
echo "" > "$pidfile"
|
||||
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
update_status)
|
||||
update_status
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
main "$@"
|
4
contrib/ui/nas-drobo/Content/uninstall.sh
Normal file
4
contrib/ui/nas-drobo/Content/uninstall.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env sh
|
||||
#
|
||||
. $(dirname $0)/scripts.sh
|
||||
_uninstall
|
3
contrib/ui/nas-drobo/Content/update.sh
Normal file
3
contrib/ui/nas-drobo/Content/update.sh
Normal file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
. $(dirname $0)/scripts.sh
|
||||
_update
|
16
contrib/ui/nas-drobo/Content/var/lib/mesh/hooks/deviceinfo
Normal file
16
contrib/ui/nas-drobo/Content/var/lib/mesh/hooks/deviceinfo
Normal file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
echo vendor=Drobo
|
||||
|
||||
# get device model, e.g., "5N"
|
||||
_get_device_model() {
|
||||
for f in /sys/devices/dri_dnas_primary/dnas_adp_1/host*/target*/*:*:*:*/model; do
|
||||
if [ -e "$f" ]; then
|
||||
cat "$f"
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
echo serial=$(cat /mnt/DroboFS/Shares/DroboApps/mesh/host_uid.txt)
|
||||
echo firmwareVersion=$(/usr/bin/esa vxver)
|
||||
echo model=$(_get_device_model)
|
BIN
contrib/ui/nas-drobo/Content/www/assets/partner-logo.png
Normal file
BIN
contrib/ui/nas-drobo/Content/www/assets/partner-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
25
contrib/ui/nas-drobo/Content/www/assets/partner.css
Normal file
25
contrib/ui/nas-drobo/Content/www/assets/partner.css
Normal file
|
@ -0,0 +1,25 @@
|
|||
body {
|
||||
color: gray;
|
||||
background: black;
|
||||
}
|
||||
.nas-apps-config-form-message.nas-apps-config-form-message-error {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* bottom */
|
||||
.nas-apps-config-form-partner-logo {
|
||||
width: 200px;
|
||||
height: 82px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.nas-apps-config-form-auth-id,
|
||||
.nas-apps-config-form-location-name {
|
||||
color: white;
|
||||
}
|
||||
.nas-apps-config-form-field input,
|
||||
.nas-apps-config-form-field select {
|
||||
color: white;
|
||||
}
|
||||
.nas-apps-config-form-field select:focus option {
|
||||
background: white;
|
||||
}
|
9
contrib/ui/nas-drobo/Content/www/assets/properties.js
Normal file
9
contrib/ui/nas-drobo/Content/www/assets/properties.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
var ed = {
|
||||
partnerId: 1046,
|
||||
brand: 'RiV Mesh',
|
||||
applicationName: "RiV Mesh Drobo App",
|
||||
nasOSName: "Drobo",
|
||||
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh"
|
||||
};
|
11
contrib/ui/nas-netgear-os6/package/DEBIAN/control
Normal file
11
contrib/ui/nas-netgear-os6/package/DEBIAN/control
Normal file
|
@ -0,0 +1,11 @@
|
|||
Source: mesh
|
||||
Package: mesh
|
||||
Version: 0.4.4
|
||||
Architecture: amd64
|
||||
Maintainer: Vadym Vikulin <vadym.vikulin@rivchain.org>
|
||||
Depends: lsb-base, debconf, readynasos (>= 6.0.5~T1271)
|
||||
Section: net
|
||||
Priority: optional
|
||||
Installed-Size: 20000
|
||||
Homepage: https://github.com/RiV-chain/RiV-mesh
|
||||
Description: RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 network
|
61
contrib/ui/nas-netgear-os6/package/DEBIAN/postinst
Executable file
61
contrib/ui/nas-netgear-os6/package/DEBIAN/postinst
Executable file
|
@ -0,0 +1,61 @@
|
|||
#!/bin/sh
|
||||
# postinst script for mesh
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postinst> `configure' <most-recently-configured-version>
|
||||
# * <old-postinst> `abort-upgrade' <new version>
|
||||
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||
# <new-version>
|
||||
# * <postinst> `abort-remove'
|
||||
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||
# <failed-install-package> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
chown -R admin:admin /apps/mesh
|
||||
if systemctl restart apache2.service; then
|
||||
# success
|
||||
event_push app meshd '<add-s resource-type="LocalApp" resource-id="LocalApp"><LocalApp appname="mesh" success="1"/></add-s>' 0 0
|
||||
else
|
||||
# error
|
||||
event_push app meshd '<add-s resource-type="LocalApp" resource-id="LocalApp"><LocalApp appname="mesh" success="0"/></add-s>' 0 0
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f /etc/mesh.conf ]; then
|
||||
mkdir -p /var/backups
|
||||
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
|
||||
cp /etc/mesh.conf /var/backups/mesh.conf.`date +%Y%m%d`
|
||||
echo "Normalising and updating /etc/mesh.conf"
|
||||
/apps/mesh/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > /etc/mesh.conf
|
||||
else
|
||||
echo "Generating initial configuration file /etc/mesh.conf"
|
||||
echo "Please familiarise yourself with this file before starting RiV-mesh"
|
||||
sh -c 'umask 0027 && /apps/mesh/bin/mesh -genconf > /etc/mesh.conf'
|
||||
fi
|
||||
|
||||
chmod 755 /etc/mesh.conf
|
||||
if command -v systemctl >/dev/null; then
|
||||
systemctl daemon-reload || echo -n "daemon not reloaded!"
|
||||
systemctl enable mesh || echo -n "systemctl enable failed!"
|
||||
systemctl restart mesh || echo -n "systemctl restart failed!"
|
||||
fi
|
||||
|
||||
exit 0
|
32
contrib/ui/nas-netgear-os6/package/DEBIAN/postrm
Executable file
32
contrib/ui/nas-netgear-os6/package/DEBIAN/postrm
Executable file
|
@ -0,0 +1,32 @@
|
|||
#! /bin/sh
|
||||
# postrm script for mesh
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postrm> `remove'
|
||||
# * <postrm> `purge'
|
||||
# * <old-postrm> `upgrade' <new-version>
|
||||
# * <new-postrm> `failed-upgrade' <old-version>
|
||||
# * <new-postrm> `abort-install'
|
||||
# * <new-postrm> `abort-install' <old-version>
|
||||
# * <new-postrm> `abort-upgrade' <old-version>
|
||||
# * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
|
||||
# for details, see /usr/share/doc/packaging-manual/
|
||||
|
||||
case "$1" in
|
||||
purge)
|
||||
rm -rf /apps/mesh
|
||||
systemctl restart apache2.service
|
||||
event_push app meshd '<delete-s resource-type="LocalApp" resource-id="LocalApp"><LocalApp appname="mesh" success="1" reboot="0"/></delete-s>' 0 0
|
||||
;;
|
||||
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postrm called with unknown argument \`$1'" >&2
|
||||
exit 0
|
||||
|
||||
esac
|
32
contrib/ui/nas-netgear-os6/package/DEBIAN/prerm
Executable file
32
contrib/ui/nas-netgear-os6/package/DEBIAN/prerm
Executable file
|
@ -0,0 +1,32 @@
|
|||
#! /bin/sh
|
||||
# prerm script for mesh
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <prerm> `remove'
|
||||
# * <old-prerm> `upgrade' <new-version>
|
||||
# * <new-prerm> `failed-upgrade' <old-version>
|
||||
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
|
||||
# * <deconfigured's-prerm> `deconfigure' `in-favour'
|
||||
# <package-being-installed> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see /usr/share/doc/packaging-manual/
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure)
|
||||
systemctl stop fvapp-mesh.service || true
|
||||
systemctl disable fvapp-mesh.service || true
|
||||
;;
|
||||
failed-upgrade)
|
||||
;;
|
||||
*)
|
||||
echo "prerm called with unknown argument \`$1'" >&2
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
exit 0
|
19
contrib/ui/nas-netgear-os6/package/apps/mesh/fvapp-mesh.service
Executable file
19
contrib/ui/nas-netgear-os6/package/apps/mesh/fvapp-mesh.service
Executable file
|
@ -0,0 +1,19 @@
|
|||
[Unit]
|
||||
Description=RiV-mesh is an early-stage implementation of a fully end-to-end encrypted IPv6 network
|
||||
|
||||
[Service]
|
||||
Type=idle
|
||||
Group=admin
|
||||
ProtectHome=true
|
||||
ProtectSystem=true
|
||||
SyslogIdentifier=mesh
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
|
||||
ExecStartPre=+-/sbin/modprobe tun
|
||||
ExecStart=/apps/mesh/bin/mesh -useconffile /etc/mesh.conf -httpaddress http://localhost:19019 -wwwroot /apps/mesh/www -logto /apps/mesh/var/log/mesh.log
|
||||
ExecStop=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
TimeoutStopSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
12
contrib/ui/nas-netgear-os6/package/apps/mesh/https.conf
Executable file
12
contrib/ui/nas-netgear-os6/package/apps/mesh/https.conf
Executable file
|
@ -0,0 +1,12 @@
|
|||
RewriteEngine on
|
||||
RewriteRule "(.*)/apps/mesh$" "$1/apps/mesh/" [R=301,L]
|
||||
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
|
||||
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
|
||||
|
||||
<Location /apps/mesh/>
|
||||
Include "/etc/frontview/apache/Admin_Auth.conf"
|
||||
SSLRequireSSL
|
||||
ProxyPreserveHost On
|
||||
ProxyPass "http://127.0.0.1:19019/"
|
||||
ProxyPassReverse "http://127.0.0.1:19019/"
|
||||
</Location>
|
10
contrib/ui/nas-netgear-os6/package/apps/mesh/var/lib/mesh/hooks/deviceinfo
Executable file
10
contrib/ui/nas-netgear-os6/package/apps/mesh/var/lib/mesh/hooks/deviceinfo
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
get_info() {
|
||||
rn_nml -g systeminfo | tr '\n' ' ' | sed -r "s|.*<$1>(.*)</$1>.*|\1|"
|
||||
}
|
||||
echo vendor=Netgear
|
||||
echo vendorOperatingSystemName="$(get_info Firmware_Name)"
|
||||
echo firmwareVersion="$(get_info Firmware_Version)"
|
||||
echo model="$(get_info Model)"
|
||||
echo serial="$(get_info Serial)"
|
BIN
contrib/ui/nas-netgear-os6/package/apps/mesh/www/assets/partner-logo.png
Executable file
BIN
contrib/ui/nas-netgear-os6/package/apps/mesh/www/assets/partner-logo.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
9
contrib/ui/nas-netgear-os6/package/apps/mesh/www/assets/partner.css
Executable file
9
contrib/ui/nas-netgear-os6/package/apps/mesh/www/assets/partner.css
Executable file
|
@ -0,0 +1,9 @@
|
|||
.nas-apps-config-form-app-logo {
|
||||
height: 110px;
|
||||
background: url(logo.png) left center no-repeat;
|
||||
background-size: 262px 56px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #692782!important;
|
||||
}
|
10
contrib/ui/nas-netgear-os6/package/apps/mesh/www/assets/properties.js
Executable file
10
contrib/ui/nas-netgear-os6/package/apps/mesh/www/assets/properties.js
Executable file
|
@ -0,0 +1,10 @@
|
|||
var ed = {
|
||||
partnerId: 252,
|
||||
applicationName: 'RiV-Mesh App',
|
||||
nasOSName: 'Ready NAS OS 6',
|
||||
vaultUrl: "https://github.com/RiV-chain/RiV-mesh",
|
||||
basicEDWebsite: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh"
|
||||
};
|
8
contrib/ui/nas-qnap/au/apache-mesh.conf
Normal file
8
contrib/ui/nas-qnap/au/apache-mesh.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
RedirectMatch 301 ^/mesh$ /mesh/
|
||||
LoadModule proxy_http_module modules/mod_proxy_http.so
|
||||
|
||||
<Location /mesh/>
|
||||
ProxyPreserveHost On
|
||||
ProxyPass "http://127.0.0.1:19019/"
|
||||
ProxyPassReverse "http://127.0.0.1:19019/"
|
||||
</Location>
|
7
contrib/ui/nas-qnap/au/var/lib/mesh/hooks/deviceinfo
Normal file
7
contrib/ui/nas-qnap/au/var/lib/mesh/hooks/deviceinfo
Normal file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
CFG=/etc/default_config/uLinux.conf
|
||||
echo vendor=QNAP
|
||||
echo vendorOperatingSystemName=$(/sbin/getcfg System OS -f $CFG)
|
||||
echo firmwareVersion=$(/sbin/getcfg System Version -f $CFG)
|
||||
echo model=$(/sbin/getcfg System Model -f $CFG)
|
||||
echo serial=$(/sbin/get_hwsn)
|
31
contrib/ui/nas-qnap/au/var/lib/mesh/hooks/webauth
Normal file
31
contrib/ui/nas-qnap/au/var/lib/mesh/hooks/webauth
Normal file
|
@ -0,0 +1,31 @@
|
|||
#!/bin/sh
|
||||
#we want read:
|
||||
#export HTTP_COOKIE='qnapuser=admin; qnappwd=L4edNyoCC15.kDBLIN05480'
|
||||
|
||||
IFS=';'
|
||||
for x in $HTTP_COOKIE
|
||||
do
|
||||
eval $x
|
||||
done
|
||||
[ -z ${qnapuser} ] && exit 1
|
||||
[ -z ${qnappwd} ] && exit 1
|
||||
|
||||
#exit with zero status on auth success
|
||||
#2-pass auth
|
||||
S=$(curl -s -k -L "http://127.0.0.1:58080/cgi-bin/authLogin.cgi?user=${qnapuser}&pwd=${qnappwd}" | tr -d '\040\011\012\015' | grep -F '<authPassed><![CDATA[1]]></authPassed>')
|
||||
[ ! 0 -eq ${#S} ] && exit 0
|
||||
|
||||
AUTH_PORT=$(cat /etc/apache-sys-proxy.conf | grep Listen | awk '{print $2}')
|
||||
if [ -n $AUTH_PORT ] ; then
|
||||
AUTH_PORT=8080
|
||||
fi
|
||||
|
||||
S=$(curl -s -k -L "http://127.0.0.1:${AUTH_PORT}/cgi-bin/authLogin.cgi?user=${qnapuser}&pwd=${qnappwd}" | tr -d '\040\011\012\015' | grep -F '<authPassed><![CDATA[1]]></authPassed>')
|
||||
[ ! 0 -eq ${#S} ] && exit 0
|
||||
|
||||
#fallback to plain password auth
|
||||
#decode password first
|
||||
plain_pwd=$(openssl enc -base64 -d <<< ${qnappwd})
|
||||
[ -z $plain_pwd ] && exit 1
|
||||
S=$(curl -s -k -L "http://127.0.0.1:${AUTH_PORT}/cgi-bin/authLogin.cgi?user=${qnapuser}&plain_pwd=${plain_pwd}" | tr -d '\040\011\012\015' | grep -F '<authPassed><![CDATA[1]]></authPassed>')
|
||||
[ 0 -eq ${#S} ] && exit 1 || exit 0
|
12
contrib/ui/nas-qnap/au/var/lib/mesh/pre_upgrade.sh
Normal file
12
contrib/ui/nas-qnap/au/var/lib/mesh/pre_upgrade.sh
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
log_exit(){
|
||||
echo $2
|
||||
exit $1
|
||||
}
|
||||
|
||||
[ -z "$MESH_USER_NAME" ] && log_exit 1 "Credentials are not set. Remove aborted"
|
||||
|
||||
rm "$MESH_APP_ROOT/bin/mesh
|
||||
rm -rf "$MESH_APP_ROOT/www"
|
||||
|
102
contrib/ui/nas-qnap/au/www/assets/get_sid.js
Normal file
102
contrib/ui/nas-qnap/au/www/assets/get_sid.js
Normal file
|
@ -0,0 +1,102 @@
|
|||
/* encode function start */
|
||||
var ezEncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var ezDecodeChars = new Array(
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
|
||||
|
||||
function utf16to8(str)
|
||||
{
|
||||
var out, i, len, c;
|
||||
out = "";
|
||||
len = str.length;
|
||||
for (i=0; i<len; i++) {
|
||||
c = str.charCodeAt(i);
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
out += str.charAt(i);
|
||||
}
|
||||
else if (c > 0x07FF) {
|
||||
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
|
||||
out += String.fromCharCode(0x80 | ((c >>6) & 0x3F));
|
||||
out += String.fromCharCode(0x80 | ((c >>0) & 0x3F));
|
||||
|
||||
}
|
||||
else {
|
||||
out += String.fromCharCode(0xC0 | ((c >>6) & 0x1F));
|
||||
out += String.fromCharCode(0x80 | ((c >>0) & 0x3F));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function utf8to16(str) {
|
||||
var out, i, len, c;
|
||||
var char2, char3;
|
||||
|
||||
out = "";
|
||||
len = str.length;
|
||||
i = 0;
|
||||
while(i < len) {
|
||||
c = str.charCodeAt(i++);
|
||||
switch(c >> 4)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
|
||||
// 0xxxxxxx
|
||||
out += str.charAt(i-1);
|
||||
break;
|
||||
case 12: case 13:
|
||||
// 110x xxxx 10xx xxxx
|
||||
char2 = str.charCodeAt(i++);
|
||||
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
|
||||
break;
|
||||
case 14:
|
||||
// 1110 xxxx10xx xxxx10xx xxxx
|
||||
char2 = str.charCodeAt(i++);
|
||||
char3 = str.charCodeAt(i++);
|
||||
out += String.fromCharCode(((c & 0x0F) << 12) |
|
||||
((char2 & 0x3F) << 6) |
|
||||
((char3 & 0x3F) << 0));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function ezEncode(str)
|
||||
{
|
||||
var out, i, len;
|
||||
var c1, c2, c3;
|
||||
|
||||
len = str.length;
|
||||
i = 0;
|
||||
out = "";
|
||||
while(i < len)
|
||||
{
|
||||
c1 = str.charCodeAt(i++) & 0xff;
|
||||
if(i == len)
|
||||
{
|
||||
out += ezEncodeChars.charAt(c1 >> 2);
|
||||
out += ezEncodeChars.charAt((c1 & 0x3) << 4);
|
||||
out += "==";
|
||||
break;
|
||||
}
|
||||
c2 = str.charCodeAt(i++);
|
||||
if(i == len)
|
||||
{
|
||||
out += ezEncodeChars.charAt(c1 >> 2);
|
||||
out += ezEncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
|
||||
out += ezEncodeChars.charAt((c2 & 0xF) << 2);
|
||||
out += "=";
|
||||
break;
|
||||
}
|
||||
c3 = str.charCodeAt(i++);
|
||||
out += ezEncodeChars.charAt(c1 >> 2);
|
||||
out += ezEncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
|
||||
out += ezEncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
|
||||
out += ezEncodeChars.charAt(c3 & 0x3F);
|
||||
}
|
||||
return out;
|
||||
}
|
BIN
contrib/ui/nas-qnap/au/www/assets/partner-logo.png
Normal file
BIN
contrib/ui/nas-qnap/au/www/assets/partner-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
104
contrib/ui/nas-qnap/au/www/assets/properties.js
Normal file
104
contrib/ui/nas-qnap/au/www/assets/properties.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
var ed = {
|
||||
partnerId: 1222,
|
||||
brand: 'RiV Mesh',
|
||||
applicationName: "RiV Mesh QNAP NAS OS App",
|
||||
nasOSName: "QNAP NAS device",
|
||||
useAuthNASRichScreen: true,
|
||||
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh",
|
||||
getNasAuthUrl: function () {
|
||||
return "/";
|
||||
}
|
||||
};
|
||||
|
||||
$(function () {
|
||||
|
||||
ed.nasLoginCall = function (nasLoginSuccess, nasLoginFailure) {
|
||||
/* encode function start */
|
||||
var ezEncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
function utf16to8(str)
|
||||
{
|
||||
var out, i, len, c;
|
||||
out = "";
|
||||
len = str.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
c = str.charCodeAt(i);
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
out += str.charAt(i);
|
||||
} else if (c > 0x07FF) {
|
||||
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
|
||||
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
|
||||
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
|
||||
|
||||
} else {
|
||||
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
|
||||
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function ezEncode(str)
|
||||
{
|
||||
var out, i, len;
|
||||
var c1, c2, c3;
|
||||
|
||||
len = str.length;
|
||||
i = 0;
|
||||
out = "";
|
||||
while (i < len)
|
||||
{
|
||||
c1 = str.charCodeAt(i++) & 0xff;
|
||||
if (i == len)
|
||||
{
|
||||
out += ezEncodeChars.charAt(c1 >> 2);
|
||||
out += ezEncodeChars.charAt((c1 & 0x3) << 4);
|
||||
out += "==";
|
||||
break;
|
||||
}
|
||||
c2 = str.charCodeAt(i++);
|
||||
if (i == len)
|
||||
{
|
||||
out += ezEncodeChars.charAt(c1 >> 2);
|
||||
out += ezEncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
|
||||
out += ezEncodeChars.charAt((c2 & 0xF) << 2);
|
||||
out += "=";
|
||||
break;
|
||||
}
|
||||
c3 = str.charCodeAt(i++);
|
||||
out += ezEncodeChars.charAt(c1 >> 2);
|
||||
out += ezEncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
|
||||
out += ezEncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
|
||||
out += ezEncodeChars.charAt(c3 & 0x3F);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (30 * 60 * 1000));
|
||||
document.cookie = "qnapuser=" + encodeURIComponent($('#nasInputUser').val()) + "; expires=" + d.toUTCString() + "; path=/";
|
||||
document.cookie = "qnappwd=" + encodeURIComponent(ezEncode(utf16to8($('#nasInputPassword').val()))) + "; expires=" + d.toUTCString() + "; path=/";
|
||||
$.ajax({url: "rest/info"}).done(function (response) {
|
||||
window.location.reload();
|
||||
checkError(response);
|
||||
}).fail(function () {
|
||||
ed.nasLogoutCall();
|
||||
nasLoginFailure();
|
||||
});
|
||||
};
|
||||
ed.nasLogoutCall = function() {
|
||||
document.cookie = "qnapuser=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
|
||||
document.cookie = "qnappwd=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
|
||||
};
|
||||
function getCookie(name) {
|
||||
var matches = document.cookie.match(new RegExp(
|
||||
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
|
||||
));
|
||||
return matches ? decodeURIComponent(matches[1]) : undefined;
|
||||
}
|
||||
ed.getNasUser = function() {
|
||||
return getCookie('qnapuser');
|
||||
};
|
||||
});
|
42
contrib/ui/nas-qnap/package/package_routines
Normal file
42
contrib/ui/nas-qnap/package/package_routines
Normal file
|
@ -0,0 +1,42 @@
|
|||
#script called from qinstall.sh
|
||||
|
||||
#SYS_QPKG_SERVICE_ENABLED="FALSE"
|
||||
QPKG_NAME="mesh"
|
||||
CONF=/etc/config/mesh.conf
|
||||
|
||||
PKG_PRE_REMOVE="{
|
||||
killall -q mesh
|
||||
rm -rf /share/Web/$QPKG_NAME
|
||||
[ -L /var/log/mesh.log ] && rm -f /var/log/mesh.log
|
||||
}"
|
||||
|
||||
PKG_MAIN_REMOVE="{
|
||||
$CMD_RM -f $CONF
|
||||
}"
|
||||
|
||||
pkg_pre_install(){
|
||||
killall -q mesh
|
||||
rm -rf /share/Web/$QPKG_NAME
|
||||
}
|
||||
|
||||
pkg_install(){
|
||||
exec 2>/tmp/mesh.log
|
||||
set -x
|
||||
if [ -f $CONF ]; then
|
||||
mkdir -p /var/backups
|
||||
echo "Backing up configuration file to /var/backups/mesh.conf.`date +%Y%m%d`"
|
||||
cp $CONF /var/backups/mesh.conf.`date +%Y%m%d`
|
||||
echo "Normalising and updating $CONF"
|
||||
${SYS_QPKG_DIR}/bin/mesh -useconf -normaliseconf < /var/backups/mesh.conf.`date +%Y%m%d` > $CONF
|
||||
else
|
||||
echo "Generating initial configuration file $config_file"
|
||||
echo "Please familiarise yourself with this file before starting RiV-mesh"
|
||||
sh -c "umask 0027 && ${SYS_QPKG_DIR}/bin/mesh -genconf > '$CONF'"
|
||||
fi
|
||||
chmod a+w $CONF
|
||||
|
||||
}
|
||||
|
||||
pkg_post_install(){
|
||||
ln -sf $SYS_QPKG_DIR/var/log/mesh.log $SYS_QPKG_DIR/www/log
|
||||
}
|
120
contrib/ui/nas-qnap/package/shared/mesh.sh
Normal file
120
contrib/ui/nas-qnap/package/shared/mesh.sh
Normal file
|
@ -0,0 +1,120 @@
|
|||
#!/bin/sh
|
||||
QPKG_CONF="/etc/config/qpkg.conf"
|
||||
CONF="/etc/config/mesh.conf"
|
||||
QPKG_NAME="mesh"
|
||||
QPKG_DIR=$(/sbin/getcfg $QPKG_NAME Install_Path -f $QPKG_CONF)
|
||||
KERNEL_MODULES+=" tun"
|
||||
|
||||
load_kernel_modules(){
|
||||
local KERNEL_VERSION=$(/bin/uname -r)
|
||||
local KERNEL_MODULES_PATH="/lib/modules"
|
||||
for M in ${KERNEL_MODULES}; do
|
||||
if [ -f ${KERNEL_MODULES_PATH}/vpn/${M}.ko ]; then
|
||||
/sbin/insmod ${KERNEL_MODULES_PATH}/vpn/${M}.ko
|
||||
continue
|
||||
fi
|
||||
if [ -f ${KERNEL_MODULES_PATH}/qvpn/${M}.ko ]; then
|
||||
/sbin/insmod ${KERNEL_MODULES_PATH}/qvpn/${M}.ko
|
||||
continue
|
||||
fi
|
||||
if [ -f ${KERNEL_MODULES_PATH}/misc/${M}.ko ]; then
|
||||
/sbin/insmod ${KERNEL_MODULES_PATH}/misc/${M}.ko
|
||||
continue
|
||||
fi
|
||||
if [ -f ${KERNEL_MODULES_PATH}/others/${M}.ko ]; then
|
||||
/sbin/insmod ${KERNEL_MODULES_PATH}/others/${M}.ko
|
||||
continue
|
||||
fi
|
||||
if [ -f ${KERNEL_MODULES_PATH}/${KERNEL_VERSION}/${M}.ko ]; then
|
||||
/sbin/insmod ${KERNEL_MODULES_PATH}/${KERNEL_VERSION}/${M}.ko
|
||||
continue
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
create_tun(){
|
||||
if ( [ ! -c /dev/net/tun ] ); then
|
||||
if ( [ ! -d /dev/net ] ); then
|
||||
mkdir -m 755 /dev/net
|
||||
fi
|
||||
mknod /dev/net/tun c 10 200
|
||||
chmod 0755 /dev/net/tun
|
||||
fi
|
||||
|
||||
# Load the tun module if not already loaded
|
||||
if ( !(lsmod | grep -q "^tun\s") ); then
|
||||
insmod /lib/modules/tun.ko
|
||||
fi
|
||||
}
|
||||
|
||||
start_service ()
|
||||
{
|
||||
exec 2>>/tmp/mesh.log
|
||||
set -x
|
||||
|
||||
#enable ipv6
|
||||
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
||||
sysctl -w net.ipv6.conf.default.disable_ipv6=0
|
||||
|
||||
# Create the necessary file structure for /dev/net/tun
|
||||
create_tun
|
||||
load_kernel_modules
|
||||
|
||||
#. /etc/init.d/vpn_common.sh && load_kernel_modules
|
||||
|
||||
if [ ! -f '/etc/config/apache/extra/apache-mesh.conf' ] ; then
|
||||
ln -sf $QPKG_DIR/apache-mesh.conf /etc/config/apache/extra/
|
||||
apache_reload=1
|
||||
fi
|
||||
|
||||
if ! grep '/etc/config/apache/extra/apache-mesh.conf' /etc/config/apache/apache.conf ; then
|
||||
echo 'Include /etc/config/apache/extra/apache-mesh.conf' >> /etc/config/apache/apache.conf
|
||||
apache_reload=1
|
||||
fi
|
||||
|
||||
if [ -n "$apache_reload" ] ; then
|
||||
/usr/local/apache/bin/apachectl -k graceful
|
||||
fi
|
||||
|
||||
# Launch the mesh in the background.
|
||||
${QPKG_DIR}/bin/mesh -useconffile "$CONF" \
|
||||
-httpaddress "http://127.0.0.1:19019" \
|
||||
-wwwroot "$QPKG_DIR/www" \
|
||||
-logto "$QPKG_DIR/var/log/mesh.log" &
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Starting $QPKG_NAME failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
stop_service ()
|
||||
{
|
||||
# Kill mesh
|
||||
pid=`pidof -s mesh`
|
||||
if [ -z "$pid" ]; then
|
||||
echo "mesh was not running"
|
||||
exit 0
|
||||
fi
|
||||
kill "$pid"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start_service
|
||||
;;
|
||||
|
||||
stop)
|
||||
stop_service
|
||||
;;
|
||||
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
14
contrib/ui/nas-synology-dsm6.0/package/dsm.mesh.conf
Normal file
14
contrib/ui/nas-synology-dsm6.0/package/dsm.mesh.conf
Normal file
|
@ -0,0 +1,14 @@
|
|||
location = /mesh {
|
||||
return 301 /mesh/;
|
||||
}
|
||||
|
||||
location ~ ^/mesh/ {
|
||||
rewrite ^/mesh/(.*) /$1 break;
|
||||
proxy_pass http://127.0.0.1:19019;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-For-Addr $server_addr;
|
||||
proxy_set_header X-Forwarded-For-Port $server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
}
|
5
contrib/ui/nas-synology-dsm6.0/package/mesh.sc
Normal file
5
contrib/ui/nas-synology-dsm6.0/package/mesh.sc
Normal file
|
@ -0,0 +1,5 @@
|
|||
[mesh]
|
||||
title="HTTP"
|
||||
desc="RiV Mesh Web interface"
|
||||
port_forward="no"
|
||||
dst.ports="19019/tcp"
|
11
contrib/ui/nas-synology-dsm6.0/package/ui/config
Normal file
11
contrib/ui/nas-synology-dsm6.0/package/ui/config
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
".url": {
|
||||
"org.mesh": {
|
||||
"type": "url",
|
||||
"title": "RiV Mesh",
|
||||
"desc": "ipv6 mesh network",
|
||||
"icon": "mesh-{0}.png",
|
||||
"url": "/webman/3rdparty/mesh/login.html"
|
||||
}
|
||||
}
|
||||
}
|
18
contrib/ui/nas-synology-dsm6.0/package/ui/login.html
Normal file
18
contrib/ui/nas-synology-dsm6.0/package/ui/login.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="/scripts/ext-3/adapter/ext/ext-base.js?v=1401997094"></script>
|
||||
<script type="text/javascript" src="/scripts/ext-3/ext-all.js?v=1401997094"></script>
|
||||
<script type="text/javascript" src="/webman/dsmtoken.cgi"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
Ext.onReady(function () {
|
||||
if (Ext.isEmpty(SYNO.SDS.Session)) {
|
||||
window.location.assign("/webman");
|
||||
} else {
|
||||
window.location.assign(Ext.urlAppend(window.location.origin + "/mesh/"));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
echo vendor=Synology
|
||||
echo vendorOperatingSystemName=DSM
|
||||
. /etc.defaults/VERSION
|
||||
echo firmwareVersion="${productversion}-${buildnumber}"
|
||||
echo $(cat /etc/avahi/services/dsminfo.service | grep model | sed -e 's/<[^>]*>//g;s/^ *//')
|
||||
echo $(cat /etc/avahi/services/dsminfo.service | grep serial | sed -e 's/<[^>]*>//g;s/^ *//')
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh
|
||||
export CONTENT_LENGTH=$HTTP_CONTENT_LENGTH
|
||||
export CONTENT_TYPE=$HTTP_CONTENT_TYPE
|
||||
|
||||
IFS=';'
|
||||
for x in $HTTP_COOKIE
|
||||
do
|
||||
case $x in
|
||||
*EdSynoToken*)
|
||||
eval $x
|
||||
;;
|
||||
esac
|
||||
done
|
||||
[ -z $QUERY_STRING ] && export QUERY_STRING=SynoToken=$EdSynoToken || export QUERY_STRING="$QUERY_STRING&SynoToken=$EdSynoToken"
|
||||
|
||||
[ ! -z $HTTP_X_REAL_IP ] && export REMOTE_ADDR=$HTTP_X_REAL_IP
|
||||
[ ! -z $HTTP_X_FORWARDED_FOR_ADDR ] && export SERVER_ADDR=$HTTP_X_FORWARDED_FOR_ADDR
|
||||
[ ! -z $HTTP_X_FORWARDED_FOR_PORT ] && export SERVER_PORT=$HTTP_X_FORWARDED_FOR_PORT
|
||||
|
||||
#exit with zero status on auth success and 1 on error
|
||||
[ ! -z $(/usr/syno/synoman/webman/modules/authenticate.cgi) ]
|
||||
exit $?
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
log_exit(){
|
||||
echo $2
|
||||
exit $1
|
||||
}
|
||||
|
||||
rm "$ED_APP_ROOT/bin/mesh
|
||||
rm -rf "$ED_APP_ROOT/www"
|
||||
rm -rf "$ED_APP_ROOT/ui"
|
Binary file not shown.
After Width: | Height: | Size: 5 KiB |
|
@ -0,0 +1,81 @@
|
|||
var ed = {
|
||||
partnerId: 1126,
|
||||
brand: 'RiV Mesh',
|
||||
applicationName: 'RiV Mesh Synology DSM App',
|
||||
nasOSName: 'Synology DSM',
|
||||
nasVisitEDWebsiteLogin: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteSignup: "https://github.com/RiV-chain/RiV-mesh",
|
||||
nasVisitEDWebsiteLoggedin: "https://github.com/RiV-chain/RiV-mesh",
|
||||
getCookie: function (name) {
|
||||
var matches = document.cookie.match(new RegExp(
|
||||
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
|
||||
));
|
||||
return matches ? decodeURIComponent(matches[1]) : undefined;
|
||||
},
|
||||
setCookie: function (key, value, expires) {
|
||||
if(expires) {
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (30 * 60 * 1000));
|
||||
expires = "; expires=" + d.toUTCString();
|
||||
} else {
|
||||
expires = "";
|
||||
}
|
||||
document.cookie = key + "=" + value + expires + "; path=/";
|
||||
},
|
||||
getNasAuthUrl: function () {
|
||||
ed.setCookie('EdSynoToken', "");
|
||||
var url = ed.getCookie('origin');
|
||||
if (url === undefined) {
|
||||
url = window.location.protocol + "//" + window.location.hostname + ":" + 5000;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
};
|
||||
$(function () {
|
||||
function params(obj) {
|
||||
if (typeof obj === 'string') {
|
||||
if (obj[0] === '?') {
|
||||
obj = obj.substring(1);
|
||||
}
|
||||
var result = {};
|
||||
obj = obj.split("&");
|
||||
obj.forEach(function (pair) {
|
||||
pair = pair.split("=");
|
||||
var key = decodeURIComponent(pair[0]);
|
||||
var value = decodeURIComponent(pair[1]);
|
||||
// If first entry with this name
|
||||
if (typeof result[key] === "undefined") {
|
||||
result[key] = value;
|
||||
// If second entry with this name
|
||||
} else if (typeof result[key] === "string") {
|
||||
result[key] = [result[key], value];
|
||||
// If third or later entry with this name
|
||||
} else {
|
||||
result[key].push(value);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} else {
|
||||
return Object.keys(obj).map(function (key) {
|
||||
return encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]);
|
||||
}).join('&');
|
||||
}
|
||||
};
|
||||
//Hide URL parameters
|
||||
var query = params(window.location.search.substring(1));
|
||||
var refresh = false;
|
||||
for (var k in query) {
|
||||
if (k === 'SynoToken') {
|
||||
ed.setCookie('EdSynoToken', query[k]);
|
||||
refresh = true;
|
||||
delete query[k];
|
||||
} else if (k === 'origin') {
|
||||
ed.setCookie('origin', query[k]);
|
||||
refresh = true;
|
||||
delete query[k];
|
||||
}
|
||||
}
|
||||
query = $.param(query);
|
||||
if (refresh)
|
||||
window.location.replace(window.location.origin + window.location.pathname + window.location.hash + ((query === "") ? "" : ("?" + query)));
|
||||
});
|
5
contrib/ui/nas-synology-dsm6.0/spk/conf/resource
Normal file
5
contrib/ui/nas-synology-dsm6.0/spk/conf/resource
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"port-config": {
|
||||
"protocol-file": "mesh.sc"
|
||||
}
|
||||
}
|
17
contrib/ui/nas-synology-dsm6.0/spk/scripts/postinst
Normal file
17
contrib/ui/nas-synology-dsm6.0/spk/scripts/postinst
Normal file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
DEBUG=true
|
||||
SH="$(readlink /proc/$$/exe)"
|
||||
if $DEBUG ; then
|
||||
echo "" > /tmp/mesh.log
|
||||
exec 2>>/tmp/mesh.log
|
||||
SH="$SH -x"
|
||||
set -x
|
||||
fi
|
||||
|
||||
BASE="/var/packages/mesh/target"
|
||||
LOG_FILE="$BASE/var/log/mesh.log"
|
||||
|
||||
ln -sf $LOG_FILE $BASE/www/log
|
||||
ln -sf $BASE/dsm.mesh.conf /etc/nginx/conf.d/dsm.mesh.conf
|
||||
nginx -s reload
|
||||
exit 0
|
8
contrib/ui/nas-synology-dsm6.0/spk/scripts/postuninst
Normal file
8
contrib/ui/nas-synology-dsm6.0/spk/scripts/postuninst
Normal file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
rm -f /var/run/mesh.pid
|
||||
LOG_SYMLINK=/var/log/mesh.log
|
||||
[ -L $LOG_SYMLINK ] && rm -f $LOG_SYMLINK
|
||||
rm -f /etc/nginx/conf.d/dsm.mesh.conf
|
||||
|
||||
exit 0
|
3
contrib/ui/nas-synology-dsm6.0/spk/scripts/postupgrade
Normal file
3
contrib/ui/nas-synology-dsm6.0/spk/scripts/postupgrade
Normal file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
exit 0
|
3
contrib/ui/nas-synology-dsm6.0/spk/scripts/preinst
Normal file
3
contrib/ui/nas-synology-dsm6.0/spk/scripts/preinst
Normal file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
exit 0
|
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